1 //===-- OptionGroupPythonClassWithDict.cpp ----------------------------------*- C++ -*-===// 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) : 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 84 OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {} 85 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(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(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 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 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