xref: /src/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1cfca06d7SDimitry Andric //===-- OptionGroupPythonClassWithDict.cpp --------------------------------===//
2ead24645SDimitry Andric //
3ead24645SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ead24645SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5ead24645SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ead24645SDimitry Andric //
7ead24645SDimitry Andric //===----------------------------------------------------------------------===//
8ead24645SDimitry Andric 
9ead24645SDimitry Andric #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
10ead24645SDimitry Andric 
11ead24645SDimitry Andric #include "lldb/Host/OptionParser.h"
12ead24645SDimitry Andric 
13ead24645SDimitry Andric using namespace lldb;
14ead24645SDimitry Andric using namespace lldb_private;
15ead24645SDimitry Andric 
OptionGroupPythonClassWithDict(const char * class_use,bool is_class,int class_option,int key_option,int value_option,uint16_t required_options)16344a3780SDimitry Andric OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict(
17344a3780SDimitry Andric     const char *class_use, bool is_class, int class_option, int key_option,
18344a3780SDimitry Andric     int value_option, uint16_t required_options)
19344a3780SDimitry Andric     : m_is_class(is_class), m_required_options(required_options) {
20706b4fc4SDimitry Andric   m_key_usage_text.assign("The key for a key/value pair passed to the "
21706b4fc4SDimitry Andric                           "implementation of a ");
22ead24645SDimitry Andric   m_key_usage_text.append(class_use);
23ead24645SDimitry Andric   m_key_usage_text.append(".  Pairs can be specified more than once.");
24ead24645SDimitry Andric 
25706b4fc4SDimitry Andric   m_value_usage_text.assign("The value for the previous key in the pair passed "
26706b4fc4SDimitry Andric                             "to the implementation of a ");
27ead24645SDimitry Andric   m_value_usage_text.append(class_use);
28ead24645SDimitry Andric   m_value_usage_text.append(".  Pairs can be specified more than once.");
29ead24645SDimitry Andric 
30706b4fc4SDimitry Andric   m_class_usage_text.assign("The name of the ");
31706b4fc4SDimitry Andric   m_class_usage_text.append(m_is_class ? "class" : "function");
32706b4fc4SDimitry Andric   m_class_usage_text.append(" that will manage a ");
33ead24645SDimitry Andric   m_class_usage_text.append(class_use);
34ead24645SDimitry Andric   m_class_usage_text.append(".");
35ead24645SDimitry Andric 
36ead24645SDimitry Andric   m_option_definition[0].usage_mask = LLDB_OPT_SET_1;
37344a3780SDimitry Andric   m_option_definition[0].required = m_required_options.Test(eScriptClass);
38706b4fc4SDimitry Andric   m_option_definition[0].long_option = "script-class";
39ead24645SDimitry Andric   m_option_definition[0].short_option = class_option;
40ead24645SDimitry Andric   m_option_definition[0].validator = nullptr;
41ead24645SDimitry Andric   m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument;
42ead24645SDimitry Andric   m_option_definition[0].enum_values = {};
43ead24645SDimitry Andric   m_option_definition[0].completion_type = 0;
44ead24645SDimitry Andric   m_option_definition[0].argument_type = eArgTypePythonClass;
45ead24645SDimitry Andric   m_option_definition[0].usage_text = m_class_usage_text.data();
46ead24645SDimitry Andric 
47706b4fc4SDimitry Andric   m_option_definition[1].usage_mask = LLDB_OPT_SET_2;
48344a3780SDimitry Andric   m_option_definition[1].required = m_required_options.Test(eDictKey);
49706b4fc4SDimitry Andric   m_option_definition[1].long_option = "structured-data-key";
50ead24645SDimitry Andric   m_option_definition[1].short_option = key_option;
51ead24645SDimitry Andric   m_option_definition[1].validator = nullptr;
52ead24645SDimitry Andric   m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument;
53ead24645SDimitry Andric   m_option_definition[1].enum_values = {};
54ead24645SDimitry Andric   m_option_definition[1].completion_type = 0;
55ead24645SDimitry Andric   m_option_definition[1].argument_type = eArgTypeNone;
56ead24645SDimitry Andric   m_option_definition[1].usage_text = m_key_usage_text.data();
57ead24645SDimitry Andric 
58706b4fc4SDimitry Andric   m_option_definition[2].usage_mask = LLDB_OPT_SET_2;
59344a3780SDimitry Andric   m_option_definition[2].required = m_required_options.Test(eDictValue);
60706b4fc4SDimitry Andric   m_option_definition[2].long_option = "structured-data-value";
61ead24645SDimitry Andric   m_option_definition[2].short_option = value_option;
62ead24645SDimitry Andric   m_option_definition[2].validator = nullptr;
63ead24645SDimitry Andric   m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument;
64ead24645SDimitry Andric   m_option_definition[2].enum_values = {};
65ead24645SDimitry Andric   m_option_definition[2].completion_type = 0;
66ead24645SDimitry Andric   m_option_definition[2].argument_type = eArgTypeNone;
67ead24645SDimitry Andric   m_option_definition[2].usage_text = m_value_usage_text.data();
68706b4fc4SDimitry Andric 
69706b4fc4SDimitry Andric   m_option_definition[3].usage_mask = LLDB_OPT_SET_3;
70344a3780SDimitry Andric   m_option_definition[3].required = m_required_options.Test(ePythonFunction);
71706b4fc4SDimitry Andric   m_option_definition[3].long_option = "python-function";
72706b4fc4SDimitry Andric   m_option_definition[3].short_option = class_option;
73706b4fc4SDimitry Andric   m_option_definition[3].validator = nullptr;
74706b4fc4SDimitry Andric   m_option_definition[3].option_has_arg = OptionParser::eRequiredArgument;
75706b4fc4SDimitry Andric   m_option_definition[3].enum_values = {};
76706b4fc4SDimitry Andric   m_option_definition[3].completion_type = 0;
77706b4fc4SDimitry Andric   m_option_definition[3].argument_type = eArgTypePythonFunction;
78706b4fc4SDimitry Andric   m_option_definition[3].usage_text = m_class_usage_text.data();
79ead24645SDimitry Andric }
80ead24645SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)81ead24645SDimitry Andric Status OptionGroupPythonClassWithDict::SetOptionValue(
82ead24645SDimitry Andric     uint32_t option_idx,
83ead24645SDimitry Andric     llvm::StringRef option_arg,
84ead24645SDimitry Andric     ExecutionContext *execution_context) {
85ead24645SDimitry Andric   Status error;
86ead24645SDimitry Andric   switch (option_idx) {
87706b4fc4SDimitry Andric   case 0:
88706b4fc4SDimitry Andric   case 3: {
89cfca06d7SDimitry Andric     m_name.assign(std::string(option_arg));
90ead24645SDimitry Andric   } break;
91ead24645SDimitry Andric   case 1: {
92706b4fc4SDimitry Andric       if (!m_dict_sp)
93706b4fc4SDimitry Andric         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
94ead24645SDimitry Andric       if (m_current_key.empty())
95cfca06d7SDimitry Andric         m_current_key.assign(std::string(option_arg));
96ead24645SDimitry Andric       else
97ead24645SDimitry Andric         error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
98ead24645SDimitry Andric                                         m_current_key.c_str());
99ead24645SDimitry Andric 
100ead24645SDimitry Andric   } break;
101ead24645SDimitry Andric   case 2: {
102706b4fc4SDimitry Andric       if (!m_dict_sp)
103706b4fc4SDimitry Andric         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
104ead24645SDimitry Andric       if (!m_current_key.empty()) {
1057fa27ce4SDimitry Andric         if (!option_arg.empty()) {
1067fa27ce4SDimitry Andric           double d = 0;
1077fa27ce4SDimitry Andric           std::string opt = option_arg.lower();
1087fa27ce4SDimitry Andric 
1097fa27ce4SDimitry Andric           if (llvm::to_integer(option_arg, d)) {
1107fa27ce4SDimitry Andric             if (opt[0] == '-')
1117fa27ce4SDimitry Andric               m_dict_sp->AddIntegerItem(m_current_key, static_cast<int64_t>(d));
1127fa27ce4SDimitry Andric             else
1137fa27ce4SDimitry Andric               m_dict_sp->AddIntegerItem(m_current_key,
1147fa27ce4SDimitry Andric                                         static_cast<uint64_t>(d));
1157fa27ce4SDimitry Andric           } else if (llvm::to_float(option_arg, d)) {
1167fa27ce4SDimitry Andric             m_dict_sp->AddFloatItem(m_current_key, d);
1177fa27ce4SDimitry Andric           } else if (opt == "true" || opt == "false") {
1187fa27ce4SDimitry Andric             m_dict_sp->AddBooleanItem(m_current_key, opt == "true");
1197fa27ce4SDimitry Andric           } else {
120ead24645SDimitry Andric             m_dict_sp->AddStringItem(m_current_key, option_arg);
1217fa27ce4SDimitry Andric           }
1227fa27ce4SDimitry Andric         }
1237fa27ce4SDimitry Andric 
124ead24645SDimitry Andric         m_current_key.clear();
125ead24645SDimitry Andric       }
126ead24645SDimitry Andric       else
127ead24645SDimitry Andric         error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
128ead24645SDimitry Andric                                        option_arg.str().c_str());
129ead24645SDimitry Andric   } break;
130ead24645SDimitry Andric   default:
131ead24645SDimitry Andric     llvm_unreachable("Unimplemented option");
132ead24645SDimitry Andric   }
133ead24645SDimitry Andric   return error;
134ead24645SDimitry Andric }
135ead24645SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)136ead24645SDimitry Andric void OptionGroupPythonClassWithDict::OptionParsingStarting(
137ead24645SDimitry Andric   ExecutionContext *execution_context) {
138ead24645SDimitry Andric   m_current_key.erase();
139706b4fc4SDimitry Andric   // Leave the dictionary shared pointer unset.  That way you can tell that
140706b4fc4SDimitry Andric   // the user didn't pass any -k -v pairs.  We want to be able to warn if these
141706b4fc4SDimitry Andric   // were passed when the function they passed won't use them.
142706b4fc4SDimitry Andric   m_dict_sp.reset();
143706b4fc4SDimitry Andric   m_name.clear();
144ead24645SDimitry Andric }
145ead24645SDimitry Andric 
OptionParsingFinished(ExecutionContext * execution_context)146ead24645SDimitry Andric Status OptionGroupPythonClassWithDict::OptionParsingFinished(
147ead24645SDimitry Andric   ExecutionContext *execution_context) {
148ead24645SDimitry Andric   Status error;
149ead24645SDimitry Andric   // If we get here and there's contents in the m_current_key, somebody must
150ead24645SDimitry Andric   // have provided a key but no value.
151ead24645SDimitry Andric   if (!m_current_key.empty())
152ead24645SDimitry Andric       error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
153ead24645SDimitry Andric                                      m_current_key.c_str());
154ead24645SDimitry Andric   return error;
155ead24645SDimitry Andric }
156ead24645SDimitry Andric 
157