xref: /llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp (revision 8cdcd41e384b4901cd796f7be58c461647e54d18)
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 
16 OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict
17     (const char *class_use,
18      bool is_class,
19      int class_option,
20      int key_option,
21      int value_option) : 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 
84 Status OptionGroupPythonClassWithDict::SetOptionValue(
85     uint32_t option_idx,
86     llvm::StringRef option_arg,
87     ExecutionContext *execution_context) {
88   Status error;
89   switch (option_idx) {
90   case 0:
91   case 3: {
92     m_name.assign(std::string(option_arg));
93   } break;
94   case 1: {
95       if (!m_dict_sp)
96         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
97       if (m_current_key.empty())
98         m_current_key.assign(std::string(option_arg));
99       else
100         error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
101                                         m_current_key.c_str());
102 
103   } break;
104   case 2: {
105       if (!m_dict_sp)
106         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
107       if (!m_current_key.empty()) {
108           m_dict_sp->AddStringItem(m_current_key, option_arg);
109           m_current_key.clear();
110       }
111       else
112         error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
113                                        option_arg.str().c_str());
114   } break;
115   default:
116     llvm_unreachable("Unimplemented option");
117   }
118   return error;
119 }
120 
121 void OptionGroupPythonClassWithDict::OptionParsingStarting(
122   ExecutionContext *execution_context) {
123   m_current_key.erase();
124   // Leave the dictionary shared pointer unset.  That way you can tell that
125   // the user didn't pass any -k -v pairs.  We want to be able to warn if these
126   // were passed when the function they passed won't use them.
127   m_dict_sp.reset();
128   m_name.clear();
129 }
130 
131 Status OptionGroupPythonClassWithDict::OptionParsingFinished(
132   ExecutionContext *execution_context) {
133   Status error;
134   // If we get here and there's contents in the m_current_key, somebody must
135   // have provided a key but no value.
136   if (!m_current_key.empty())
137       error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
138                                      m_current_key.c_str());
139   return error;
140 }
141 
142