15ffd83dbSDimitry Andric //===-- OptionGroupPythonClassWithDict.cpp --------------------------------===//
29dba64beSDimitry Andric //
39dba64beSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49dba64beSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
59dba64beSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69dba64beSDimitry Andric //
79dba64beSDimitry Andric //===----------------------------------------------------------------------===//
89dba64beSDimitry Andric 
99dba64beSDimitry Andric #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
109dba64beSDimitry Andric 
119dba64beSDimitry Andric #include "lldb/Host/OptionParser.h"
129dba64beSDimitry Andric 
139dba64beSDimitry Andric using namespace lldb;
149dba64beSDimitry Andric using namespace lldb_private;
159dba64beSDimitry Andric 
169dba64beSDimitry Andric OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict
179dba64beSDimitry Andric     (const char *class_use,
18480093f4SDimitry Andric      bool is_class,
199dba64beSDimitry Andric      int class_option,
209dba64beSDimitry Andric      int key_option,
21480093f4SDimitry Andric      int value_option) : OptionGroup(), m_is_class(is_class) {
22480093f4SDimitry Andric   m_key_usage_text.assign("The key for a key/value pair passed to the "
23480093f4SDimitry Andric                           "implementation of a ");
249dba64beSDimitry Andric   m_key_usage_text.append(class_use);
259dba64beSDimitry Andric   m_key_usage_text.append(".  Pairs can be specified more than once.");
269dba64beSDimitry Andric 
27480093f4SDimitry Andric   m_value_usage_text.assign("The value for the previous key in the pair passed "
28480093f4SDimitry Andric                             "to the implementation of a ");
299dba64beSDimitry Andric   m_value_usage_text.append(class_use);
309dba64beSDimitry Andric   m_value_usage_text.append(".  Pairs can be specified more than once.");
319dba64beSDimitry Andric 
32480093f4SDimitry Andric   m_class_usage_text.assign("The name of the ");
33480093f4SDimitry Andric   m_class_usage_text.append(m_is_class ? "class" : "function");
34480093f4SDimitry Andric   m_class_usage_text.append(" that will manage a ");
359dba64beSDimitry Andric   m_class_usage_text.append(class_use);
369dba64beSDimitry Andric   m_class_usage_text.append(".");
379dba64beSDimitry Andric 
389dba64beSDimitry Andric   m_option_definition[0].usage_mask = LLDB_OPT_SET_1;
39480093f4SDimitry Andric   m_option_definition[0].required = true;
40480093f4SDimitry Andric   m_option_definition[0].long_option = "script-class";
419dba64beSDimitry Andric   m_option_definition[0].short_option = class_option;
429dba64beSDimitry Andric   m_option_definition[0].validator = nullptr;
439dba64beSDimitry Andric   m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument;
449dba64beSDimitry Andric   m_option_definition[0].enum_values = {};
459dba64beSDimitry Andric   m_option_definition[0].completion_type = 0;
469dba64beSDimitry Andric   m_option_definition[0].argument_type = eArgTypePythonClass;
479dba64beSDimitry Andric   m_option_definition[0].usage_text = m_class_usage_text.data();
489dba64beSDimitry Andric 
49480093f4SDimitry Andric   m_option_definition[1].usage_mask = LLDB_OPT_SET_2;
50480093f4SDimitry Andric   m_option_definition[1].required = false;
51480093f4SDimitry Andric   m_option_definition[1].long_option = "structured-data-key";
529dba64beSDimitry Andric   m_option_definition[1].short_option = key_option;
539dba64beSDimitry Andric   m_option_definition[1].validator = nullptr;
549dba64beSDimitry Andric   m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument;
559dba64beSDimitry Andric   m_option_definition[1].enum_values = {};
569dba64beSDimitry Andric   m_option_definition[1].completion_type = 0;
579dba64beSDimitry Andric   m_option_definition[1].argument_type = eArgTypeNone;
589dba64beSDimitry Andric   m_option_definition[1].usage_text = m_key_usage_text.data();
599dba64beSDimitry Andric 
60480093f4SDimitry Andric   m_option_definition[2].usage_mask = LLDB_OPT_SET_2;
61480093f4SDimitry Andric   m_option_definition[2].required = false;
62480093f4SDimitry Andric   m_option_definition[2].long_option = "structured-data-value";
639dba64beSDimitry Andric   m_option_definition[2].short_option = value_option;
649dba64beSDimitry Andric   m_option_definition[2].validator = nullptr;
659dba64beSDimitry Andric   m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument;
669dba64beSDimitry Andric   m_option_definition[2].enum_values = {};
679dba64beSDimitry Andric   m_option_definition[2].completion_type = 0;
689dba64beSDimitry Andric   m_option_definition[2].argument_type = eArgTypeNone;
699dba64beSDimitry Andric   m_option_definition[2].usage_text = m_value_usage_text.data();
70480093f4SDimitry Andric 
71480093f4SDimitry Andric   m_option_definition[3].usage_mask = LLDB_OPT_SET_3;
72480093f4SDimitry Andric   m_option_definition[3].required = true;
73480093f4SDimitry Andric   m_option_definition[3].long_option = "python-function";
74480093f4SDimitry Andric   m_option_definition[3].short_option = class_option;
75480093f4SDimitry Andric   m_option_definition[3].validator = nullptr;
76480093f4SDimitry Andric   m_option_definition[3].option_has_arg = OptionParser::eRequiredArgument;
77480093f4SDimitry Andric   m_option_definition[3].enum_values = {};
78480093f4SDimitry Andric   m_option_definition[3].completion_type = 0;
79480093f4SDimitry Andric   m_option_definition[3].argument_type = eArgTypePythonFunction;
80480093f4SDimitry Andric   m_option_definition[3].usage_text = m_class_usage_text.data();
81480093f4SDimitry Andric 
829dba64beSDimitry Andric }
839dba64beSDimitry Andric 
849dba64beSDimitry Andric OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {}
859dba64beSDimitry Andric 
869dba64beSDimitry Andric Status OptionGroupPythonClassWithDict::SetOptionValue(
879dba64beSDimitry Andric     uint32_t option_idx,
889dba64beSDimitry Andric     llvm::StringRef option_arg,
899dba64beSDimitry Andric     ExecutionContext *execution_context) {
909dba64beSDimitry Andric   Status error;
919dba64beSDimitry Andric   switch (option_idx) {
92480093f4SDimitry Andric   case 0:
93480093f4SDimitry Andric   case 3: {
945ffd83dbSDimitry Andric     m_name.assign(std::string(option_arg));
959dba64beSDimitry Andric   } break;
969dba64beSDimitry Andric   case 1: {
97480093f4SDimitry Andric       if (!m_dict_sp)
98480093f4SDimitry Andric         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
999dba64beSDimitry Andric       if (m_current_key.empty())
1005ffd83dbSDimitry Andric         m_current_key.assign(std::string(option_arg));
1019dba64beSDimitry Andric       else
1029dba64beSDimitry Andric         error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
1039dba64beSDimitry Andric                                         m_current_key.c_str());
1049dba64beSDimitry Andric 
1059dba64beSDimitry Andric   } break;
1069dba64beSDimitry Andric   case 2: {
107480093f4SDimitry Andric       if (!m_dict_sp)
108480093f4SDimitry Andric         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
1099dba64beSDimitry Andric       if (!m_current_key.empty()) {
1109dba64beSDimitry Andric           m_dict_sp->AddStringItem(m_current_key, option_arg);
1119dba64beSDimitry Andric           m_current_key.clear();
1129dba64beSDimitry Andric       }
1139dba64beSDimitry Andric       else
1149dba64beSDimitry Andric         error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
1159dba64beSDimitry Andric                                        option_arg.str().c_str());
1169dba64beSDimitry Andric   } break;
1179dba64beSDimitry Andric   default:
1189dba64beSDimitry Andric     llvm_unreachable("Unimplemented option");
1199dba64beSDimitry Andric   }
1209dba64beSDimitry Andric   return error;
1219dba64beSDimitry Andric }
1229dba64beSDimitry Andric 
1239dba64beSDimitry Andric void OptionGroupPythonClassWithDict::OptionParsingStarting(
1249dba64beSDimitry Andric   ExecutionContext *execution_context) {
1259dba64beSDimitry Andric   m_current_key.erase();
126480093f4SDimitry Andric   // Leave the dictionary shared pointer unset.  That way you can tell that
127480093f4SDimitry Andric   // the user didn't pass any -k -v pairs.  We want to be able to warn if these
128480093f4SDimitry Andric   // were passed when the function they passed won't use them.
129480093f4SDimitry Andric   m_dict_sp.reset();
130480093f4SDimitry Andric   m_name.clear();
1319dba64beSDimitry Andric }
1329dba64beSDimitry Andric 
1339dba64beSDimitry Andric Status OptionGroupPythonClassWithDict::OptionParsingFinished(
1349dba64beSDimitry Andric   ExecutionContext *execution_context) {
1359dba64beSDimitry Andric   Status error;
1369dba64beSDimitry Andric   // If we get here and there's contents in the m_current_key, somebody must
1379dba64beSDimitry Andric   // have provided a key but no value.
1389dba64beSDimitry Andric   if (!m_current_key.empty())
1399dba64beSDimitry Andric       error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
1409dba64beSDimitry Andric                                      m_current_key.c_str());
1419dba64beSDimitry Andric   return error;
1429dba64beSDimitry Andric }
1439dba64beSDimitry Andric 
144