1f9d8bbeeSJim Ingham //===-- OptionGroupPythonClassWithDict.cpp ----------------------------------*- C++ -*-===//
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 
16943a2481SJim Ingham OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict
17943a2481SJim Ingham     (const char *class_use,
18738af7a6SJim Ingham      bool is_class,
19943a2481SJim Ingham      int class_option,
20943a2481SJim Ingham      int key_option,
21738af7a6SJim Ingham      int value_option) : OptionGroup(), m_is_class(is_class) {
22738af7a6SJim Ingham   m_key_usage_text.assign("The key for a key/value pair passed to the "
23738af7a6SJim Ingham                           "implementation of a ");
24943a2481SJim Ingham   m_key_usage_text.append(class_use);
25943a2481SJim Ingham   m_key_usage_text.append(".  Pairs can be specified more than once.");
26943a2481SJim Ingham 
27738af7a6SJim Ingham   m_value_usage_text.assign("The value for the previous key in the pair passed "
28738af7a6SJim Ingham                             "to the implementation of a ");
29943a2481SJim Ingham   m_value_usage_text.append(class_use);
30943a2481SJim Ingham   m_value_usage_text.append(".  Pairs can be specified more than once.");
31943a2481SJim Ingham 
32738af7a6SJim Ingham   m_class_usage_text.assign("The name of the ");
33738af7a6SJim Ingham   m_class_usage_text.append(m_is_class ? "class" : "function");
34738af7a6SJim Ingham   m_class_usage_text.append(" that will manage a ");
35943a2481SJim Ingham   m_class_usage_text.append(class_use);
36943a2481SJim Ingham   m_class_usage_text.append(".");
37943a2481SJim Ingham 
38943a2481SJim Ingham   m_option_definition[0].usage_mask = LLDB_OPT_SET_1;
39738af7a6SJim Ingham   m_option_definition[0].required = true;
40738af7a6SJim Ingham   m_option_definition[0].long_option = "script-class";
41943a2481SJim Ingham   m_option_definition[0].short_option = class_option;
42943a2481SJim Ingham   m_option_definition[0].validator = nullptr;
43943a2481SJim Ingham   m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument;
44943a2481SJim Ingham   m_option_definition[0].enum_values = {};
45943a2481SJim Ingham   m_option_definition[0].completion_type = 0;
46943a2481SJim Ingham   m_option_definition[0].argument_type = eArgTypePythonClass;
47943a2481SJim Ingham   m_option_definition[0].usage_text = m_class_usage_text.data();
48943a2481SJim Ingham 
49738af7a6SJim Ingham   m_option_definition[1].usage_mask = LLDB_OPT_SET_2;
50738af7a6SJim Ingham   m_option_definition[1].required = false;
51738af7a6SJim Ingham   m_option_definition[1].long_option = "structured-data-key";
52943a2481SJim Ingham   m_option_definition[1].short_option = key_option;
53943a2481SJim Ingham   m_option_definition[1].validator = nullptr;
54943a2481SJim Ingham   m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument;
55943a2481SJim Ingham   m_option_definition[1].enum_values = {};
56943a2481SJim Ingham   m_option_definition[1].completion_type = 0;
57943a2481SJim Ingham   m_option_definition[1].argument_type = eArgTypeNone;
58943a2481SJim Ingham   m_option_definition[1].usage_text = m_key_usage_text.data();
59943a2481SJim Ingham 
60738af7a6SJim Ingham   m_option_definition[2].usage_mask = LLDB_OPT_SET_2;
61738af7a6SJim Ingham   m_option_definition[2].required = false;
62738af7a6SJim Ingham   m_option_definition[2].long_option = "structured-data-value";
63943a2481SJim Ingham   m_option_definition[2].short_option = value_option;
64943a2481SJim Ingham   m_option_definition[2].validator = nullptr;
65943a2481SJim Ingham   m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument;
66943a2481SJim Ingham   m_option_definition[2].enum_values = {};
67943a2481SJim Ingham   m_option_definition[2].completion_type = 0;
68943a2481SJim Ingham   m_option_definition[2].argument_type = eArgTypeNone;
69943a2481SJim Ingham   m_option_definition[2].usage_text = m_value_usage_text.data();
70738af7a6SJim Ingham 
71738af7a6SJim Ingham   m_option_definition[3].usage_mask = LLDB_OPT_SET_3;
72738af7a6SJim Ingham   m_option_definition[3].required = true;
73738af7a6SJim Ingham   m_option_definition[3].long_option = "python-function";
74738af7a6SJim Ingham   m_option_definition[3].short_option = class_option;
75738af7a6SJim Ingham   m_option_definition[3].validator = nullptr;
76738af7a6SJim Ingham   m_option_definition[3].option_has_arg = OptionParser::eRequiredArgument;
77738af7a6SJim Ingham   m_option_definition[3].enum_values = {};
78738af7a6SJim Ingham   m_option_definition[3].completion_type = 0;
79738af7a6SJim Ingham   m_option_definition[3].argument_type = eArgTypePythonFunction;
80738af7a6SJim Ingham   m_option_definition[3].usage_text = m_class_usage_text.data();
81738af7a6SJim Ingham 
82943a2481SJim Ingham }
83943a2481SJim Ingham 
84943a2481SJim Ingham OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {}
85943a2481SJim Ingham 
86943a2481SJim Ingham Status OptionGroupPythonClassWithDict::SetOptionValue(
87943a2481SJim Ingham     uint32_t option_idx,
88943a2481SJim Ingham     llvm::StringRef option_arg,
89943a2481SJim Ingham     ExecutionContext *execution_context) {
90943a2481SJim Ingham   Status error;
91943a2481SJim Ingham   switch (option_idx) {
92738af7a6SJim Ingham   case 0:
93738af7a6SJim Ingham   case 3: {
94738af7a6SJim Ingham     m_name.assign(option_arg);
95943a2481SJim Ingham   } break;
96943a2481SJim Ingham   case 1: {
97738af7a6SJim Ingham       if (!m_dict_sp)
98738af7a6SJim Ingham         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
99943a2481SJim Ingham       if (m_current_key.empty())
100943a2481SJim Ingham         m_current_key.assign(option_arg);
101943a2481SJim Ingham       else
102943a2481SJim Ingham         error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
103943a2481SJim Ingham                                         m_current_key.c_str());
104943a2481SJim Ingham 
105943a2481SJim Ingham   } break;
106943a2481SJim Ingham   case 2: {
107738af7a6SJim Ingham       if (!m_dict_sp)
108738af7a6SJim Ingham         m_dict_sp = std::make_shared<StructuredData::Dictionary>();
109943a2481SJim Ingham       if (!m_current_key.empty()) {
110943a2481SJim Ingham           m_dict_sp->AddStringItem(m_current_key, option_arg);
111943a2481SJim Ingham           m_current_key.clear();
112943a2481SJim Ingham       }
113943a2481SJim Ingham       else
114943a2481SJim Ingham         error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
115943a2481SJim Ingham                                        option_arg.str().c_str());
116943a2481SJim Ingham   } break;
117943a2481SJim Ingham   default:
118943a2481SJim Ingham     llvm_unreachable("Unimplemented option");
119943a2481SJim Ingham   }
120943a2481SJim Ingham   return error;
121943a2481SJim Ingham }
122943a2481SJim Ingham 
123943a2481SJim Ingham void OptionGroupPythonClassWithDict::OptionParsingStarting(
124943a2481SJim Ingham   ExecutionContext *execution_context) {
125943a2481SJim Ingham   m_current_key.erase();
126738af7a6SJim Ingham   // Leave the dictionary shared pointer unset.  That way you can tell that
127738af7a6SJim Ingham   // the user didn't pass any -k -v pairs.  We want to be able to warn if these
128738af7a6SJim Ingham   // were passed when the function they passed won't use them.
129738af7a6SJim Ingham   m_dict_sp.reset();
130*3151d7afSJim Ingham   m_name.clear();
131943a2481SJim Ingham }
132943a2481SJim Ingham 
133943a2481SJim Ingham Status OptionGroupPythonClassWithDict::OptionParsingFinished(
134943a2481SJim Ingham   ExecutionContext *execution_context) {
135943a2481SJim Ingham   Status error;
136943a2481SJim Ingham   // If we get here and there's contents in the m_current_key, somebody must
137943a2481SJim Ingham   // have provided a key but no value.
138943a2481SJim Ingham   if (!m_current_key.empty())
139943a2481SJim Ingham       error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
140943a2481SJim Ingham                                      m_current_key.c_str());
141943a2481SJim Ingham   return error;
142943a2481SJim Ingham }
143943a2481SJim Ingham 
144