| //===-- 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 |
| error.SetErrorStringWithFormat("Key: \"%s\" missing value.", |
| m_current_key.c_str()); |
| |
| } break; |
| case 2: { |
| if (!m_dict_sp) |
| m_dict_sp = std::make_shared<StructuredData::Dictionary>(); |
| if (!m_current_key.empty()) { |
| m_dict_sp->AddStringItem(m_current_key, option_arg); |
| m_current_key.clear(); |
| } |
| else |
| error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.", |
| option_arg.str().c_str()); |
| } 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.SetErrorStringWithFormat("Key: \"%s\" missing value.", |
| m_current_key.c_str()); |
| return error; |
| } |
| |