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

source code of lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp