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 //===----------------------------------------------------------------------===//
10 #include "CommandObjectCommands.h"
14 // Other libraries and framework includes
15 #include "llvm/ADT/StringRef.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/OptionValueUInt64.h"
28 #include "lldb/Interpreter/Options.h"
29 #include "lldb/Interpreter/ScriptInterpreter.h"
32 using namespace lldb_private;
34 //-------------------------------------------------------------------------
35 // CommandObjectCommandsSource
36 //-------------------------------------------------------------------------
38 class CommandObjectCommandsHistory : public CommandObjectParsed
41 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
42 CommandObjectParsed (interpreter,
44 "Dump the history of commands in this session.",
46 m_options (interpreter)
50 ~CommandObjectCommandsHistory () {}
60 class CommandOptions : public Options
64 CommandOptions (CommandInterpreter &interpreter) :
65 Options (interpreter),
77 SetOptionValue (uint32_t option_idx, const char *option_arg)
80 const int short_option = m_getopt_table[option_idx].val;
85 error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
88 if (option_arg && strcmp("end", option_arg) == 0)
90 m_start_idx.SetCurrentValue(UINT64_MAX);
91 m_start_idx.SetOptionWasSet();
94 error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
97 error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
100 m_clear.SetCurrentValue(true);
101 m_clear.SetOptionWasSet();
104 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
112 OptionParsingStarting ()
120 const OptionDefinition*
123 return g_option_table;
126 // Options table: Required for subclasses of Options.
128 static OptionDefinition g_option_table[];
130 // Instance variables to hold the values for command options.
132 OptionValueUInt64 m_start_idx;
133 OptionValueUInt64 m_stop_idx;
134 OptionValueUInt64 m_count;
135 OptionValueBoolean m_clear;
139 DoExecute (Args& command, CommandReturnObject &result)
141 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
143 m_interpreter.GetCommandHistory().Clear();
144 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
148 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
150 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
151 result.SetStatus(lldb::eReturnStatusFailed);
155 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
156 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
157 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
159 const CommandHistory& history(m_interpreter.GetCommandHistory());
161 if (start_idx.first && start_idx.second == UINT64_MAX)
165 start_idx.second = history.GetSize() - count.second;
166 stop_idx.second = history.GetSize() - 1;
168 else if (stop_idx.first)
170 start_idx.second = stop_idx.second;
171 stop_idx.second = history.GetSize() - 1;
175 start_idx.second = 0;
176 stop_idx.second = history.GetSize() - 1;
181 if (!start_idx.first && !stop_idx.first && !count.first)
183 start_idx.second = 0;
184 stop_idx.second = history.GetSize() - 1;
186 else if (start_idx.first)
190 stop_idx.second = start_idx.second + count.second - 1;
192 else if (!stop_idx.first)
194 stop_idx.second = history.GetSize() - 1;
197 else if (stop_idx.first)
201 if (stop_idx.second >= count.second)
202 start_idx.second = stop_idx.second - count.second + 1;
204 start_idx.second = 0;
207 else /* if (count.first) */
209 start_idx.second = 0;
210 stop_idx.second = count.second - 1;
213 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
216 return result.Succeeded();
220 CommandOptions m_options;
224 CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
226 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
227 { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
228 { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
229 { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean, "Clears the current command history."},
230 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
234 //-------------------------------------------------------------------------
235 // CommandObjectCommandsSource
236 //-------------------------------------------------------------------------
238 class CommandObjectCommandsSource : public CommandObjectParsed
241 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
242 CommandObjectParsed (interpreter,
244 "Read in debugger commands from the file <filename> and execute them.",
246 m_options (interpreter)
248 CommandArgumentEntry arg;
249 CommandArgumentData file_arg;
251 // Define the first (and only) variant of this arg.
252 file_arg.arg_type = eArgTypeFilename;
253 file_arg.arg_repetition = eArgRepeatPlain;
255 // There is only one variant this argument could be; put it into the argument entry.
256 arg.push_back (file_arg);
258 // Push the data for the first argument into the m_arguments vector.
259 m_arguments.push_back (arg);
262 ~CommandObjectCommandsSource () {}
265 GetRepeatCommand (Args ¤t_command_args, uint32_t index)
271 HandleArgumentCompletion (Args &input,
273 int &cursor_char_position,
274 OptionElementVector &opt_element_vector,
275 int match_start_point,
276 int max_return_elements,
280 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
281 completion_str.erase (cursor_char_position);
283 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
284 CommandCompletions::eDiskFileCompletion,
285 completion_str.c_str(),
291 return matches.GetSize();
302 class CommandOptions : public Options
306 CommandOptions (CommandInterpreter &interpreter) :
307 Options (interpreter),
308 m_stop_on_error (true),
309 m_silent_run (false),
310 m_stop_on_continue (true)
318 SetOptionValue (uint32_t option_idx, const char *option_arg)
321 const int short_option = m_getopt_table[option_idx].val;
323 switch (short_option)
326 error = m_stop_on_error.SetValueFromString(option_arg);
330 error = m_stop_on_continue.SetValueFromString(option_arg);
334 error = m_silent_run.SetValueFromString(option_arg);
338 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
346 OptionParsingStarting ()
348 m_stop_on_error.Clear();
349 m_silent_run.Clear();
350 m_stop_on_continue.Clear();
353 const OptionDefinition*
356 return g_option_table;
359 // Options table: Required for subclasses of Options.
361 static OptionDefinition g_option_table[];
363 // Instance variables to hold the values for command options.
365 OptionValueBoolean m_stop_on_error;
366 OptionValueBoolean m_silent_run;
367 OptionValueBoolean m_stop_on_continue;
371 DoExecute(Args& command, CommandReturnObject &result)
373 const size_t argc = command.GetArgumentCount();
376 const char *filename = command.GetArgumentAtIndex(0);
378 FileSpec cmd_file (filename, true);
379 ExecutionContext *exe_ctx = NULL; // Just use the default context.
381 // If any options were set, then use them
382 if (m_options.m_stop_on_error.OptionWasSet() ||
383 m_options.m_silent_run.OptionWasSet() ||
384 m_options.m_stop_on_continue.OptionWasSet())
386 // Use user set settings
387 CommandInterpreterRunOptions options;
388 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
389 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
390 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
391 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
393 m_interpreter.HandleCommandsFromFile (cmd_file,
401 // No options were set, inherit any settings from nested "command source" commands,
402 // or set to sane default settings...
403 CommandInterpreterRunOptions options;
404 m_interpreter.HandleCommandsFromFile (cmd_file,
413 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
414 result.SetStatus (eReturnStatusFailed);
416 return result.Succeeded();
419 CommandOptions m_options;
423 CommandObjectCommandsSource::CommandOptions::g_option_table[] =
425 { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
426 { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
427 { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
428 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
431 #pragma mark CommandObjectCommandsAlias
432 //-------------------------------------------------------------------------
433 // CommandObjectCommandsAlias
434 //-------------------------------------------------------------------------
436 static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
437 "You must define a Python function with this signature:\n"
438 "def my_command_impl(debugger, args, result, internal_dict):\n";
441 class CommandObjectCommandsAlias : public CommandObjectRaw
446 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
447 CommandObjectRaw (interpreter,
449 "Allow users to define their own debugger command abbreviations.",
453 "'alias' allows the user to create a short-cut or abbreviation for long \
454 commands, multi-word commands, and commands that take particular options. \
455 Below are some simple examples of how one might use the 'alias' command:" R"(
457 (lldb) command alias sc script
459 Creates the abbreviation 'sc' for the 'script' command.
461 (lldb) command alias bp breakpoint
463 )" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
464 breakpoint commands are two-word commands, the user would still need to \
465 enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
467 (lldb) command alias bpl breakpoint list
469 Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
471 )" "An alias can include some options for the command, with the values either \
472 filled in at the time the alias is created, or specified as positional \
473 arguments, to be filled in when the alias is invoked. The following example \
474 shows how to create aliases with options:" R"(
476 (lldb) command alias bfl breakpoint set -f %1 -l %2
478 )" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
479 options already part of the alias. So if the user wants to set a breakpoint \
480 by file and line without explicitly having to use the -f and -l options, the \
481 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \
482 for the actual arguments that will be passed when the alias command is used. \
483 The number in the placeholder refers to the position/order the actual value \
484 occupies when the alias is used. All the occurrences of '%1' in the alias \
485 will be replaced with the first argument, all the occurrences of '%2' in the \
486 alias will be replaced with the second argument, and so on. This also allows \
487 actual arguments to be used multiple times within an alias (see 'process \
488 launch' example below)." R"(
490 )" "Note: the positional arguments must substitute as whole words in the resultant \
491 command, so you can't at present do something like this to append the file extension \
494 (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
496 )" "For more complex aliasing, use the \"command regex\" command instead. In the \
497 'bfl' case above, the actual file value will be filled in with the first argument \
498 following 'bfl' and the actual line number value will be filled in with the second \
499 argument. The user would use this alias as follows:" R"(
501 (lldb) command alias bfl breakpoint set -f %1 -l %2
502 (lldb) bfl my-file.c 137
504 This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
508 (lldb) command alias pltty process launch -s -o %1 -e %1
509 (lldb) pltty /dev/tty0
511 Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
513 )" "If the user always wanted to pass the same value to a particular option, the \
514 alias could be defined with that value directly in the alias as a constant, \
515 rather than using a positional placeholder:" R"(
517 (lldb) command alias bl3 breakpoint set -f %1 -l 3
519 Always sets a breakpoint on line 3 of whatever file is indicated.)"
522 CommandArgumentEntry arg1;
523 CommandArgumentEntry arg2;
524 CommandArgumentEntry arg3;
525 CommandArgumentData alias_arg;
526 CommandArgumentData cmd_arg;
527 CommandArgumentData options_arg;
529 // Define the first (and only) variant of this arg.
530 alias_arg.arg_type = eArgTypeAliasName;
531 alias_arg.arg_repetition = eArgRepeatPlain;
533 // There is only one variant this argument could be; put it into the argument entry.
534 arg1.push_back (alias_arg);
536 // Define the first (and only) variant of this arg.
537 cmd_arg.arg_type = eArgTypeCommandName;
538 cmd_arg.arg_repetition = eArgRepeatPlain;
540 // There is only one variant this argument could be; put it into the argument entry.
541 arg2.push_back (cmd_arg);
543 // Define the first (and only) variant of this arg.
544 options_arg.arg_type = eArgTypeAliasOptions;
545 options_arg.arg_repetition = eArgRepeatOptional;
547 // There is only one variant this argument could be; put it into the argument entry.
548 arg3.push_back (options_arg);
550 // Push the data for the first argument into the m_arguments vector.
551 m_arguments.push_back (arg1);
552 m_arguments.push_back (arg2);
553 m_arguments.push_back (arg3);
556 ~CommandObjectCommandsAlias ()
562 DoExecute (const char *raw_command_line, CommandReturnObject &result)
564 Args args (raw_command_line);
565 std::string raw_command_string (raw_command_line);
567 size_t argc = args.GetArgumentCount();
571 result.AppendError ("'alias' requires at least two arguments");
572 result.SetStatus (eReturnStatusFailed);
576 // Get the alias command.
578 const std::string alias_command = args.GetArgumentAtIndex (0);
580 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
581 // does the stripping itself.
582 size_t pos = raw_command_string.find (alias_command);
585 raw_command_string = raw_command_string.substr (alias_command.size());
586 pos = raw_command_string.find_first_not_of (' ');
587 if ((pos != std::string::npos) && (pos > 0))
588 raw_command_string = raw_command_string.substr (pos);
592 result.AppendError ("Error parsing command string. No alias created.");
593 result.SetStatus (eReturnStatusFailed);
598 // Verify that the command is alias-able.
599 if (m_interpreter.CommandExists (alias_command.c_str()))
601 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
602 alias_command.c_str());
603 result.SetStatus (eReturnStatusFailed);
607 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
608 // raw_command_string is returned with the name of the command object stripped off the front.
609 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
613 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
614 " No alias created.", raw_command_string.c_str());
615 result.SetStatus (eReturnStatusFailed);
618 else if (!cmd_obj->WantsRawCommandString ())
620 // Note that args was initialized with the original command, and has not been updated to this point.
621 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
622 return HandleAliasingNormalCommand (args, result);
626 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
628 return result.Succeeded();
632 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
634 // Verify & handle any options/arguments passed to the alias command
636 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
637 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
639 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
641 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
643 result.AppendError ("Unable to create requested alias.\n");
644 result.SetStatus (eReturnStatusFailed);
649 if (m_interpreter.AliasExists (alias_command.c_str())
650 || m_interpreter.UserCommandExists (alias_command.c_str()))
652 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
653 if (temp_option_arg_sp.get())
655 if (option_arg_vector->size() == 0)
656 m_interpreter.RemoveAliasOptions (alias_command.c_str());
658 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
659 alias_command.c_str());
664 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
665 if (option_arg_vector->size() > 0)
666 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
667 result.SetStatus (eReturnStatusSuccessFinishNoResult);
671 result.AppendError ("Unable to create requested alias.\n");
672 result.SetStatus (eReturnStatusFailed);
674 return result.Succeeded ();
678 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
680 size_t argc = args.GetArgumentCount();
684 result.AppendError ("'alias' requires at least two arguments");
685 result.SetStatus (eReturnStatusFailed);
689 const std::string alias_command = args.GetArgumentAtIndex(0);
690 const std::string actual_command = args.GetArgumentAtIndex(1);
692 args.Shift(); // Shift the alias command word off the argument vector.
693 args.Shift(); // Shift the old command word off the argument vector.
695 // Verify that the command is alias'able, and get the appropriate command object.
697 if (m_interpreter.CommandExists (alias_command.c_str()))
699 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
700 alias_command.c_str());
701 result.SetStatus (eReturnStatusFailed);
705 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
706 CommandObjectSP subcommand_obj_sp;
707 bool use_subcommand = false;
708 if (command_obj_sp.get())
710 CommandObject *cmd_obj = command_obj_sp.get();
711 CommandObject *sub_cmd_obj = NULL;
712 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
713 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
715 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
719 const std::string sub_command = args.GetArgumentAtIndex(0);
720 assert (sub_command.length() != 0);
721 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
722 if (subcommand_obj_sp.get())
724 sub_cmd_obj = subcommand_obj_sp.get();
725 use_subcommand = true;
726 args.Shift(); // Shift the sub_command word off the argument vector.
727 cmd_obj = sub_cmd_obj;
731 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
732 "Unable to create alias.\n",
733 sub_command.c_str(), actual_command.c_str());
734 result.SetStatus (eReturnStatusFailed);
740 // Verify & handle any options/arguments passed to the alias command
742 if (args.GetArgumentCount () > 0)
744 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
746 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
748 std::string args_string;
749 args.GetCommandString (args_string);
751 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
753 result.AppendError ("Unable to create requested alias.\n");
754 result.SetStatus (eReturnStatusFailed);
761 if (m_interpreter.AliasExists (alias_command.c_str())
762 || m_interpreter.UserCommandExists (alias_command.c_str()))
764 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
765 if (tmp_option_arg_sp.get())
767 if (option_arg_vector->size() == 0)
768 m_interpreter.RemoveAliasOptions (alias_command.c_str());
770 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
771 alias_command.c_str());
775 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
777 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
778 if (option_arg_vector->size() > 0)
779 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
780 result.SetStatus (eReturnStatusSuccessFinishNoResult);
784 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
785 result.SetStatus (eReturnStatusFailed);
790 return result.Succeeded();
795 #pragma mark CommandObjectCommandsUnalias
796 //-------------------------------------------------------------------------
797 // CommandObjectCommandsUnalias
798 //-------------------------------------------------------------------------
800 class CommandObjectCommandsUnalias : public CommandObjectParsed
803 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
804 CommandObjectParsed (interpreter,
806 "Allow the user to remove/delete a user-defined command abbreviation.",
809 CommandArgumentEntry arg;
810 CommandArgumentData alias_arg;
812 // Define the first (and only) variant of this arg.
813 alias_arg.arg_type = eArgTypeAliasName;
814 alias_arg.arg_repetition = eArgRepeatPlain;
816 // There is only one variant this argument could be; put it into the argument entry.
817 arg.push_back (alias_arg);
819 // Push the data for the first argument into the m_arguments vector.
820 m_arguments.push_back (arg);
823 ~CommandObjectCommandsUnalias()
829 DoExecute (Args& args, CommandReturnObject &result)
831 CommandObject::CommandMap::iterator pos;
832 CommandObject *cmd_obj;
834 if (args.GetArgumentCount() != 0)
836 const char *command_name = args.GetArgumentAtIndex(0);
837 cmd_obj = m_interpreter.GetCommandObject(command_name);
840 if (m_interpreter.CommandExists (command_name))
842 if (cmd_obj->IsRemovable())
844 result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
849 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
852 result.SetStatus (eReturnStatusFailed);
857 if (m_interpreter.RemoveAlias (command_name) == false)
859 if (m_interpreter.AliasExists (command_name))
860 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
863 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
864 result.SetStatus (eReturnStatusFailed);
867 result.SetStatus (eReturnStatusSuccessFinishNoResult);
872 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
873 "current list of commands.\n",
875 result.SetStatus (eReturnStatusFailed);
880 result.AppendError ("must call 'unalias' with a valid alias");
881 result.SetStatus (eReturnStatusFailed);
884 return result.Succeeded();
888 #pragma mark CommandObjectCommandsDelete
889 //-------------------------------------------------------------------------
890 // CommandObjectCommandsDelete
891 //-------------------------------------------------------------------------
893 class CommandObjectCommandsDelete : public CommandObjectParsed
896 CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
897 CommandObjectParsed (interpreter,
899 "Allow the user to delete user-defined regular expression, python or multi-word commands.",
902 CommandArgumentEntry arg;
903 CommandArgumentData alias_arg;
905 // Define the first (and only) variant of this arg.
906 alias_arg.arg_type = eArgTypeCommandName;
907 alias_arg.arg_repetition = eArgRepeatPlain;
909 // There is only one variant this argument could be; put it into the argument entry.
910 arg.push_back (alias_arg);
912 // Push the data for the first argument into the m_arguments vector.
913 m_arguments.push_back (arg);
916 ~CommandObjectCommandsDelete()
922 DoExecute (Args& args, CommandReturnObject &result)
924 CommandObject::CommandMap::iterator pos;
926 if (args.GetArgumentCount() != 0)
928 const char *command_name = args.GetArgumentAtIndex(0);
929 if (m_interpreter.CommandExists (command_name))
931 if (m_interpreter.RemoveCommand (command_name))
933 result.SetStatus (eReturnStatusSuccessFinishNoResult);
937 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
939 result.SetStatus (eReturnStatusFailed);
944 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
946 result.SetStatus (eReturnStatusFailed);
951 result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
952 result.SetStatus (eReturnStatusFailed);
955 return result.Succeeded();
959 //-------------------------------------------------------------------------
960 // CommandObjectCommandsAddRegex
961 //-------------------------------------------------------------------------
962 #pragma mark CommandObjectCommandsAddRegex
964 class CommandObjectCommandsAddRegex :
965 public CommandObjectParsed,
966 public IOHandlerDelegateMultiline
969 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
970 CommandObjectParsed (interpreter,
972 "Allow the user to create a regular expression command.",
973 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
974 IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
975 m_options (interpreter)
978 )" "This command allows the user to create powerful regular expression commands \
979 with substitutions. The regular expressions and substitutions are specified \
980 using the regular expression substitution format of:" R"(
984 )" "<regex> is a regular expression that can use parenthesis to capture regular \
985 expression input and substitute the captured matches in the output using %1 \
986 for the first match, %2 for the second, and so on." R"(
988 )" "The regular expressions can all be specified on the command line if more than \
989 one argument is provided. If just the command name is provided on the command \
990 line, then the regular expressions and substitutions can be entered on separate \
991 lines, followed by an empty line to terminate the command definition." R"(
995 )" "The following example will define a regular expression command named 'f' that \
996 will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
997 a number follows 'f':" R"(
999 (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
1003 ~CommandObjectCommandsAddRegex()
1011 IOHandlerActivated (IOHandler &io_handler) override
1013 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1016 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");
1022 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
1024 io_handler.SetIsDone(true);
1025 if (m_regex_cmd_ap.get())
1028 if (lines.SplitIntoLines (data))
1030 const size_t num_lines = lines.GetSize();
1031 bool check_only = false;
1032 for (size_t i=0; i<num_lines; ++i)
1034 llvm::StringRef bytes_strref (lines[i]);
1035 Error error = AppendRegexSubstitution (bytes_strref, check_only);
1038 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
1040 StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
1041 out_stream->Printf("error: %s\n", error.AsCString());
1046 if (m_regex_cmd_ap->HasRegexEntries())
1048 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1049 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1055 DoExecute (Args& command, CommandReturnObject &result) override
1057 const size_t argc = command.GetArgumentCount();
1060 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
1061 result.SetStatus (eReturnStatusFailed);
1066 const char *name = command.GetArgumentAtIndex(0);
1067 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1069 m_options.GetHelp (),
1070 m_options.GetSyntax (),
1077 Debugger &debugger = m_interpreter.GetDebugger();
1078 bool color_prompt = debugger.GetUseColor();
1079 const bool multiple_lines = true; // Get multiple lines
1080 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
1081 IOHandler::Type::Other,
1082 "lldb-regex", // Name of input reader for history
1084 NULL, // Continuation prompt
1087 0, // Don't show line numbers
1092 debugger.PushIOHandler(io_handler_sp);
1093 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1098 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
1100 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
1101 bool check_only = false;
1102 error = AppendRegexSubstitution (arg_strref, check_only);
1107 if (error.Success())
1109 AddRegexCommandToInterpreter();
1114 result.AppendError (error.AsCString());
1115 result.SetStatus (eReturnStatusFailed);
1119 return result.Succeeded();
1123 AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only)
1127 if (m_regex_cmd_ap.get() == NULL)
1129 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
1130 (int)regex_sed.size(),
1135 size_t regex_sed_size = regex_sed.size();
1137 if (regex_sed_size <= 1)
1139 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
1140 (int)regex_sed.size(),
1145 if (regex_sed[0] != 's')
1147 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
1148 (int)regex_sed.size(),
1152 const size_t first_separator_char_pos = 1;
1153 // use the char that follows 's' as the regex separator character
1154 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1155 const char separator_char = regex_sed[first_separator_char_pos];
1156 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1158 if (second_separator_char_pos == std::string::npos)
1160 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
1162 (int)(regex_sed.size() - first_separator_char_pos - 1),
1163 regex_sed.data() + (first_separator_char_pos + 1),
1164 (int)regex_sed.size(),
1169 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1171 if (third_separator_char_pos == std::string::npos)
1173 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
1175 (int)(regex_sed.size() - second_separator_char_pos - 1),
1176 regex_sed.data() + (second_separator_char_pos + 1),
1177 (int)regex_sed.size(),
1182 if (third_separator_char_pos != regex_sed_size - 1)
1184 // Make sure that everything that follows the last regex
1186 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1188 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1189 (int)third_separator_char_pos + 1,
1191 (int)(regex_sed.size() - third_separator_char_pos - 1),
1192 regex_sed.data() + (third_separator_char_pos + 1));
1197 else if (first_separator_char_pos + 1 == second_separator_char_pos)
1199 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1203 (int)regex_sed.size(),
1207 else if (second_separator_char_pos + 1 == third_separator_char_pos)
1209 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1213 (int)regex_sed.size(),
1218 if (check_only == false)
1220 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1221 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1222 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1229 AddRegexCommandToInterpreter()
1231 if (m_regex_cmd_ap.get())
1233 if (m_regex_cmd_ap->HasRegexEntries())
1235 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1236 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1242 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1244 class CommandOptions : public Options
1248 CommandOptions (CommandInterpreter &interpreter) :
1249 Options (interpreter)
1254 ~CommandOptions (){}
1257 SetOptionValue (uint32_t option_idx, const char *option_arg)
1260 const int short_option = m_getopt_table[option_idx].val;
1262 switch (short_option)
1265 m_help.assign (option_arg);
1268 m_syntax.assign (option_arg);
1272 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1280 OptionParsingStarting ()
1286 const OptionDefinition*
1289 return g_option_table;
1292 // Options table: Required for subclasses of Options.
1294 static OptionDefinition g_option_table[];
1301 return m_help.c_str();
1306 if (m_syntax.empty())
1308 return m_syntax.c_str();
1310 // Instance variables to hold the values for command options.
1313 std::string m_syntax;
1317 GetOptions () override
1322 CommandOptions m_options;
1326 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1328 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1329 { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1330 { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL }
1334 class CommandObjectPythonFunction : public CommandObjectRaw
1337 std::string m_function_name;
1338 ScriptedCommandSynchronicity m_synchro;
1339 bool m_fetched_help_long;
1343 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1347 ScriptedCommandSynchronicity synch) :
1348 CommandObjectRaw (interpreter,
1352 m_function_name(funct),
1354 m_fetched_help_long(false)
1357 SetHelp(help.c_str());
1360 StreamString stream;
1361 stream.Printf("For more information run 'help %s'",name.c_str());
1362 SetHelp(stream.GetData());
1367 ~CommandObjectPythonFunction ()
1372 IsRemovable () const
1380 return m_function_name;
1383 ScriptedCommandSynchronicity
1389 virtual const char *
1392 if (!m_fetched_help_long)
1394 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1397 std::string docstring;
1398 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1399 if (!docstring.empty())
1400 SetHelpLong(docstring);
1403 return CommandObjectRaw::GetHelpLong();
1408 DoExecute (const char *raw_command_line, CommandReturnObject &result)
1410 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1414 result.SetStatus(eReturnStatusInvalid);
1416 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1421 m_exe_ctx) == false)
1423 result.AppendError(error.AsCString());
1424 result.SetStatus(eReturnStatusFailed);
1428 // Don't change the status if the command already set it...
1429 if (result.GetStatus() == eReturnStatusInvalid)
1431 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1432 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1434 result.SetStatus(eReturnStatusSuccessFinishResult);
1438 return result.Succeeded();
1443 class CommandObjectScriptingObject : public CommandObjectRaw
1446 StructuredData::GenericSP m_cmd_obj_sp;
1447 ScriptedCommandSynchronicity m_synchro;
1448 bool m_fetched_help_short:1;
1449 bool m_fetched_help_long:1;
1453 CommandObjectScriptingObject (CommandInterpreter &interpreter,
1455 StructuredData::GenericSP cmd_obj_sp,
1456 ScriptedCommandSynchronicity synch) :
1457 CommandObjectRaw (interpreter,
1461 m_cmd_obj_sp(cmd_obj_sp),
1463 m_fetched_help_short(false),
1464 m_fetched_help_long(false)
1466 StreamString stream;
1467 stream.Printf("For more information run 'help %s'",name.c_str());
1468 SetHelp(stream.GetData());
1469 if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1470 GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
1474 ~CommandObjectScriptingObject ()
1479 IsRemovable () const
1484 StructuredData::GenericSP
1485 GetImplementingObject ()
1487 return m_cmd_obj_sp;
1490 ScriptedCommandSynchronicity
1496 virtual const char *
1499 if (!m_fetched_help_short)
1501 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1504 std::string docstring;
1505 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
1506 if (!docstring.empty())
1510 return CommandObjectRaw::GetHelp();
1513 virtual const char *
1516 if (!m_fetched_help_long)
1518 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1521 std::string docstring;
1522 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
1523 if (!docstring.empty())
1524 SetHelpLong(docstring);
1527 return CommandObjectRaw::GetHelpLong();
1532 DoExecute (const char *raw_command_line, CommandReturnObject &result)
1534 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1538 result.SetStatus(eReturnStatusInvalid);
1540 if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
1545 m_exe_ctx) == false)
1547 result.AppendError(error.AsCString());
1548 result.SetStatus(eReturnStatusFailed);
1552 // Don't change the status if the command already set it...
1553 if (result.GetStatus() == eReturnStatusInvalid)
1555 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1556 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1558 result.SetStatus(eReturnStatusSuccessFinishResult);
1562 return result.Succeeded();
1567 //-------------------------------------------------------------------------
1568 // CommandObjectCommandsScriptImport
1569 //-------------------------------------------------------------------------
1571 class CommandObjectCommandsScriptImport : public CommandObjectParsed
1574 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1575 CommandObjectParsed (interpreter,
1576 "command script import",
1577 "Import a scripting module in LLDB.",
1579 m_options(interpreter)
1581 CommandArgumentEntry arg1;
1582 CommandArgumentData cmd_arg;
1584 // Define the first (and only) variant of this arg.
1585 cmd_arg.arg_type = eArgTypeFilename;
1586 cmd_arg.arg_repetition = eArgRepeatPlus;
1588 // There is only one variant this argument could be; put it into the argument entry.
1589 arg1.push_back (cmd_arg);
1591 // Push the data for the first argument into the m_arguments vector.
1592 m_arguments.push_back (arg1);
1595 ~CommandObjectCommandsScriptImport ()
1600 HandleArgumentCompletion (Args &input,
1602 int &cursor_char_position,
1603 OptionElementVector &opt_element_vector,
1604 int match_start_point,
1605 int max_return_elements,
1606 bool &word_complete,
1607 StringList &matches)
1609 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1610 completion_str.erase (cursor_char_position);
1612 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1613 CommandCompletions::eDiskFileCompletion,
1614 completion_str.c_str(),
1616 max_return_elements,
1620 return matches.GetSize();
1631 class CommandOptions : public Options
1635 CommandOptions (CommandInterpreter &interpreter) :
1636 Options (interpreter)
1641 ~CommandOptions (){}
1644 SetOptionValue (uint32_t option_idx, const char *option_arg)
1647 const int short_option = m_getopt_table[option_idx].val;
1649 switch (short_option)
1652 m_allow_reload = true;
1655 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1663 OptionParsingStarting ()
1665 m_allow_reload = true;
1668 const OptionDefinition*
1671 return g_option_table;
1674 // Options table: Required for subclasses of Options.
1676 static OptionDefinition g_option_table[];
1678 // Instance variables to hold the values for command options.
1680 bool m_allow_reload;
1684 DoExecute (Args& command, CommandReturnObject &result)
1686 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1688 result.AppendError ("only scripting language supported for module importing is currently Python");
1689 result.SetStatus (eReturnStatusFailed);
1693 size_t argc = command.GetArgumentCount();
1696 result.AppendError("command script import needs one or more arguments");
1697 result.SetStatus (eReturnStatusFailed);
1705 std::string path = command.GetArgumentAtIndex(i);
1708 const bool init_session = true;
1709 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1710 // commands won't ever be recursively invoked, but it's actually possible to craft
1711 // a Python script that does other "command script imports" in __lldb_init_module
1712 // the real fix is to have recursive commands possible with a CommandInvocation object
1713 // separate from the CommandObject itself, so that recursive command invocations
1714 // won't stomp on each other (wrt to execution contents, options, and more)
1716 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
1717 m_options.m_allow_reload,
1721 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1725 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1726 result.SetStatus (eReturnStatusFailed);
1730 return result.Succeeded();
1733 CommandOptions m_options;
1737 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1739 { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, NULL, 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."},
1740 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1744 //-------------------------------------------------------------------------
1745 // CommandObjectCommandsScriptAdd
1746 //-------------------------------------------------------------------------
1748 class CommandObjectCommandsScriptAdd :
1749 public CommandObjectParsed,
1750 public IOHandlerDelegateMultiline
1753 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1754 CommandObjectParsed (interpreter,
1755 "command script add",
1756 "Add a scripted function as an LLDB command.",
1758 IOHandlerDelegateMultiline ("DONE"),
1759 m_options (interpreter)
1761 CommandArgumentEntry arg1;
1762 CommandArgumentData cmd_arg;
1764 // Define the first (and only) variant of this arg.
1765 cmd_arg.arg_type = eArgTypeCommandName;
1766 cmd_arg.arg_repetition = eArgRepeatPlain;
1768 // There is only one variant this argument could be; put it into the argument entry.
1769 arg1.push_back (cmd_arg);
1771 // Push the data for the first argument into the m_arguments vector.
1772 m_arguments.push_back (arg1);
1775 ~CommandObjectCommandsScriptAdd ()
1787 class CommandOptions : public Options
1791 CommandOptions (CommandInterpreter &interpreter) :
1792 Options (interpreter),
1796 m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1801 ~CommandOptions (){}
1804 SetOptionValue (uint32_t option_idx, const char *option_arg)
1807 const int short_option = m_getopt_table[option_idx].val;
1809 switch (short_option)
1813 m_funct_name.assign(option_arg);
1817 m_class_name.assign(option_arg);
1821 m_short_help.assign(option_arg);
1824 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1825 if (!error.Success())
1826 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1829 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1837 OptionParsingStarting ()
1839 m_class_name.clear();
1840 m_funct_name.clear();
1841 m_short_help.clear();
1842 m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1845 const OptionDefinition*
1848 return g_option_table;
1851 // Options table: Required for subclasses of Options.
1853 static OptionDefinition g_option_table[];
1855 // Instance variables to hold the values for command options.
1857 std::string m_class_name;
1858 std::string m_funct_name;
1859 std::string m_short_help;
1860 ScriptedCommandSynchronicity m_synchronicity;
1864 IOHandlerActivated (IOHandler &io_handler)
1866 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1869 output_sp->PutCString(g_python_command_instructions);
1876 IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1878 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1880 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1885 lines.SplitIntoLines(data);
1886 if (lines.GetSize() > 0)
1888 std::string funct_name_str;
1889 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1891 if (funct_name_str.empty())
1893 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1898 // everything should be fine now, let's add this alias
1900 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1902 funct_name_str.c_str(),
1906 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1908 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
1915 error_sp->Printf ("error: unable to create function, didn't add python command.\n");
1921 error_sp->Printf ("error: empty function, didn't add python command.\n");
1927 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
1931 io_handler.SetIsDone(true);
1938 DoExecute (Args& command, CommandReturnObject &result)
1941 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1943 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1944 result.SetStatus (eReturnStatusFailed);
1948 size_t argc = command.GetArgumentCount();
1952 result.AppendError ("'command script add' requires one argument");
1953 result.SetStatus (eReturnStatusFailed);
1957 // Store the options in case we get multi-line input
1958 m_cmd_name = command.GetArgumentAtIndex(0);
1959 m_short_help.assign(m_options.m_short_help);
1960 m_synchronicity = m_options.m_synchronicity;
1962 if (m_options.m_class_name.empty())
1964 if (m_options.m_funct_name.empty())
1966 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
1967 *this, // IOHandlerDelegate
1968 true, // Run IOHandler in async mode
1969 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1973 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1975 m_options.m_funct_name,
1976 m_options.m_short_help,
1978 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
1980 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1984 result.AppendError("cannot add command");
1985 result.SetStatus (eReturnStatusFailed);
1991 ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
1994 result.AppendError("cannot find ScriptInterpreter");
1995 result.SetStatus(eReturnStatusFailed);
1999 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
2002 result.AppendError("cannot create helper object");
2003 result.SetStatus(eReturnStatusFailed);
2007 CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
2011 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
2013 result.SetStatus (eReturnStatusSuccessFinishNoResult);
2017 result.AppendError("cannot add command");
2018 result.SetStatus (eReturnStatusFailed);
2022 return result.Succeeded();
2026 CommandOptions m_options;
2027 std::string m_cmd_name;
2028 std::string m_short_help;
2029 ScriptedCommandSynchronicity m_synchronicity;
2032 static OptionEnumValueElement g_script_synchro_type[] =
2034 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
2035 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
2036 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
2041 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2043 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
2044 { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."},
2045 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
2046 { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
2047 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2050 //-------------------------------------------------------------------------
2051 // CommandObjectCommandsScriptList
2052 //-------------------------------------------------------------------------
2054 class CommandObjectCommandsScriptList : public CommandObjectParsed
2059 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
2060 CommandObjectParsed (interpreter,
2061 "command script list",
2062 "List defined scripted commands.",
2067 ~CommandObjectCommandsScriptList ()
2072 DoExecute (Args& command, CommandReturnObject &result)
2075 m_interpreter.GetHelp(result,
2076 CommandInterpreter::eCommandTypesUserDef);
2078 result.SetStatus (eReturnStatusSuccessFinishResult);
2086 //-------------------------------------------------------------------------
2087 // CommandObjectCommandsScriptClear
2088 //-------------------------------------------------------------------------
2090 class CommandObjectCommandsScriptClear : public CommandObjectParsed
2095 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
2096 CommandObjectParsed (interpreter,
2097 "command script clear",
2098 "Delete all scripted commands.",
2103 ~CommandObjectCommandsScriptClear ()
2109 DoExecute (Args& command, CommandReturnObject &result)
2112 m_interpreter.RemoveAllUser();
2114 result.SetStatus (eReturnStatusSuccessFinishResult);
2120 //-------------------------------------------------------------------------
2121 // CommandObjectCommandsScriptDelete
2122 //-------------------------------------------------------------------------
2124 class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2127 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
2128 CommandObjectParsed (interpreter,
2129 "command script delete",
2130 "Delete a scripted command.",
2133 CommandArgumentEntry arg1;
2134 CommandArgumentData cmd_arg;
2136 // Define the first (and only) variant of this arg.
2137 cmd_arg.arg_type = eArgTypeCommandName;
2138 cmd_arg.arg_repetition = eArgRepeatPlain;
2140 // There is only one variant this argument could be; put it into the argument entry.
2141 arg1.push_back (cmd_arg);
2143 // Push the data for the first argument into the m_arguments vector.
2144 m_arguments.push_back (arg1);
2147 ~CommandObjectCommandsScriptDelete ()
2153 DoExecute (Args& command, CommandReturnObject &result)
2156 size_t argc = command.GetArgumentCount();
2160 result.AppendError ("'command script delete' requires one argument");
2161 result.SetStatus (eReturnStatusFailed);
2165 const char* cmd_name = command.GetArgumentAtIndex(0);
2167 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2169 m_interpreter.RemoveUser(cmd_name);
2170 result.SetStatus (eReturnStatusSuccessFinishResult);
2174 result.AppendErrorWithFormat ("command %s not found", cmd_name);
2175 result.SetStatus (eReturnStatusFailed);
2178 return result.Succeeded();
2183 #pragma mark CommandObjectMultiwordCommandsScript
2185 //-------------------------------------------------------------------------
2186 // CommandObjectMultiwordCommandsScript
2187 //-------------------------------------------------------------------------
2189 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2192 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2193 CommandObjectMultiword (interpreter,
2195 "A set of commands for managing or customizing script commands.",
2196 "command script <subcommand> [<subcommand-options>]")
2198 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2199 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2200 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2201 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2202 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2205 ~CommandObjectMultiwordCommandsScript ()
2212 #pragma mark CommandObjectMultiwordCommands
2214 //-------------------------------------------------------------------------
2215 // CommandObjectMultiwordCommands
2216 //-------------------------------------------------------------------------
2218 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
2219 CommandObjectMultiword (interpreter,
2221 "A set of commands for managing or customizing the debugger commands.",
2222 "command <subcommand> [<subcommand-options>]")
2224 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2225 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2226 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2227 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2228 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2229 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2230 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2233 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()