180814287SRaphael Isemann //===-- OptionGroupPythonClassWithDict.cpp --------------------------------===// 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 16c16fef19SMed Ismail Bennani OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict( 17c16fef19SMed Ismail Bennani const char *class_use, bool is_class, int class_option, int key_option, 18c16fef19SMed Ismail Bennani int value_option, uint16_t required_options) 19c16fef19SMed Ismail Bennani : m_is_class(is_class), m_required_options(required_options) { 20738af7a6SJim Ingham m_key_usage_text.assign("The key for a key/value pair passed to the " 21738af7a6SJim Ingham "implementation of a "); 22943a2481SJim Ingham m_key_usage_text.append(class_use); 23943a2481SJim Ingham m_key_usage_text.append(". Pairs can be specified more than once."); 24943a2481SJim Ingham 25738af7a6SJim Ingham m_value_usage_text.assign("The value for the previous key in the pair passed " 26738af7a6SJim Ingham "to the implementation of a "); 27943a2481SJim Ingham m_value_usage_text.append(class_use); 28943a2481SJim Ingham m_value_usage_text.append(". Pairs can be specified more than once."); 29943a2481SJim Ingham 30738af7a6SJim Ingham m_class_usage_text.assign("The name of the "); 31738af7a6SJim Ingham m_class_usage_text.append(m_is_class ? "class" : "function"); 32738af7a6SJim Ingham m_class_usage_text.append(" that will manage a "); 33943a2481SJim Ingham m_class_usage_text.append(class_use); 34943a2481SJim Ingham m_class_usage_text.append("."); 35943a2481SJim Ingham 36943a2481SJim Ingham m_option_definition[0].usage_mask = LLDB_OPT_SET_1; 37c16fef19SMed Ismail Bennani m_option_definition[0].required = m_required_options.Test(eScriptClass); 38738af7a6SJim Ingham m_option_definition[0].long_option = "script-class"; 39943a2481SJim Ingham m_option_definition[0].short_option = class_option; 40943a2481SJim Ingham m_option_definition[0].validator = nullptr; 41943a2481SJim Ingham m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument; 42943a2481SJim Ingham m_option_definition[0].enum_values = {}; 43943a2481SJim Ingham m_option_definition[0].completion_type = 0; 44943a2481SJim Ingham m_option_definition[0].argument_type = eArgTypePythonClass; 45943a2481SJim Ingham m_option_definition[0].usage_text = m_class_usage_text.data(); 46943a2481SJim Ingham 47738af7a6SJim Ingham m_option_definition[1].usage_mask = LLDB_OPT_SET_2; 48c16fef19SMed Ismail Bennani m_option_definition[1].required = m_required_options.Test(eDictKey); 49738af7a6SJim Ingham m_option_definition[1].long_option = "structured-data-key"; 50943a2481SJim Ingham m_option_definition[1].short_option = key_option; 51943a2481SJim Ingham m_option_definition[1].validator = nullptr; 52943a2481SJim Ingham m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument; 53943a2481SJim Ingham m_option_definition[1].enum_values = {}; 54943a2481SJim Ingham m_option_definition[1].completion_type = 0; 55943a2481SJim Ingham m_option_definition[1].argument_type = eArgTypeNone; 56943a2481SJim Ingham m_option_definition[1].usage_text = m_key_usage_text.data(); 57943a2481SJim Ingham 58738af7a6SJim Ingham m_option_definition[2].usage_mask = LLDB_OPT_SET_2; 59c16fef19SMed Ismail Bennani m_option_definition[2].required = m_required_options.Test(eDictValue); 60738af7a6SJim Ingham m_option_definition[2].long_option = "structured-data-value"; 61943a2481SJim Ingham m_option_definition[2].short_option = value_option; 62943a2481SJim Ingham m_option_definition[2].validator = nullptr; 63943a2481SJim Ingham m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument; 64943a2481SJim Ingham m_option_definition[2].enum_values = {}; 65943a2481SJim Ingham m_option_definition[2].completion_type = 0; 66943a2481SJim Ingham m_option_definition[2].argument_type = eArgTypeNone; 67943a2481SJim Ingham m_option_definition[2].usage_text = m_value_usage_text.data(); 68738af7a6SJim Ingham 69738af7a6SJim Ingham m_option_definition[3].usage_mask = LLDB_OPT_SET_3; 70c16fef19SMed Ismail Bennani m_option_definition[3].required = m_required_options.Test(ePythonFunction); 71738af7a6SJim Ingham m_option_definition[3].long_option = "python-function"; 72738af7a6SJim Ingham m_option_definition[3].short_option = class_option; 73738af7a6SJim Ingham m_option_definition[3].validator = nullptr; 74738af7a6SJim Ingham m_option_definition[3].option_has_arg = OptionParser::eRequiredArgument; 75738af7a6SJim Ingham m_option_definition[3].enum_values = {}; 76738af7a6SJim Ingham m_option_definition[3].completion_type = 0; 77738af7a6SJim Ingham m_option_definition[3].argument_type = eArgTypePythonFunction; 78738af7a6SJim Ingham m_option_definition[3].usage_text = m_class_usage_text.data(); 79943a2481SJim Ingham } 80943a2481SJim Ingham 81943a2481SJim Ingham Status OptionGroupPythonClassWithDict::SetOptionValue( 82943a2481SJim Ingham uint32_t option_idx, 83943a2481SJim Ingham llvm::StringRef option_arg, 84943a2481SJim Ingham ExecutionContext *execution_context) { 85943a2481SJim Ingham Status error; 86943a2481SJim Ingham switch (option_idx) { 87738af7a6SJim Ingham case 0: 88738af7a6SJim Ingham case 3: { 89adcd0268SBenjamin Kramer m_name.assign(std::string(option_arg)); 90943a2481SJim Ingham } break; 91943a2481SJim Ingham case 1: { 92738af7a6SJim Ingham if (!m_dict_sp) 93738af7a6SJim Ingham m_dict_sp = std::make_shared<StructuredData::Dictionary>(); 94943a2481SJim Ingham if (m_current_key.empty()) 95adcd0268SBenjamin Kramer m_current_key.assign(std::string(option_arg)); 96943a2481SJim Ingham else 97*0642cd76SAdrian Prantl return Status::FromErrorStringWithFormatv("Key: \"{0}\" missing value.", 98*0642cd76SAdrian Prantl m_current_key); 99943a2481SJim Ingham 100943a2481SJim Ingham } break; 101943a2481SJim Ingham case 2: { 102738af7a6SJim Ingham if (!m_dict_sp) 103738af7a6SJim Ingham m_dict_sp = std::make_shared<StructuredData::Dictionary>(); 104943a2481SJim Ingham if (!m_current_key.empty()) { 1051370a1cbSMed Ismail Bennani if (!option_arg.empty()) { 1061370a1cbSMed Ismail Bennani double d = 0; 1071370a1cbSMed Ismail Bennani std::string opt = option_arg.lower(); 1081370a1cbSMed Ismail Bennani 1091370a1cbSMed Ismail Bennani if (llvm::to_integer(option_arg, d)) { 1101370a1cbSMed Ismail Bennani if (opt[0] == '-') 1111370a1cbSMed Ismail Bennani m_dict_sp->AddIntegerItem(m_current_key, static_cast<int64_t>(d)); 1121370a1cbSMed Ismail Bennani else 1131370a1cbSMed Ismail Bennani m_dict_sp->AddIntegerItem(m_current_key, 1141370a1cbSMed Ismail Bennani static_cast<uint64_t>(d)); 1151370a1cbSMed Ismail Bennani } else if (llvm::to_float(option_arg, d)) { 1161370a1cbSMed Ismail Bennani m_dict_sp->AddFloatItem(m_current_key, d); 1171370a1cbSMed Ismail Bennani } else if (opt == "true" || opt == "false") { 1181370a1cbSMed Ismail Bennani m_dict_sp->AddBooleanItem(m_current_key, opt == "true"); 1191370a1cbSMed Ismail Bennani } else { 120943a2481SJim Ingham m_dict_sp->AddStringItem(m_current_key, option_arg); 1211370a1cbSMed Ismail Bennani } 1221370a1cbSMed Ismail Bennani } 1231370a1cbSMed Ismail Bennani 124943a2481SJim Ingham m_current_key.clear(); 125943a2481SJim Ingham } 126943a2481SJim Ingham else 127*0642cd76SAdrian Prantl return Status::FromErrorStringWithFormatv( 128*0642cd76SAdrian Prantl "Value: \"{0}\" missing matching key.", option_arg); 129943a2481SJim Ingham } break; 130943a2481SJim Ingham default: 131943a2481SJim Ingham llvm_unreachable("Unimplemented option"); 132943a2481SJim Ingham } 133943a2481SJim Ingham return error; 134943a2481SJim Ingham } 135943a2481SJim Ingham 136943a2481SJim Ingham void OptionGroupPythonClassWithDict::OptionParsingStarting( 137943a2481SJim Ingham ExecutionContext *execution_context) { 138943a2481SJim Ingham m_current_key.erase(); 139738af7a6SJim Ingham // Leave the dictionary shared pointer unset. That way you can tell that 140738af7a6SJim Ingham // the user didn't pass any -k -v pairs. We want to be able to warn if these 141738af7a6SJim Ingham // were passed when the function they passed won't use them. 142738af7a6SJim Ingham m_dict_sp.reset(); 1433151d7afSJim Ingham m_name.clear(); 144943a2481SJim Ingham } 145943a2481SJim Ingham 146943a2481SJim Ingham Status OptionGroupPythonClassWithDict::OptionParsingFinished( 147943a2481SJim Ingham ExecutionContext *execution_context) { 148943a2481SJim Ingham Status error; 149943a2481SJim Ingham // If we get here and there's contents in the m_current_key, somebody must 150943a2481SJim Ingham // have provided a key but no value. 151943a2481SJim Ingham if (!m_current_key.empty()) 152*0642cd76SAdrian Prantl error = Status::FromErrorStringWithFormat("Key: \"%s\" missing value.", 153943a2481SJim Ingham m_current_key.c_str()); 154943a2481SJim Ingham return error; 155943a2481SJim Ingham } 156943a2481SJim Ingham 157