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 }
72
73 Options *GetOptions() override { return &m_options; }
74
75protected:
76 class CommandOptions : public Options {
77 public:
79 : m_stop_on_error(true), m_silent_run(false), m_stop_on_continue(true),
81
82 ~CommandOptions() override = default;
83
84 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
85 ExecutionContext *execution_context) override {
87 const int short_option = m_getopt_table[option_idx].val;
88
89 switch (short_option) {
90 case 'e':
92 break;
93
94 case 'c':
96 break;
97
98 case 'C':
100 break;
101
102 case 's':
104 break;
105
106 default:
107 llvm_unreachable("Unimplemented option");
108 }
109
110 return error;
111 }
112
113 void OptionParsingStarting(ExecutionContext *execution_context) override {
118 }
119
120 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
121 return llvm::ArrayRef(g_source_options);
122 }
123
124 // Instance variables to hold the values for command options.
125
130 };
131
132 bool DoExecute(Args &command, CommandReturnObject &result) override {
133 if (command.GetArgumentCount() != 1) {
135 "'%s' takes exactly one executable filename argument.\n",
136 GetCommandName().str().c_str());
137 return false;
138 }
139
140 FileSpec source_dir = {};
143 if (!source_dir) {
144 result.AppendError("command source -C can only be specified "
145 "from a command file");
147 return false;
148 }
149 }
150
151 FileSpec cmd_file(command[0].ref());
152 if (source_dir) {
153 // Prepend the source_dir to the cmd_file path:
154 if (!cmd_file.IsRelative()) {
155 result.AppendError("command source -C can only be used "
156 "with a relative path.");
158 return false;
159 }
160 cmd_file.MakeAbsolute(source_dir);
161 }
162
163 FileSystem::Instance().Resolve(cmd_file);
164
166 // If any options were set, then use them
171 options.SetStopOnContinue(
173
176
177 // Individual silent setting is override for global command echo settings.
179 options.SetSilent(true);
180 } else {
181 options.SetPrintResults(true);
182 options.SetPrintErrors(true);
185 }
186 }
187
188 m_interpreter.HandleCommandsFromFile(cmd_file, options, result);
189 return result.Succeeded();
190 }
191
193};
194
195#pragma mark CommandObjectCommandsAlias
196// CommandObjectCommandsAlias
197
198#define LLDB_OPTIONS_alias
199#include "CommandOptions.inc"
200
202 "Enter your Python command(s). Type 'DONE' to end.\n"
203 "You must define a Python function with this signature:\n"
204 "def my_command_impl(debugger, args, exe_ctx, result, internal_dict):\n";
205
207protected:
209 public:
210 CommandOptions() = default;
211
212 ~CommandOptions() override = default;
213
214 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
215 return llvm::ArrayRef(g_alias_options);
216 }
217
218 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
219 ExecutionContext *execution_context) override {
221
222 const int short_option = GetDefinitions()[option_idx].short_option;
223 std::string option_str(option_value);
224
225 switch (short_option) {
226 case 'h':
227 m_help.SetCurrentValue(option_str);
229 break;
230
231 case 'H':
232 m_long_help.SetCurrentValue(option_str);
234 break;
235
236 default:
237 llvm_unreachable("Unimplemented option");
238 }
239
240 return error;
241 }
242
243 void OptionParsingStarting(ExecutionContext *execution_context) override {
244 m_help.Clear();
246 }
247
250 };
251
254
255public:
256 Options *GetOptions() override { return &m_option_group; }
257
260 interpreter, "command alias",
261 "Define a custom command in terms of an existing command.") {
264
266 "'alias' allows the user to create a short-cut or abbreviation for long \
267commands, multi-word commands, and commands that take particular options. \
268Below are some simple examples of how one might use the 'alias' command:"
269 R"(
270
271(lldb) command alias sc script
272
273 Creates the abbreviation 'sc' for the 'script' command.
274
275(lldb) command alias bp breakpoint
276
277)"
278 " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
279breakpoint commands are two-word commands, the user would still need to \
280enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'."
281 R"(
282
283(lldb) command alias bpl breakpoint list
284
285 Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
286
287)"
288 "An alias can include some options for the command, with the values either \
289filled in at the time the alias is created, or specified as positional \
290arguments, to be filled in when the alias is invoked. The following example \
291shows how to create aliases with options:"
292 R"(
293
294(lldb) command alias bfl breakpoint set -f %1 -l %2
295
296)"
297 " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
298options already part of the alias. So if the user wants to set a breakpoint \
299by file and line without explicitly having to use the -f and -l options, the \
300user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \
301for the actual arguments that will be passed when the alias command is used. \
302The number in the placeholder refers to the position/order the actual value \
303occupies when the alias is used. All the occurrences of '%1' in the alias \
304will be replaced with the first argument, all the occurrences of '%2' in the \
305alias will be replaced with the second argument, and so on. This also allows \
306actual arguments to be used multiple times within an alias (see 'process \
307launch' example below)."
308 R"(
309
310)"
311 "Note: the positional arguments must substitute as whole words in the resultant \
312command, so you can't at present do something like this to append the file extension \
313\".cpp\":"
314 R"(
315
316(lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
317
318)"
319 "For more complex aliasing, use the \"command regex\" command instead. In the \
320'bfl' case above, the actual file value will be filled in with the first argument \
321following 'bfl' and the actual line number value will be filled in with the second \
322argument. The user would use this alias as follows:"
323 R"(
324
325(lldb) command alias bfl breakpoint set -f %1 -l %2
326(lldb) bfl my-file.c 137
327
328This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
329
330Another example:
331
332(lldb) command alias pltty process launch -s -o %1 -e %1
333(lldb) pltty /dev/tty0
334
335 Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
336
337)"
338 "If the user always wanted to pass the same value to a particular option, the \
339alias could be defined with that value directly in the alias as a constant, \
340rather than using a positional placeholder:"
341 R"(
343(lldb) command alias bl3 breakpoint set -f %1 -l 3
344
345 Always sets a breakpoint on line 3 of whatever file is indicated.)");
346
350 CommandArgumentData alias_arg;
351 CommandArgumentData cmd_arg;
352 CommandArgumentData options_arg;
353
354 // Define the first (and only) variant of this arg.
355 alias_arg.arg_type = eArgTypeAliasName;
357
358 // There is only one variant this argument could be; put it into the
359 // argument entry.
360 arg1.push_back(alias_arg);
361
362 // Define the first (and only) variant of this arg.
365
366 // There is only one variant this argument could be; put it into the
367 // argument entry.
368 arg2.push_back(cmd_arg);
369
370 // Define the first (and only) variant of this arg.
371 options_arg.arg_type = eArgTypeAliasOptions;
373
374 // There is only one variant this argument could be; put it into the
375 // argument entry.
376 arg3.push_back(options_arg);
377
378 // Push the data for the first argument into the m_arguments vector.
379 m_arguments.push_back(arg1);
380 m_arguments.push_back(arg2);
381 m_arguments.push_back(arg3);
382 }
383
384 ~CommandObjectCommandsAlias() override = default;
385
386protected:
387 bool DoExecute(llvm::StringRef raw_command_line,
388 CommandReturnObject &result) override {
389 if (raw_command_line.empty()) {
390 result.AppendError("'command alias' requires at least two arguments");
391 return false;
392 }
393
396
397 OptionsWithRaw args_with_suffix(raw_command_line);
398
399 if (args_with_suffix.HasArgs())
400 if (!ParseOptionsAndNotify(args_with_suffix.GetArgs(), result,
401 m_option_group, exe_ctx))
402 return false;
403
404 llvm::StringRef raw_command_string = args_with_suffix.GetRawPart();
405 Args args(raw_command_string);
406
407 if (args.GetArgumentCount() < 2) {
408 result.AppendError("'command alias' requires at least two arguments");
409 return false;
410 }
411
412 // Get the alias command.
413
414 auto alias_command = args[0].ref();
415 if (alias_command.startswith("-")) {
416 result.AppendError("aliases starting with a dash are not supported");
417 if (alias_command == "--help" || alias_command == "--long-help") {
418 result.AppendWarning("if trying to pass options to 'command alias' add "
419 "a -- at the end of the options");
420 }
421 return false;
422 }
423
424 // Strip the new alias name off 'raw_command_string' (leave it on args,
425 // which gets passed to 'Execute', which does the stripping itself.
426 size_t pos = raw_command_string.find(alias_command);
427 if (pos == 0) {
428 raw_command_string = raw_command_string.substr(alias_command.size());
429 pos = raw_command_string.find_first_not_of(' ');
430 if ((pos != std::string::npos) && (pos > 0))
431 raw_command_string = raw_command_string.substr(pos);
432 } else {
433 result.AppendError("Error parsing command string. No alias created.");
434 return false;
435 }
437 // Verify that the command is alias-able.
438 if (m_interpreter.CommandExists(alias_command)) {
440 "'%s' is a permanent debugger command and cannot be redefined.\n",
441 args[0].c_str());
442 return false;
443 }
444
445 if (m_interpreter.UserMultiwordCommandExists(alias_command)) {
447 "'%s' is a user container command and cannot be overwritten.\n"
448 "Delete it first with 'command container delete'\n",
449 args[0].c_str());
450 return false;
451 }
452
453 // Get CommandObject that is being aliased. The command name is read from
454 // the front of raw_command_string. raw_command_string is returned with the
455 // name of the command object stripped off the front.
456 llvm::StringRef original_raw_command_string = raw_command_string;
457 CommandObject *cmd_obj =
458 m_interpreter.GetCommandObjectForCommand(raw_command_string);
459
460 if (!cmd_obj) {
461 result.AppendErrorWithFormat("invalid command given to 'command alias'. "
462 "'%s' does not begin with a valid command."
463 " No alias created.",
464 original_raw_command_string.str().c_str());
465 return false;
466 } else if (!cmd_obj->WantsRawCommandString()) {
467 // Note that args was initialized with the original command, and has not
468 // been updated to this point. Therefore can we pass it to the version of
469 // Execute that does not need/expect raw input in the alias.
470 return HandleAliasingNormalCommand(args, result);
471 } else {
472 return HandleAliasingRawCommand(alias_command, raw_command_string,
473 *cmd_obj, result);
475 return result.Succeeded();
476 }
477
478 bool HandleAliasingRawCommand(llvm::StringRef alias_command,
479 llvm::StringRef raw_command_string,
480 CommandObject &cmd_obj,
481 CommandReturnObject &result) {
482 // Verify & handle any options/arguments passed to the alias command
483
484 OptionArgVectorSP option_arg_vector_sp =
486
487 const bool include_aliases = true;
488 // Look up the command using command's name first. This is to resolve
489 // aliases when you are making nested aliases. But if you don't find
490 // it that way, then it wasn't an alias and we can just use the object
491 // we were passed in.
493 cmd_obj.GetCommandName(), include_aliases);
494 if (!cmd_obj_sp)
495 cmd_obj_sp = cmd_obj.shared_from_this();
496
497 if (m_interpreter.AliasExists(alias_command) ||
498 m_interpreter.UserCommandExists(alias_command)) {
500 "Overwriting existing definition for '%s'.\n",
501 alias_command.str().c_str());
502 }
504 alias_command, cmd_obj_sp, raw_command_string)) {
506 alias->SetHelp(m_command_options.m_help.GetCurrentValue());
508 alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
510 } else {
511 result.AppendError("Unable to create requested alias.\n");
512 }
513 return result.Succeeded();
514 }
515
517 size_t argc = args.GetArgumentCount();
518
519 if (argc < 2) {
520 result.AppendError("'command alias' requires at least two arguments");
521 return false;
522 }
523
524 // Save these in std::strings since we're going to shift them off.
525 const std::string alias_command(std::string(args[0].ref()));
526 const std::string actual_command(std::string(args[1].ref()));
527
528 args.Shift(); // Shift the alias command word off the argument vector.
529 args.Shift(); // Shift the old command word off the argument vector.
530
531 // Verify that the command is alias'able, and get the appropriate command
532 // object.
533
534 if (m_interpreter.CommandExists(alias_command)) {
536 "'%s' is a permanent debugger command and cannot be redefined.\n",
537 alias_command.c_str());
538 return false;
539 }
540
541 if (m_interpreter.UserMultiwordCommandExists(alias_command)) {
543 "'%s' is user container command and cannot be overwritten.\n"
544 "Delete it first with 'command container delete'",
545 alias_command.c_str());
546 return false;
547 }
548
549 CommandObjectSP command_obj_sp(
550 m_interpreter.GetCommandSPExact(actual_command, true));
551 CommandObjectSP subcommand_obj_sp;
552 bool use_subcommand = false;
553 if (!command_obj_sp) {
554 result.AppendErrorWithFormat("'%s' is not an existing command.\n",
555 actual_command.c_str());
556 return false;
557 }
558 CommandObject *cmd_obj = command_obj_sp.get();
559 CommandObject *sub_cmd_obj = nullptr;
560 OptionArgVectorSP option_arg_vector_sp =
562
563 while (cmd_obj->IsMultiwordObject() && !args.empty()) {
564 auto sub_command = args[0].ref();
565 assert(!sub_command.empty());
566 subcommand_obj_sp = cmd_obj->GetSubcommandSP(sub_command);
567 if (!subcommand_obj_sp) {
569 "'%s' is not a valid sub-command of '%s'. "
570 "Unable to create alias.\n",
571 args[0].c_str(), actual_command.c_str());
572 return false;
573 }
574
575 sub_cmd_obj = subcommand_obj_sp.get();
576 use_subcommand = true;
577 args.Shift(); // Shift the sub_command word off the argument vector.
578 cmd_obj = sub_cmd_obj;
579 }
580
581 // Verify & handle any options/arguments passed to the alias command
582
583 std::string args_string;
584
585 if (!args.empty()) {
586 CommandObjectSP tmp_sp =
588 if (use_subcommand)
589 tmp_sp = m_interpreter.GetCommandSPExact(sub_cmd_obj->GetCommandName());
590
591 args.GetCommandString(args_string);
592 }
593
594 if (m_interpreter.AliasExists(alias_command) ||
595 m_interpreter.UserCommandExists(alias_command)) {
597 "Overwriting existing definition for '%s'.\n", alias_command.c_str());
598 }
599
601 alias_command, use_subcommand ? subcommand_obj_sp : command_obj_sp,
602 args_string)) {
604 alias->SetHelp(m_command_options.m_help.GetCurrentValue());
606 alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
608 } else {
609 result.AppendError("Unable to create requested alias.\n");
610 return false;
611 }
612
613 return result.Succeeded();
614 }
615};
616
617#pragma mark CommandObjectCommandsUnalias
618// CommandObjectCommandsUnalias
619
621public:
624 interpreter, "command unalias",
625 "Delete one or more custom commands defined by 'command alias'.",
626 nullptr) {
628 CommandArgumentData alias_arg;
629
630 // Define the first (and only) variant of this arg.
631 alias_arg.arg_type = eArgTypeAliasName;
633
634 // There is only one variant this argument could be; put it into the
635 // argument entry.
636 arg.push_back(alias_arg);
637
638 // Push the data for the first argument into the m_arguments vector.
639 m_arguments.push_back(arg);
640 }
641
642 ~CommandObjectCommandsUnalias() override = default;
643
644 void
646 OptionElementVector &opt_element_vector) override {
647 if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0)
648 return;
649
650 for (const auto &ent : m_interpreter.GetAliases()) {
651 request.TryCompleteCurrentArg(ent.first, ent.second->GetHelp());
652 }
653 }
654
655protected:
656 bool DoExecute(Args &args, CommandReturnObject &result) override {
657 CommandObject::CommandMap::iterator pos;
658 CommandObject *cmd_obj;
659
660 if (args.empty()) {
661 result.AppendError("must call 'unalias' with a valid alias");
662 return false;
663 }
664
665 auto command_name = args[0].ref();
666 cmd_obj = m_interpreter.GetCommandObject(command_name);
667 if (!cmd_obj) {
669 "'%s' is not a known command.\nTry 'help' to see a "
670 "current list of commands.\n",
671 args[0].c_str());
672 return false;
673 }
674
675 if (m_interpreter.CommandExists(command_name)) {
676 if (cmd_obj->IsRemovable()) {
678 "'%s' is not an alias, it is a debugger command which can be "
679 "removed using the 'command delete' command.\n",
680 args[0].c_str());
681 } else {
683 "'%s' is a permanent debugger command and cannot be removed.\n",
684 args[0].c_str());
685 }
686 return false;
687 }
688
689 if (!m_interpreter.RemoveAlias(command_name)) {
690 if (m_interpreter.AliasExists(command_name))
692 "Error occurred while attempting to unalias '%s'.\n",
693 args[0].c_str());
694 else
695 result.AppendErrorWithFormat("'%s' is not an existing alias.\n",
696 args[0].c_str());
697 return false;
698 }
699
701 return result.Succeeded();
702 }
703};
704
705#pragma mark CommandObjectCommandsDelete
706// CommandObjectCommandsDelete
707
709public:
712 interpreter, "command delete",
713 "Delete one or more custom commands defined by 'command regex'.",
714 nullptr) {
716 CommandArgumentData alias_arg;
717
718 // Define the first (and only) variant of this arg.
719 alias_arg.arg_type = eArgTypeCommandName;
721
722 // There is only one variant this argument could be; put it into the
723 // argument entry.
724 arg.push_back(alias_arg);
725
726 // Push the data for the first argument into the m_arguments vector.
727 m_arguments.push_back(arg);
728 }
729
730 ~CommandObjectCommandsDelete() override = default;
731
732 void
734 OptionElementVector &opt_element_vector) override {
735 if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0)
736 return;
737
738 for (const auto &ent : m_interpreter.GetCommands()) {
739 if (ent.second->IsRemovable())
740 request.TryCompleteCurrentArg(ent.first, ent.second->GetHelp());
741 }
742 }
743
744protected:
745 bool DoExecute(Args &args, CommandReturnObject &result) override {
746 CommandObject::CommandMap::iterator pos;
747
748 if (args.empty()) {
749 result.AppendErrorWithFormat("must call '%s' with one or more valid user "
750 "defined regular expression command names",
751 GetCommandName().str().c_str());
752 return false;
753 }
754
755 auto command_name = args[0].ref();
756 if (!m_interpreter.CommandExists(command_name)) {
757 StreamString error_msg_stream;
758 const bool generate_upropos = true;
759 const bool generate_type_lookup = false;
761 &error_msg_stream, command_name, llvm::StringRef(), llvm::StringRef(),
762 generate_upropos, generate_type_lookup);
763 result.AppendError(error_msg_stream.GetString());
764 return false;
765 }
766
767 if (!m_interpreter.RemoveCommand(command_name)) {
769 "'%s' is a permanent debugger command and cannot be removed.\n",
770 args[0].c_str());
771 return false;
772 }
773
775 return true;
776 }
777};
778
779// CommandObjectCommandsAddRegex
780
781#define LLDB_OPTIONS_regex
782#include "CommandOptions.inc"
783
784#pragma mark CommandObjectCommandsAddRegex
785
788public:
791 interpreter, "command regex",
792 "Define a custom command in terms of "
793 "existing commands by matching "
794 "regular expressions.",
795 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
799 R"(
800)"
801 "This command allows the user to create powerful regular expression commands \
802with substitutions. The regular expressions and substitutions are specified \
803using the regular expression substitution format of:"
804 R"(
805
806 s/<regex>/<subst>/
807
808)"
809 "<regex> is a regular expression that can use parenthesis to capture regular \
810expression input and substitute the captured matches in the output using %1 \
811for the first match, %2 for the second, and so on."
812 R"(
813
814)"
815 "The regular expressions can all be specified on the command line if more than \
816one argument is provided. If just the command name is provided on the command \
817line, then the regular expressions and substitutions can be entered on separate \
818lines, followed by an empty line to terminate the command definition."
819 R"(
820
821EXAMPLES
822
823)"
824 "The following example will define a regular expression command named 'f' that \
825will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
826a number follows 'f':"
827 R"(
828
829 (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')");
831 m_arguments.push_back({thread_arg});
832 }
833
834 ~CommandObjectCommandsAddRegex() override = default;
835
836protected:
837 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
838 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
839 if (output_sp && interactive) {
840 output_sp->PutCString("Enter one or more sed substitution commands in "
841 "the form: 's/<regex>/<subst>/'.\nTerminate the "
842 "substitution list with an empty line.\n");
843 output_sp->Flush();
844 }
845 }
846
847 void IOHandlerInputComplete(IOHandler &io_handler,
848 std::string &data) override {
849 io_handler.SetIsDone(true);
850 if (m_regex_cmd_up) {
851 StringList lines;
852 if (lines.SplitIntoLines(data)) {
853 bool check_only = false;
854 for (const std::string &line : lines) {
855 Status error = AppendRegexSubstitution(line, check_only);
856 if (error.Fail()) {
857 if (!GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) {
859 out_stream->Printf("error: %s\n", error.AsCString());
860 }
861 }
862 }
863 }
864 if (m_regex_cmd_up->HasRegexEntries()) {
865 CommandObjectSP cmd_sp(m_regex_cmd_up.release());
866 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
867 }
868 }
869 }
870
871 bool DoExecute(Args &command, CommandReturnObject &result) override {
872 const size_t argc = command.GetArgumentCount();
873 if (argc == 0) {
874 result.AppendError("usage: 'command regex <command-name> "
875 "[s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
876 return false;
877 }
878
880 auto name = command[0].ref();
881 m_regex_cmd_up = std::make_unique<CommandObjectRegexCommand>(
883 true);
884
885 if (argc == 1) {
886 Debugger &debugger = GetDebugger();
887 bool color_prompt = debugger.GetUseColor();
888 const bool multiple_lines = true; // Get multiple lines
889 IOHandlerSP io_handler_sp(new IOHandlerEditline(
890 debugger, IOHandler::Type::Other,
891 "lldb-regex", // Name of input reader for history
892 llvm::StringRef("> "), // Prompt
893 llvm::StringRef(), // Continuation prompt
894 multiple_lines, color_prompt,
895 0, // Don't show line numbers
896 *this));
897
898 if (io_handler_sp) {
899 debugger.RunIOHandlerAsync(io_handler_sp);
901 }
902 } else {
903 for (auto &entry : command.entries().drop_front()) {
904 bool check_only = false;
905 error = AppendRegexSubstitution(entry.ref(), check_only);
906 if (error.Fail())
907 break;
909
910 if (error.Success()) {
912 }
913 }
914 if (error.Fail()) {
915 result.AppendError(error.AsCString());
916 }
917
918 return result.Succeeded();
919 }
920
921 Status AppendRegexSubstitution(const llvm::StringRef &regex_sed,
922 bool check_only) {
924
925 if (!m_regex_cmd_up) {
926 error.SetErrorStringWithFormat(
927 "invalid regular expression command object for: '%.*s'",
928 (int)regex_sed.size(), regex_sed.data());
929 return error;
930 }
931
932 size_t regex_sed_size = regex_sed.size();
933
934 if (regex_sed_size <= 1) {
935 error.SetErrorStringWithFormat(
936 "regular expression substitution string is too short: '%.*s'",
937 (int)regex_sed.size(), regex_sed.data());
938 return error;
939 }
940
941 if (regex_sed[0] != 's') {
942 error.SetErrorStringWithFormat("regular expression substitution string "
943 "doesn't start with 's': '%.*s'",
944 (int)regex_sed.size(), regex_sed.data());
945 return error;
946 }
947 const size_t first_separator_char_pos = 1;
948 // use the char that follows 's' as the regex separator character so we can
949 // have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
950 const char separator_char = regex_sed[first_separator_char_pos];
951 const size_t second_separator_char_pos =
952 regex_sed.find(separator_char, first_separator_char_pos + 1);
953
954 if (second_separator_char_pos == std::string::npos) {
955 error.SetErrorStringWithFormat(
956 "missing second '%c' separator char after '%.*s' in '%.*s'",
957 separator_char,
958 (int)(regex_sed.size() - first_separator_char_pos - 1),
959 regex_sed.data() + (first_separator_char_pos + 1),
960 (int)regex_sed.size(), regex_sed.data());
961 return error;
962 }
963
964 const size_t third_separator_char_pos =
965 regex_sed.find(separator_char, second_separator_char_pos + 1);
966
967 if (third_separator_char_pos == std::string::npos) {
968 error.SetErrorStringWithFormat(
969 "missing third '%c' separator char after '%.*s' in '%.*s'",
970 separator_char,
971 (int)(regex_sed.size() - second_separator_char_pos - 1),
972 regex_sed.data() + (second_separator_char_pos + 1),
973 (int)regex_sed.size(), regex_sed.data());
974 return error;
975 }
976
977 if (third_separator_char_pos != regex_sed_size - 1) {
978 // Make sure that everything that follows the last regex separator char
979 if (regex_sed.find_first_not_of("\t\n\v\f\r ",
980 third_separator_char_pos + 1) !=
981 std::string::npos) {
982 error.SetErrorStringWithFormat(
983 "extra data found after the '%.*s' regular expression substitution "
984 "string: '%.*s'",
985 (int)third_separator_char_pos + 1, regex_sed.data(),
986 (int)(regex_sed.size() - third_separator_char_pos - 1),
987 regex_sed.data() + (third_separator_char_pos + 1));
988 return error;
989 }
990 } else if (first_separator_char_pos + 1 == second_separator_char_pos) {
991 error.SetErrorStringWithFormat(
992 "<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
993 separator_char, separator_char, separator_char, (int)regex_sed.size(),
994 regex_sed.data());
995 return error;
996 } else if (second_separator_char_pos + 1 == third_separator_char_pos) {
997 error.SetErrorStringWithFormat(
998 "<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
999 separator_char, separator_char, separator_char, (int)regex_sed.size(),
1000 regex_sed.data());
1001 return error;
1002 }
1004 if (!check_only) {
1005 std::string regex(std::string(regex_sed.substr(
1006 first_separator_char_pos + 1,
1007 second_separator_char_pos - first_separator_char_pos - 1)));
1008 std::string subst(std::string(regex_sed.substr(
1009 second_separator_char_pos + 1,
1010 third_separator_char_pos - second_separator_char_pos - 1)));
1011 m_regex_cmd_up->AddRegexCommand(regex, subst);
1012 }
1013 return error;
1014 }
1018 if (m_regex_cmd_up->HasRegexEntries()) {
1020 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1022 }
1023 }
1024
1025private:
1026 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_up;
1027
1028 class CommandOptions : public Options {
1029 public:
1030 CommandOptions() = default;
1031
1032 ~CommandOptions() override = default;
1033
1034 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1035 ExecutionContext *execution_context) override {
1036 Status error;
1037 const int short_option = m_getopt_table[option_idx].val;
1038
1039 switch (short_option) {
1040 case 'h':
1041 m_help.assign(std::string(option_arg));
1042 break;
1043 case 's':
1044 m_syntax.assign(std::string(option_arg));
1045 break;
1046 default:
1047 llvm_unreachable("Unimplemented option");
1048 }
1050 return error;
1052
1053 void OptionParsingStarting(ExecutionContext *execution_context) override {
1054 m_help.clear();
1055 m_syntax.clear();
1058 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1059 return llvm::ArrayRef(g_regex_options);
1061
1062 llvm::StringRef GetHelp() { return m_help; }
1063
1064 llvm::StringRef GetSyntax() { return m_syntax; }
1065
1066 protected:
1067 // Instance variables to hold the values for command options.
1068
1069 std::string m_help;
1070 std::string m_syntax;
1071 };
1072
1073 Options *GetOptions() override { return &m_options; }
1074
1075 CommandOptions m_options;
1076};
1077
1079public:
1080 CommandObjectPythonFunction(CommandInterpreter &interpreter, std::string name,
1081 std::string funct, std::string help,
1083 CompletionType completion_type)
1084 : CommandObjectRaw(interpreter, name), m_function_name(funct),
1085 m_synchro(synch), m_completion_type(completion_type) {
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
1119 void
1121 OptionElementVector &opt_element_vector) override {
1123 GetCommandInterpreter(), m_completion_type, request, nullptr);
1124 }
1125
1126 bool WantsCompletion() override { return true; }
1127
1128protected:
1129 bool DoExecute(llvm::StringRef raw_command_line,
1130 CommandReturnObject &result) override {
1132
1133 Status error;
1134
1136
1137 if (!scripter || !scripter->RunScriptBasedCommand(
1138 m_function_name.c_str(), raw_command_line, m_synchro,
1139 result, error, m_exe_ctx)) {
1140 result.AppendError(error.AsCString());
1141 } else {
1142 // Don't change the status if the command already set it...
1143 if (result.GetStatus() == eReturnStatusInvalid) {
1144 if (result.GetOutputData().empty())
1146 else
1148 }
1149 }
1150
1151 return result.Succeeded();
1152 }
1153
1154private:
1155 std::string m_function_name;
1159};
1160
1162public:
1164 std::string name,
1165 StructuredData::GenericSP cmd_obj_sp,
1167 CompletionType completion_type)
1168 : CommandObjectRaw(interpreter, name), m_cmd_obj_sp(cmd_obj_sp),
1169 m_synchro(synch), m_fetched_help_short(false),
1170 m_fetched_help_long(false), m_completion_type(completion_type) {
1171 StreamString stream;
1172 stream.Printf("For more information run 'help %s'", name.c_str());
1173 SetHelp(stream.GetString());
1174 if (ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter())
1175 GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
1176 }
1177
1178 ~CommandObjectScriptingObject() override = default;
1179
1180 void
1182 OptionElementVector &opt_element_vector) override {
1184 GetCommandInterpreter(), m_completion_type, request, nullptr);
1185 }
1186
1187 bool WantsCompletion() override { return true; }
1188
1189 bool IsRemovable() const override { return true; }
1190
1192
1193 llvm::StringRef GetHelp() override {
1195 return CommandObjectRaw::GetHelp();
1197 if (!scripter)
1198 return CommandObjectRaw::GetHelp();
1199 std::string docstring;
1201 scripter->GetShortHelpForCommandObject(m_cmd_obj_sp, docstring);
1202 if (!docstring.empty())
1203 SetHelp(docstring);
1204
1205 return CommandObjectRaw::GetHelp();
1206 }
1207
1208 llvm::StringRef GetHelpLong() override {
1210 return CommandObjectRaw::GetHelpLong();
1211
1213 if (!scripter)
1214 return CommandObjectRaw::GetHelpLong();
1215
1216 std::string docstring;
1218 scripter->GetLongHelpForCommandObject(m_cmd_obj_sp, docstring);
1219 if (!docstring.empty())
1220 SetHelpLong(docstring);
1221 return CommandObjectRaw::GetHelpLong();
1222 }
1223
1224protected:
1225 bool DoExecute(llvm::StringRef raw_command_line,
1226 CommandReturnObject &result) override {
1228
1229 Status error;
1230
1232
1233 if (!scripter ||
1234 !scripter->RunScriptBasedCommand(m_cmd_obj_sp, raw_command_line,
1235 m_synchro, result, error, m_exe_ctx)) {
1236 result.AppendError(error.AsCString());
1237 } else {
1238 // Don't change the status if the command already set it...
1239 if (result.GetStatus() == eReturnStatusInvalid) {
1240 if (result.GetOutputData().empty())
1242 else
1244 }
1245 }
1246
1247 return result.Succeeded();
1248 }
1249
1250private:
1256};
1257
1258// CommandObjectCommandsScriptImport
1259#define LLDB_OPTIONS_script_import
1260#include "CommandOptions.inc"
1261
1263public:
1265 : CommandObjectParsed(interpreter, "command script import",
1266 "Import a scripting module in LLDB.", nullptr) {
1268 CommandArgumentData cmd_arg;
1269
1270 // Define the first (and only) variant of this arg.
1271 cmd_arg.arg_type = eArgTypeFilename;
1273
1274 // There is only one variant this argument could be; put it into the
1275 // argument entry.
1276 arg1.push_back(cmd_arg);
1277
1278 // Push the data for the first argument into the m_arguments vector.
1279 m_arguments.push_back(arg1);
1280 }
1281
1283
1284 void
1286 OptionElementVector &opt_element_vector) override {
1289 }
1290
1291 Options *GetOptions() override { return &m_options; }
1292
1293protected:
1294 class CommandOptions : public Options {
1295 public:
1296 CommandOptions() = default;
1297
1298 ~CommandOptions() override = default;
1299
1300 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1301 ExecutionContext *execution_context) override {
1302 Status error;
1303 const int short_option = m_getopt_table[option_idx].val;
1304
1305 switch (short_option) {
1306 case 'r':
1307 // NO-OP
1308 break;
1309 case 'c':
1311 break;
1312 case 's':
1313 silent = true;
1314 break;
1315 default:
1316 llvm_unreachable("Unimplemented option");
1317 }
1318
1319 return error;
1320 }
1321
1322 void OptionParsingStarting(ExecutionContext *execution_context) override {
1324 }
1325
1326 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1327 return llvm::ArrayRef(g_script_import_options);
1328 }
1330 bool silent = false;
1331 };
1332
1333 bool DoExecute(Args &command, CommandReturnObject &result) override {
1334 if (command.empty()) {
1335 result.AppendError("command script import needs one or more arguments");
1336 return false;
1337 }
1338
1339 FileSpec source_dir = {};
1342 if (!source_dir) {
1343 result.AppendError("command script import -c can only be specified "
1344 "from a command file");
1345 return false;
1346 }
1347 }
1348
1349 for (auto &entry : command.entries()) {
1350 Status error;
1351
1352 LoadScriptOptions options;
1353 options.SetInitSession(true);
1354 options.SetSilent(m_options.silent);
1355
1356 // FIXME: this is necessary because CommandObject::CheckRequirements()
1357 // assumes that commands won't ever be recursively invoked, but it's
1358 // actually possible to craft a Python script that does other "command
1359 // script imports" in __lldb_init_module the real fix is to have
1360 // recursive commands possible with a CommandInvocation object separate
1361 // from the CommandObject itself, so that recursive command invocations
1362 // won't stomp on each other (wrt to execution contents, options, and
1363 // more)
1364 m_exe_ctx.Clear();
1365 if (GetDebugger().GetScriptInterpreter()->LoadScriptingModule(
1366 entry.c_str(), options, error, /*module_sp=*/nullptr,
1367 source_dir)) {
1369 } else {
1370 result.AppendErrorWithFormat("module importing failed: %s",
1371 error.AsCString());
1372 }
1373 }
1374
1375 return result.Succeeded();
1376 }
1377
1379};
1380
1381#define LLDB_OPTIONS_script_add
1382#include "CommandOptions.inc"
1383
1386public:
1388 : CommandObjectParsed(interpreter, "command script add",
1389 "Add a scripted function as an LLDB command.",
1390 "Add a scripted function as an lldb command. "
1391 "If you provide a single argument, the command "
1392 "will be added at the root level of the command "
1393 "hierarchy. If there are more arguments they "
1394 "must be a path to a user-added container "
1395 "command, and the last element will be the new "
1396 "command name."),
1399 CommandArgumentData cmd_arg;
1400
1401 // This is one or more command names, which form the path to the command
1402 // you want to add.
1403 cmd_arg.arg_type = eArgTypeCommand;
1405
1406 // There is only one variant this argument could be; put it into the
1407 // argument entry.
1408 arg1.push_back(cmd_arg);
1409
1410 // Push the data for the first argument into the m_arguments vector.
1411 m_arguments.push_back(arg1);
1412 }
1413
1415
1416 Options *GetOptions() override { return &m_options; }
1417
1418 void
1420 OptionElementVector &opt_element_vector) override {
1422 opt_element_vector);
1423 }
1424
1425protected:
1426 class CommandOptions : public Options {
1427 public:
1428 CommandOptions() = default;
1429
1430 ~CommandOptions() override = default;
1431
1432 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1433 ExecutionContext *execution_context) override {
1434 Status error;
1435 const int short_option = m_getopt_table[option_idx].val;
1436
1437 switch (short_option) {
1438 case 'f':
1439 if (!option_arg.empty())
1440 m_funct_name = std::string(option_arg);
1441 break;
1442 case 'c':
1443 if (!option_arg.empty())
1444 m_class_name = std::string(option_arg);
1445 break;
1446 case 'h':
1447 if (!option_arg.empty())
1448 m_short_help = std::string(option_arg);
1449 break;
1450 case 'o':
1452 break;
1453 case 's':
1456 option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
1457 if (!error.Success())
1458 error.SetErrorStringWithFormat(
1459 "unrecognized value for synchronicity '%s'",
1460 option_arg.str().c_str());
1461 break;
1462 case 'C': {
1463 Status error;
1464 OptionDefinition definition = GetDefinitions()[option_idx];
1465 lldb::CompletionType completion_type =
1467 option_arg, definition.enum_values, eNoCompletion, error));
1468 if (!error.Success())
1469 error.SetErrorStringWithFormat(
1470 "unrecognized value for command completion type '%s'",
1471 option_arg.str().c_str());
1472 m_completion_type = completion_type;
1473 } break;
1474 default:
1475 llvm_unreachable("Unimplemented option");
1476 }
1477
1478 return error;
1479 }
1480
1481 void OptionParsingStarting(ExecutionContext *execution_context) override {
1482 m_class_name.clear();
1483 m_funct_name.clear();
1484 m_short_help.clear();
1488 }
1489
1490 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1491 return llvm::ArrayRef(g_script_add_options);
1492 }
1493
1494 // Instance variables to hold the values for command options.
1495
1496 std::string m_class_name;
1497 std::string m_funct_name;
1498 std::string m_short_help;
1503 };
1504
1505 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
1506 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
1507 if (output_sp && interactive) {
1508 output_sp->PutCString(g_python_command_instructions);
1509 output_sp->Flush();
1510 }
1511 }
1512
1514 std::string &data) override {
1515 StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
1516
1518 if (interpreter) {
1519 StringList lines;
1520 lines.SplitIntoLines(data);
1521 if (lines.GetSize() > 0) {
1522 std::string funct_name_str;
1523 if (interpreter->GenerateScriptAliasFunction(lines, funct_name_str)) {
1524 if (funct_name_str.empty()) {
1525 error_sp->Printf("error: unable to obtain a function name, didn't "
1526 "add python command.\n");
1527 error_sp->Flush();
1528 } else {
1529 // everything should be fine now, let's add this alias
1530
1532 m_interpreter, m_cmd_name, funct_name_str, m_short_help,
1534 if (!m_container) {
1536 m_cmd_name, command_obj_sp, m_overwrite);
1537 if (error.Fail()) {
1538 error_sp->Printf("error: unable to add selected command: '%s'",
1539 error.AsCString());
1540 error_sp->Flush();
1541 }
1542 } else {
1543 llvm::Error llvm_error = m_container->LoadUserSubcommand(
1544 m_cmd_name, command_obj_sp, m_overwrite);
1545 if (llvm_error) {
1546 error_sp->Printf("error: unable to add selected command: '%s'",
1547 llvm::toString(std::move(llvm_error)).c_str());
1548 error_sp->Flush();
1549 }
1550 }
1551 }
1552 } else {
1553 error_sp->Printf(
1554 "error: unable to create function, didn't add python command\n");
1555 error_sp->Flush();
1556 }
1557 } else {
1558 error_sp->Printf("error: empty function, didn't add python command\n");
1559 error_sp->Flush();
1560 }
1561 } else {
1562 error_sp->Printf(
1563 "error: script interpreter missing, didn't add python command\n");
1564 error_sp->Flush();
1565 }
1566
1567 io_handler.SetIsDone(true);
1568 }
1569
1570 bool DoExecute(Args &command, CommandReturnObject &result) override {
1571 if (GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) {
1572 result.AppendError("only scripting language supported for scripted "
1573 "commands is currently Python");
1574 return false;
1575 }
1576
1577 if (command.GetArgumentCount() == 0) {
1578 result.AppendError("'command script add' requires at least one argument");
1579 return false;
1580 }
1581 // Store the options in case we get multi-line input, also figure out the
1582 // default if not user supplied:
1583 switch (m_options.m_overwrite_lazy) {
1584 case eLazyBoolCalculate:
1586 break;
1587 case eLazyBoolYes:
1588 m_overwrite = true;
1589 break;
1590 case eLazyBoolNo:
1591 m_overwrite = false;
1592 }
1593
1594 Status path_error;
1596 command, true, path_error);
1597
1598 if (path_error.Fail()) {
1599 result.AppendErrorWithFormat("error in command path: %s",
1600 path_error.AsCString());
1601 return false;
1602 }
1603
1604 if (!m_container) {
1605 // This is getting inserted into the root of the interpreter.
1606 m_cmd_name = std::string(command[0].ref());
1607 } else {
1608 size_t num_args = command.GetArgumentCount();
1609 m_cmd_name = std::string(command[num_args - 1].ref());
1610 }
1611
1615
1616 // Handle the case where we prompt for the script code first:
1617 if (m_options.m_class_name.empty() && m_options.m_funct_name.empty()) {
1619 *this); // IOHandlerDelegate
1620 return result.Succeeded();
1621 }
1622
1623 CommandObjectSP new_cmd_sp;
1624 if (m_options.m_class_name.empty()) {
1625 new_cmd_sp.reset(new CommandObjectPythonFunction(
1628 } else {
1630 if (!interpreter) {
1631 result.AppendError("cannot find ScriptInterpreter");
1632 return false;
1633 }
1634
1635 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(
1636 m_options.m_class_name.c_str());
1637 if (!cmd_obj_sp) {
1638 result.AppendErrorWithFormatv("cannot create helper object for: "
1639 "'{0}'", m_options.m_class_name);
1640 return false;
1641 }
1642
1643 new_cmd_sp.reset(new CommandObjectScriptingObject(
1646 }
1647
1648 // Assume we're going to succeed...
1650 if (!m_container) {
1651 Status add_error =
1653 if (add_error.Fail())
1654 result.AppendErrorWithFormat("cannot add command: %s",
1655 add_error.AsCString());
1656 } else {
1657 llvm::Error llvm_error =
1659 if (llvm_error)
1660 result.AppendErrorWithFormat("cannot add command: %s",
1661 llvm::toString(std::move(llvm_error)).c_str());
1662 }
1663 return result.Succeeded();
1664 }
1665
1667 std::string m_cmd_name;
1669 std::string m_short_help;
1670 bool m_overwrite = false;
1674};
1675
1676// CommandObjectCommandsScriptList
1677
1679public:
1681 : CommandObjectParsed(interpreter, "command script list",
1682 "List defined top-level scripted commands.",
1683 nullptr) {}
1684
1686
1687 bool DoExecute(Args &command, CommandReturnObject &result) override {
1689
1691
1692 return true;
1693 }
1694};
1695
1696// CommandObjectCommandsScriptClear
1697
1699public:
1701 : CommandObjectParsed(interpreter, "command script clear",
1702 "Delete all scripted commands.", nullptr) {}
1703
1705
1706protected:
1707 bool DoExecute(Args &command, CommandReturnObject &result) override {
1709
1711
1712 return true;
1713 }
1714};
1715
1716// CommandObjectCommandsScriptDelete
1717
1719public:
1722 interpreter, "command script delete",
1723 "Delete a scripted command by specifying the path to the command.",
1724 nullptr) {
1726 CommandArgumentData cmd_arg;
1727
1728 // This is a list of command names forming the path to the command
1729 // to be deleted.
1730 cmd_arg.arg_type = eArgTypeCommand;
1732
1733 // There is only one variant this argument could be; put it into the
1734 // argument entry.
1735 arg1.push_back(cmd_arg);
1736
1737 // Push the data for the first argument into the m_arguments vector.
1738 m_arguments.push_back(arg1);
1739 }
1740
1742
1743 void
1745 OptionElementVector &opt_element_vector) override {
1747 m_interpreter, request, opt_element_vector);
1748 }
1749
1750protected:
1751 bool DoExecute(Args &command, CommandReturnObject &result) override {
1752
1753 llvm::StringRef root_cmd = command[0].ref();
1754 size_t num_args = command.GetArgumentCount();
1755
1756 if (root_cmd.empty()) {
1757 result.AppendErrorWithFormat("empty root command name");
1758 return false;
1759 }
1762 result.AppendErrorWithFormat("can only delete user defined commands, "
1763 "but no user defined commands found");
1764 return false;
1765 }
1766
1768 if (!cmd_sp) {
1769 result.AppendErrorWithFormat("command '%s' not found.",
1770 command[0].c_str());
1771 return false;
1772 }
1773 if (!cmd_sp->IsUserCommand()) {
1774 result.AppendErrorWithFormat("command '%s' is not a user command.",
1775 command[0].c_str());
1776 return false;
1777 }
1778 if (cmd_sp->GetAsMultiwordCommand() && num_args == 1) {
1779 result.AppendErrorWithFormat("command '%s' is a multi-word command.\n "
1780 "Delete with \"command container delete\"",
1781 command[0].c_str());
1782 return false;
1783 }
1784
1785 if (command.GetArgumentCount() == 1) {
1786 m_interpreter.RemoveUser(root_cmd);
1788 return true;
1789 }
1790 // We're deleting a command from a multiword command. Verify the command
1791 // path:
1792 Status error;
1793 CommandObjectMultiword *container =
1795 error);
1796 if (error.Fail()) {
1797 result.AppendErrorWithFormat("could not resolve command path: %s",
1798 error.AsCString());
1799 return false;
1800 }
1801 if (!container) {
1802 // This means that command only had a leaf command, so the container is
1803 // the root. That should have been handled above.
1804 result.AppendErrorWithFormat("could not find a container for '%s'",
1805 command[0].c_str());
1806 return false;
1807 }
1808 const char *leaf_cmd = command[num_args - 1].c_str();
1809 llvm::Error llvm_error = container->RemoveUserSubcommand(leaf_cmd,
1810 /* multiword not okay */ false);
1811 if (llvm_error) {
1812 result.AppendErrorWithFormat("could not delete command '%s': %s",
1813 leaf_cmd,
1814 llvm::toString(std::move(llvm_error)).c_str());
1815 return false;
1816 }
1817
1818 Stream &out_stream = result.GetOutputStream();
1819
1820 out_stream << "Deleted command:";
1821 for (size_t idx = 0; idx < num_args; idx++) {
1822 out_stream << ' ';
1823 out_stream << command[idx].c_str();
1824 }
1825 out_stream << '\n';
1827 return true;
1828 }
1829};
1830
1831#pragma mark CommandObjectMultiwordCommandsScript
1832
1833// CommandObjectMultiwordCommandsScript
1834
1836public:
1839 interpreter, "command script",
1840 "Commands for managing custom "
1841 "commands implemented by "
1842 "interpreter scripts.",
1843 "command script <subcommand> [<subcommand-options>]") {
1845 new CommandObjectCommandsScriptAdd(interpreter)));
1847 "delete",
1850 "clear",
1853 interpreter)));
1855 "import",
1857 }
1858
1860};
1861
1862#pragma mark CommandObjectCommandContainer
1863#define LLDB_OPTIONS_container_add
1864#include "CommandOptions.inc"
1865
1867public:
1870 interpreter, "command container add",
1871 "Add a container command to lldb. Adding to built-"
1872 "in container commands is not allowed.",
1873 "command container add [[path1]...] container-name") {
1875 CommandArgumentData cmd_arg;
1876
1877 // This is one or more command names, which form the path to the command
1878 // you want to add.
1879 cmd_arg.arg_type = eArgTypeCommand;
1881
1882 // There is only one variant this argument could be; put it into the
1883 // argument entry.
1884 arg1.push_back(cmd_arg);
1885
1886 // Push the data for the first argument into the m_arguments vector.
1887 m_arguments.push_back(arg1);
1888 }
1889
1891
1892 Options *GetOptions() override { return &m_options; }
1893
1894 void
1896 OptionElementVector &opt_element_vector) override {
1898 m_interpreter, request, opt_element_vector);
1899 }
1900
1901protected:
1902 class CommandOptions : public Options {
1903 public:
1904 CommandOptions() = default;
1905
1906 ~CommandOptions() override = default;
1907
1908 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1909 ExecutionContext *execution_context) override {
1910 Status error;
1911 const int short_option = m_getopt_table[option_idx].val;
1912
1913 switch (short_option) {
1914 case 'h':
1915 if (!option_arg.empty())
1916 m_short_help = std::string(option_arg);
1917 break;
1918 case 'o':
1919 m_overwrite = true;
1920 break;
1921 case 'H':
1922 if (!option_arg.empty())
1923 m_long_help = std::string(option_arg);
1924 break;
1925 default:
1926 llvm_unreachable("Unimplemented option");
1927 }
1928
1929 return error;
1930 }
1931
1932 void OptionParsingStarting(ExecutionContext *execution_context) override {
1933 m_short_help.clear();
1934 m_long_help.clear();
1935 m_overwrite = false;
1936 }
1937
1938 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1939 return llvm::ArrayRef(g_container_add_options);
1940 }
1941
1942 // Instance variables to hold the values for command options.
1943
1944 std::string m_short_help;
1945 std::string m_long_help;
1946 bool m_overwrite = false;
1947 };
1948 bool DoExecute(Args &command, CommandReturnObject &result) override {
1949 size_t num_args = command.GetArgumentCount();
1950
1951 if (num_args == 0) {
1952 result.AppendError("no command was specified");
1953 return false;
1954 }
1955
1956 if (num_args == 1) {
1957 // We're adding this as a root command, so use the interpreter.
1958 const char *cmd_name = command.GetArgumentAtIndex(0);
1959 auto cmd_sp = CommandObjectSP(new CommandObjectMultiword(
1960 GetCommandInterpreter(), cmd_name, m_options.m_short_help.c_str(),
1961 m_options.m_long_help.c_str()));
1962 cmd_sp->GetAsMultiwordCommand()->SetRemovable(true);
1964 cmd_name, cmd_sp, m_options.m_overwrite);
1965 if (add_error.Fail()) {
1966 result.AppendErrorWithFormat("error adding command: %s",
1967 add_error.AsCString());
1968 return false;
1969 }
1971 return true;
1972 }
1973
1974 // We're adding this to a subcommand, first find the subcommand:
1975 Status path_error;
1976 CommandObjectMultiword *add_to_me =
1978 path_error);
1979
1980 if (!add_to_me) {
1981 result.AppendErrorWithFormat("error adding command: %s",
1982 path_error.AsCString());
1983 return false;
1984 }
1985
1986 const char *cmd_name = command.GetArgumentAtIndex(num_args - 1);
1987 auto cmd_sp = CommandObjectSP(new CommandObjectMultiword(
1988 GetCommandInterpreter(), cmd_name, m_options.m_short_help.c_str(),
1989 m_options.m_long_help.c_str()));
1990 llvm::Error llvm_error =
1991 add_to_me->LoadUserSubcommand(cmd_name, cmd_sp, m_options.m_overwrite);
1992 if (llvm_error) {
1993 result.AppendErrorWithFormat("error adding subcommand: %s",
1994 llvm::toString(std::move(llvm_error)).c_str());
1995 return false;
1996 }
1997
1999 return true;
2000 }
2001
2002private:
2004};
2005
2006#define LLDB_OPTIONS_multiword_delete
2007#include "CommandOptions.inc"
2009public:
2012 interpreter, "command container delete",
2013 "Delete a container command previously added to "
2014 "lldb.",
2015 "command container delete [[path1] ...] container-cmd") {
2017 CommandArgumentData cmd_arg;
2018
2019 // This is one or more command names, which form the path to the command
2020 // you want to add.
2021 cmd_arg.arg_type = eArgTypeCommand;
2023
2024 // There is only one variant this argument could be; put it into the
2025 // argument entry.
2026 arg1.push_back(cmd_arg);
2027
2028 // Push the data for the first argument into the m_arguments vector.
2029 m_arguments.push_back(arg1);
2030 }
2031
2033
2034 void
2036 OptionElementVector &opt_element_vector) override {
2038 m_interpreter, request, opt_element_vector);
2039 }
2040
2041protected:
2042 bool DoExecute(Args &command, CommandReturnObject &result) override {
2043 size_t num_args = command.GetArgumentCount();
2044
2045 if (num_args == 0) {
2046 result.AppendError("No command was specified.");
2047 return false;
2048 }
2049
2050 if (num_args == 1) {
2051 // We're removing a root command, so we need to delete it from the
2052 // interpreter.
2053 const char *cmd_name = command.GetArgumentAtIndex(0);
2054 // Let's do a little more work here so we can do better error reporting.
2056 CommandObjectSP cmd_sp = interp.GetCommandSPExact(cmd_name);
2057 if (!cmd_sp) {
2058 result.AppendErrorWithFormat("container command %s doesn't exist.",
2059 cmd_name);
2060 return false;
2061 }
2062 if (!cmd_sp->IsUserCommand()) {
2063 result.AppendErrorWithFormat(
2064 "container command %s is not a user command", cmd_name);
2065 return false;
2066 }
2067 if (!cmd_sp->GetAsMultiwordCommand()) {
2068 result.AppendErrorWithFormat("command %s is not a container command",
2069 cmd_name);
2070 return false;
2071 }
2072
2073 bool did_remove = GetCommandInterpreter().RemoveUserMultiword(cmd_name);
2074 if (!did_remove) {
2075 result.AppendErrorWithFormat("error removing command %s.", cmd_name);
2076 return false;
2077 }
2078
2080 return true;
2081 }
2082
2083 // We're removing a subcommand, first find the subcommand's owner:
2084 Status path_error;
2085 CommandObjectMultiword *container =
2087 path_error);
2088
2089 if (!container) {
2090 result.AppendErrorWithFormat("error removing container command: %s",
2091 path_error.AsCString());
2092 return false;
2093 }
2094 const char *leaf = command.GetArgumentAtIndex(num_args - 1);
2095 llvm::Error llvm_error =
2096 container->RemoveUserSubcommand(leaf, /* multiword okay */ true);
2097 if (llvm_error) {
2098 result.AppendErrorWithFormat("error removing container command: %s",
2099 llvm::toString(std::move(llvm_error)).c_str());
2100 return false;
2101 }
2103 return true;
2104 }
2105};
2106
2108public:
2111 interpreter, "command container",
2112 "Commands for adding container commands to lldb. "
2113 "Container commands are containers for other commands. You can "
2114 "add nested container commands by specifying a command path, "
2115 "but you can't add commands into the built-in command hierarchy.",
2116 "command container <subcommand> [<subcommand-options>]") {
2118 interpreter)));
2120 "delete",
2122 }
2123
2125};
2126
2127#pragma mark CommandObjectMultiwordCommands
2128
2129// CommandObjectMultiwordCommands
2130
2132 CommandInterpreter &interpreter)
2133 : CommandObjectMultiword(interpreter, "command",
2134 "Commands for managing custom LLDB commands.",
2135 "command <subcommand> [<subcommand-options>]") {
2136 LoadSubCommand("source",
2138 LoadSubCommand("alias",
2141 new CommandObjectCommandsUnalias(interpreter)));
2142 LoadSubCommand("delete",
2145 interpreter)));
2147 "regex", CommandObjectSP(new CommandObjectCommandsAddRegex(interpreter)));
2149 "script",
2151}
2152
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)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
ScriptedCommandSynchronicity GetSynchronicity()
CommandObjectPythonFunction(CommandInterpreter &interpreter, std::string name, std::string funct, std::string help, ScriptedCommandSynchronicity synch, CompletionType completion_type)
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
CommandObjectScriptingObject(CommandInterpreter &interpreter, std::string name, StructuredData::GenericSP cmd_obj_sp, ScriptedCommandSynchronicity synch, CompletionType completion_type)
StructuredData::GenericSP m_cmd_obj_sp
ScriptedCommandSynchronicity m_synchro
ScriptedCommandSynchronicity GetSynchronicity()
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
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:285
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:263
bool GetCommandString(std::string &command) const
Definition: Args.cpp:211
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, bool force=false)
Remove a command if it is removable (python or regex command).
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:79
lldb::StreamSP GetAsyncOutputStream()
Definition: Debugger.cpp:1263
CommandInterpreter & GetCommandInterpreter()
Definition: Debugger.h:175
bool GetUseColor() const
Definition: Debugger.cpp:402
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
Definition: Debugger.cpp:1163
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
Definition: Debugger.cpp:1632
"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:507
void MakeAbsolute(const FileSpec &dir)
Make the FileSpec absolute by treating it relative to dir.
Definition: FileSpec.cpp:530
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:190
lldb::StreamFileSP GetErrorStreamFileSP()
Definition: IOHandler.cpp:107
lldb::StreamFileSP GetOutputStreamFileSP()
Definition: IOHandler.cpp:105
void SetIsDone(bool b)
Definition: IOHandler.h:86
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
@ eDiskFileCompletion
@ eScriptLanguagePython
std::shared_ptr< lldb_private::IOHandler > IOHandlerSP
Definition: lldb-forward.h:342
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
Definition: lldb-forward.h:315
std::shared_ptr< lldb_private::Stream > StreamSP
Definition: lldb-forward.h:407
@ eReturnStatusFailed
@ eReturnStatusSuccessFinishResult
@ eReturnStatusInvalid
@ eReturnStatusSuccessFinishNoResult
@ eArgTypeSEDStylePair
@ eArgTypeFilename
@ eArgTypeCommandName
@ eArgTypeAliasName
@ eArgTypeAliasOptions
std::shared_ptr< lldb_private::StreamFile > StreamFileSP
Definition: lldb-forward.h:408
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)
OptionEnumValues enum_values
If not empty, an array of enum values.