1 //===-- OptionGroupPythonClassWithDict.cpp --------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
10
11 #include "lldb/Host/OptionParser.h"
12
13 using namespace lldb;
14 using namespace lldb_private;
15
OptionGroupPythonClassWithDict(const char * class_use,bool is_class,int class_option,int key_option,int value_option)16 OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict
17 (const char *class_use,
18 bool is_class,
19 int class_option,
20 int key_option,
21 int value_option) : OptionGroup(), m_is_class(is_class) {
22 m_key_usage_text.assign("The key for a key/value pair passed to the "
23 "implementation of a ");
24 m_key_usage_text.append(class_use);
25 m_key_usage_text.append(". Pairs can be specified more than once.");
26
27 m_value_usage_text.assign("The value for the previous key in the pair passed "
28 "to the implementation of a ");
29 m_value_usage_text.append(class_use);
30 m_value_usage_text.append(". Pairs can be specified more than once.");
31
32 m_class_usage_text.assign("The name of the ");
33 m_class_usage_text.append(m_is_class ? "class" : "function");
34 m_class_usage_text.append(" that will manage a ");
35 m_class_usage_text.append(class_use);
36 m_class_usage_text.append(".");
37
38 m_option_definition[0].usage_mask = LLDB_OPT_SET_1;
39 m_option_definition[0].required = true;
40 m_option_definition[0].long_option = "script-class";
41 m_option_definition[0].short_option = class_option;
42 m_option_definition[0].validator = nullptr;
43 m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument;
44 m_option_definition[0].enum_values = {};
45 m_option_definition[0].completion_type = 0;
46 m_option_definition[0].argument_type = eArgTypePythonClass;
47 m_option_definition[0].usage_text = m_class_usage_text.data();
48
49 m_option_definition[1].usage_mask = LLDB_OPT_SET_2;
50 m_option_definition[1].required = false;
51 m_option_definition[1].long_option = "structured-data-key";
52 m_option_definition[1].short_option = key_option;
53 m_option_definition[1].validator = nullptr;
54 m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument;
55 m_option_definition[1].enum_values = {};
56 m_option_definition[1].completion_type = 0;
57 m_option_definition[1].argument_type = eArgTypeNone;
58 m_option_definition[1].usage_text = m_key_usage_text.data();
59
60 m_option_definition[2].usage_mask = LLDB_OPT_SET_2;
61 m_option_definition[2].required = false;
62 m_option_definition[2].long_option = "structured-data-value";
63 m_option_definition[2].short_option = value_option;
64 m_option_definition[2].validator = nullptr;
65 m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument;
66 m_option_definition[2].enum_values = {};
67 m_option_definition[2].completion_type = 0;
68 m_option_definition[2].argument_type = eArgTypeNone;
69 m_option_definition[2].usage_text = m_value_usage_text.data();
70
71 m_option_definition[3].usage_mask = LLDB_OPT_SET_3;
72 m_option_definition[3].required = true;
73 m_option_definition[3].long_option = "python-function";
74 m_option_definition[3].short_option = class_option;
75 m_option_definition[3].validator = nullptr;
76 m_option_definition[3].option_has_arg = OptionParser::eRequiredArgument;
77 m_option_definition[3].enum_values = {};
78 m_option_definition[3].completion_type = 0;
79 m_option_definition[3].argument_type = eArgTypePythonFunction;
80 m_option_definition[3].usage_text = m_class_usage_text.data();
81
82 }
83
~OptionGroupPythonClassWithDict()84 OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {}
85
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)86 Status OptionGroupPythonClassWithDict::SetOptionValue(
87 uint32_t option_idx,
88 llvm::StringRef option_arg,
89 ExecutionContext *execution_context) {
90 Status error;
91 switch (option_idx) {
92 case 0:
93 case 3: {
94 m_name.assign(std::string(option_arg));
95 } break;
96 case 1: {
97 if (!m_dict_sp)
98 m_dict_sp = std::make_shared<StructuredData::Dictionary>();
99 if (m_current_key.empty())
100 m_current_key.assign(std::string(option_arg));
101 else
102 error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
103 m_current_key.c_str());
104
105 } break;
106 case 2: {
107 if (!m_dict_sp)
108 m_dict_sp = std::make_shared<StructuredData::Dictionary>();
109 if (!m_current_key.empty()) {
110 m_dict_sp->AddStringItem(m_current_key, option_arg);
111 m_current_key.clear();
112 }
113 else
114 error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
115 option_arg.str().c_str());
116 } break;
117 default:
118 llvm_unreachable("Unimplemented option");
119 }
120 return error;
121 }
122
OptionParsingStarting(ExecutionContext * execution_context)123 void OptionGroupPythonClassWithDict::OptionParsingStarting(
124 ExecutionContext *execution_context) {
125 m_current_key.erase();
126 // Leave the dictionary shared pointer unset. That way you can tell that
127 // the user didn't pass any -k -v pairs. We want to be able to warn if these
128 // were passed when the function they passed won't use them.
129 m_dict_sp.reset();
130 m_name.clear();
131 }
132
OptionParsingFinished(ExecutionContext * execution_context)133 Status OptionGroupPythonClassWithDict::OptionParsingFinished(
134 ExecutionContext *execution_context) {
135 Status error;
136 // If we get here and there's contents in the m_current_key, somebody must
137 // have provided a key but no value.
138 if (!m_current_key.empty())
139 error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
140 m_current_key.c_str());
141 return error;
142 }
143
144