1*943a2481SJim Ingham //===-- OptionGroupKeyValue.cpp ----------------------------------*- C++ -*-===//
2*943a2481SJim Ingham //
3*943a2481SJim Ingham // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*943a2481SJim Ingham // See https://llvm.org/LICENSE.txt for license information.
5*943a2481SJim Ingham // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*943a2481SJim Ingham //
7*943a2481SJim Ingham //===----------------------------------------------------------------------===//
8*943a2481SJim Ingham 
9*943a2481SJim Ingham #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
10*943a2481SJim Ingham 
11*943a2481SJim Ingham #include "lldb/Host/OptionParser.h"
12*943a2481SJim Ingham 
13*943a2481SJim Ingham using namespace lldb;
14*943a2481SJim Ingham using namespace lldb_private;
15*943a2481SJim Ingham 
16*943a2481SJim Ingham OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict
17*943a2481SJim Ingham     (const char *class_use,
18*943a2481SJim Ingham      int class_option,
19*943a2481SJim Ingham      int key_option,
20*943a2481SJim Ingham      int value_option,
21*943a2481SJim Ingham      char *class_long_option,
22*943a2481SJim Ingham      const char *key_long_option,
23*943a2481SJim Ingham      const char *value_long_option,
24*943a2481SJim Ingham      bool required) {
25*943a2481SJim Ingham   m_key_usage_text.assign("The key for a key/value pair passed to the class"
26*943a2481SJim Ingham                             " that implements a ");
27*943a2481SJim Ingham   m_key_usage_text.append(class_use);
28*943a2481SJim Ingham   m_key_usage_text.append(".  Pairs can be specified more than once.");
29*943a2481SJim Ingham 
30*943a2481SJim Ingham   m_value_usage_text.assign("The value for a previous key in the pair passed to"
31*943a2481SJim Ingham                             " the class that implements a ");
32*943a2481SJim Ingham   m_value_usage_text.append(class_use);
33*943a2481SJim Ingham   m_value_usage_text.append(".  Pairs can be specified more than once.");
34*943a2481SJim Ingham 
35*943a2481SJim Ingham   m_class_usage_text.assign("The name of the class that will manage a ");
36*943a2481SJim Ingham   m_class_usage_text.append(class_use);
37*943a2481SJim Ingham   m_class_usage_text.append(".");
38*943a2481SJim Ingham 
39*943a2481SJim Ingham   m_option_definition[0].usage_mask = LLDB_OPT_SET_1;
40*943a2481SJim Ingham   m_option_definition[0].required = required;
41*943a2481SJim Ingham   m_option_definition[0].long_option = class_long_option;
42*943a2481SJim Ingham   m_option_definition[0].short_option = class_option;
43*943a2481SJim Ingham   m_option_definition[0].validator = nullptr;
44*943a2481SJim Ingham   m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument;
45*943a2481SJim Ingham   m_option_definition[0].enum_values = {};
46*943a2481SJim Ingham   m_option_definition[0].completion_type = 0;
47*943a2481SJim Ingham   m_option_definition[0].argument_type = eArgTypePythonClass;
48*943a2481SJim Ingham   m_option_definition[0].usage_text = m_class_usage_text.data();
49*943a2481SJim Ingham 
50*943a2481SJim Ingham   m_option_definition[1].usage_mask = LLDB_OPT_SET_1;
51*943a2481SJim Ingham   m_option_definition[1].required = required;
52*943a2481SJim Ingham   m_option_definition[1].long_option = key_long_option;
53*943a2481SJim Ingham   m_option_definition[1].short_option = key_option;
54*943a2481SJim Ingham   m_option_definition[1].validator = nullptr;
55*943a2481SJim Ingham   m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument;
56*943a2481SJim Ingham   m_option_definition[1].enum_values = {};
57*943a2481SJim Ingham   m_option_definition[1].completion_type = 0;
58*943a2481SJim Ingham   m_option_definition[1].argument_type = eArgTypeNone;
59*943a2481SJim Ingham   m_option_definition[1].usage_text = m_key_usage_text.data();
60*943a2481SJim Ingham 
61*943a2481SJim Ingham   m_option_definition[2].usage_mask = LLDB_OPT_SET_1;
62*943a2481SJim Ingham   m_option_definition[2].required = required;
63*943a2481SJim Ingham   m_option_definition[2].long_option = value_long_option;
64*943a2481SJim Ingham   m_option_definition[2].short_option = value_option;
65*943a2481SJim Ingham   m_option_definition[2].validator = nullptr;
66*943a2481SJim Ingham   m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument;
67*943a2481SJim Ingham   m_option_definition[2].enum_values = {};
68*943a2481SJim Ingham   m_option_definition[2].completion_type = 0;
69*943a2481SJim Ingham   m_option_definition[2].argument_type = eArgTypeNone;
70*943a2481SJim Ingham   m_option_definition[2].usage_text = m_value_usage_text.data();
71*943a2481SJim Ingham }
72*943a2481SJim Ingham 
73*943a2481SJim Ingham OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {}
74*943a2481SJim Ingham 
75*943a2481SJim Ingham Status OptionGroupPythonClassWithDict::SetOptionValue(
76*943a2481SJim Ingham     uint32_t option_idx,
77*943a2481SJim Ingham     llvm::StringRef option_arg,
78*943a2481SJim Ingham     ExecutionContext *execution_context) {
79*943a2481SJim Ingham   Status error;
80*943a2481SJim Ingham   const int short_option = m_option_definition[option_idx].short_option;
81*943a2481SJim Ingham   switch (option_idx) {
82*943a2481SJim Ingham   case 0: {
83*943a2481SJim Ingham     m_class_name.assign(option_arg);
84*943a2481SJim Ingham   } break;
85*943a2481SJim Ingham   case 1: {
86*943a2481SJim Ingham       if (m_current_key.empty())
87*943a2481SJim Ingham         m_current_key.assign(option_arg);
88*943a2481SJim Ingham       else
89*943a2481SJim Ingham         error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
90*943a2481SJim Ingham                                         m_current_key.c_str());
91*943a2481SJim Ingham 
92*943a2481SJim Ingham   } break;
93*943a2481SJim Ingham   case 2: {
94*943a2481SJim Ingham       if (!m_current_key.empty()) {
95*943a2481SJim Ingham           m_dict_sp->AddStringItem(m_current_key, option_arg);
96*943a2481SJim Ingham           m_current_key.clear();
97*943a2481SJim Ingham       }
98*943a2481SJim Ingham       else
99*943a2481SJim Ingham         error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.",
100*943a2481SJim Ingham                                        option_arg.str().c_str());
101*943a2481SJim Ingham   } break;
102*943a2481SJim Ingham   default:
103*943a2481SJim Ingham     llvm_unreachable("Unimplemented option");
104*943a2481SJim Ingham   }
105*943a2481SJim Ingham   return error;
106*943a2481SJim Ingham }
107*943a2481SJim Ingham 
108*943a2481SJim Ingham void OptionGroupPythonClassWithDict::OptionParsingStarting(
109*943a2481SJim Ingham   ExecutionContext *execution_context) {
110*943a2481SJim Ingham   m_current_key.erase();
111*943a2481SJim Ingham   m_dict_sp = std::make_shared<StructuredData::Dictionary>();
112*943a2481SJim Ingham }
113*943a2481SJim Ingham 
114*943a2481SJim Ingham Status OptionGroupPythonClassWithDict::OptionParsingFinished(
115*943a2481SJim Ingham   ExecutionContext *execution_context) {
116*943a2481SJim Ingham   Status error;
117*943a2481SJim Ingham   // If we get here and there's contents in the m_current_key, somebody must
118*943a2481SJim Ingham   // have provided a key but no value.
119*943a2481SJim Ingham   if (!m_current_key.empty())
120*943a2481SJim Ingham       error.SetErrorStringWithFormat("Key: \"%s\" missing value.",
121*943a2481SJim Ingham                                      m_current_key.c_str());
122*943a2481SJim Ingham   return error;
123*943a2481SJim Ingham }
124*943a2481SJim Ingham 
125