LLDB mainline
CommandObjectCommands.cpp
Go to the documentation of this file.
1//===-- CommandObjectCommands.cpp -----------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "CommandObjectHelp.h"
12#include "lldb/Core/Debugger.h"
13#include "lldb/Core/IOHandler.h"
24#include "lldb/Utility/Args.h"
26#include "llvm/ADT/StringRef.h"
27#include <optional>
28
29using namespace lldb;
30using namespace lldb_private;
31
32// CommandObjectCommandsSource
33
34#define LLDB_OPTIONS_source
35#include "CommandOptions.inc"
36
38public:
41 interpreter, "command source",
42 "Read and execute LLDB commands from the file <filename>.",
43 nullptr) {
45 CommandArgumentData file_arg;
46
47 // Define the first (and only) variant of this arg.
48 file_arg.arg_type = eArgTypeFilename;
50
51 // There is only one variant this argument could be; put it into the
52 // argument entry.
53 arg.push_back(file_arg);
54
55 // Push the data for the first argument into the m_arguments vector.
56 m_arguments.push_back(arg);
57 }
58
59 ~CommandObjectCommandsSource() override = default;
60
61 std::optional<std::string> GetRepeatCommand(Args &current_command_args,
62 uint32_t index) override {
63 return std::string("");
64 }
65
66 void
68 OptionElementVector &opt_element_vector) override {
71 request, nullptr);
72 }
73
74 Options *GetOptions() override { return &m_options; }
75
76protected:
77 class CommandOptions : public Options {
78 public:
80 : m_stop_on_error(true), m_silent_run(false), m_stop_on_continue(true),
82
83 ~CommandOptions() override = default;
84
85 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
86 ExecutionContext *execution_context) override {
88 const int short_option = m_getopt_table[option_idx].val;
89
90 switch (short_option) {
91 case 'e':
93 break;
94
95 case 'c':
97 break;
98
99 case 'C':
101 break;
102
103 case 's':
105 break;
106
107 default:
108 llvm_unreachable("Unimplemented option");
109 }
110
111 return error;
112 }
113
114 void OptionParsingStarting(ExecutionContext *execution_context) override {
119 }
120
121 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
122 return llvm::ArrayRef(g_source_options);
123 }
124
125 // Instance variables to hold the values for command options.
126
131 };
132
133 bool DoExecute(Args &command, CommandReturnObject &result) override {
134 if (command.GetArgumentCount() != 1) {
136 "'%s' takes exactly one executable filename argument.\n",
137 GetCommandName().str().c_str());
138 return false;
139 }
140
141 FileSpec source_dir = {};
144 if (!source_dir) {
145 result.AppendError("command source -C can only be specified "
146 "from a command file");
148 return false;
149 }
150 }
151
152 FileSpec cmd_file(command[0].ref());
153 if (source_dir) {
154 // Prepend the source_dir to the cmd_file path:
155 if (!cmd_file.IsRelative()) {
156 result.AppendError("command source -C can only be used "
157 "with a relative path.");
159 return false;
160 }
161 cmd_file.MakeAbsolute(source_dir);
162 }
163
164 FileSystem::Instance().Resolve(cmd_file);
165
167 // If any options were set, then use them
172 options.SetStopOnContinue(
174
177
178 // Individual silent setting is override for global command echo settings.
180 options.SetSilent(true);
181 } else {
182 options.SetPrintResults(true);
183 options.SetPrintErrors(true);
186 }
187 }
188
189 m_interpreter.HandleCommandsFromFile(cmd_file, options, result);
190 return result.Succeeded();
191 }
192
194};
195
196#pragma mark CommandObjectCommandsAlias
197// CommandObjectCommandsAlias
198
199#define LLDB_OPTIONS_alias
200#include "CommandOptions.inc"
201
203 "Enter your Python command(s). Type 'DONE' to end.\n"
204 "You must define a Python function with this signature:\n"
205 "def my_command_impl(debugger, args, exe_ctx, result, internal_dict):\n";
206
208protected:
210 public:
211 CommandOptions() = default;
212
213 ~CommandOptions() override = default;
214
215 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
216 return llvm::ArrayRef(g_alias_options);
217 }
218
219 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
220 ExecutionContext *execution_context) override {
222
223 const int short_option = GetDefinitions()[option_idx].short_option;
224 std::string option_str(option_value);
225
226 switch (short_option) {
227 case 'h':
228 m_help.SetCurrentValue(option_str);
230 break;
231
232 case 'H':
233 m_long_help.SetCurrentValue(option_str);
235 break;
236
237 default:
238 llvm_unreachable("Unimplemented option");
239 }
240
241 return error;
242 }
243
244 void OptionParsingStarting(ExecutionContext *execution_context) override {
245 m_help.Clear();
247 }
248
251 };
252
255
256public:
257 Options *GetOptions() override { return &m_option_group; }
258
261 interpreter, "command alias",
262 "Define a custom command in terms of an existing command.") {
265
267 "'alias' allows the user to create a short-cut or abbreviation for long \
268commands, multi-word commands, and commands that take particular options. \
269Below are some simple examples of how one might use the 'alias' command:"
270 R"(
271
272(lldb) command alias sc script
273
274 Creates the abbreviation 'sc' for the 'script' command.
275
276(lldb) command alias bp breakpoint
277
278)"
279 " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
280breakpoint commands are two-word commands, the user would still need to \
281enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'."
282 R"(
283
284(lldb) command alias bpl breakpoint list
285
286 Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
287
288)"
289 "An alias can include some options for the command, with the values either \
290filled in at the time the alias is created, or specified as positional \
291arguments, to be filled in when the alias is invoked. The following example \
292shows how to create aliases with options:"
293 R"(
294
295(lldb) command alias bfl breakpoint set -f %1 -l %2
296
297)"
298 " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
299options already part of the alias. So if the user wants to set a breakpoint \
300by file and line without explicitly having to use the -f and -l options, the \
301user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \
302for the actual arguments that will be passed when the alias command is used. \
303The number in the placeholder refers to the position/order the actual value \
304occupies when the alias is used. All the occurrences of '%1' in the alias \
305will be replaced with the first argument, all the occurrences of '%2' in the \
306alias will be replaced with the second argument, and so on. This also allows \
307actual arguments to be used multiple times within an alias (see 'process \
308launch' example below)."
309 R"(
310
311)"
312 "Note: the positional arguments must substitute as whole words in the resultant \
313command, so you can't at present do something like this to append the file extension \
314\".cpp\":"
315 R"(
316
317(lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
318
319)"
320 "For more complex aliasing, use the \"command regex\" command instead. In the \
321'bfl' case above, the actual file value will be filled in with the first argument \
322following 'bfl' and the actual line number value will be filled in with the second \
323argument. The user would use this alias as follows:"
324 R"(
325
326(lldb) command alias bfl breakpoint set -f %1 -l %2
327(lldb) bfl my-file.c 137
328
329This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
330
331Another example:
332
333(lldb) command alias pltty process launch -s -o %1 -e %1
334(lldb) pltty /dev/tty0
335
336 Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
337
338)"
339 "If the user always wanted to pass the same value to a particular option, the \
340alias could be defined with that value directly in the alias as a constant, \
341rather than using a positional placeholder:"
342 R"(
344(lldb) command alias bl3 breakpoint set -f %1 -l 3
345
346 Always sets a breakpoint on line 3 of whatever file is indicated.)");
347
351 CommandArgumentData alias_arg;
352 CommandArgumentData cmd_arg;
353 CommandArgumentData options_arg;
354
355 // Define the first (and only) variant of this arg.
356 alias_arg.arg_type = eArgTypeAliasName;
358
359 // There is only one variant this argument could be; put it into the
360 // argument entry.
361 arg1.push_back(alias_arg);
362
363 // Define the first (and only) variant of this arg.
366
367 // There is only one variant this argument could be; put it into the
368 // argument entry.
369 arg2.push_back(cmd_arg);
370
371 // Define the first (and only) variant of this arg.
372 options_arg.arg_type = eArgTypeAliasOptions;
374
375 // There is only one variant this argument could be; put it into the
376 // argument entry.
377 arg3.push_back(options_arg);
378
379 // Push the data for the first argument into the m_arguments vector.
380 m_arguments.push_back(arg1);
381 m_arguments.push_back(arg2);
382 m_arguments.push_back(arg3);
383 }
384
385 ~CommandObjectCommandsAlias() override = default;
386
387protected:
388 bool DoExecute(llvm::StringRef raw_command_line,
389 CommandReturnObject &result) override {
390 if (raw_command_line.empty()) {
391 result.AppendError("'command alias' requires at least two arguments");
392 return false;
393 }
394
397
398 OptionsWithRaw args_with_suffix(raw_command_line);
399
400 if (args_with_suffix.HasArgs())
401 if (!ParseOptionsAndNotify(args_with_suffix.GetArgs(), result,
402 m_option_group, exe_ctx))
403 return false;
404
405 llvm::StringRef raw_command_string = args_with_suffix.GetRawPart();
406 Args args(raw_command_string);
407
408 if (args.GetArgumentCount() < 2) {
409 result.AppendError("'command alias' requires at least two arguments");
410 return false;
411 }
412
413 // Get the alias command.
414
415 auto alias_command = args[0].ref();
416 if (alias_command.startswith("-")) {
417 result.AppendError("aliases starting with a dash are not supported");
418 if (alias_command == "--help" || alias_command == "--long-help") {
419 result.AppendWarning("if trying to pass options to 'command alias' add "
420 "a -- at the end of the options");
421 }
422 return false;
423 }
424
425 // Strip the new alias name off 'raw_command_string' (leave it on args,
426 // which gets passed to 'Execute', which does the stripping itself.
427 size_t pos = raw_command_string.find(alias_command);
428 if (pos == 0) {
429 raw_command_string = raw_command_string.substr(alias_command.size());
430 pos = raw_command_string.find_first_not_of(' ');
431 if ((pos != std::string::npos) && (pos > 0))
432 raw_command_string = raw_command_string.substr(pos);
433 } else {
434 result.AppendError("Error parsing command string. No alias created.");
435 return false;
436 }
438 // Verify that the command is alias-able.
439 if (m_interpreter.CommandExists(alias_command)) {
441 "'%s' is a permanent debugger command and cannot be redefined.\n",
442 args[0].c_str());
443 return false;
444 }
445
446 if (m_interpreter.UserMultiwordCommandExists(alias_command)) {
448 "'%s' is a user container command and cannot be overwritten.\n"
449 "Delete it first with 'command container delete'\n",
450 args[0].c_str());
451 return false;
452 }
453
454 // Get CommandObject that is being aliased. The command name is read from
455 // the front of raw_command_string. raw_command_string is returned with the
456 // name of the command object stripped off the front.
457 llvm::StringRef original_raw_command_string = raw_command_string;
458 CommandObject *cmd_obj =
459 m_interpreter.GetCommandObjectForCommand(raw_command_string);
460
461 if (!cmd_obj) {
462 result.AppendErrorWithFormat("invalid command given to 'command alias'. "
463 "'%s' does not begin with a valid command."
464 " No alias created.",
465 original_raw_command_string.str().c_str());
466 return false;
467 } else if (!cmd_obj->WantsRawCommandString()) {
468 // Note that args was initialized with the original command, and has not
469 // been updated to this point. Therefore can we pass it to the version of
470 // Execute that does not need/expect raw input in the alias.
471 return HandleAliasingNormalCommand(args, result);
472 } else {
473 return HandleAliasingRawCommand(alias_command, raw_command_string,
474 *cmd_obj, result);
476 return result.Succeeded();
477 }
478
479 bool HandleAliasingRawCommand(llvm::StringRef alias_command,
480 llvm::StringRef raw_command_string,
481 CommandObject &cmd_obj,
482 CommandReturnObject &result) {
483 // Verify & handle any options/arguments passed to the alias command
484
485 OptionArgVectorSP option_arg_vector_sp =
487
488 const bool include_aliases = true;
489 // Look up the command using command's name first. This is to resolve
490 // aliases when you are making nested aliases. But if you don't find
491 // it that way, then it wasn't an alias and we can just use the object
492 // we were passed in.
493 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact(
494 cmd_obj.GetCommandName(), include_aliases);
495 if (!cmd_obj_sp)
496 cmd_obj_sp = cmd_obj.shared_from_this();
497
498 if (m_interpreter.AliasExists(alias_command) ||
499 m_interpreter.UserCommandExists(alias_command)) {
501 "Overwriting existing definition for '%s'.\n",
502 alias_command.str().c_str());
503 }
505 alias_command, cmd_obj_sp, raw_command_string)) {
507 alias->SetHelp(m_command_options.m_help.GetCurrentValue());
509 alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
511 } else {
512 result.AppendError("Unable to create requested alias.\n");
513 }
514 return result.Succeeded();
515 }
516
518 size_t argc = args.GetArgumentCount();
519
520 if (argc < 2) {
521 result.AppendError("'command alias' requires at least two arguments");
522 return false;
523 }
524
525 // Save these in std::strings since we're going to shift them off.
526 const std::string alias_command(std::string(args[0].ref()));
527 const std::string actual_command(std::string(args[1].ref()));
528
529 args.Shift(); // Shift the alias command word off the argument vector.
530 args.Shift(); // Shift the old command word off the argument vector.
531
532 // Verify that the command is alias'able, and get the appropriate command
533 // object.
534
535 if (m_interpreter.CommandExists(alias_command)) {
537 "'%s' is a permanent debugger command and cannot be redefined.\n",
538 alias_command.c_str());
539 return false;
540 }
541
542 if (m_interpreter.UserMultiwordCommandExists(alias_command)) {
544 "'%s' is user container command and cannot be overwritten.\n"
545 "Delete it first with 'command container delete'",
546 alias_command.c_str());
547 return false;
548 }
549
550 CommandObjectSP command_obj_sp(
551 m_interpreter.GetCommandSPExact(actual_command, true));
552 CommandObjectSP subcommand_obj_sp;
553 bool use_subcommand = false;
554 if (!command_obj_sp) {
555 result.AppendErrorWithFormat("'%s' is not an existing command.\n",
556 actual_command.c_str());
557 return false;
558 }
559 CommandObject *cmd_obj = command_obj_sp.get();
560 CommandObject *sub_cmd_obj = nullptr;
561 OptionArgVectorSP option_arg_vector_sp =
563
564 while (cmd_obj->IsMultiwordObject() && !args.empty()) {
565 auto sub_command = args[0].ref();
566 assert(!sub_command.empty());
567 subcommand_obj_sp = cmd_obj->GetSubcommandSP(sub_command);
568 if (!subcommand_obj_sp) {
570 "'%s' is not a valid sub-command of '%s'. "
571 "Unable to create alias.\n",
572 args[0].c_str(), actual_command.c_str());
573 return false;
574 }
575
576 sub_cmd_obj = subcommand_obj_sp.get();
577 use_subcommand = true;
578 args.Shift(); // Shift the sub_command word off the argument vector.
579 cmd_obj = sub_cmd_obj;
580 }
581
582 // Verify & handle any options/arguments passed to the alias command
583
584 std::string args_string;
585
586 if (!args.empty()) {
587 CommandObjectSP tmp_sp =
589 if (use_subcommand)
590 tmp_sp = m_interpreter.GetCommandSPExact(sub_cmd_obj->GetCommandName());
591
592 args.GetCommandString(args_string);
593 }
594
595 if (m_interpreter.AliasExists(alias_command) ||
596 m_interpreter.UserCommandExists(alias_command)) {
598 "Overwriting existing definition for '%s'.\n", alias_command.c_str());
599 }
600
602 alias_command, use_subcommand ? subcommand_obj_sp : command_obj_sp,
603 args_string)) {
605 alias->SetHelp(m_command_options.m_help.GetCurrentValue());
607 alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
609 } else {
610 result.AppendError("Unable to create requested alias.\n");
611 return false;
612 }
613
614 return result.Succeeded();
615 }
616};
617
618#pragma mark CommandObjectCommandsUnalias
619// CommandObjectCommandsUnalias
620
622public:
625 interpreter, "command unalias",
626 "Delete one or more custom commands defined by 'command alias'.",
627 nullptr) {
629 CommandArgumentData alias_arg;
630
631 // Define the first (and only) variant of this arg.
632 alias_arg.arg_type = eArgTypeAliasName;
634
635 // There is only one variant this argument could be; put it into the
636 // argument entry.
637 arg.push_back(alias_arg);
638
639 // Push the data for the first argument into the m_arguments vector.
640 m_arguments.push_back(arg);
641 }
642
643 ~CommandObjectCommandsUnalias() override = default;
644
645 void
647 OptionElementVector &opt_element_vector) override {
648 if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0)
649 return;
650
651 for (const auto &ent : m_interpreter.GetAliases()) {
652 request.TryCompleteCurrentArg(ent.first, ent.second->GetHelp());
653 }
654 }
655
656protected:
657 bool DoExecute(Args &args, CommandReturnObject &result) override {
658 CommandObject::CommandMap::iterator pos;
659 CommandObject *cmd_obj;
660
661 if (args.empty()) {
662 result.AppendError("must call 'unalias' with a valid alias");
663 return false;
664 }
665
666 auto command_name = args[0].ref();
667 cmd_obj = m_interpreter.GetCommandObject(command_name);
668 if (!cmd_obj) {
670 "'%s' is not a known command.\nTry 'help' to see a "
671 "current list of commands.\n",
672 args[0].c_str());
673 return false;
674 }
675
676 if (m_interpreter.CommandExists(command_name)) {
677 if (cmd_obj->IsRemovable()) {
679 "'%s' is not an alias, it is a debugger command which can be "
680 "removed using the 'command delete' command.\n",
681 args[0].c_str());
682 } else {
684 "'%s' is a permanent debugger command and cannot be removed.\n",
685 args[0].c_str());
686 }
687 return false;
688 }
689
690 if (!m_interpreter.RemoveAlias(command_name)) {
691 if (m_interpreter.AliasExists(command_name))
693 "Error occurred while attempting to unalias '%s'.\n",
694 args[0].c_str());
695 else
696 result.AppendErrorWithFormat("'%s' is not an existing alias.\n",
697 args[0].c_str());
698 return false;
699 }
700
702 return result.Succeeded();
703 }
704};
705
706#pragma mark CommandObjectCommandsDelete
707// CommandObjectCommandsDelete
708
710public:
713 interpreter, "command delete",
714 "Delete one or more custom commands defined by 'command regex'.",
715 nullptr) {
717 CommandArgumentData alias_arg;
718
719 // Define the first (and only) variant of this arg.
720 alias_arg.arg_type = eArgTypeCommandName;
722
723 // There is only one variant this argument could be; put it into the
724 // argument entry.
725 arg.push_back(alias_arg);
726
727 // Push the data for the first argument into the m_arguments vector.
728 m_arguments.push_back(arg);
729 }
730
731 ~CommandObjectCommandsDelete() override = default;
732
733 void
735 OptionElementVector &opt_element_vector) override {
736 if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0)
737 return;
738
739 for (const auto &ent : m_interpreter.GetCommands()) {
740 if (ent.second->IsRemovable())
741 request.TryCompleteCurrentArg(ent.first, ent.second->GetHelp());
742 }
743 }
744
745protected:
746 bool DoExecute(Args &args, CommandReturnObject &result) override {
747 CommandObject::CommandMap::iterator pos;
748
749 if (args.empty()) {
750 result.AppendErrorWithFormat("must call '%s' with one or more valid user "
751 "defined regular expression command names",
752 GetCommandName().str().c_str());
753 return false;
754 }
755
756 auto command_name = args[0].ref();
757 if (!m_interpreter.CommandExists(command_name)) {
758 StreamString error_msg_stream;
759 const bool generate_upropos = true;
760 const bool generate_type_lookup = false;
762 &error_msg_stream, command_name, llvm::StringRef(), llvm::StringRef(),
763 generate_upropos, generate_type_lookup);
764 result.AppendError(error_msg_stream.GetString());
765 return false;
766 }
767
768 if (!m_interpreter.RemoveCommand(command_name)) {
770 "'%s' is a permanent debugger command and cannot be removed.\n",
771 args[0].c_str());
772 return false;
773 }
774
776 return true;
777 }
778};
779
780// CommandObjectCommandsAddRegex
781
782#define LLDB_OPTIONS_regex
783#include "CommandOptions.inc"
784
785#pragma mark CommandObjectCommandsAddRegex
786
789public:
792 interpreter, "command regex",
793 "Define a custom command in terms of "
794 "existing commands by matching "
795 "regular expressions.",
796 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
800 R"(
801)"
802 "This command allows the user to create powerful regular expression commands \
803with substitutions. The regular expressions and substitutions are specified \
804using the regular expression substitution format of:"
805 R"(
806
807 s/<regex>/<subst>/
808
809)"
810 "<regex> is a regular expression that can use parenthesis to capture regular \
811expression input and substitute the captured matches in the output using %1 \
812for the first match, %2 for the second, and so on."
813 R"(
814
815)"
816 "The regular expressions can all be specified on the command line if more than \
817one argument is provided. If just the command name is provided on the command \
818line, then the regular expressions and substitutions can be entered on separate \
819lines, followed by an empty line to terminate the command definition."
820 R"(
821
822EXAMPLES
823
824)"
825 "The following example will define a regular expression command named 'f' that \
826will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
827a number follows 'f':"
828 R"(
829
830 (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')");
832 m_arguments.push_back({thread_arg});
833 }
834
835 ~CommandObjectCommandsAddRegex() override = default;
836
837protected:
838 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
839 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
840 if (output_sp && interactive) {
841 output_sp->PutCString("Enter one or more sed substitution commands in "
842 "the form: 's/<regex>/<subst>/'.\nTerminate the "
843 "substitution list with an empty line.\n");
844 output_sp->Flush();
845 }
846 }
847
848 void IOHandlerInputComplete(IOHandler &io_handler,
849 std::string &data) override {
850 io_handler.SetIsDone(true);
851 if (m_regex_cmd_up) {
852 StringList lines;
853 if (lines.SplitIntoLines(data)) {
854 bool check_only = false;
855 for (const std::string &line : lines) {
856 Status error = AppendRegexSubstitution(line, check_only);
857 if (error.Fail()) {
858 if (!GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) {
859 StreamSP out_stream = GetDebugger().GetAsyncOutputStream();
860 out_stream->Printf("error: %s\n", error.AsCString());
861 }
862 }
863 }
864 }
865 if (m_regex_cmd_up->HasRegexEntries()) {
866 CommandObjectSP cmd_sp(m_regex_cmd_up.release());
867 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
868 }
869 }
870 }
871
872 bool DoExecute(Args &command, CommandReturnObject &result) override {
873 const size_t argc = command.GetArgumentCount();
874 if (argc == 0) {
875 result.AppendError("usage: 'command regex <command-name> "
876 "[s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
877 return false;
878 }
879
881 auto name = command[0].ref();
882 m_regex_cmd_up = std::make_unique<CommandObjectRegexCommand>(
884 true);
885
886 if (argc == 1) {
887 Debugger &debugger = GetDebugger();
888 bool color_prompt = debugger.GetUseColor();
889 const bool multiple_lines = true; // Get multiple lines
890 IOHandlerSP io_handler_sp(new IOHandlerEditline(
891 debugger, IOHandler::Type::Other,
892 "lldb-regex", // Name of input reader for history
893 llvm::StringRef("> "), // Prompt
894 llvm::StringRef(), // Continuation prompt
895 multiple_lines, color_prompt,
896 0, // Don't show line numbers
897 *this));
898
899 if (io_handler_sp) {
900 debugger.RunIOHandlerAsync(io_handler_sp);
902 }
903 } else {
904 for (auto &entry : command.entries().drop_front()) {
905 bool check_only = false;
906 error = AppendRegexSubstitution(entry.ref(), check_only);
907 if (error.Fail())
908 break;
910
911 if (error.Success()) {
913 }
914 }
915 if (error.Fail()) {
916 result.AppendError(error.AsCString());
917 }
918
919 return result.Succeeded();
920 }
921
922 Status AppendRegexSubstitution(const llvm::StringRef &regex_sed,
923 bool check_only) {
925
926 if (!m_regex_cmd_up) {
927 error.SetErrorStringWithFormat(
928 "invalid regular expression command object for: '%.*s'",
929 (int)regex_sed.size(), regex_sed.data());
930 return error;
931 }
932
933 size_t regex_sed_size = regex_sed.size();
934
935 if (regex_sed_size <= 1) {
936 error.SetErrorStringWithFormat(
937 "regular expression substitution string is too short: '%.*s'",
938 (int)regex_sed.size(), regex_sed.data());
939 return error;
940 }
941
942 if (regex_sed[0] != 's') {
943 error.SetErrorStringWithFormat("regular expression substitution string "
944 "doesn't start with 's': '%.*s'",
945 (int)regex_sed.size(), regex_sed.data());
946 return error;
947 }
948 const size_t first_separator_char_pos = 1;
949 // use the char that follows 's' as the regex separator character so we can
950 // have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
951 const char separator_char = regex_sed[first_separator_char_pos];
952 const size_t second_separator_char_pos =
953 regex_sed.find(separator_char, first_separator_char_pos + 1);
954
955 if (second_separator_char_pos == std::string::npos) {
956 error.SetErrorStringWithFormat(
957 "missing second '%c' separator char after '%.*s' in '%.*s'",
958 separator_char,
959 (int)(regex_sed.size() - first_separator_char_pos - 1),
960 regex_sed.data() + (first_separator_char_pos + 1),
961 (int)regex_sed.size(), regex_sed.data());
962 return error;
963 }
964
965 const size_t third_separator_char_pos =
966 regex_sed.find(separator_char, second_separator_char_pos + 1);
967
968 if (third_separator_char_pos == std::string::npos) {
969 error.SetErrorStringWithFormat(
970 "missing third '%c' separator char after '%.*s' in '%.*s'",
971 separator_char,
972 (int)(regex_sed.size() - second_separator_char_pos - 1),
973 regex_sed.data() + (second_separator_char_pos + 1),
974 (int)regex_sed.size(), regex_sed.data());
975 return error;
976 }
977
978 if (third_separator_char_pos != regex_sed_size - 1) {
979 // Make sure that everything that follows the last regex separator char
980 if (regex_sed.find_first_not_of("\t\n\v\f\r ",
981 third_separator_char_pos + 1) !=
982 std::string::npos) {
983 error.SetErrorStringWithFormat(
984 "extra data found after the '%.*s' regular expression substitution "
985 "string: '%.*s'",
986 (int)third_separator_char_pos + 1, regex_sed.data(),
987 (int)(regex_sed.size() - third_separator_char_pos - 1),
988 regex_sed.data() + (third_separator_char_pos + 1));
989 return error;
990 }
991 } else if (first_separator_char_pos + 1 == second_separator_char_pos) {
992 error.SetErrorStringWithFormat(
993 "<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
994 separator_char, separator_char, separator_char, (int)regex_sed.size(),
995 regex_sed.data());
996 return error;
997 } else if (second_separator_char_pos + 1 == third_separator_char_pos) {
998 error.SetErrorStringWithFormat(
999 "<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1000 separator_char, separator_char, separator_char, (int)regex_sed.size(),
1001 regex_sed.data());
1002 return error;
1003 }
1005 if (!check_only) {
1006 std::string regex(std::string(regex_sed.substr(
1007 first_separator_char_pos + 1,
1008 second_separator_char_pos - first_separator_char_pos - 1)));
1009 std::string subst(std::string(regex_sed.substr(
1010 second_separator_char_pos + 1,
1011 third_separator_char_pos - second_separator_char_pos - 1)));
1012 m_regex_cmd_up->AddRegexCommand(regex, subst);
1013 }
1014 return error;
1015 }
1019 if (m_regex_cmd_up->HasRegexEntries()) {
1020 CommandObjectSP cmd_sp(m_regex_cmd_up.release());
1021 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1023 }
1024 }
1025
1026private:
1027 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_up;
1028
1029 class CommandOptions : public Options {
1030 public:
1031 CommandOptions() = default;
1032
1033 ~CommandOptions() override = default;
1034
1035 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1036 ExecutionContext *execution_context) override {
1037 Status error;
1038 const int short_option = m_getopt_table[option_idx].val;
1039
1040 switch (short_option) {
1041 case 'h':
1042 m_help.assign(std::string(option_arg));
1043 break;
1044 case 's':
1045 m_syntax.assign(std::string(option_arg));
1046 break;
1047 default:
1048 llvm_unreachable("Unimplemented option");
1049 }
1051 return error;
1053
1054 void OptionParsingStarting(ExecutionContext *execution_context) override {
1055 m_help.clear();
1056 m_syntax.clear();
1059 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1060 return llvm::ArrayRef(g_regex_options);
1062
1063 llvm::StringRef GetHelp() { return m_help; }
1064
1065 llvm::StringRef GetSyntax() { return m_syntax; }
1066
1067 protected:
1068 // Instance variables to hold the values for command options.
1069
1070 std::string m_help;
1071 std::string m_syntax;
1072 };
1073
1074 Options *GetOptions() override { return &m_options; }
1075
1076 CommandOptions m_options;
1077};
1078
1080public:
1081 CommandObjectPythonFunction(CommandInterpreter &interpreter, std::string name,
1082 std::string funct, std::string help,
1084 : CommandObjectRaw(interpreter, name), m_function_name(funct),
1085 m_synchro(synch) {
1086 if (!help.empty())
1087 SetHelp(help);
1088 else {
1089 StreamString stream;
1090 stream.Printf("For more information run 'help %s'", name.c_str());
1091 SetHelp(stream.GetString());
1092 }
1093 }
1094
1095 ~CommandObjectPythonFunction() override = default;
1096
1097 bool IsRemovable() const override { return true; }
1098
1099 const std::string &GetFunctionName() { return m_function_name; }
1100
1102
1103 llvm::StringRef GetHelpLong() override {
1105 return CommandObjectRaw::GetHelpLong();
1106
1108 if (!scripter)
1109 return CommandObjectRaw::GetHelpLong();
1110
1111 std::string docstring;
1113 scripter->GetDocumentationForItem(m_function_name.c_str(), docstring);
1114 if (!docstring.empty())
1115 SetHelpLong(docstring);
1116 return CommandObjectRaw::GetHelpLong();
1117 }
1118
1119protected:
1120 bool DoExecute(llvm::StringRef raw_command_line,
1121 CommandReturnObject &result) override {
1123
1124 Status error;
1125
1127
1128 if (!scripter || !scripter->RunScriptBasedCommand(
1129 m_function_name.c_str(), raw_command_line, m_synchro,
1130 result, error, m_exe_ctx)) {
1131 result.AppendError(error.AsCString());
1132 } else {
1133 // Don't change the status if the command already set it...
1134 if (result.GetStatus() == eReturnStatusInvalid) {
1135 if (result.GetOutputData().empty())
1137 else
1139 }
1140 }
1141
1142 return result.Succeeded();
1143 }
1144
1145private:
1146 std::string m_function_name;
1149};
1150
1152public:
1154 std::string name,
1155 StructuredData::GenericSP cmd_obj_sp,
1157 : CommandObjectRaw(interpreter, name), m_cmd_obj_sp(cmd_obj_sp),
1158 m_synchro(synch), m_fetched_help_short(false),
1159 m_fetched_help_long(false) {
1160 StreamString stream;
1161 stream.Printf("For more information run 'help %s'", name.c_str());
1162 SetHelp(stream.GetString());
1163 if (ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter())
1164 GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
1165 }
1166
1167 ~CommandObjectScriptingObject() override = default;
1168
1169 bool IsRemovable() const override { return true; }
1170
1172
1173 llvm::StringRef GetHelp() override {
1175 return CommandObjectRaw::GetHelp();
1177 if (!scripter)
1178 return CommandObjectRaw::GetHelp();
1179 std::string docstring;
1181 scripter->GetShortHelpForCommandObject(m_cmd_obj_sp, docstring);
1182 if (!docstring.empty())
1183 SetHelp(docstring);
1184
1185 return CommandObjectRaw::GetHelp();
1186 }
1187
1188 llvm::StringRef GetHelpLong() override {
1190 return CommandObjectRaw::GetHelpLong();
1191
1193 if (!scripter)
1194 return CommandObjectRaw::GetHelpLong();
1195
1196 std::string docstring;
1198 scripter->GetLongHelpForCommandObject(m_cmd_obj_sp, docstring);
1199 if (!docstring.empty())
1200 SetHelpLong(docstring);
1201 return CommandObjectRaw::GetHelpLong();
1202 }
1203
1204protected:
1205 bool DoExecute(llvm::StringRef raw_command_line,
1206 CommandReturnObject &result) override {
1208
1209 Status error;
1210
1212
1213 if (!scripter ||
1214 !scripter->RunScriptBasedCommand(m_cmd_obj_sp, raw_command_line,
1215 m_synchro, result, error, m_exe_ctx)) {
1216 result.AppendError(error.AsCString());
1217 } else {
1218 // Don't change the status if the command already set it...
1219 if (result.GetStatus() == eReturnStatusInvalid) {
1220 if (result.GetOutputData().empty())
1222 else
1224 }
1225 }
1226
1227 return result.Succeeded();
1228 }
1229
1230private:
1235};
1236
1237// CommandObjectCommandsScriptImport
1238#define LLDB_OPTIONS_script_import
1239#include "CommandOptions.inc"
1240
1242public:
1244 : CommandObjectParsed(interpreter, "command script import",
1245 "Import a scripting module in LLDB.", nullptr) {
1247 CommandArgumentData cmd_arg;
1248
1249 // Define the first (and only) variant of this arg.
1250 cmd_arg.arg_type = eArgTypeFilename;
1252
1253 // There is only one variant this argument could be; put it into the
1254 // argument entry.
1255 arg1.push_back(cmd_arg);
1256
1257 // Push the data for the first argument into the m_arguments vector.
1258 m_arguments.push_back(arg1);
1259 }
1260
1262
1263 void
1265 OptionElementVector &opt_element_vector) override {
1268 request, nullptr);
1269 }
1270
1271 Options *GetOptions() override { return &m_options; }
1272
1273protected:
1274 class CommandOptions : public Options {
1275 public:
1276 CommandOptions() = default;
1277
1278 ~CommandOptions() override = default;
1279
1280 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1281 ExecutionContext *execution_context) override {
1282 Status error;
1283 const int short_option = m_getopt_table[option_idx].val;
1284
1285 switch (short_option) {
1286 case 'r':
1287 // NO-OP
1288 break;
1289 case 'c':
1291 break;
1292 case 's':
1293 silent = true;
1294 break;
1295 default:
1296 llvm_unreachable("Unimplemented option");
1297 }
1298
1299 return error;
1300 }
1301
1302 void OptionParsingStarting(ExecutionContext *execution_context) override {
1304 }
1305
1306 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1307 return llvm::ArrayRef(g_script_import_options);
1308 }
1310 bool silent = false;
1311 };
1312
1313 bool DoExecute(Args &command, CommandReturnObject &result) override {
1314 if (command.empty()) {
1315 result.AppendError("command script import needs one or more arguments");
1316 return false;
1317 }
1318
1319 FileSpec source_dir = {};
1322 if (!source_dir) {
1323 result.AppendError("command script import -c can only be specified "
1324 "from a command file");
1325 return false;
1326 }
1327 }
1328
1329 for (auto &entry : command.entries()) {
1330 Status error;
1331
1332 LoadScriptOptions options;
1333 options.SetInitSession(true);
1334 options.SetSilent(m_options.silent);
1335
1336 // FIXME: this is necessary because CommandObject::CheckRequirements()
1337 // assumes that commands won't ever be recursively invoked, but it's
1338 // actually possible to craft a Python script that does other "command
1339 // script imports" in __lldb_init_module the real fix is to have
1340 // recursive commands possible with a CommandInvocation object separate
1341 // from the CommandObject itself, so that recursive command invocations
1342 // won't stomp on each other (wrt to execution contents, options, and
1343 // more)
1344 m_exe_ctx.Clear();
1345 if (GetDebugger().GetScriptInterpreter()->LoadScriptingModule(
1346 entry.c_str(), options, error, /*module_sp=*/nullptr,
1347 source_dir)) {
1349 } else {
1350 result.AppendErrorWithFormat("module importing failed: %s",
1351 error.AsCString());
1352 }
1353 }
1354
1355 return result.Succeeded();
1356 }
1357
1359};
1360
1361#define LLDB_OPTIONS_script_add
1362#include "CommandOptions.inc"
1363
1366public:
1368 : CommandObjectParsed(interpreter, "command script add",
1369 "Add a scripted function as an LLDB command.",
1370 "Add a scripted function as an lldb command. "
1371 "If you provide a single argument, the command "
1372 "will be added at the root level of the command "
1373 "hierarchy. If there are more arguments they "
1374 "must be a path to a user-added container "
1375 "command, and the last element will be the new "
1376 "command name."),
1379 CommandArgumentData cmd_arg;
1380
1381 // This is one or more command names, which form the path to the command
1382 // you want to add.
1383 cmd_arg.arg_type = eArgTypeCommand;
1385
1386 // There is only one variant this argument could be; put it into the
1387 // argument entry.
1388 arg1.push_back(cmd_arg);
1389
1390 // Push the data for the first argument into the m_arguments vector.
1391 m_arguments.push_back(arg1);
1392 }
1393
1395
1396 Options *GetOptions() override { return &m_options; }
1397
1398 void
1400 OptionElementVector &opt_element_vector) override {
1402 opt_element_vector);
1403 }
1404
1405protected:
1406 class CommandOptions : public Options {
1407 public:
1408 CommandOptions() = default;
1409
1410 ~CommandOptions() override = default;
1411
1412 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1413 ExecutionContext *execution_context) override {
1414 Status error;
1415 const int short_option = m_getopt_table[option_idx].val;
1416
1417 switch (short_option) {
1418 case 'f':
1419 if (!option_arg.empty())
1420 m_funct_name = std::string(option_arg);
1421 break;
1422 case 'c':
1423 if (!option_arg.empty())
1424 m_class_name = std::string(option_arg);
1425 break;
1426 case 'h':
1427 if (!option_arg.empty())
1428 m_short_help = std::string(option_arg);
1429 break;
1430 case 'o':
1432 break;
1433 case 's':
1436 option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
1437 if (!error.Success())
1438 error.SetErrorStringWithFormat(
1439 "unrecognized value for synchronicity '%s'",
1440 option_arg.str().c_str());
1441 break;
1442 default:
1443 llvm_unreachable("Unimplemented option");
1444 }
1445
1446 return error;
1447 }
1448
1449 void OptionParsingStarting(ExecutionContext *execution_context) override {
1450 m_class_name.clear();
1451 m_funct_name.clear();
1452 m_short_help.clear();
1455 }
1456
1457 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1458 return llvm::ArrayRef(g_script_add_options);
1459 }
1460
1461 // Instance variables to hold the values for command options.
1462
1463 std::string m_class_name;
1464 std::string m_funct_name;
1465 std::string m_short_help;
1469 };
1470
1471 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
1472 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
1473 if (output_sp && interactive) {
1474 output_sp->PutCString(g_python_command_instructions);
1475 output_sp->Flush();
1476 }
1477 }
1478
1480 std::string &data) override {
1481 StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
1482
1484 if (interpreter) {
1485 StringList lines;
1486 lines.SplitIntoLines(data);
1487 if (lines.GetSize() > 0) {
1488 std::string funct_name_str;
1489 if (interpreter->GenerateScriptAliasFunction(lines, funct_name_str)) {
1490 if (funct_name_str.empty()) {
1491 error_sp->Printf("error: unable to obtain a function name, didn't "
1492 "add python command.\n");
1493 error_sp->Flush();
1494 } else {
1495 // everything should be fine now, let's add this alias
1496
1497 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(
1498 m_interpreter, m_cmd_name, funct_name_str, m_short_help,
1500 if (!m_container) {
1502 m_cmd_name, command_obj_sp, m_overwrite);
1503 if (error.Fail()) {
1504 error_sp->Printf("error: unable to add selected command: '%s'",
1505 error.AsCString());
1506 error_sp->Flush();
1507 }
1508 } else {
1509 llvm::Error llvm_error = m_container->LoadUserSubcommand(
1510 m_cmd_name, command_obj_sp, m_overwrite);
1511 if (llvm_error) {
1512 error_sp->Printf("error: unable to add selected command: '%s'",
1513 llvm::toString(std::move(llvm_error)).c_str());
1514 error_sp->Flush();
1515 }
1516 }
1517 }
1518 } else {
1519 error_sp->Printf(
1520 "error: unable to create function, didn't add python command\n");
1521 error_sp->Flush();
1522 }
1523 } else {
1524 error_sp->Printf("error: empty function, didn't add python command\n");
1525 error_sp->Flush();
1526 }
1527 } else {
1528 error_sp->Printf(
1529 "error: script interpreter missing, didn't add python command\n");
1530 error_sp->Flush();
1531 }
1532
1533 io_handler.SetIsDone(true);
1534 }
1535
1536 bool DoExecute(Args &command, CommandReturnObject &result) override {
1537 if (GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) {
1538 result.AppendError("only scripting language supported for scripted "
1539 "commands is currently Python");
1540 return false;
1541 }
1542
1543 if (command.GetArgumentCount() == 0) {
1544 result.AppendError("'command script add' requires at least one argument");
1545 return false;
1546 }
1547 // Store the options in case we get multi-line input, also figure out the
1548 // default if not user supplied:
1549 switch (m_options.m_overwrite_lazy) {
1550 case eLazyBoolCalculate:
1552 break;
1553 case eLazyBoolYes:
1554 m_overwrite = true;
1555 break;
1556 case eLazyBoolNo:
1557 m_overwrite = false;
1558 }
1559
1560 Status path_error;
1562 command, true, path_error);
1563
1564 if (path_error.Fail()) {
1565 result.AppendErrorWithFormat("error in command path: %s",
1566 path_error.AsCString());
1567 return false;
1568 }
1569
1570 if (!m_container) {
1571 // This is getting inserted into the root of the interpreter.
1572 m_cmd_name = std::string(command[0].ref());
1573 } else {
1574 size_t num_args = command.GetArgumentCount();
1575 m_cmd_name = std::string(command[num_args - 1].ref());
1576 }
1577
1580
1581 // Handle the case where we prompt for the script code first:
1582 if (m_options.m_class_name.empty() && m_options.m_funct_name.empty()) {
1584 *this); // IOHandlerDelegate
1585 return result.Succeeded();
1586 }
1587
1588 CommandObjectSP new_cmd_sp;
1589 if (m_options.m_class_name.empty()) {
1590 new_cmd_sp.reset(new CommandObjectPythonFunction(
1593 } else {
1595 if (!interpreter) {
1596 result.AppendError("cannot find ScriptInterpreter");
1597 return false;
1598 }
1599
1600 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(
1601 m_options.m_class_name.c_str());
1602 if (!cmd_obj_sp) {
1603 result.AppendErrorWithFormatv("cannot create helper object for: "
1604 "'{0}'", m_options.m_class_name);
1605 return false;
1606 }
1607
1608 new_cmd_sp.reset(new CommandObjectScriptingObject(
1610 }
1611
1612 // Assume we're going to succeed...
1614 if (!m_container) {
1615 Status add_error =
1617 if (add_error.Fail())
1618 result.AppendErrorWithFormat("cannot add command: %s",
1619 add_error.AsCString());
1620 } else {
1621 llvm::Error llvm_error =
1623 if (llvm_error)
1624 result.AppendErrorWithFormat("cannot add command: %s",
1625 llvm::toString(std::move(llvm_error)).c_str());
1626 }
1627 return result.Succeeded();
1628 }
1629
1631 std::string m_cmd_name;
1633 std::string m_short_help;
1634 bool m_overwrite = false;
1637};
1638
1639// CommandObjectCommandsScriptList
1640
1642public:
1644 : CommandObjectParsed(interpreter, "command script list",
1645 "List defined top-level scripted commands.",
1646 nullptr) {}
1647
1649
1650 bool DoExecute(Args &command, CommandReturnObject &result) override {
1652
1654
1655 return true;
1656 }
1657};
1658
1659// CommandObjectCommandsScriptClear
1660
1662public:
1664 : CommandObjectParsed(interpreter, "command script clear",
1665 "Delete all scripted commands.", nullptr) {}
1666
1668
1669protected:
1670 bool DoExecute(Args &command, CommandReturnObject &result) override {
1672
1674
1675 return true;
1676 }
1677};
1678
1679// CommandObjectCommandsScriptDelete
1680
1682public:
1685 interpreter, "command script delete",
1686 "Delete a scripted command by specifying the path to the command.",
1687 nullptr) {
1689 CommandArgumentData cmd_arg;
1690
1691 // This is a list of command names forming the path to the command
1692 // to be deleted.
1693 cmd_arg.arg_type = eArgTypeCommand;
1695
1696 // There is only one variant this argument could be; put it into the
1697 // argument entry.
1698 arg1.push_back(cmd_arg);
1699
1700 // Push the data for the first argument into the m_arguments vector.
1701 m_arguments.push_back(arg1);
1702 }
1703
1705
1706 void
1708 OptionElementVector &opt_element_vector) override {
1710 opt_element_vector);
1711 }
1712
1713protected:
1714 bool DoExecute(Args &command, CommandReturnObject &result) override {
1715
1716 llvm::StringRef root_cmd = command[0].ref();
1717 size_t num_args = command.GetArgumentCount();
1718
1719 if (root_cmd.empty()) {
1720 result.AppendErrorWithFormat("empty root command name");
1721 return false;
1722 }
1725 result.AppendErrorWithFormat("can only delete user defined commands, "
1726 "but no user defined commands found");
1727 return false;
1728 }
1729
1730 CommandObjectSP cmd_sp = m_interpreter.GetCommandSPExact(root_cmd);
1731 if (!cmd_sp) {
1732 result.AppendErrorWithFormat("command '%s' not found.",
1733 command[0].c_str());
1734 return false;
1735 }
1736 if (!cmd_sp->IsUserCommand()) {
1737 result.AppendErrorWithFormat("command '%s' is not a user command.",
1738 command[0].c_str());
1739 return false;
1740 }
1741 if (cmd_sp->GetAsMultiwordCommand() && num_args == 1) {
1742 result.AppendErrorWithFormat("command '%s' is a multi-word command.\n "
1743 "Delete with \"command container delete\"",
1744 command[0].c_str());
1745 return false;
1746 }
1747
1748 if (command.GetArgumentCount() == 1) {
1749 m_interpreter.RemoveUser(root_cmd);
1751 return true;
1752 }
1753 // We're deleting a command from a multiword command. Verify the command
1754 // path:
1755 Status error;
1756 CommandObjectMultiword *container =
1758 error);
1759 if (error.Fail()) {
1760 result.AppendErrorWithFormat("could not resolve command path: %s",
1761 error.AsCString());
1762 return false;
1763 }
1764 if (!container) {
1765 // This means that command only had a leaf command, so the container is
1766 // the root. That should have been handled above.
1767 result.AppendErrorWithFormat("could not find a container for '%s'",
1768 command[0].c_str());
1769 return false;
1770 }
1771 const char *leaf_cmd = command[num_args - 1].c_str();
1772 llvm::Error llvm_error = container->RemoveUserSubcommand(leaf_cmd,
1773 /* multiword not okay */ false);
1774 if (llvm_error) {
1775 result.AppendErrorWithFormat("could not delete command '%s': %s",
1776 leaf_cmd,
1777 llvm::toString(std::move(llvm_error)).c_str());
1778 return false;
1779 }
1780
1781 Stream &out_stream = result.GetOutputStream();
1782
1783 out_stream << "Deleted command:";
1784 for (size_t idx = 0; idx < num_args; idx++) {
1785 out_stream << ' ';
1786 out_stream << command[idx].c_str();
1787 }
1788 out_stream << '\n';
1790 return true;
1791 }
1792};
1793
1794#pragma mark CommandObjectMultiwordCommandsScript
1795
1796// CommandObjectMultiwordCommandsScript
1797
1799public:
1802 interpreter, "command script",
1803 "Commands for managing custom "
1804 "commands implemented by "
1805 "interpreter scripts.",
1806 "command script <subcommand> [<subcommand-options>]") {
1807 LoadSubCommand("add", CommandObjectSP(
1808 new CommandObjectCommandsScriptAdd(interpreter)));
1810 "delete",
1811 CommandObjectSP(new CommandObjectCommandsScriptDelete(interpreter)));
1813 "clear",
1814 CommandObjectSP(new CommandObjectCommandsScriptClear(interpreter)));
1815 LoadSubCommand("list", CommandObjectSP(new CommandObjectCommandsScriptList(
1816 interpreter)));
1818 "import",
1819 CommandObjectSP(new CommandObjectCommandsScriptImport(interpreter)));
1820 }
1821
1823};
1824
1825#pragma mark CommandObjectCommandContainer
1826#define LLDB_OPTIONS_container_add
1827#include "CommandOptions.inc"
1828
1830public:
1833 interpreter, "command container add",
1834 "Add a container command to lldb. Adding to built-"
1835 "in container commands is not allowed.",
1836 "command container add [[path1]...] container-name") {
1838 CommandArgumentData cmd_arg;
1839
1840 // This is one or more command names, which form the path to the command
1841 // you want to add.
1842 cmd_arg.arg_type = eArgTypeCommand;
1844
1845 // There is only one variant this argument could be; put it into the
1846 // argument entry.
1847 arg1.push_back(cmd_arg);
1848
1849 // Push the data for the first argument into the m_arguments vector.
1850 m_arguments.push_back(arg1);
1851 }
1852
1854
1855 Options *GetOptions() override { return &m_options; }
1856
1857 void
1859 OptionElementVector &opt_element_vector) override {
1861 opt_element_vector);
1862 }
1863
1864protected:
1865 class CommandOptions : public Options {
1866 public:
1867 CommandOptions() = default;
1868
1869 ~CommandOptions() override = default;
1870
1871 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1872 ExecutionContext *execution_context) override {
1873 Status error;
1874 const int short_option = m_getopt_table[option_idx].val;
1875
1876 switch (short_option) {
1877 case 'h':
1878 if (!option_arg.empty())
1879 m_short_help = std::string(option_arg);
1880 break;
1881 case 'o':
1882 m_overwrite = true;
1883 break;
1884 case 'H':
1885 if (!option_arg.empty())
1886 m_long_help = std::string(option_arg);
1887 break;
1888 default:
1889 llvm_unreachable("Unimplemented option");
1890 }
1891
1892 return error;
1893 }
1894
1895 void OptionParsingStarting(ExecutionContext *execution_context) override {
1896 m_short_help.clear();
1897 m_long_help.clear();
1898 m_overwrite = false;
1899 }
1900
1901 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1902 return llvm::ArrayRef(g_container_add_options);
1903 }
1904
1905 // Instance variables to hold the values for command options.
1906
1907 std::string m_short_help;
1908 std::string m_long_help;
1909 bool m_overwrite = false;
1910 };
1911 bool DoExecute(Args &command, CommandReturnObject &result) override {
1912 size_t num_args = command.GetArgumentCount();
1913
1914 if (num_args == 0) {
1915 result.AppendError("no command was specified");
1916 return false;
1917 }
1918
1919 if (num_args == 1) {
1920 // We're adding this as a root command, so use the interpreter.
1921 const char *cmd_name = command.GetArgumentAtIndex(0);
1922 auto cmd_sp = CommandObjectSP(new CommandObjectMultiword(
1923 GetCommandInterpreter(), cmd_name, m_options.m_short_help.c_str(),
1924 m_options.m_long_help.c_str()));
1925 cmd_sp->GetAsMultiwordCommand()->SetRemovable(true);
1927 cmd_name, cmd_sp, m_options.m_overwrite);
1928 if (add_error.Fail()) {
1929 result.AppendErrorWithFormat("error adding command: %s",
1930 add_error.AsCString());
1931 return false;
1932 }
1934 return true;
1935 }
1936
1937 // We're adding this to a subcommand, first find the subcommand:
1938 Status path_error;
1939 CommandObjectMultiword *add_to_me =
1941 path_error);
1942
1943 if (!add_to_me) {
1944 result.AppendErrorWithFormat("error adding command: %s",
1945 path_error.AsCString());
1946 return false;
1947 }
1948
1949 const char *cmd_name = command.GetArgumentAtIndex(num_args - 1);
1950 auto cmd_sp = CommandObjectSP(new CommandObjectMultiword(
1951 GetCommandInterpreter(), cmd_name, m_options.m_short_help.c_str(),
1952 m_options.m_long_help.c_str()));
1953 llvm::Error llvm_error =
1954 add_to_me->LoadUserSubcommand(cmd_name, cmd_sp, m_options.m_overwrite);
1955 if (llvm_error) {
1956 result.AppendErrorWithFormat("error adding subcommand: %s",
1957 llvm::toString(std::move(llvm_error)).c_str());
1958 return false;
1959 }
1960
1962 return true;
1963 }
1964
1965private:
1967};
1968
1969#define LLDB_OPTIONS_multiword_delete
1970#include "CommandOptions.inc"
1972public:
1975 interpreter, "command container delete",
1976 "Delete a container command previously added to "
1977 "lldb.",
1978 "command container delete [[path1] ...] container-cmd") {
1980 CommandArgumentData cmd_arg;
1981
1982 // This is one or more command names, which form the path to the command
1983 // you want to add.
1984 cmd_arg.arg_type = eArgTypeCommand;
1986
1987 // There is only one variant this argument could be; put it into the
1988 // argument entry.
1989 arg1.push_back(cmd_arg);
1990
1991 // Push the data for the first argument into the m_arguments vector.
1992 m_arguments.push_back(arg1);
1993 }
1994
1996
1997 void
1999 OptionElementVector &opt_element_vector) override {
2001 opt_element_vector);
2002 }
2003
2004protected:
2005 bool DoExecute(Args &command, CommandReturnObject &result) override {
2006 size_t num_args = command.GetArgumentCount();
2007
2008 if (num_args == 0) {
2009 result.AppendError("No command was specified.");
2010 return false;
2011 }
2012
2013 if (num_args == 1) {
2014 // We're removing a root command, so we need to delete it from the
2015 // interpreter.
2016 const char *cmd_name = command.GetArgumentAtIndex(0);
2017 // Let's do a little more work here so we can do better error reporting.
2019 CommandObjectSP cmd_sp = interp.GetCommandSPExact(cmd_name);
2020 if (!cmd_sp) {
2021 result.AppendErrorWithFormat("container command %s doesn't exist.",
2022 cmd_name);
2023 return false;
2024 }
2025 if (!cmd_sp->IsUserCommand()) {
2026 result.AppendErrorWithFormat(
2027 "container command %s is not a user command", cmd_name);
2028 return false;
2029 }
2030 if (!cmd_sp->GetAsMultiwordCommand()) {
2031 result.AppendErrorWithFormat("command %s is not a container command",
2032 cmd_name);
2033 return false;
2034 }
2035
2036 bool did_remove = GetCommandInterpreter().RemoveUserMultiword(cmd_name);
2037 if (!did_remove) {
2038 result.AppendErrorWithFormat("error removing command %s.", cmd_name);
2039 return false;
2040 }
2041
2043 return true;
2044 }
2045
2046 // We're removing a subcommand, first find the subcommand's owner:
2047 Status path_error;
2048 CommandObjectMultiword *container =
2050 path_error);
2051
2052 if (!container) {
2053 result.AppendErrorWithFormat("error removing container command: %s",
2054 path_error.AsCString());
2055 return false;
2056 }
2057 const char *leaf = command.GetArgumentAtIndex(num_args - 1);
2058 llvm::Error llvm_error =
2059 container->RemoveUserSubcommand(leaf, /* multiword okay */ true);
2060 if (llvm_error) {
2061 result.AppendErrorWithFormat("error removing container command: %s",
2062 llvm::toString(std::move(llvm_error)).c_str());
2063 return false;
2064 }
2066 return true;
2067 }
2068};
2069
2071public:
2074 interpreter, "command container",
2075 "Commands for adding container commands to lldb. "
2076 "Container commands are containers for other commands. You can "
2077 "add nested container commands by specifying a command path, "
2078 "but you can't add commands into the built-in command hierarchy.",
2079 "command container <subcommand> [<subcommand-options>]") {
2080 LoadSubCommand("add", CommandObjectSP(new CommandObjectCommandsContainerAdd(
2081 interpreter)));
2083 "delete",
2084 CommandObjectSP(new CommandObjectCommandsContainerDelete(interpreter)));
2085 }
2086
2088};
2089
2090#pragma mark CommandObjectMultiwordCommands
2091
2092// CommandObjectMultiwordCommands
2093
2095 CommandInterpreter &interpreter)
2096 : CommandObjectMultiword(interpreter, "command",
2097 "Commands for managing custom LLDB commands.",
2098 "command <subcommand> [<subcommand-options>]") {
2099 LoadSubCommand("source",
2100 CommandObjectSP(new CommandObjectCommandsSource(interpreter)));
2101 LoadSubCommand("alias",
2102 CommandObjectSP(new CommandObjectCommandsAlias(interpreter)));
2103 LoadSubCommand("unalias", CommandObjectSP(
2104 new CommandObjectCommandsUnalias(interpreter)));
2105 LoadSubCommand("delete",
2106 CommandObjectSP(new CommandObjectCommandsDelete(interpreter)));
2107 LoadSubCommand("container", CommandObjectSP(new CommandObjectCommandContainer(
2108 interpreter)));
2110 "regex", CommandObjectSP(new CommandObjectCommandsAddRegex(interpreter)));
2112 "script",
2113 CommandObjectSP(new CommandObjectMultiwordCommandsScript(interpreter)));
2114}
2115
static const char * g_python_command_instructions
static llvm::raw_ostream & error(Stream &strm)
CommandObjectCommandContainer(CommandInterpreter &interpreter)
~CommandObjectCommandContainer() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
std::unique_ptr< CommandObjectRegexCommand > m_regex_cmd_up
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
~CommandObjectCommandsAddRegex() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectCommandsAddRegex(CommandInterpreter &interpreter)
Status AppendRegexSubstitution(const llvm::StringRef &regex_sed, bool check_only)
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
bool HandleAliasingNormalCommand(Args &args, CommandReturnObject &result)
bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
~CommandObjectCommandsAlias() override=default
bool HandleAliasingRawCommand(llvm::StringRef alias_command, llvm::StringRef raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
CommandObjectCommandsAlias(CommandInterpreter &interpreter)
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
~CommandObjectCommandsContainerAdd() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectCommandsContainerAdd(CommandInterpreter &interpreter)
CommandObjectCommandsContainerDelete(CommandInterpreter &interpreter)
bool DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
~CommandObjectCommandsContainerDelete() override=default
CommandObjectCommandsDelete(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
bool DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectCommandsDelete() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
bool DoExecute(Args &command, CommandReturnObject &result) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
~CommandObjectCommandsScriptAdd() override=default
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
ScriptedCommandSynchronicity m_synchronicity
CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter)
CommandObjectCommandsScriptClear(CommandInterpreter &interpreter)
~CommandObjectCommandsScriptClear() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectCommandsScriptDelete() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectCommandsScriptImport(CommandInterpreter &interpreter)
~CommandObjectCommandsScriptImport() override=default
~CommandObjectCommandsScriptList() override=default
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectCommandsScriptList(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
std::optional< std::string > GetRepeatCommand(Args &current_command_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectCommandsSource(CommandInterpreter &interpreter)
~CommandObjectCommandsSource() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectCommandsUnalias(CommandInterpreter &interpreter)
~CommandObjectCommandsUnalias() override=default
bool DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectMultiwordCommandsScript() override=default
CommandObjectMultiwordCommandsScript(CommandInterpreter &interpreter)
CommandObjectPythonFunction(CommandInterpreter &interpreter, std::string name, std::string funct, std::string help, ScriptedCommandSynchronicity synch)
ScriptedCommandSynchronicity GetSynchronicity()
ScriptedCommandSynchronicity m_synchro
bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
llvm::StringRef GetHelpLong() override
~CommandObjectPythonFunction() override=default
llvm::StringRef GetHelp() override
llvm::StringRef GetHelpLong() override
bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
~CommandObjectScriptingObject() override=default
StructuredData::GenericSP m_cmd_obj_sp
ScriptedCommandSynchronicity m_synchro
CommandObjectScriptingObject(CommandInterpreter &interpreter, std::string name, StructuredData::GenericSP cmd_obj_sp, ScriptedCommandSynchronicity synch)
ScriptedCommandSynchronicity GetSynchronicity()
A command line argument class.
Definition: Args.h:33
void Shift()
Shifts the first argument C string value of the array off the argument array.
Definition: Args.cpp:286
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.h:116
llvm::ArrayRef< ArgEntry > entries() const
Definition: Args.h:128
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition: Args.cpp:264
bool GetCommandString(std::string &command) const
Definition: Args.cpp:212
bool empty() const
Definition: Args.h:118
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
static void CompleteModifiableCmdPathArgs(CommandInterpreter &interpreter, CompletionRequest &request, OptionElementVector &opt_element_vector)
This completer works for commands whose only arguments are a command path.
void SetStopOnContinue(bool stop_on_continue)
bool UserMultiwordCommandExists(llvm::StringRef cmd) const
Determine whether a root-level user multiword command with this name exists.
bool RemoveAlias(llvm::StringRef alias_name)
CommandAlias * AddAlias(llvm::StringRef alias_name, lldb::CommandObjectSP &command_obj_sp, llvm::StringRef args_string=llvm::StringRef())
CommandObject * GetCommandObject(llvm::StringRef cmd, StringList *matches=nullptr, StringList *descriptions=nullptr) const
ExecutionContext GetExecutionContext() const
CommandObjectMultiword * VerifyUserMultiwordCmdPath(Args &path, bool leaf_is_command, Status &result)
Look up the command pointed to by path encoded in the arguments of the incoming command object.
Status AddUserCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
bool AliasExists(llvm::StringRef cmd) const
Determine whether an alias command with this name exists.
void GetHelp(CommandReturnObject &result, uint32_t types=eCommandTypesAllThem)
bool CommandExists(llvm::StringRef cmd) const
Determine whether a root level, built-in command with this name exists.
void GetPythonCommandsFromIOHandler(const char *prompt, IOHandlerDelegate &delegate, void *baton=nullptr)
lldb::CommandObjectSP GetCommandSPExact(llvm::StringRef cmd, bool include_aliases=false) const
bool RemoveUser(llvm::StringRef alias_name)
CommandObject * GetCommandObjectForCommand(llvm::StringRef &command_line)
bool RemoveUserMultiword(llvm::StringRef multiword_name)
bool UserCommandExists(llvm::StringRef cmd) const
Determine whether a root-level user command with this name exists.
const CommandObject::CommandMap & GetCommands() const
void HandleCommandsFromFile(FileSpec &file, const ExecutionContext &context, const CommandInterpreterRunOptions &options, CommandReturnObject &result)
Execute a list of commands from a file.
bool RemoveCommand(llvm::StringRef cmd)
const CommandObject::CommandMap & GetAliases() const
static void GenerateAdditionalHelpAvenuesMessage(Stream *s, llvm::StringRef command, llvm::StringRef prefix, llvm::StringRef subcommand, bool include_upropos=true, bool include_type_lookup=true)
CommandObjectMultiwordCommands(CommandInterpreter &interpreter)
llvm::Error LoadUserSubcommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj, bool can_replace) override
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
llvm::Error RemoveUserSubcommand(llvm::StringRef cmd_name, bool multiword_okay)
std::vector< CommandArgumentData > CommandArgumentEntry
virtual void SetHelpLong(llvm::StringRef str)
virtual bool WantsRawCommandString()=0
bool ParseOptionsAndNotify(Args &args, CommandReturnObject &result, OptionGroupOptions &group_options, ExecutionContext &exe_ctx)
llvm::StringRef GetCommandName() const
virtual bool IsMultiwordObject()
ExecutionContext m_exe_ctx
std::vector< CommandArgumentEntry > m_arguments
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
Flags & GetFlags()
The flags accessor.
virtual bool IsRemovable() const
virtual void SetHelp(llvm::StringRef str)
virtual lldb::CommandObjectSP GetSubcommandSP(llvm::StringRef sub_cmd, StringList *matches=nullptr)
void AppendErrorWithFormatv(const char *format, Args &&... args)
void void AppendError(llvm::StringRef in_string)
void AppendWarningWithFormat(const char *format,...) __attribute__((format(printf
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
lldb::ReturnStatus GetStatus() const
void void AppendWarning(llvm::StringRef in_string)
"lldb/Utility/ArgCompletionRequest.h"
void TryCompleteCurrentArg(llvm::StringRef completion, llvm::StringRef description="")
Adds a possible completion string if the completion would complete the current argument.
A class to manage flag bits.
Definition: Debugger.h:78
lldb::StreamSP GetAsyncOutputStream()
Definition: Debugger.cpp:1225
CommandInterpreter & GetCommandInterpreter()
Definition: Debugger.h:171
bool GetUseColor() const
Definition: Debugger.cpp:375
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
Definition: Debugger.cpp:1125
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
Definition: Debugger.cpp:1560
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void Clear()
Clear the object's state.
A file utility class.
Definition: FileSpec.h:56
bool IsRelative() const
Returns true if the filespec represents a relative path.
Definition: FileSpec.cpp:493
void MakeAbsolute(const FileSpec &dir)
Make the FileSpec absolute by treating it relative to dir.
Definition: FileSpec.cpp:516
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
static FileSystem & Instance()
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
Definition: Flags.h:73
A delegate class for use with IOHandler subclasses.
Definition: IOHandler.h:191
lldb::StreamFileSP GetErrorStreamFileSP()
Definition: IOHandler.cpp:107
lldb::StreamFileSP GetOutputStreamFileSP()
Definition: IOHandler.cpp:105
void SetIsDone(bool b)
Definition: IOHandler.h:87
LoadScriptOptions & SetInitSession(bool b)
LoadScriptOptions & SetSilent(bool b)
void Append(OptionGroup *group)
Append options from a OptionGroup class.
Definition: Options.cpp:755
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
const char * GetCurrentValue() const
Status SetCurrentValue(llvm::StringRef value)
A pair of an option list with a 'raw' string as a suffix.
Definition: Args.h:315
A command line option parsing protocol class.
Definition: Options.h:58
void NotifyOptionParsingStarting(ExecutionContext *execution_context)
Definition: Options.cpp:33
std::vector< Option > m_getopt_table
Definition: Options.h:198
virtual StructuredData::GenericSP CreateScriptCommandObject(const char *class_name)
virtual bool RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, ScriptedCommandSynchronicity synchronicity, lldb_private::CommandReturnObject &cmd_retobj, Status &error, const lldb_private::ExecutionContext &exe_ctx)
virtual bool GenerateScriptAliasFunction(StringList &input, std::string &output)
virtual bool GetDocumentationForItem(const char *item, std::string &dest)
virtual bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string &dest)
virtual bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string &dest)
An error handling class.
Definition: Status.h:44
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
size_t SplitIntoLines(const std::string &lines)
Definition: StringList.cpp:152
size_t GetSize() const
Definition: StringList.cpp:74
std::shared_ptr< Generic > GenericSP
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:43
std::shared_ptr< OptionArgVector > OptionArgVectorSP
Definition: Options.h:30
std::vector< std::tuple< std::string, int, std::string > > OptionArgVector
Definition: Options.h:29
Definition: SBAddress.h:15
@ eScriptLanguagePython
@ eReturnStatusFailed
@ eReturnStatusSuccessFinishResult
@ eReturnStatusInvalid
@ eReturnStatusSuccessFinishNoResult
@ eArgTypeSEDStylePair
@ eArgTypeFilename
@ eArgTypeCommandName
@ eArgTypeAliasName
@ eArgTypeAliasOptions
Used to build individual command argument lists.
Definition: CommandObject.h:93
static int64_t ToOptionEnum(llvm::StringRef s, const OptionEnumValues &enum_values, int32_t fail_value, Status &error)