diff options
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/Commands/CommandObjectBreakpoint.cpp | 40 | ||||
| -rw-r--r-- | lldb/source/Commands/Options.td | 11 | ||||
| -rw-r--r-- | lldb/source/Interpreter/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp | 124 | ||||
| -rw-r--r-- | lldb/source/Interpreter/Options.cpp | 4 |
5 files changed, 139 insertions, 41 deletions
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index e73c924de8a..4700b626b32 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -16,6 +16,7 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/OptionValueUInt64.h" @@ -241,12 +242,16 @@ public: interpreter, "breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.", "breakpoint set <cmd-options>"), + m_python_class_options("scripted breakpoint", 'P'), m_bp_opts(), m_options() { // We're picking up all the normal options, commands and disable. + m_all_options.Append(&m_python_class_options, LLDB_OPT_SET_1, + LLDB_OPT_SET_11); m_all_options.Append(&m_bp_opts, LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4, LLDB_OPT_SET_ALL); - m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); + m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, + LLDB_OPT_SET_ALL); m_all_options.Append(&m_options); m_all_options.Finalize(); } @@ -352,14 +357,6 @@ public: m_hardware = true; break; - case 'k': { - if (m_current_key.empty()) - m_current_key.assign(option_arg); - else - error.SetErrorStringWithFormat("Key: %s missing value.", - m_current_key.c_str()); - - } break; case 'K': { bool success; bool value; @@ -441,10 +438,6 @@ public: m_source_text_regexp.assign(option_arg); break; - case 'P': - m_python_class.assign(option_arg); - break; - case 'r': m_func_regexp.assign(option_arg); break; @@ -458,16 +451,6 @@ public: m_func_name_type_mask |= eFunctionNameTypeSelector; break; - case 'v': { - if (!m_current_key.empty()) { - m_extra_args_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; - case 'w': { bool success; m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); @@ -510,8 +493,6 @@ public: m_exception_extra_args.Clear(); m_move_to_nearest_code = eLazyBoolCalculate; m_source_regex_func_names.clear(); - m_python_class.clear(); - m_extra_args_sp = std::make_shared<StructuredData::Dictionary>(); m_current_key.clear(); } @@ -543,8 +524,6 @@ public: Args m_exception_extra_args; LazyBool m_move_to_nearest_code; std::unordered_set<std::string> m_source_regex_func_names; - std::string m_python_class; - StructuredData::DictionarySP m_extra_args_sp; std::string m_current_key; }; @@ -565,7 +544,7 @@ protected: BreakpointSetType break_type = eSetTypeInvalid; - if (!m_options.m_python_class.empty()) + if (!m_python_class_options.GetClassName().empty()) break_type = eSetTypeScripted; else if (m_options.m_line_num != 0) break_type = eSetTypeFileAndLine; @@ -721,9 +700,9 @@ protected: Status error; bp_sp = target.CreateScriptedBreakpoint( - m_options.m_python_class, &(m_options.m_modules), + m_python_class_options.GetClassName().c_str(), &(m_options.m_modules), &(m_options.m_filenames), false, m_options.m_hardware, - m_options.m_extra_args_sp, &error); + m_python_class_options.GetStructuredData(), &error); if (error.Fail()) { result.AppendErrorWithFormat( "Error setting extra exception arguments: %s", @@ -818,6 +797,7 @@ private: BreakpointOptionGroup m_bp_opts; BreakpointDummyOptionGroup m_dummy_options; + OptionGroupPythonClassWithDict m_python_class_options; CommandOptions m_options; OptionGroupOptions m_all_options; }; diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 7791302c3da..477b5532946 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -163,17 +163,6 @@ let Command = "breakpoint set" in { "match against all source files, pass the \"--all-files\" option.">; def breakpoint_set_all_files : Option<"all-files", "A">, Group<9>, Desc<"All files are searched for source pattern matches.">; - def breakpoint_set_python_class : Option<"python-class", "P">, Group<11>, - Arg<"PythonClass">, Required, Desc<"The name of the class that implement " - "a scripted breakpoint.">; - def breakpoint_set_python_class_key : Option<"python-class-key", "k">, - Group<11>, Arg<"None">, - Desc<"The key for a key/value pair passed to the class that implements a " - "scripted breakpoint. Can be specified more than once.">; - def breakpoint_set_python_class_value : Option<"python-class-value", "v">, - Group<11>, Arg<"None">, Desc<"The value for the previous key in the pair " - "passed to the class that implements a scripted breakpoint. " - "Can be specified more than once.">; def breakpoint_set_language_exception : Option<"language-exception", "E">, Group<10>, Arg<"Language">, Required, Desc<"Set the breakpoint on exceptions thrown by the specified language " diff --git a/lldb/source/Interpreter/CMakeLists.txt b/lldb/source/Interpreter/CMakeLists.txt index 6486256c16c..3900799b056 100644 --- a/lldb/source/Interpreter/CMakeLists.txt +++ b/lldb/source/Interpreter/CMakeLists.txt @@ -20,6 +20,7 @@ add_lldb_library(lldbInterpreter OptionGroupBoolean.cpp OptionGroupFile.cpp OptionGroupFormat.cpp + OptionGroupPythonClassWithDict.cpp OptionGroupOutputFile.cpp OptionGroupPlatform.cpp OptionGroupString.cpp diff --git a/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp b/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp new file mode 100644 index 00000000000..6b167866a60 --- /dev/null +++ b/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp @@ -0,0 +1,124 @@ +//===-- OptionGroupKeyValue.cpp ----------------------------------*- C++ -*-===// +// +// 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, + int class_option, + int key_option, + int value_option, + char *class_long_option, + const char *key_long_option, + const char *value_long_option, + bool required) { + m_key_usage_text.assign("The key for a key/value pair passed to the class" + " that implements 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 a previous key in the pair passed to" + " the class that implements 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 class 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 = required; + m_option_definition[0].long_option = class_long_option; + 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_1; + m_option_definition[1].required = required; + m_option_definition[1].long_option = key_long_option; + 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_1; + m_option_definition[2].required = required; + m_option_definition[2].long_option = value_long_option; + 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(); +} + +OptionGroupPythonClassWithDict::~OptionGroupPythonClassWithDict() {} + +Status OptionGroupPythonClassWithDict::SetOptionValue( + uint32_t option_idx, + llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Status error; + const int short_option = m_option_definition[option_idx].short_option; + switch (option_idx) { + case 0: { + m_class_name.assign(option_arg); + } break; + case 1: { + if (m_current_key.empty()) + m_current_key.assign(option_arg); + else + error.SetErrorStringWithFormat("Key: \"%s\" missing value.", + m_current_key.c_str()); + + } break; + case 2: { + 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(); + m_dict_sp = std::make_shared<StructuredData::Dictionary>(); +} + +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; +} + diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp index 465271d2f96..0bceea14269 100644 --- a/lldb/source/Interpreter/Options.cpp +++ b/lldb/source/Interpreter/Options.cpp @@ -1380,6 +1380,10 @@ llvm::Expected<Args> Options::Parse(const Args &args, ? nullptr : OptionParser::GetOptionArgument(), execution_context); + // If the Option setting returned an error, we should stop parsing + // and return the error. + if (error.Fail()) + break; } else { error.SetErrorStringWithFormat("invalid option with value '%i'", val); } |

