================
@@ -3584,6 +3584,221 @@ class CommandObjectBreakpointWrite : public
CommandObjectParsed {
CommandOptions m_options;
};
+#pragma mark override add
+#define LLDB_OPTIONS_breakpoint_override_add
+#include "CommandOptions.inc"
+
+class CommandObjectBreakpointOverrideAdd : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointOverrideAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint override add",
+ "Add a scripted breakpoint override resolver.",
+ nullptr),
+ m_python_class_options("breakpoint override resolver", true, 'P') {
+ // 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_2, LLDB_OPT_SET_1);
+ m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_all_options.Append(&m_options, llvm::ArrayRef<llvm::StringRef>());
+ m_all_options.Finalize();
+ }
+
+ ~CommandObjectBreakpointOverrideAdd() override = default;
+
+ class CommandOptions : public OptionGroup {
+ public:
+ CommandOptions() = default;
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = GetDefinitions()[option_idx].short_option;
+
+ switch (short_option) {
+ case 'd':
+ m_description.assign(std::string(option_arg));
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_description.clear();
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::ArrayRef(g_breakpoint_override_add_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ std::string m_description;
+ };
+ Options *GetOptions() override { return &m_all_options; }
+
+protected:
+ void DoExecute(Args &command, CommandReturnObject &result) override {
+ Target &target =
+ m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
+ uint64_t id = target.AddBreakpointResolverOverride(
+ m_python_class_options.GetName(),
+ m_python_class_options.GetStructuredData(), m_options.m_description);
+ result.AppendMessageWithFormatv("{0}", id);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+
+private:
+ BreakpointDummyOptionGroup m_dummy_options;
+ OptionGroupPythonClassWithDict m_python_class_options;
+ CommandOptions m_options;
+ OptionGroupOptions m_all_options;
+};
+
+class CommandObjectBreakpointOverrideDelete : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointOverrideDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint override delete",
+ "Add a scripted breakpoint override resolver.",
+ nullptr) {
+ AddSimpleArgumentList(eArgTypeIndex, eArgRepeatOptional);
+ m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_1);
+ m_all_options.Finalize();
+ }
+
+ ~CommandObjectBreakpointOverrideDelete() override = default;
+
+protected:
+ void DoExecute(Args &command, CommandReturnObject &result) override {
+ Target &target =
+ m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
+
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ if (m_interpreter.Confirm("Delete all breakpoint overrides?", false)) {
+ target.ClearBreakpointResolverOverrides();
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return;
+ }
+
+ for (auto &entry : command.entries()) {
+ uint64_t id;
+ bool success;
+ if (!entry.ref().getAsInteger(0, id))
+ success = target.RemoveBreakpointResolverOverride(id);
+ else {
+ result.AppendErrorWithFormatv("Index not an integer: {0}",
entry.ref());
+ result.SetStatus(eReturnStatusFailed);
+ return;
+ }
+ if (!success) {
+ result.AppendErrorWithFormatv("Cannot delete override: {0}", id);
+ result.SetStatus(eReturnStatusFailed);
+ return;
+ }
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+
+private:
+ BreakpointDummyOptionGroup m_dummy_options;
+ OptionGroupOptions m_all_options;
+};
+
+class CommandObjectBreakpointOverrideList : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointOverrideList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "breakpoint override list",
+ "List the current scripted breakpoint override resolvers.",
+ nullptr) {
+ AddSimpleArgumentList(eArgTypeIndex, eArgRepeatOptional);
+ m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_1);
+ m_all_options.Finalize();
+ }
+
+ ~CommandObjectBreakpointOverrideList() override = default;
+
+protected:
+ void DoExecute(Args &command, CommandReturnObject &result) override {
+ Target &target =
+ m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
+
+ const size_t argc = command.GetArgumentCount();
+ std::vector<uint64_t> idxs;
+ if (argc != 0) {
+ for (auto &entry : command.entries()) {
+ uint64_t id;
+ if (entry.ref().getAsInteger(0, id))
+ idxs.push_back(id);
+ else {
+ result.AppendErrorWithFormatv("Index not an integer: {0}",
+ entry.ref());
+ result.SetStatus(eReturnStatusFailed);
+ return;
+ }
----------------
JDevlieghere wrote:
This is inverted. Confusingly, `getAsInteger` returns true on error:
> If the string is invalid or if only a subset of the string is valid, this
> returns true to signify the error. The
string is considered erroneous if empty or if it overflows T.
Also, if part of the if-else needs braces, the other one does too even if it's
a single line.
```suggestion
if (!entry.ref().getAsInteger(0, id)) {
idxs.push_back(id);
} else {
result.AppendErrorWithFormatv("Index not an integer: {0}",
entry.ref());
result.SetStatus(eReturnStatusFailed);
return;
}
```
https://github.com/llvm/llvm-project/pull/195392
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits