180814287SRaphael Isemann //===-- OptionGroupPythonClassWithDict.cpp --------------------------------===//
2943a2481SJim Ingham //
3943a2481SJim Ingham // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4943a2481SJim Ingham // See https://llvm.org/LICENSE.txt for license information.
5943a2481SJim Ingham // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6943a2481SJim Ingham //
7943a2481SJim Ingham //===----------------------------------------------------------------------===//
8943a2481SJim Ingham 
9943a2481SJim Ingham #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
10943a2481SJim Ingham 
11943a2481SJim Ingham #include "lldb/Host/OptionParser.h"
12943a2481SJim Ingham 
13943a2481SJim Ingham using namespace lldb;
14943a2481SJim Ingham using namespace lldb_private;
15943a2481SJim Ingham 
OptionGroupPythonClassWithDict(const char * class_use,bool is_class,int class_option,int key_option,int value_option,uint16_t required_options)16*c16fef19SMed Ismail Bennani OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict(
17*c16fef19SMed Ismail Bennani     const char *class_use, bool is_class, int class_option, int key_option,
18*c16fef19SMed Ismail Bennani     int value_option, uint16_t required_options)
19*c16fef19SMed Ismail Bennani     : m_is_class(is_class), m_required_options(required_options) {
20738af7a6SJim Ingham   m_key_usage_text.assign("The key for a key/value pair passed to the "
21738af7a6SJim Ingham                           "implementation of a ");
22943a2481SJim Ingham   m_key_usage_text.append(class_use);
23943a2481SJim Ingham   m_key_usage_text.append(".  Pairs can be specified more than once.");
24943a2481SJim Ingham 
25738af7a6SJim Ingham   m_value_usage_text.assign("The value for the previous key in the pair passed "
26738af7a6SJim Ingham                             "to the implementation of a ");
27943a2481SJim Ingham   m_value_usage_text.append(class_use);
28943a2481SJim Ingham   m_value_usage_text.append(".  Pairs can be specified more than once.");
29943a2481SJim Ingham 
30738af7a6SJim Ingham   m_class_usage_text.assign("The name of the ");
31738af7a6SJim Ingham   m_class_usage_text.append(m_is_class ? "class" : "function");
32738af7a6SJim Ingham   m_class_usage_text.append(" that will manage a ");
33943a2481SJim Ingham   m_class_usage_text.append(class_use);
34943a2481SJim Ingham   m_class_usage_text.append(".");
35943a2481SJim Ingham 
36943a2481SJim Ingham   m_option_definition[0].usage_mask = LLDB_OPT_SET_1;
37*c16fef19SMed Ismail Bennani   m_option_definition[0].required = m_required_options.Test(eScriptClass);
38738af7a6SJim Ingham   m_option_definition[0].long_option = "script-class";
39943a2481SJim Ingham   m_option_definition[0].short_option = class_option;
40943a2481SJim Ingham   m_option_definition[0].validator = nullptr;
41943a2481SJim Ingham   m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument;
42943a2481SJim Ingham   m_option_definition[0].enum_values = {};
43943a2481SJim Ingham   m_option_definition[0].completion_type = 0;
44943a2481SJim Ingham   m_option_definition[0].argument_type = eArgTypePythonClass;
45943a2481SJim Ingham   m_option_definition[0].usage_text = m_class_usage_text.data();
46943a2481SJim Ingham 
47738af7a6SJim Ingham   m_option_definition[1].usage_mask = LLDB_OPT_SET_2;
48*c16fef19SMed Ismail Bennani   m_option_definition[1].required = m_required_options.Test(eDictKey);
49738af7a6SJim Ingham   m_option_definition[1].long_option = "structured-data-key";
50943a2481SJim Ingham   m_option_definition[1].short_option = key_option;
51943a2481SJim Ingham   m_option_definition[1].validator = nullptr;
52943a2481SJim Ingham   m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument;
53943a2481SJim Ingham   m_option_definition[1].enum_values = {};
54943a2481SJim Ingham   m_option_definition[1].completion_type = 0;
55943a2481SJim Ingham   m_option_definition[1].argument_type = eArgTypeNone;
56943a2481SJim Ingham   m_option_definition[1].usage_text = m_key_usage_text.data();
57943a2481SJim Ingham 
58738af7a6SJim Ingham   m_option_definition[2].usage_mask = LLDB_OPT_SET_2;
59*c16fef19SMed Ismail Bennani   m_option_definition[2].required = m_required_options.Test(eDictValue);
60738af7a6SJim Ingham   m_option_definition[2].long_option = "structured-data-value";
61943a2481SJim Ingham   m_option_definition[2].short_option = value_option;
62943a2481SJim Ingham   m_option_definition[2].validator = nullptr;
63943a2481SJim Ingham   m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument;
64943a2481SJim Ingham   m_option_definition[2].enum_values = {};
65943a2481SJim Ingham   m_option_definition[2].completion_type = 0;
66943a2481SJim Ingham   m_option_definition[2].argument_type = eArgTypeNone;
67943a2481SJim Ingham   m_option_definition[2].usage_text = m_value_usage_text.data();
68738af7a6SJim Ingham 
69738af7a6SJim Ingham   m_option_definition[3].usage_mask = LLDB_OPT_SET_3;
70*c16fef19SMed Ismail Bennani   m_option_definition[3].required = m_required_options.Test(ePythonFunction);
71738af7a6SJim Ingham   m_option_definition[3].long_option = "python-function";
72738af7a6SJim Ingham   m_option_definition[3].short_option = class_option;
73738af7a6SJim Ingham   m_option_definition[3].validator = nullptr;
74738af7a6SJim Ingham   m_option_definition[3].option_has_arg = OptionParser::eRequiredArgument;
75738af7a6SJim Ingham   m_option_definition[3].enum_values = {};
76738af7a6SJim Ingham   m_option_definition[3].completion_type = 0;
77738af7a6SJim Ingham   m_option_definition[3].argument_type = eArgTypePythonFunction;
78738af7a6SJim Ingham   m_option_definition[3].usage_text = m_class_usage_text.data();
79943a2481SJim Ingham }
80943a2481SJim Ingham 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)81943a2481SJim Ingham Status OptionGroupPythonClassWithDict::SetOptionValue(
82943a2481SJim Ingham     uint32_t option_idx,
83943a2481SJim Ingham     llvm::StringRef option_arg,
84943a2481SJim Ingham     ExecutionContext *execution_context) {
85943a2481SJim Ingham   Status error;
86943a2481SJim Ingham   switch (option_idx) {
87738af7a6SJim Ingham   case 0:
88738af7a6SJim Ingham   case 3: {
89adcd0268SBenjamin Kramer     m_name.assign(std::string(option_arg));
90943a2481SJim Ingham   } break;
91943a2481SJim Ingham   case 1: {
92738af7a6SJim Ingham       if (!m_dict_sp)
93738af7a6SJim Ingham         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
94943a2481SJim Ingham       if (m_current_key.empty())
95adcd0268SBenjamin Kramer         m_current_key.assign(std::string(option_arg));
96943a2481SJim Ingham       else
97943a2481SJim Ingham         error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
98943a2481SJim Ingham                                         m_current_key.c_str());
99943a2481SJim Ingham 
100943a2481SJim Ingham   } break;
101943a2481SJim Ingham   case 2: {
102738af7a6SJim Ingham       if (!m_dict_sp)
103738af7a6SJim Ingham         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
104943a2481SJim Ingham       if (!m_current_key.empty()) {
105943a2481SJim Ingham           m_dict_sp->AddStringItem(m_current_key, option_arg);
106943a2481SJim Ingham           m_current_key.clear();
107943a2481SJim Ingham       }
108943a2481SJim Ingham       else
109943a2481SJim Ingham         error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
110943a2481SJim Ingham                                        option_arg.str().c_str());
111943a2481SJim Ingham   } break;
112943a2481SJim Ingham   default:
113943a2481SJim Ingham     llvm_unreachable("Unimplemented option");
114943a2481SJim Ingham   }
115943a2481SJim Ingham   return error;
116943a2481SJim Ingham }
117943a2481SJim Ingham 
OptionParsingStarting(ExecutionContext * execution_context)118943a2481SJim Ingham void OptionGroupPythonClassWithDict::OptionParsingStarting(
119943a2481SJim Ingham   ExecutionContext *execution_context) {
120943a2481SJim Ingham   m_current_key.erase();
121738af7a6SJim Ingham   // Leave the dictionary shared pointer unset.  That way you can tell that
122738af7a6SJim Ingham   // the user didn't pass any -k -v pairs.  We want to be able to warn if these
123738af7a6SJim Ingham   // were passed when the function they passed won't use them.
124738af7a6SJim Ingham   m_dict_sp.reset();
1253151d7afSJim Ingham   m_name.clear();
126943a2481SJim Ingham }
127943a2481SJim Ingham 
OptionParsingFinished(ExecutionContext * execution_context)128943a2481SJim Ingham Status OptionGroupPythonClassWithDict::OptionParsingFinished(
129943a2481SJim Ingham   ExecutionContext *execution_context) {
130943a2481SJim Ingham   Status error;
131943a2481SJim Ingham   // If we get here and there's contents in the m_current_key, somebody must
132943a2481SJim Ingham   // have provided a key but no value.
133943a2481SJim Ingham   if (!m_current_key.empty())
134943a2481SJim Ingham       error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
135943a2481SJim Ingham                                      m_current_key.c_str());
136943a2481SJim Ingham   return error;
137943a2481SJim Ingham }
138943a2481SJim Ingham 
139