1 //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // Other libraries and framework includes
13 #include "llvm/ADT/StringRef.h"
16 #include "CommandObjectCommands.h"
17 #include "CommandObjectHelp.h"
18 #include "lldb/Core/Debugger.h"
19 #include "lldb/Core/IOHandler.h"
20 #include "lldb/Core/StringList.h"
21 #include "lldb/Interpreter/Args.h"
22 #include "lldb/Interpreter/CommandHistory.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/CommandObjectRegexCommand.h"
25 #include "lldb/Interpreter/CommandReturnObject.h"
26 #include "lldb/Interpreter/OptionValueBoolean.h"
27 #include "lldb/Interpreter/OptionValueString.h"
28 #include "lldb/Interpreter/OptionValueUInt64.h"
29 #include "lldb/Interpreter/Options.h"
30 #include "lldb/Interpreter/ScriptInterpreter.h"
33 using namespace lldb_private;
35 //-------------------------------------------------------------------------
36 // CommandObjectCommandsSource
37 //-------------------------------------------------------------------------
39 class CommandObjectCommandsHistory : public CommandObjectParsed
42 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
43 CommandObjectParsed(interpreter,
45 "Dump the history of commands in this session.",
47 m_options (interpreter)
51 ~CommandObjectCommandsHistory() override = default;
54 GetOptions () override
60 class CommandOptions : public Options
63 CommandOptions (CommandInterpreter &interpreter) :
64 Options (interpreter),
72 ~CommandOptions() override = default;
75 SetOptionValue (uint32_t option_idx, const char *option_arg) override
78 const int short_option = m_getopt_table[option_idx].val;
83 error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
86 if (option_arg && strcmp("end", option_arg) == 0)
88 m_start_idx.SetCurrentValue(UINT64_MAX);
89 m_start_idx.SetOptionWasSet();
92 error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
95 error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
98 m_clear.SetCurrentValue(true);
99 m_clear.SetOptionWasSet();
102 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
110 OptionParsingStarting () override
118 const OptionDefinition*
119 GetDefinitions () override
121 return g_option_table;
124 // Options table: Required for subclasses of Options.
126 static OptionDefinition g_option_table[];
128 // Instance variables to hold the values for command options.
130 OptionValueUInt64 m_start_idx;
131 OptionValueUInt64 m_stop_idx;
132 OptionValueUInt64 m_count;
133 OptionValueBoolean m_clear;
137 DoExecute (Args& command, CommandReturnObject &result) override
139 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
141 m_interpreter.GetCommandHistory().Clear();
142 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
146 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
148 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
149 result.SetStatus(lldb::eReturnStatusFailed);
153 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
154 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
155 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
157 const CommandHistory& history(m_interpreter.GetCommandHistory());
159 if (start_idx.first && start_idx.second == UINT64_MAX)
163 start_idx.second = history.GetSize() - count.second;
164 stop_idx.second = history.GetSize() - 1;
166 else if (stop_idx.first)
168 start_idx.second = stop_idx.second;
169 stop_idx.second = history.GetSize() - 1;
173 start_idx.second = 0;
174 stop_idx.second = history.GetSize() - 1;
179 if (!start_idx.first && !stop_idx.first && !count.first)
181 start_idx.second = 0;
182 stop_idx.second = history.GetSize() - 1;
184 else if (start_idx.first)
188 stop_idx.second = start_idx.second + count.second - 1;
190 else if (!stop_idx.first)
192 stop_idx.second = history.GetSize() - 1;
195 else if (stop_idx.first)
199 if (stop_idx.second >= count.second)
200 start_idx.second = stop_idx.second - count.second + 1;
202 start_idx.second = 0;
205 else /* if (count.first) */
207 start_idx.second = 0;
208 stop_idx.second = count.second - 1;
211 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
214 return result.Succeeded();
218 CommandOptions m_options;
222 CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
224 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
225 { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
226 { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
227 { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clears the current command history."},
228 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
231 //-------------------------------------------------------------------------
232 // CommandObjectCommandsSource
233 //-------------------------------------------------------------------------
235 class CommandObjectCommandsSource : public CommandObjectParsed
238 CommandObjectCommandsSource(CommandInterpreter &interpreter)
239 : CommandObjectParsed(interpreter, "command source", "Read and execute LLDB commands from the file <filename>.",
241 m_options(interpreter)
243 CommandArgumentEntry arg;
244 CommandArgumentData file_arg;
246 // Define the first (and only) variant of this arg.
247 file_arg.arg_type = eArgTypeFilename;
248 file_arg.arg_repetition = eArgRepeatPlain;
250 // There is only one variant this argument could be; put it into the argument entry.
251 arg.push_back (file_arg);
253 // Push the data for the first argument into the m_arguments vector.
254 m_arguments.push_back (arg);
257 ~CommandObjectCommandsSource() override = default;
260 GetRepeatCommand (Args ¤t_command_args, uint32_t index) override
266 HandleArgumentCompletion (Args &input,
268 int &cursor_char_position,
269 OptionElementVector &opt_element_vector,
270 int match_start_point,
271 int max_return_elements,
273 StringList &matches) override
275 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
276 completion_str.erase (cursor_char_position);
278 CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
279 CommandCompletions::eDiskFileCompletion,
280 completion_str.c_str(),
286 return matches.GetSize();
290 GetOptions () override
296 class CommandOptions : public Options
299 CommandOptions (CommandInterpreter &interpreter) :
300 Options (interpreter),
301 m_stop_on_error (true),
302 m_silent_run (false),
303 m_stop_on_continue (true)
307 ~CommandOptions() override = default;
310 SetOptionValue (uint32_t option_idx, const char *option_arg) override
313 const int short_option = m_getopt_table[option_idx].val;
315 switch (short_option)
318 error = m_stop_on_error.SetValueFromString(option_arg);
322 error = m_stop_on_continue.SetValueFromString(option_arg);
326 error = m_silent_run.SetValueFromString(option_arg);
330 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
338 OptionParsingStarting () override
340 m_stop_on_error.Clear();
341 m_silent_run.Clear();
342 m_stop_on_continue.Clear();
345 const OptionDefinition*
346 GetDefinitions () override
348 return g_option_table;
351 // Options table: Required for subclasses of Options.
353 static OptionDefinition g_option_table[];
355 // Instance variables to hold the values for command options.
357 OptionValueBoolean m_stop_on_error;
358 OptionValueBoolean m_silent_run;
359 OptionValueBoolean m_stop_on_continue;
363 DoExecute(Args& command, CommandReturnObject &result) override
365 const size_t argc = command.GetArgumentCount();
368 const char *filename = command.GetArgumentAtIndex(0);
370 FileSpec cmd_file (filename, true);
371 ExecutionContext *exe_ctx = nullptr; // Just use the default context.
373 // If any options were set, then use them
374 if (m_options.m_stop_on_error.OptionWasSet() ||
375 m_options.m_silent_run.OptionWasSet() ||
376 m_options.m_stop_on_continue.OptionWasSet())
378 // Use user set settings
379 CommandInterpreterRunOptions options;
380 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
381 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
382 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
383 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
385 m_interpreter.HandleCommandsFromFile (cmd_file,
392 // No options were set, inherit any settings from nested "command source" commands,
393 // or set to sane default settings...
394 CommandInterpreterRunOptions options;
395 m_interpreter.HandleCommandsFromFile (cmd_file,
403 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
404 result.SetStatus (eReturnStatusFailed);
406 return result.Succeeded();
409 CommandOptions m_options;
413 CommandObjectCommandsSource::CommandOptions::g_option_table[] =
415 { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
416 { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
417 { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
418 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
421 #pragma mark CommandObjectCommandsAlias
422 //-------------------------------------------------------------------------
423 // CommandObjectCommandsAlias
424 //-------------------------------------------------------------------------
426 static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
427 "You must define a Python function with this signature:\n"
428 "def my_command_impl(debugger, args, result, internal_dict):\n";
430 class CommandObjectCommandsAlias : public CommandObjectRaw
433 class CommandOptions : public OptionGroup
442 ~CommandOptions() override = default;
445 GetNumDefinitions () override
450 const OptionDefinition*
451 GetDefinitions () override
453 return g_option_table;
457 SetOptionValue (CommandInterpreter &interpreter,
459 const char *option_value) override
463 const int short_option = g_option_table[option_idx].short_option;
465 switch (short_option)
468 m_help.SetCurrentValue(option_value);
469 m_help.SetOptionWasSet();
473 m_long_help.SetCurrentValue(option_value);
474 m_long_help.SetOptionWasSet();
478 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
486 OptionParsingStarting (CommandInterpreter &interpreter) override
492 // Options table: Required for subclasses of Options.
494 static OptionDefinition g_option_table[];
495 OptionValueString m_help;
496 OptionValueString m_long_help;
499 OptionGroupOptions m_option_group;
500 CommandOptions m_command_options;
504 GetOptions () override
506 return &m_option_group;
509 CommandObjectCommandsAlias(CommandInterpreter &interpreter)
510 : CommandObjectRaw(interpreter, "command alias", "Define a custom command in terms of an existing command.",
512 m_option_group(interpreter),
515 m_option_group.Append(&m_command_options);
516 m_option_group.Finalize();
519 "'alias' allows the user to create a short-cut or abbreviation for long \
520 commands, multi-word commands, and commands that take particular options. \
521 Below are some simple examples of how one might use the 'alias' command:" R"(
523 (lldb) command alias sc script
525 Creates the abbreviation 'sc' for the 'script' command.
527 (lldb) command alias bp breakpoint
529 )" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
530 breakpoint commands are two-word commands, the user would still need to \
531 enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
533 (lldb) command alias bpl breakpoint list
535 Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
537 )" "An alias can include some options for the command, with the values either \
538 filled in at the time the alias is created, or specified as positional \
539 arguments, to be filled in when the alias is invoked. The following example \
540 shows how to create aliases with options:" R"(
542 (lldb) command alias bfl breakpoint set -f %1 -l %2
544 )" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
545 options already part of the alias. So if the user wants to set a breakpoint \
546 by file and line without explicitly having to use the -f and -l options, the \
547 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \
548 for the actual arguments that will be passed when the alias command is used. \
549 The number in the placeholder refers to the position/order the actual value \
550 occupies when the alias is used. All the occurrences of '%1' in the alias \
551 will be replaced with the first argument, all the occurrences of '%2' in the \
552 alias will be replaced with the second argument, and so on. This also allows \
553 actual arguments to be used multiple times within an alias (see 'process \
554 launch' example below)." R"(
556 )" "Note: the positional arguments must substitute as whole words in the resultant \
557 command, so you can't at present do something like this to append the file extension \
560 (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
562 )" "For more complex aliasing, use the \"command regex\" command instead. In the \
563 'bfl' case above, the actual file value will be filled in with the first argument \
564 following 'bfl' and the actual line number value will be filled in with the second \
565 argument. The user would use this alias as follows:" R"(
567 (lldb) command alias bfl breakpoint set -f %1 -l %2
568 (lldb) bfl my-file.c 137
570 This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
574 (lldb) command alias pltty process launch -s -o %1 -e %1
575 (lldb) pltty /dev/tty0
577 Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
579 )" "If the user always wanted to pass the same value to a particular option, the \
580 alias could be defined with that value directly in the alias as a constant, \
581 rather than using a positional placeholder:" R"(
583 (lldb) command alias bl3 breakpoint set -f %1 -l 3
585 Always sets a breakpoint on line 3 of whatever file is indicated.)"
588 CommandArgumentEntry arg1;
589 CommandArgumentEntry arg2;
590 CommandArgumentEntry arg3;
591 CommandArgumentData alias_arg;
592 CommandArgumentData cmd_arg;
593 CommandArgumentData options_arg;
595 // Define the first (and only) variant of this arg.
596 alias_arg.arg_type = eArgTypeAliasName;
597 alias_arg.arg_repetition = eArgRepeatPlain;
599 // There is only one variant this argument could be; put it into the argument entry.
600 arg1.push_back (alias_arg);
602 // Define the first (and only) variant of this arg.
603 cmd_arg.arg_type = eArgTypeCommandName;
604 cmd_arg.arg_repetition = eArgRepeatPlain;
606 // There is only one variant this argument could be; put it into the argument entry.
607 arg2.push_back (cmd_arg);
609 // Define the first (and only) variant of this arg.
610 options_arg.arg_type = eArgTypeAliasOptions;
611 options_arg.arg_repetition = eArgRepeatOptional;
613 // There is only one variant this argument could be; put it into the argument entry.
614 arg3.push_back (options_arg);
616 // Push the data for the first argument into the m_arguments vector.
617 m_arguments.push_back (arg1);
618 m_arguments.push_back (arg2);
619 m_arguments.push_back (arg3);
622 ~CommandObjectCommandsAlias() override = default;
626 DoExecute (const char *raw_command_line, CommandReturnObject &result) override
628 if (!raw_command_line || !raw_command_line[0])
630 result.AppendError ("'command alias' requires at least two arguments");
634 m_option_group.NotifyOptionParsingStarting();
636 const char * remainder = nullptr;
638 if (raw_command_line[0] == '-')
640 // We have some options and these options MUST end with --.
641 const char *end_options = nullptr;
642 const char *s = raw_command_line;
645 end_options = ::strstr (s, "--");
648 end_options += 2; // Get past the "--"
649 if (::isspace (end_options[0]))
651 remainder = end_options;
652 while (::isspace (*remainder))
662 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
663 if (!ParseOptions (args, result))
666 Error error (m_option_group.NotifyOptionParsingFinished());
669 result.AppendError (error.AsCString());
670 result.SetStatus (eReturnStatusFailed);
675 if (nullptr == remainder)
676 remainder = raw_command_line;
678 std::string raw_command_string (remainder);
679 Args args (raw_command_string.c_str());
681 size_t argc = args.GetArgumentCount();
685 result.AppendError ("'command alias' requires at least two arguments");
686 result.SetStatus (eReturnStatusFailed);
690 // Get the alias command.
692 const std::string alias_command = args.GetArgumentAtIndex (0);
693 if (alias_command.size() > 1 &&
694 alias_command[0] == '-')
696 result.AppendError("aliases starting with a dash are not supported");
697 if (alias_command == "--help" || alias_command == "--long-help")
699 result.AppendWarning("if trying to pass options to 'command alias' add a -- at the end of the options");
701 result.SetStatus (eReturnStatusFailed);
705 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
706 // does the stripping itself.
707 size_t pos = raw_command_string.find (alias_command);
710 raw_command_string = raw_command_string.substr (alias_command.size());
711 pos = raw_command_string.find_first_not_of (' ');
712 if ((pos != std::string::npos) && (pos > 0))
713 raw_command_string = raw_command_string.substr (pos);
717 result.AppendError ("Error parsing command string. No alias created.");
718 result.SetStatus (eReturnStatusFailed);
723 // Verify that the command is alias-able.
724 if (m_interpreter.CommandExists (alias_command.c_str()))
726 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
727 alias_command.c_str());
728 result.SetStatus (eReturnStatusFailed);
732 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
733 // raw_command_string is returned with the name of the command object stripped off the front.
734 std::string original_raw_command_string(raw_command_string);
735 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
739 result.AppendErrorWithFormat ("invalid command given to 'command alias'. '%s' does not begin with a valid command."
740 " No alias created.", original_raw_command_string.c_str());
741 result.SetStatus (eReturnStatusFailed);
744 else if (!cmd_obj->WantsRawCommandString ())
746 // Note that args was initialized with the original command, and has not been updated to this point.
747 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
748 return HandleAliasingNormalCommand (args, result);
752 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
754 return result.Succeeded();
758 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
760 // Verify & handle any options/arguments passed to the alias command
762 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
764 if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false))
766 if (m_interpreter.AliasExists (alias_command.c_str())
767 || m_interpreter.UserCommandExists (alias_command.c_str()))
769 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
770 alias_command.c_str());
772 if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str()))
774 if (m_command_options.m_help.OptionWasSet())
775 alias->SetHelp(m_command_options.m_help.GetCurrentValue());
776 if (m_command_options.m_long_help.OptionWasSet())
777 alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
778 result.SetStatus (eReturnStatusSuccessFinishNoResult);
782 result.AppendError ("Unable to create requested alias.\n");
783 result.SetStatus (eReturnStatusFailed);
789 result.AppendError ("Unable to create requested alias.\n");
790 result.SetStatus (eReturnStatusFailed);
793 return result.Succeeded ();
797 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
799 size_t argc = args.GetArgumentCount();
803 result.AppendError ("'command alias' requires at least two arguments");
804 result.SetStatus (eReturnStatusFailed);
808 const std::string alias_command = args.GetArgumentAtIndex(0);
809 const std::string actual_command = args.GetArgumentAtIndex(1);
811 args.Shift(); // Shift the alias command word off the argument vector.
812 args.Shift(); // Shift the old command word off the argument vector.
814 // Verify that the command is alias'able, and get the appropriate command object.
816 if (m_interpreter.CommandExists (alias_command.c_str()))
818 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
819 alias_command.c_str());
820 result.SetStatus (eReturnStatusFailed);
824 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
825 CommandObjectSP subcommand_obj_sp;
826 bool use_subcommand = false;
829 CommandObject *cmd_obj = command_obj_sp.get();
830 CommandObject *sub_cmd_obj = nullptr;
831 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
833 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
837 const std::string sub_command = args.GetArgumentAtIndex(0);
838 assert (sub_command.length() != 0);
839 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
840 if (subcommand_obj_sp)
842 sub_cmd_obj = subcommand_obj_sp.get();
843 use_subcommand = true;
844 args.Shift(); // Shift the sub_command word off the argument vector.
845 cmd_obj = sub_cmd_obj;
849 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
850 "Unable to create alias.\n",
851 sub_command.c_str(), actual_command.c_str());
852 result.SetStatus (eReturnStatusFailed);
858 // Verify & handle any options/arguments passed to the alias command
860 std::string args_string;
862 if (args.GetArgumentCount () > 0)
864 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
866 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
868 args.GetCommandString (args_string);
871 if (m_interpreter.AliasExists (alias_command.c_str())
872 || m_interpreter.UserCommandExists (alias_command.c_str()))
874 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
875 alias_command.c_str());
878 if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(),
879 use_subcommand ? subcommand_obj_sp : command_obj_sp,
880 args_string.c_str()))
882 if (m_command_options.m_help.OptionWasSet())
883 alias->SetHelp(m_command_options.m_help.GetCurrentValue());
884 if (m_command_options.m_long_help.OptionWasSet())
885 alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
886 result.SetStatus (eReturnStatusSuccessFinishNoResult);
890 result.AppendError ("Unable to create requested alias.\n");
891 result.SetStatus (eReturnStatusFailed);
897 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
898 result.SetStatus (eReturnStatusFailed);
903 return result.Succeeded();
908 CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
910 { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Help text for this command"},
911 { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Long help text for this command"},
912 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
915 #pragma mark CommandObjectCommandsUnalias
916 //-------------------------------------------------------------------------
917 // CommandObjectCommandsUnalias
918 //-------------------------------------------------------------------------
920 class CommandObjectCommandsUnalias : public CommandObjectParsed
923 CommandObjectCommandsUnalias(CommandInterpreter &interpreter)
924 : CommandObjectParsed(interpreter, "command unalias",
925 "Delete one or more custom commands defined by 'command alias'.", nullptr)
927 CommandArgumentEntry arg;
928 CommandArgumentData alias_arg;
930 // Define the first (and only) variant of this arg.
931 alias_arg.arg_type = eArgTypeAliasName;
932 alias_arg.arg_repetition = eArgRepeatPlain;
934 // There is only one variant this argument could be; put it into the argument entry.
935 arg.push_back (alias_arg);
937 // Push the data for the first argument into the m_arguments vector.
938 m_arguments.push_back (arg);
941 ~CommandObjectCommandsUnalias() override = default;
945 DoExecute (Args& args, CommandReturnObject &result) override
947 CommandObject::CommandMap::iterator pos;
948 CommandObject *cmd_obj;
950 if (args.GetArgumentCount() != 0)
952 const char *command_name = args.GetArgumentAtIndex(0);
953 cmd_obj = m_interpreter.GetCommandObject(command_name);
956 if (m_interpreter.CommandExists (command_name))
958 if (cmd_obj->IsRemovable())
960 result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
965 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
968 result.SetStatus (eReturnStatusFailed);
972 if (!m_interpreter.RemoveAlias(command_name))
974 if (m_interpreter.AliasExists (command_name))
975 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
978 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
979 result.SetStatus (eReturnStatusFailed);
982 result.SetStatus (eReturnStatusSuccessFinishNoResult);
987 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
988 "current list of commands.\n",
990 result.SetStatus (eReturnStatusFailed);
995 result.AppendError ("must call 'unalias' with a valid alias");
996 result.SetStatus (eReturnStatusFailed);
999 return result.Succeeded();
1003 #pragma mark CommandObjectCommandsDelete
1004 //-------------------------------------------------------------------------
1005 // CommandObjectCommandsDelete
1006 //-------------------------------------------------------------------------
1008 class CommandObjectCommandsDelete : public CommandObjectParsed
1011 CommandObjectCommandsDelete(CommandInterpreter &interpreter)
1012 : CommandObjectParsed(interpreter, "command delete",
1013 "Delete one or more custom commands defined by 'command regex'.", nullptr)
1015 CommandArgumentEntry arg;
1016 CommandArgumentData alias_arg;
1018 // Define the first (and only) variant of this arg.
1019 alias_arg.arg_type = eArgTypeCommandName;
1020 alias_arg.arg_repetition = eArgRepeatPlain;
1022 // There is only one variant this argument could be; put it into the argument entry.
1023 arg.push_back (alias_arg);
1025 // Push the data for the first argument into the m_arguments vector.
1026 m_arguments.push_back (arg);
1029 ~CommandObjectCommandsDelete() override = default;
1033 DoExecute (Args& args, CommandReturnObject &result) override
1035 CommandObject::CommandMap::iterator pos;
1037 if (args.GetArgumentCount() != 0)
1039 const char *command_name = args.GetArgumentAtIndex(0);
1040 if (m_interpreter.CommandExists (command_name))
1042 if (m_interpreter.RemoveCommand (command_name))
1044 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1048 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
1050 result.SetStatus (eReturnStatusFailed);
1055 StreamString error_msg_stream;
1056 const bool generate_apropos = true;
1057 const bool generate_type_lookup = false;
1058 CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
1063 generate_type_lookup);
1064 result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
1065 result.SetStatus (eReturnStatusFailed);
1070 result.AppendErrorWithFormat(
1071 "must call '%s' with one or more valid user defined regular expression command names",
1073 result.SetStatus (eReturnStatusFailed);
1076 return result.Succeeded();
1080 //-------------------------------------------------------------------------
1081 // CommandObjectCommandsAddRegex
1082 //-------------------------------------------------------------------------
1083 #pragma mark CommandObjectCommandsAddRegex
1085 class CommandObjectCommandsAddRegex :
1086 public CommandObjectParsed,
1087 public IOHandlerDelegateMultiline
1090 CommandObjectCommandsAddRegex(CommandInterpreter &interpreter)
1091 : CommandObjectParsed(interpreter, "command regex",
1092 "Define a custom command in terms of existing commands by matching regular expressions.",
1093 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
1094 IOHandlerDelegateMultiline("", IOHandlerDelegate::Completion::LLDBCommand),
1095 m_options(interpreter)
1098 )" "This command allows the user to create powerful regular expression commands \
1099 with substitutions. The regular expressions and substitutions are specified \
1100 using the regular expression substitution format of:" R"(
1104 )" "<regex> is a regular expression that can use parenthesis to capture regular \
1105 expression input and substitute the captured matches in the output using %1 \
1106 for the first match, %2 for the second, and so on." R"(
1108 )" "The regular expressions can all be specified on the command line if more than \
1109 one argument is provided. If just the command name is provided on the command \
1110 line, then the regular expressions and substitutions can be entered on separate \
1111 lines, followed by an empty line to terminate the command definition." R"(
1115 )" "The following example will define a regular expression command named 'f' that \
1116 will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
1117 a number follows 'f':" R"(
1119 (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
1123 ~CommandObjectCommandsAddRegex() override = default;
1127 IOHandlerActivated (IOHandler &io_handler) override
1129 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1132 output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n");
1138 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
1140 io_handler.SetIsDone(true);
1144 if (lines.SplitIntoLines (data))
1146 const size_t num_lines = lines.GetSize();
1147 bool check_only = false;
1148 for (size_t i=0; i<num_lines; ++i)
1150 llvm::StringRef bytes_strref (lines[i]);
1151 Error error = AppendRegexSubstitution (bytes_strref, check_only);
1154 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
1156 StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
1157 out_stream->Printf("error: %s\n", error.AsCString());
1162 if (m_regex_cmd_ap->HasRegexEntries())
1164 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1165 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1171 DoExecute (Args& command, CommandReturnObject &result) override
1173 const size_t argc = command.GetArgumentCount();
1176 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
1177 result.SetStatus (eReturnStatusFailed);
1182 const char *name = command.GetArgumentAtIndex(0);
1183 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1185 m_options.GetHelp (),
1186 m_options.GetSyntax (),
1193 Debugger &debugger = m_interpreter.GetDebugger();
1194 bool color_prompt = debugger.GetUseColor();
1195 const bool multiple_lines = true; // Get multiple lines
1196 IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
1197 IOHandler::Type::Other,
1198 "lldb-regex", // Name of input reader for history
1200 nullptr, // Continuation prompt
1203 0, // Don't show line numbers
1208 debugger.PushIOHandler(io_handler_sp);
1209 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1214 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
1216 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
1217 bool check_only = false;
1218 error = AppendRegexSubstitution (arg_strref, check_only);
1223 if (error.Success())
1225 AddRegexCommandToInterpreter();
1230 result.AppendError (error.AsCString());
1231 result.SetStatus (eReturnStatusFailed);
1235 return result.Succeeded();
1239 AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only)
1243 if (!m_regex_cmd_ap)
1245 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
1246 (int)regex_sed.size(),
1251 size_t regex_sed_size = regex_sed.size();
1253 if (regex_sed_size <= 1)
1255 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
1256 (int)regex_sed.size(),
1261 if (regex_sed[0] != 's')
1263 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
1264 (int)regex_sed.size(),
1268 const size_t first_separator_char_pos = 1;
1269 // use the char that follows 's' as the regex separator character
1270 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1271 const char separator_char = regex_sed[first_separator_char_pos];
1272 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1274 if (second_separator_char_pos == std::string::npos)
1276 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
1278 (int)(regex_sed.size() - first_separator_char_pos - 1),
1279 regex_sed.data() + (first_separator_char_pos + 1),
1280 (int)regex_sed.size(),
1285 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1287 if (third_separator_char_pos == std::string::npos)
1289 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
1291 (int)(regex_sed.size() - second_separator_char_pos - 1),
1292 regex_sed.data() + (second_separator_char_pos + 1),
1293 (int)regex_sed.size(),
1298 if (third_separator_char_pos != regex_sed_size - 1)
1300 // Make sure that everything that follows the last regex
1302 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1304 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1305 (int)third_separator_char_pos + 1,
1307 (int)(regex_sed.size() - third_separator_char_pos - 1),
1308 regex_sed.data() + (third_separator_char_pos + 1));
1312 else if (first_separator_char_pos + 1 == second_separator_char_pos)
1314 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1318 (int)regex_sed.size(),
1322 else if (second_separator_char_pos + 1 == third_separator_char_pos)
1324 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1328 (int)regex_sed.size(),
1335 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1336 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1337 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1344 AddRegexCommandToInterpreter()
1348 if (m_regex_cmd_ap->HasRegexEntries())
1350 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1351 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1357 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1359 class CommandOptions : public Options
1362 CommandOptions (CommandInterpreter &interpreter) :
1363 Options (interpreter)
1367 ~CommandOptions() override = default;
1370 SetOptionValue (uint32_t option_idx, const char *option_arg) override
1373 const int short_option = m_getopt_table[option_idx].val;
1375 switch (short_option)
1378 m_help.assign (option_arg);
1381 m_syntax.assign (option_arg);
1384 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1392 OptionParsingStarting () override
1398 const OptionDefinition*
1399 GetDefinitions () override
1401 return g_option_table;
1404 // Options table: Required for subclasses of Options.
1406 static OptionDefinition g_option_table[];
1411 return (m_help.empty() ? nullptr : m_help.c_str());
1417 return (m_syntax.empty() ? nullptr : m_syntax.c_str());
1421 // Instance variables to hold the values for command options.
1424 std::string m_syntax;
1428 GetOptions () override
1433 CommandOptions m_options;
1437 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1439 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."},
1440 { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1441 { 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
1444 class CommandObjectPythonFunction : public CommandObjectRaw
1447 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1451 ScriptedCommandSynchronicity synch) :
1452 CommandObjectRaw(interpreter,
1456 m_function_name(funct),
1458 m_fetched_help_long(false)
1461 SetHelp(help.c_str());
1464 StreamString stream;
1465 stream.Printf("For more information run 'help %s'",name.c_str());
1466 SetHelp(stream.GetData());
1470 ~CommandObjectPythonFunction() override = default;
1473 IsRemovable () const override
1481 return m_function_name;
1484 ScriptedCommandSynchronicity
1491 GetHelpLong () override
1493 if (!m_fetched_help_long)
1495 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1498 std::string docstring;
1499 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1500 if (!docstring.empty())
1501 SetHelpLong(docstring.c_str());
1504 return CommandObjectRaw::GetHelpLong();
1509 DoExecute (const char *raw_command_line, CommandReturnObject &result) override
1511 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1515 result.SetStatus(eReturnStatusInvalid);
1517 if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(),
1524 result.AppendError(error.AsCString());
1525 result.SetStatus(eReturnStatusFailed);
1529 // Don't change the status if the command already set it...
1530 if (result.GetStatus() == eReturnStatusInvalid)
1532 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
1533 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1535 result.SetStatus(eReturnStatusSuccessFinishResult);
1539 return result.Succeeded();
1543 std::string m_function_name;
1544 ScriptedCommandSynchronicity m_synchro;
1545 bool m_fetched_help_long;
1548 class CommandObjectScriptingObject : public CommandObjectRaw
1551 CommandObjectScriptingObject (CommandInterpreter &interpreter,
1553 StructuredData::GenericSP cmd_obj_sp,
1554 ScriptedCommandSynchronicity synch) :
1555 CommandObjectRaw(interpreter,
1559 m_cmd_obj_sp(cmd_obj_sp),
1561 m_fetched_help_short(false),
1562 m_fetched_help_long(false)
1564 StreamString stream;
1565 stream.Printf("For more information run 'help %s'",name.c_str());
1566 SetHelp(stream.GetData());
1567 if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1568 GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
1571 ~CommandObjectScriptingObject() override = default;
1574 IsRemovable () const override
1579 StructuredData::GenericSP
1580 GetImplementingObject ()
1582 return m_cmd_obj_sp;
1585 ScriptedCommandSynchronicity
1594 if (!m_fetched_help_short)
1596 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1599 std::string docstring;
1600 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
1601 if (!docstring.empty())
1602 SetHelp(docstring.c_str());
1605 return CommandObjectRaw::GetHelp();
1609 GetHelpLong () override
1611 if (!m_fetched_help_long)
1613 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1616 std::string docstring;
1617 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
1618 if (!docstring.empty())
1619 SetHelpLong(docstring.c_str());
1622 return CommandObjectRaw::GetHelpLong();
1627 DoExecute (const char *raw_command_line, CommandReturnObject &result) override
1629 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1633 result.SetStatus(eReturnStatusInvalid);
1635 if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp,
1642 result.AppendError(error.AsCString());
1643 result.SetStatus(eReturnStatusFailed);
1647 // Don't change the status if the command already set it...
1648 if (result.GetStatus() == eReturnStatusInvalid)
1650 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
1651 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1653 result.SetStatus(eReturnStatusSuccessFinishResult);
1657 return result.Succeeded();
1661 StructuredData::GenericSP m_cmd_obj_sp;
1662 ScriptedCommandSynchronicity m_synchro;
1663 bool m_fetched_help_short: 1;
1664 bool m_fetched_help_long: 1;
1667 //-------------------------------------------------------------------------
1668 // CommandObjectCommandsScriptImport
1669 //-------------------------------------------------------------------------
1671 class CommandObjectCommandsScriptImport : public CommandObjectParsed
1674 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1675 CommandObjectParsed(interpreter,
1676 "command script import",
1677 "Import a scripting module in LLDB.",
1679 m_options(interpreter)
1681 CommandArgumentEntry arg1;
1682 CommandArgumentData cmd_arg;
1684 // Define the first (and only) variant of this arg.
1685 cmd_arg.arg_type = eArgTypeFilename;
1686 cmd_arg.arg_repetition = eArgRepeatPlus;
1688 // There is only one variant this argument could be; put it into the argument entry.
1689 arg1.push_back (cmd_arg);
1691 // Push the data for the first argument into the m_arguments vector.
1692 m_arguments.push_back (arg1);
1695 ~CommandObjectCommandsScriptImport() override = default;
1698 HandleArgumentCompletion (Args &input,
1700 int &cursor_char_position,
1701 OptionElementVector &opt_element_vector,
1702 int match_start_point,
1703 int max_return_elements,
1704 bool &word_complete,
1705 StringList &matches) override
1707 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1708 completion_str.erase (cursor_char_position);
1710 CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
1711 CommandCompletions::eDiskFileCompletion,
1712 completion_str.c_str(),
1714 max_return_elements,
1718 return matches.GetSize();
1722 GetOptions () override
1728 class CommandOptions : public Options
1731 CommandOptions (CommandInterpreter &interpreter) :
1732 Options (interpreter)
1736 ~CommandOptions() override = default;
1739 SetOptionValue (uint32_t option_idx, const char *option_arg) override
1742 const int short_option = m_getopt_table[option_idx].val;
1744 switch (short_option)
1747 m_allow_reload = true;
1750 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1758 OptionParsingStarting () override
1760 m_allow_reload = true;
1763 const OptionDefinition*
1764 GetDefinitions () override
1766 return g_option_table;
1769 // Options table: Required for subclasses of Options.
1771 static OptionDefinition g_option_table[];
1773 // Instance variables to hold the values for command options.
1775 bool m_allow_reload;
1779 DoExecute (Args& command, CommandReturnObject &result) override
1781 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1783 result.AppendError ("only scripting language supported for module importing is currently Python");
1784 result.SetStatus (eReturnStatusFailed);
1788 size_t argc = command.GetArgumentCount();
1791 result.AppendError("command script import needs one or more arguments");
1792 result.SetStatus (eReturnStatusFailed);
1800 std::string path = command.GetArgumentAtIndex(i);
1803 const bool init_session = true;
1804 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1805 // commands won't ever be recursively invoked, but it's actually possible to craft
1806 // a Python script that does other "command script imports" in __lldb_init_module
1807 // the real fix is to have recursive commands possible with a CommandInvocation object
1808 // separate from the CommandObject itself, so that recursive command invocations
1809 // won't stomp on each other (wrt to execution contents, options, and more)
1811 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
1812 m_options.m_allow_reload,
1816 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1820 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1821 result.SetStatus (eReturnStatusFailed);
1825 return result.Succeeded();
1828 CommandOptions m_options;
1832 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1834 { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."},
1835 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
1838 //-------------------------------------------------------------------------
1839 // CommandObjectCommandsScriptAdd
1840 //-------------------------------------------------------------------------
1842 class CommandObjectCommandsScriptAdd :
1843 public CommandObjectParsed,
1844 public IOHandlerDelegateMultiline
1847 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1848 CommandObjectParsed(interpreter,
1849 "command script add",
1850 "Add a scripted function as an LLDB command.",
1852 IOHandlerDelegateMultiline ("DONE"),
1853 m_options (interpreter)
1855 CommandArgumentEntry arg1;
1856 CommandArgumentData cmd_arg;
1858 // Define the first (and only) variant of this arg.
1859 cmd_arg.arg_type = eArgTypeCommandName;
1860 cmd_arg.arg_repetition = eArgRepeatPlain;
1862 // There is only one variant this argument could be; put it into the argument entry.
1863 arg1.push_back (cmd_arg);
1865 // Push the data for the first argument into the m_arguments vector.
1866 m_arguments.push_back (arg1);
1869 ~CommandObjectCommandsScriptAdd() override = default;
1872 GetOptions () override
1878 class CommandOptions : public Options
1881 CommandOptions (CommandInterpreter &interpreter) :
1882 Options (interpreter),
1886 m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1890 ~CommandOptions() override = default;
1893 SetOptionValue (uint32_t option_idx, const char *option_arg) override
1896 const int short_option = m_getopt_table[option_idx].val;
1898 switch (short_option)
1902 m_funct_name.assign(option_arg);
1906 m_class_name.assign(option_arg);
1910 m_short_help.assign(option_arg);
1913 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1914 if (!error.Success())
1915 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1918 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1926 OptionParsingStarting () override
1928 m_class_name.clear();
1929 m_funct_name.clear();
1930 m_short_help.clear();
1931 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1934 const OptionDefinition*
1935 GetDefinitions () override
1937 return g_option_table;
1940 // Options table: Required for subclasses of Options.
1942 static OptionDefinition g_option_table[];
1944 // Instance variables to hold the values for command options.
1946 std::string m_class_name;
1947 std::string m_funct_name;
1948 std::string m_short_help;
1949 ScriptedCommandSynchronicity m_synchronicity;
1953 IOHandlerActivated (IOHandler &io_handler) override
1955 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1958 output_sp->PutCString(g_python_command_instructions);
1965 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
1967 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1969 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1974 lines.SplitIntoLines(data);
1975 if (lines.GetSize() > 0)
1977 std::string funct_name_str;
1978 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1980 if (funct_name_str.empty())
1982 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1987 // everything should be fine now, let's add this alias
1989 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1991 funct_name_str.c_str(),
1995 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1997 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
2004 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
2010 error_sp->Printf ("error: empty function, didn't add python command.\n");
2016 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
2020 io_handler.SetIsDone(true);
2025 DoExecute (Args& command, CommandReturnObject &result) override
2027 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
2029 result.AppendError ("only scripting language supported for scripted commands is currently Python");
2030 result.SetStatus (eReturnStatusFailed);
2034 size_t argc = command.GetArgumentCount();
2038 result.AppendError ("'command script add' requires one argument");
2039 result.SetStatus (eReturnStatusFailed);
2043 // Store the options in case we get multi-line input
2044 m_cmd_name = command.GetArgumentAtIndex(0);
2045 m_short_help.assign(m_options.m_short_help);
2046 m_synchronicity = m_options.m_synchronicity;
2048 if (m_options.m_class_name.empty())
2050 if (m_options.m_funct_name.empty())
2052 m_interpreter.GetPythonCommandsFromIOHandler(" ", // Prompt
2053 *this, // IOHandlerDelegate
2054 true, // Run IOHandler in async mode
2055 nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
2059 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
2061 m_options.m_funct_name,
2062 m_options.m_short_help,
2064 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
2066 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2070 result.AppendError("cannot add command");
2071 result.SetStatus (eReturnStatusFailed);
2077 ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
2080 result.AppendError("cannot find ScriptInterpreter");
2081 result.SetStatus(eReturnStatusFailed);
2085 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
2088 result.AppendError("cannot create helper object");
2089 result.SetStatus(eReturnStatusFailed);
2093 CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
2097 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
2099 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2103 result.AppendError("cannot add command");
2104 result.SetStatus (eReturnStatusFailed);
2108 return result.Succeeded();
2111 CommandOptions m_options;
2112 std::string m_cmd_name;
2113 std::string m_short_help;
2114 ScriptedCommandSynchronicity m_synchronicity;
2117 static OptionEnumValueElement g_script_synchro_type[] =
2119 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
2120 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
2121 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
2122 { 0, nullptr, nullptr }
2126 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2128 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
2129 { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."},
2130 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."},
2131 { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
2132 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
2135 //-------------------------------------------------------------------------
2136 // CommandObjectCommandsScriptList
2137 //-------------------------------------------------------------------------
2139 class CommandObjectCommandsScriptList : public CommandObjectParsed
2142 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
2143 CommandObjectParsed(interpreter,
2144 "command script list",
2145 "List defined scripted commands.",
2150 ~CommandObjectCommandsScriptList() override = default;
2153 DoExecute (Args& command, CommandReturnObject &result) override
2155 m_interpreter.GetHelp(result,
2156 CommandInterpreter::eCommandTypesUserDef);
2158 result.SetStatus (eReturnStatusSuccessFinishResult);
2164 //-------------------------------------------------------------------------
2165 // CommandObjectCommandsScriptClear
2166 //-------------------------------------------------------------------------
2168 class CommandObjectCommandsScriptClear : public CommandObjectParsed
2171 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
2172 CommandObjectParsed(interpreter,
2173 "command script clear",
2174 "Delete all scripted commands.",
2179 ~CommandObjectCommandsScriptClear() override = default;
2183 DoExecute (Args& command, CommandReturnObject &result) override
2185 m_interpreter.RemoveAllUser();
2187 result.SetStatus (eReturnStatusSuccessFinishResult);
2193 //-------------------------------------------------------------------------
2194 // CommandObjectCommandsScriptDelete
2195 //-------------------------------------------------------------------------
2197 class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2200 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
2201 CommandObjectParsed(interpreter,
2202 "command script delete",
2203 "Delete a scripted command.",
2206 CommandArgumentEntry arg1;
2207 CommandArgumentData cmd_arg;
2209 // Define the first (and only) variant of this arg.
2210 cmd_arg.arg_type = eArgTypeCommandName;
2211 cmd_arg.arg_repetition = eArgRepeatPlain;
2213 // There is only one variant this argument could be; put it into the argument entry.
2214 arg1.push_back (cmd_arg);
2216 // Push the data for the first argument into the m_arguments vector.
2217 m_arguments.push_back (arg1);
2220 ~CommandObjectCommandsScriptDelete() override = default;
2224 DoExecute (Args& command, CommandReturnObject &result) override
2227 size_t argc = command.GetArgumentCount();
2231 result.AppendError ("'command script delete' requires one argument");
2232 result.SetStatus (eReturnStatusFailed);
2236 const char* cmd_name = command.GetArgumentAtIndex(0);
2238 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2240 m_interpreter.RemoveUser(cmd_name);
2241 result.SetStatus (eReturnStatusSuccessFinishResult);
2245 result.AppendErrorWithFormat ("command %s not found", cmd_name);
2246 result.SetStatus (eReturnStatusFailed);
2249 return result.Succeeded();
2253 #pragma mark CommandObjectMultiwordCommandsScript
2255 //-------------------------------------------------------------------------
2256 // CommandObjectMultiwordCommandsScript
2257 //-------------------------------------------------------------------------
2259 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2262 CommandObjectMultiwordCommandsScript(CommandInterpreter &interpreter)
2263 : CommandObjectMultiword(interpreter, "command script",
2264 "Commands for managing custom commands implemented by interpreter scripts.",
2265 "command script <subcommand> [<subcommand-options>]")
2267 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2268 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2269 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2270 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2271 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2274 ~CommandObjectMultiwordCommandsScript() override = default;
2277 #pragma mark CommandObjectMultiwordCommands
2279 //-------------------------------------------------------------------------
2280 // CommandObjectMultiwordCommands
2281 //-------------------------------------------------------------------------
2283 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(CommandInterpreter &interpreter)
2284 : CommandObjectMultiword(interpreter, "command", "Commands for managing custom LLDB commands.",
2285 "command <subcommand> [<subcommand-options>]")
2287 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2288 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2289 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2290 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2291 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2292 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2293 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2296 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default;