| //===-- OptionGroupPythonClassWithDict.cpp --------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" | |
| #include "lldb/Host/OptionParser.h" | |
| using namespace lldb; | |
| using namespace lldb_private; | |
| OptionGroupPythonClassWithDict::OptionGroupPythonClassWithDict( | |
| const char *class_use, bool is_class, int class_option, int key_option, | |
| int value_option, uint16_t required_options) | |
| : m_is_class(is_class), m_required_options(required_options) { | |
| m_key_usage_text.assign("The key for a key/value pair passed to the " | |
| "implementation of a "); | |
| m_key_usage_text.append(class_use); | |
| m_key_usage_text.append(". Pairs can be specified more than once."); | |
| m_value_usage_text.assign("The value for the previous key in the pair passed " | |
| "to the implementation of a "); | |
| m_value_usage_text.append(class_use); | |
| m_value_usage_text.append(". Pairs can be specified more than once."); | |
| m_class_usage_text.assign("The name of the "); | |
| m_class_usage_text.append(m_is_class ? "class" : "function"); | |
| m_class_usage_text.append(" that will manage a "); | |
| m_class_usage_text.append(class_use); | |
| m_class_usage_text.append("."); | |
| m_option_definition[0].usage_mask = LLDB_OPT_SET_1; | |
| m_option_definition[0].required = m_required_options.Test(eScriptClass); | |
| m_option_definition[0].long_option = "script-class"; | |
| m_option_definition[0].short_option = class_option; | |
| m_option_definition[0].validator = nullptr; | |
| m_option_definition[0].option_has_arg = OptionParser::eRequiredArgument; | |
| m_option_definition[0].enum_values = {}; | |
| m_option_definition[0].completion_type = 0; | |
| m_option_definition[0].argument_type = eArgTypePythonClass; | |
| m_option_definition[0].usage_text = m_class_usage_text.data(); | |
| m_option_definition[1].usage_mask = LLDB_OPT_SET_2; | |
| m_option_definition[1].required = m_required_options.Test(eDictKey); | |
| m_option_definition[1].long_option = "structured-data-key"; | |
| m_option_definition[1].short_option = key_option; | |
| m_option_definition[1].validator = nullptr; | |
| m_option_definition[1].option_has_arg = OptionParser::eRequiredArgument; | |
| m_option_definition[1].enum_values = {}; | |
| m_option_definition[1].completion_type = 0; | |
| m_option_definition[1].argument_type = eArgTypeNone; | |
| m_option_definition[1].usage_text = m_key_usage_text.data(); | |
| m_option_definition[2].usage_mask = LLDB_OPT_SET_2; | |
| m_option_definition[2].required = m_required_options.Test(eDictValue); | |
| m_option_definition[2].long_option = "structured-data-value"; | |
| m_option_definition[2].short_option = value_option; | |
| m_option_definition[2].validator = nullptr; | |
| m_option_definition[2].option_has_arg = OptionParser::eRequiredArgument; | |
| m_option_definition[2].enum_values = {}; | |
| m_option_definition[2].completion_type = 0; | |
| m_option_definition[2].argument_type = eArgTypeNone; | |
| m_option_definition[2].usage_text = m_value_usage_text.data(); | |
| m_option_definition[3].usage_mask = LLDB_OPT_SET_3; | |
| m_option_definition[3].required = m_required_options.Test(ePythonFunction); | |
| m_option_definition[3].long_option = "python-function"; | |
| m_option_definition[3].short_option = class_option; | |
| m_option_definition[3].validator = nullptr; | |
| m_option_definition[3].option_has_arg = OptionParser::eRequiredArgument; | |
| m_option_definition[3].enum_values = {}; | |
| m_option_definition[3].completion_type = 0; | |
| m_option_definition[3].argument_type = eArgTypePythonFunction; | |
| m_option_definition[3].usage_text = m_class_usage_text.data(); | |
| } | |
| Status OptionGroupPythonClassWithDict::SetOptionValue( | |
| uint32_t option_idx, | |
| llvm::StringRef option_arg, | |
| ExecutionContext *execution_context) { | |
| Status error; | |
| switch (option_idx) { | |
| case 0: | |
| case 3: { | |
| m_name.assign(std::string(option_arg)); | |
| } break; | |
| case 1: { | |
| if (!m_dict_sp) | |
| m_dict_sp = std::make_shared<StructuredData::Dictionary>(); | |
| if (m_current_key.empty()) | |
| m_current_key.assign(std::string(option_arg)); | |
| else | |
| return Status::FromErrorStringWithFormatv("Key: \"{0}\" missing value.", | |
| m_current_key); | |
| } break; | |
| case 2: { | |
| if (!m_dict_sp) | |
| m_dict_sp = std::make_shared<StructuredData::Dictionary>(); | |
| if (!m_current_key.empty()) { | |
| if (!option_arg.empty()) { | |
| double d = 0; | |
| std::string opt = option_arg.lower(); | |
| if (llvm::to_integer(option_arg, d)) { | |
| if (opt[0] == '-') | |
| m_dict_sp->AddIntegerItem(m_current_key, static_cast<int64_t>(d)); | |
| else | |
| m_dict_sp->AddIntegerItem(m_current_key, | |
| static_cast<uint64_t>(d)); | |
| } else if (llvm::to_float(option_arg, d)) { | |
| m_dict_sp->AddFloatItem(m_current_key, d); | |
| } else if (opt == "true" || opt == "false") { | |
| m_dict_sp->AddBooleanItem(m_current_key, opt == "true"); | |
| } else { | |
| m_dict_sp->AddStringItem(m_current_key, option_arg); | |
| } | |
| } | |
| m_current_key.clear(); | |
| } | |
| else | |
| return Status::FromErrorStringWithFormatv( | |
| "Value: \"{0}\" missing matching key.", option_arg); | |
| } break; | |
| default: | |
| llvm_unreachable("Unimplemented option"); | |
| } | |
| return error; | |
| } | |
| void OptionGroupPythonClassWithDict::OptionParsingStarting( | |
| ExecutionContext *execution_context) { | |
| m_current_key.erase(); | |
| // Leave the dictionary shared pointer unset. That way you can tell that | |
| // the user didn't pass any -k -v pairs. We want to be able to warn if these | |
| // were passed when the function they passed won't use them. | |
| m_dict_sp.reset(); | |
| m_name.clear(); | |
| } | |
| Status OptionGroupPythonClassWithDict::OptionParsingFinished( | |
| ExecutionContext *execution_context) { | |
| Status error; | |
| // If we get here and there's contents in the m_current_key, somebody must | |
| // have provided a key but no value. | |
| if (!m_current_key.empty()) | |
| error = Status::FromErrorStringWithFormat("Key: \"%s\" missing value.", | |
| m_current_key.c_str()); | |
| return error; | |
| } | |