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 "lldb/lldb-python.h"
12 #include "CommandObjectCommands.h"
16 // Other libraries and framework includes
17 #include "llvm/ADT/StringRef.h"
20 #include "lldb/Core/Debugger.h"
21 #include "lldb/Core/InputReader.h"
22 #include "lldb/Core/InputReaderEZ.h"
23 #include "lldb/Core/StringList.h"
24 #include "lldb/Interpreter/Args.h"
25 #include "lldb/Interpreter/CommandHistory.h"
26 #include "lldb/Interpreter/CommandInterpreter.h"
27 #include "lldb/Interpreter/CommandObjectRegexCommand.h"
28 #include "lldb/Interpreter/CommandReturnObject.h"
29 #include "lldb/Interpreter/OptionValueBoolean.h"
30 #include "lldb/Interpreter/OptionValueUInt64.h"
31 #include "lldb/Interpreter/Options.h"
32 #include "lldb/Interpreter/ScriptInterpreter.h"
33 #include "lldb/Interpreter/ScriptInterpreterPython.h"
36 using namespace lldb_private;
38 //-------------------------------------------------------------------------
39 // CommandObjectCommandsSource
40 //-------------------------------------------------------------------------
42 class CommandObjectCommandsHistory : public CommandObjectParsed
45 CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
46 CommandObjectParsed (interpreter,
48 "Dump the history of commands in this session.",
50 m_options (interpreter)
54 ~CommandObjectCommandsHistory () {}
64 class CommandOptions : public Options
68 CommandOptions (CommandInterpreter &interpreter) :
69 Options (interpreter),
81 SetOptionValue (uint32_t option_idx, const char *option_arg)
84 const int short_option = m_getopt_table[option_idx].val;
89 error = m_count.SetValueFromCString(option_arg,eVarSetOperationAssign);
92 if (option_arg && strcmp("end", option_arg) == 0)
94 m_start_idx.SetCurrentValue(UINT64_MAX);
95 m_start_idx.SetOptionWasSet();
98 error = m_start_idx.SetValueFromCString(option_arg,eVarSetOperationAssign);
101 error = m_stop_idx.SetValueFromCString(option_arg,eVarSetOperationAssign);
104 m_clear.SetCurrentValue(true);
105 m_clear.SetOptionWasSet();
108 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
116 OptionParsingStarting ()
124 const OptionDefinition*
127 return g_option_table;
130 // Options table: Required for subclasses of Options.
132 static OptionDefinition g_option_table[];
134 // Instance variables to hold the values for command options.
136 OptionValueUInt64 m_start_idx;
137 OptionValueUInt64 m_stop_idx;
138 OptionValueUInt64 m_count;
139 OptionValueBoolean m_clear;
143 DoExecute (Args& command, CommandReturnObject &result)
145 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
147 m_interpreter.GetCommandHistory().Clear();
148 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
152 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
154 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
155 result.SetStatus(lldb::eReturnStatusFailed);
159 std::pair<bool,uint64_t> start_idx = {m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue()};
160 std::pair<bool,uint64_t> stop_idx = {m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue()};
161 std::pair<bool,uint64_t> count = {m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue()};
163 const CommandHistory& history(m_interpreter.GetCommandHistory());
165 if (start_idx.first && start_idx.second == UINT64_MAX)
169 start_idx.second = history.GetSize() - count.second;
170 stop_idx.second = history.GetSize() - 1;
172 else if (stop_idx.first)
174 start_idx.second = stop_idx.second;
175 stop_idx.second = history.GetSize() - 1;
179 start_idx.second = 0;
180 stop_idx.second = history.GetSize() - 1;
185 if (!start_idx.first && !stop_idx.first && !count.first)
187 start_idx.second = 0;
188 stop_idx.second = history.GetSize() - 1;
190 else if (start_idx.first)
194 stop_idx.second = start_idx.second + count.second - 1;
196 else if (!stop_idx.first)
198 stop_idx.second = history.GetSize() - 1;
201 else if (stop_idx.first)
205 if (stop_idx.second >= count.second)
206 start_idx.second = stop_idx.second - count.second + 1;
208 start_idx.second = 0;
211 else /* if (count.first) */
213 start_idx.second = 0;
214 stop_idx.second = count.second - 1;
217 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
220 return result.Succeeded();
224 CommandOptions m_options;
228 CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
230 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
231 { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
232 { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
233 { LLDB_OPT_SET_2, false, "clear", 'C', no_argument, NULL, 0, eArgTypeBoolean, "Clears the current command history."},
234 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
238 //-------------------------------------------------------------------------
239 // CommandObjectCommandsSource
240 //-------------------------------------------------------------------------
242 class CommandObjectCommandsSource : public CommandObjectParsed
245 CommandObjectCommandsSource(CommandInterpreter &interpreter) :
246 CommandObjectParsed (interpreter,
248 "Read in debugger commands from the file <filename> and execute them.",
250 m_options (interpreter)
252 CommandArgumentEntry arg;
253 CommandArgumentData file_arg;
255 // Define the first (and only) variant of this arg.
256 file_arg.arg_type = eArgTypeFilename;
257 file_arg.arg_repetition = eArgRepeatPlain;
259 // There is only one variant this argument could be; put it into the argument entry.
260 arg.push_back (file_arg);
262 // Push the data for the first argument into the m_arguments vector.
263 m_arguments.push_back (arg);
266 ~CommandObjectCommandsSource () {}
269 GetRepeatCommand (Args ¤t_command_args, uint32_t index)
275 HandleArgumentCompletion (Args &input,
277 int &cursor_char_position,
278 OptionElementVector &opt_element_vector,
279 int match_start_point,
280 int max_return_elements,
284 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
285 completion_str.erase (cursor_char_position);
287 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
288 CommandCompletions::eDiskFileCompletion,
289 completion_str.c_str(),
295 return matches.GetSize();
306 class CommandOptions : public Options
310 CommandOptions (CommandInterpreter &interpreter) :
311 Options (interpreter),
312 m_stop_on_error (true)
320 SetOptionValue (uint32_t option_idx, const char *option_arg)
323 const int short_option = m_getopt_table[option_idx].val;
326 switch (short_option)
329 error = m_stop_on_error.SetValueFromCString(option_arg);
332 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
334 error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
337 m_silent_run = Args::StringToBoolean(option_arg, true, &success);
339 error.SetErrorStringWithFormat("invalid value for silent-run: %s", option_arg);
342 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
350 OptionParsingStarting ()
352 m_stop_on_error.Clear();
353 m_silent_run = false;
354 m_stop_on_continue = true;
357 const OptionDefinition*
360 return g_option_table;
363 // Options table: Required for subclasses of Options.
365 static OptionDefinition g_option_table[];
367 // Instance variables to hold the values for command options.
369 OptionValueBoolean m_stop_on_error;
371 bool m_stop_on_continue;
375 DoExecute(Args& command, CommandReturnObject &result)
377 const size_t argc = command.GetArgumentCount();
380 const char *filename = command.GetArgumentAtIndex(0);
382 result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
384 FileSpec cmd_file (filename, true);
385 ExecutionContext *exe_ctx = NULL; // Just use the default context.
386 bool echo_commands = !m_options.m_silent_run;
387 bool print_results = true;
388 bool stop_on_error = m_options.m_stop_on_error.OptionWasSet() ? (bool)m_options.m_stop_on_error : m_interpreter.GetStopCmdSourceOnError();
390 m_interpreter.HandleCommandsFromFile (cmd_file,
392 m_options.m_stop_on_continue,
401 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
402 result.SetStatus (eReturnStatusFailed);
404 return result.Succeeded();
407 CommandOptions m_options;
411 CommandObjectCommandsSource::CommandOptions::g_option_table[] =
413 { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
414 { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
415 { LLDB_OPT_SET_ALL, false, "silent-run", 's', required_argument, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
416 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
419 #pragma mark CommandObjectCommandsAlias
420 //-------------------------------------------------------------------------
421 // CommandObjectCommandsAlias
422 //-------------------------------------------------------------------------
424 static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
425 "You must define a Python function with this signature:\n"
426 "def my_command_impl(debugger, args, result, internal_dict):";
429 class CommandObjectCommandsAlias : public CommandObjectRaw
434 CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
435 CommandObjectRaw (interpreter,
437 "Allow users to define their own debugger command abbreviations.",
441 "'alias' allows the user to create a short-cut or abbreviation for long \n\
442 commands, multi-word commands, and commands that take particular options. \n\
443 Below are some simple examples of how one might use the 'alias' command: \n\
444 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\
446 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\
447 // command. Since breakpoint commands are two-word \n\
448 // commands, the user will still need to enter the \n\
449 // second word after 'bp', e.g. 'bp enable' or \n\
451 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
452 // two-word command 'breakpoint list'. \n\
453 \nAn alias can include some options for the command, with the values either \n\
454 filled in at the time the alias is created, or specified as positional \n\
455 arguments, to be filled in when the alias is invoked. The following example \n\
456 shows how to create aliases with options: \n\
458 'command alias bfl breakpoint set -f %1 -l %2' \n\
459 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
460 options already part of the alias. So if the user wants to set a breakpoint \n\
461 by file and line without explicitly having to use the -f and -l options, the \n\
462 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\
463 for the actual arguments that will be passed when the alias command is used. \n\
464 The number in the placeholder refers to the position/order the actual value \n\
465 occupies when the alias is used. All the occurrences of '%1' in the alias \n\
466 will be replaced with the first argument, all the occurrences of '%2' in the \n\
467 alias will be replaced with the second argument, and so on. This also allows \n\
468 actual arguments to be used multiple times within an alias (see 'process \n\
469 launch' example below). \n\
470 Note: the positional arguments must substitute as whole words in the resultant\n\
471 command, so you can't at present do something like:\n\
473 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
475 to get the file extension \".cpp\" automatically appended. For more complex\n\
476 aliasing, use the \"command regex\" command instead.\n\
477 \nSo in the 'bfl' case, the actual file value will be \n\
478 filled in with the first argument following 'bfl' and the actual line number \n\
479 value will be filled in with the second argument. The user would use this \n\
480 alias as follows: \n\
481 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\
482 <... some time later ...> \n\
483 (lldb) bfl my-file.c 137 \n\
484 \nThis would be the same as if the user had entered \n\
485 'breakpoint set -f my-file.c -l 137'. \n\
486 \nAnother example: \n\
487 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\
488 (lldb) pltty /dev/tty0 \n\
489 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
490 \nIf the user always wanted to pass the same value to a particular option, the \n\
491 alias could be defined with that value directly in the alias as a constant, \n\
492 rather than using a positional placeholder: \n\
493 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\
494 // 3 of whatever file is indicated. \n");
496 CommandArgumentEntry arg1;
497 CommandArgumentEntry arg2;
498 CommandArgumentEntry arg3;
499 CommandArgumentData alias_arg;
500 CommandArgumentData cmd_arg;
501 CommandArgumentData options_arg;
503 // Define the first (and only) variant of this arg.
504 alias_arg.arg_type = eArgTypeAliasName;
505 alias_arg.arg_repetition = eArgRepeatPlain;
507 // There is only one variant this argument could be; put it into the argument entry.
508 arg1.push_back (alias_arg);
510 // Define the first (and only) variant of this arg.
511 cmd_arg.arg_type = eArgTypeCommandName;
512 cmd_arg.arg_repetition = eArgRepeatPlain;
514 // There is only one variant this argument could be; put it into the argument entry.
515 arg2.push_back (cmd_arg);
517 // Define the first (and only) variant of this arg.
518 options_arg.arg_type = eArgTypeAliasOptions;
519 options_arg.arg_repetition = eArgRepeatOptional;
521 // There is only one variant this argument could be; put it into the argument entry.
522 arg3.push_back (options_arg);
524 // Push the data for the first argument into the m_arguments vector.
525 m_arguments.push_back (arg1);
526 m_arguments.push_back (arg2);
527 m_arguments.push_back (arg3);
530 ~CommandObjectCommandsAlias ()
536 DoExecute (const char *raw_command_line, CommandReturnObject &result)
538 Args args (raw_command_line);
539 std::string raw_command_string (raw_command_line);
541 size_t argc = args.GetArgumentCount();
545 result.AppendError ("'alias' requires at least two arguments");
546 result.SetStatus (eReturnStatusFailed);
550 // Get the alias command.
552 const std::string alias_command = args.GetArgumentAtIndex (0);
554 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
555 // does the stripping itself.
556 size_t pos = raw_command_string.find (alias_command);
559 raw_command_string = raw_command_string.substr (alias_command.size());
560 pos = raw_command_string.find_first_not_of (' ');
561 if ((pos != std::string::npos) && (pos > 0))
562 raw_command_string = raw_command_string.substr (pos);
566 result.AppendError ("Error parsing command string. No alias created.");
567 result.SetStatus (eReturnStatusFailed);
572 // Verify that the command is alias-able.
573 if (m_interpreter.CommandExists (alias_command.c_str()))
575 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
576 alias_command.c_str());
577 result.SetStatus (eReturnStatusFailed);
581 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
582 // raw_command_string is returned with the name of the command object stripped off the front.
583 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
587 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
588 " No alias created.", raw_command_string.c_str());
589 result.SetStatus (eReturnStatusFailed);
592 else if (!cmd_obj->WantsRawCommandString ())
594 // Note that args was initialized with the original command, and has not been updated to this point.
595 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
596 return HandleAliasingNormalCommand (args, result);
600 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
602 return result.Succeeded();
606 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
608 // Verify & handle any options/arguments passed to the alias command
610 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
611 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
613 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
615 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
617 result.AppendError ("Unable to create requested alias.\n");
618 result.SetStatus (eReturnStatusFailed);
623 if (m_interpreter.AliasExists (alias_command.c_str())
624 || m_interpreter.UserCommandExists (alias_command.c_str()))
626 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
627 if (temp_option_arg_sp.get())
629 if (option_arg_vector->size() == 0)
630 m_interpreter.RemoveAliasOptions (alias_command.c_str());
632 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
633 alias_command.c_str());
638 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
639 if (option_arg_vector->size() > 0)
640 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
641 result.SetStatus (eReturnStatusSuccessFinishNoResult);
645 result.AppendError ("Unable to create requested alias.\n");
646 result.SetStatus (eReturnStatusFailed);
648 return result.Succeeded ();
652 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
654 size_t argc = args.GetArgumentCount();
658 result.AppendError ("'alias' requires at least two arguments");
659 result.SetStatus (eReturnStatusFailed);
663 const std::string alias_command = args.GetArgumentAtIndex(0);
664 const std::string actual_command = args.GetArgumentAtIndex(1);
666 args.Shift(); // Shift the alias command word off the argument vector.
667 args.Shift(); // Shift the old command word off the argument vector.
669 // Verify that the command is alias'able, and get the appropriate command object.
671 if (m_interpreter.CommandExists (alias_command.c_str()))
673 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
674 alias_command.c_str());
675 result.SetStatus (eReturnStatusFailed);
679 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
680 CommandObjectSP subcommand_obj_sp;
681 bool use_subcommand = false;
682 if (command_obj_sp.get())
684 CommandObject *cmd_obj = command_obj_sp.get();
685 CommandObject *sub_cmd_obj = NULL;
686 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
687 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
689 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
693 const std::string sub_command = args.GetArgumentAtIndex(0);
694 assert (sub_command.length() != 0);
695 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
696 if (subcommand_obj_sp.get())
698 sub_cmd_obj = subcommand_obj_sp.get();
699 use_subcommand = true;
700 args.Shift(); // Shift the sub_command word off the argument vector.
701 cmd_obj = sub_cmd_obj;
705 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
706 "Unable to create alias.\n",
707 sub_command.c_str(), actual_command.c_str());
708 result.SetStatus (eReturnStatusFailed);
714 // Verify & handle any options/arguments passed to the alias command
716 if (args.GetArgumentCount () > 0)
718 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
720 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
722 std::string args_string;
723 args.GetCommandString (args_string);
725 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
727 result.AppendError ("Unable to create requested alias.\n");
728 result.SetStatus (eReturnStatusFailed);
735 if (m_interpreter.AliasExists (alias_command.c_str())
736 || m_interpreter.UserCommandExists (alias_command.c_str()))
738 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
739 if (tmp_option_arg_sp.get())
741 if (option_arg_vector->size() == 0)
742 m_interpreter.RemoveAliasOptions (alias_command.c_str());
744 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
745 alias_command.c_str());
749 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
751 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
752 if (option_arg_vector->size() > 0)
753 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
754 result.SetStatus (eReturnStatusSuccessFinishNoResult);
758 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
759 result.SetStatus (eReturnStatusFailed);
764 return result.Succeeded();
769 #pragma mark CommandObjectCommandsUnalias
770 //-------------------------------------------------------------------------
771 // CommandObjectCommandsUnalias
772 //-------------------------------------------------------------------------
774 class CommandObjectCommandsUnalias : public CommandObjectParsed
777 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
778 CommandObjectParsed (interpreter,
780 "Allow the user to remove/delete a user-defined command abbreviation.",
783 CommandArgumentEntry arg;
784 CommandArgumentData alias_arg;
786 // Define the first (and only) variant of this arg.
787 alias_arg.arg_type = eArgTypeAliasName;
788 alias_arg.arg_repetition = eArgRepeatPlain;
790 // There is only one variant this argument could be; put it into the argument entry.
791 arg.push_back (alias_arg);
793 // Push the data for the first argument into the m_arguments vector.
794 m_arguments.push_back (arg);
797 ~CommandObjectCommandsUnalias()
803 DoExecute (Args& args, CommandReturnObject &result)
805 CommandObject::CommandMap::iterator pos;
806 CommandObject *cmd_obj;
808 if (args.GetArgumentCount() != 0)
810 const char *command_name = args.GetArgumentAtIndex(0);
811 cmd_obj = m_interpreter.GetCommandObject(command_name);
814 if (m_interpreter.CommandExists (command_name))
816 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
818 result.SetStatus (eReturnStatusFailed);
823 if (m_interpreter.RemoveAlias (command_name) == false)
825 if (m_interpreter.AliasExists (command_name))
826 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
829 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
830 result.SetStatus (eReturnStatusFailed);
833 result.SetStatus (eReturnStatusSuccessFinishNoResult);
838 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
839 "current list of commands.\n",
841 result.SetStatus (eReturnStatusFailed);
846 result.AppendError ("must call 'unalias' with a valid alias");
847 result.SetStatus (eReturnStatusFailed);
850 return result.Succeeded();
854 //-------------------------------------------------------------------------
855 // CommandObjectCommandsAddRegex
856 //-------------------------------------------------------------------------
857 #pragma mark CommandObjectCommandsAddRegex
859 class CommandObjectCommandsAddRegex : public CommandObjectParsed
862 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
863 CommandObjectParsed (interpreter,
865 "Allow the user to create a regular expression command.",
866 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
867 m_options (interpreter)
870 "This command allows the user to create powerful regular expression commands\n"
871 "with substitutions. The regular expressions and substitutions are specified\n"
872 "using the regular exression substitution format of:\n"
874 " s/<regex>/<subst>/\n"
876 "<regex> is a regular expression that can use parenthesis to capture regular\n"
877 "expression input and substitute the captured matches in the output using %1\n"
878 "for the first match, %2 for the second, and so on.\n"
880 "The regular expressions can all be specified on the command line if more than\n"
881 "one argument is provided. If just the command name is provided on the command\n"
882 "line, then the regular expressions and substitutions can be entered on separate\n"
883 " lines, followed by an empty line to terminate the command definition.\n"
887 "The following example will define a regular expression command named 'f' that\n"
888 "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
889 "a number follows 'f':\n"
891 " (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
896 ~CommandObjectCommandsAddRegex()
903 DoExecute (Args& command, CommandReturnObject &result)
905 const size_t argc = command.GetArgumentCount();
908 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
909 result.SetStatus (eReturnStatusFailed);
914 const char *name = command.GetArgumentAtIndex(0);
915 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
917 m_options.GetHelp (),
918 m_options.GetSyntax (),
923 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
926 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
928 eInputReaderGranularityLine, // token size, to pass to callback function
934 m_interpreter.GetDebugger().PushInputReader (reader_sp);
935 result.SetStatus (eReturnStatusSuccessFinishNoResult);
942 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
944 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
945 error = AppendRegexSubstitution (arg_strref);
952 AddRegexCommandToInterpreter();
957 result.AppendError (error.AsCString());
958 result.SetStatus (eReturnStatusFailed);
962 return result.Succeeded();
966 AppendRegexSubstitution (const llvm::StringRef ®ex_sed)
970 if (m_regex_cmd_ap.get() == NULL)
972 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
973 (int)regex_sed.size(),
978 size_t regex_sed_size = regex_sed.size();
980 if (regex_sed_size <= 1)
982 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
983 (int)regex_sed.size(),
988 if (regex_sed[0] != 's')
990 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
991 (int)regex_sed.size(),
995 const size_t first_separator_char_pos = 1;
996 // use the char that follows 's' as the regex separator character
997 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
998 const char separator_char = regex_sed[first_separator_char_pos];
999 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1001 if (second_separator_char_pos == std::string::npos)
1003 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
1005 (int)(regex_sed.size() - first_separator_char_pos - 1),
1006 regex_sed.data() + (first_separator_char_pos + 1));
1010 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1012 if (third_separator_char_pos == std::string::npos)
1014 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
1016 (int)(regex_sed.size() - second_separator_char_pos - 1),
1017 regex_sed.data() + (second_separator_char_pos + 1));
1021 if (third_separator_char_pos != regex_sed_size - 1)
1023 // Make sure that everything that follows the last regex
1025 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1027 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1028 (int)third_separator_char_pos + 1,
1030 (int)(regex_sed.size() - third_separator_char_pos - 1),
1031 regex_sed.data() + (third_separator_char_pos + 1));
1036 else if (first_separator_char_pos + 1 == second_separator_char_pos)
1038 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1042 (int)regex_sed.size(),
1046 else if (second_separator_char_pos + 1 == third_separator_char_pos)
1048 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1052 (int)regex_sed.size(),
1056 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1057 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1058 m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1064 AddRegexCommandToInterpreter()
1066 if (m_regex_cmd_ap.get())
1068 if (m_regex_cmd_ap->HasRegexEntries())
1070 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1071 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1077 InputReaderDidCancel()
1079 m_regex_cmd_ap.reset();
1083 InputReaderCallback (void *baton,
1084 InputReader &reader,
1085 lldb::InputReaderAction notification,
1089 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
1090 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
1092 switch (notification)
1094 case eInputReaderActivate:
1097 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1098 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1099 out_stream->Flush();
1102 case eInputReaderReactivate:
1105 case eInputReaderDeactivate:
1108 case eInputReaderAsynchronousOutputWritten:
1111 case eInputReaderGotToken:
1112 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1115 reader.SetIsDone(true);
1118 llvm::StringRef bytes_strref (bytes, bytes_len);
1119 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1124 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1125 out_stream->Printf("error: %s\n", error.AsCString());
1126 out_stream->Flush();
1128 add_regex_cmd->InputReaderDidCancel ();
1129 reader.SetIsDone (true);
1134 case eInputReaderInterrupt:
1136 reader.SetIsDone (true);
1139 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1140 out_stream->PutCString("Regular expression command creations was cancelled.\n");
1141 out_stream->Flush();
1143 add_regex_cmd->InputReaderDidCancel ();
1147 case eInputReaderEndOfFile:
1148 reader.SetIsDone (true);
1151 case eInputReaderDone:
1152 add_regex_cmd->AddRegexCommandToInterpreter();
1160 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1162 class CommandOptions : public Options
1166 CommandOptions (CommandInterpreter &interpreter) :
1167 Options (interpreter)
1172 ~CommandOptions (){}
1175 SetOptionValue (uint32_t option_idx, const char *option_arg)
1178 const int short_option = m_getopt_table[option_idx].val;
1180 switch (short_option)
1183 m_help.assign (option_arg);
1186 m_syntax.assign (option_arg);
1190 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1198 OptionParsingStarting ()
1204 const OptionDefinition*
1207 return g_option_table;
1210 // Options table: Required for subclasses of Options.
1212 static OptionDefinition g_option_table[];
1219 return m_help.c_str();
1224 if (m_syntax.empty())
1226 return m_syntax.c_str();
1228 // Instance variables to hold the values for command options.
1231 std::string m_syntax;
1240 CommandOptions m_options;
1244 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1246 { LLDB_OPT_SET_1, false, "help" , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1247 { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1248 { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL }
1252 class CommandObjectPythonFunction : public CommandObjectRaw
1255 std::string m_function_name;
1256 ScriptedCommandSynchronicity m_synchro;
1257 bool m_fetched_help_long;
1261 CommandObjectPythonFunction (CommandInterpreter &interpreter,
1264 ScriptedCommandSynchronicity synch) :
1265 CommandObjectRaw (interpreter,
1267 (std::string("Run Python function ") + funct).c_str(),
1269 m_function_name(funct),
1271 m_fetched_help_long(false)
1276 ~CommandObjectPythonFunction ()
1281 IsRemovable () const
1289 return m_function_name;
1292 ScriptedCommandSynchronicity
1298 virtual const char *
1301 if (!m_fetched_help_long)
1303 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1306 std::string docstring;
1307 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1308 if (!docstring.empty())
1309 SetHelpLong(docstring);
1312 return CommandObjectRaw::GetHelpLong();
1317 DoExecute (const char *raw_command_line, CommandReturnObject &result)
1319 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1323 result.SetStatus(eReturnStatusInvalid);
1325 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1331 result.AppendError(error.AsCString());
1332 result.SetStatus(eReturnStatusFailed);
1336 // Don't change the status if the command already set it...
1337 if (result.GetStatus() == eReturnStatusInvalid)
1339 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1340 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1342 result.SetStatus(eReturnStatusSuccessFinishResult);
1346 return result.Succeeded();
1351 //-------------------------------------------------------------------------
1352 // CommandObjectCommandsScriptImport
1353 //-------------------------------------------------------------------------
1355 class CommandObjectCommandsScriptImport : public CommandObjectParsed
1358 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1359 CommandObjectParsed (interpreter,
1360 "command script import",
1361 "Import a scripting module in LLDB.",
1363 m_options(interpreter)
1365 CommandArgumentEntry arg1;
1366 CommandArgumentData cmd_arg;
1368 // Define the first (and only) variant of this arg.
1369 cmd_arg.arg_type = eArgTypeFilename;
1370 cmd_arg.arg_repetition = eArgRepeatPlain;
1372 // There is only one variant this argument could be; put it into the argument entry.
1373 arg1.push_back (cmd_arg);
1375 // Push the data for the first argument into the m_arguments vector.
1376 m_arguments.push_back (arg1);
1379 ~CommandObjectCommandsScriptImport ()
1384 HandleArgumentCompletion (Args &input,
1386 int &cursor_char_position,
1387 OptionElementVector &opt_element_vector,
1388 int match_start_point,
1389 int max_return_elements,
1390 bool &word_complete,
1391 StringList &matches)
1393 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1394 completion_str.erase (cursor_char_position);
1396 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1397 CommandCompletions::eDiskFileCompletion,
1398 completion_str.c_str(),
1400 max_return_elements,
1404 return matches.GetSize();
1415 class CommandOptions : public Options
1419 CommandOptions (CommandInterpreter &interpreter) :
1420 Options (interpreter)
1425 ~CommandOptions (){}
1428 SetOptionValue (uint32_t option_idx, const char *option_arg)
1431 const int short_option = m_getopt_table[option_idx].val;
1433 switch (short_option)
1436 m_allow_reload = true;
1439 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1447 OptionParsingStarting ()
1449 m_allow_reload = true;
1452 const OptionDefinition*
1455 return g_option_table;
1458 // Options table: Required for subclasses of Options.
1460 static OptionDefinition g_option_table[];
1462 // Instance variables to hold the values for command options.
1464 bool m_allow_reload;
1468 DoExecute (Args& command, CommandReturnObject &result)
1471 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1473 result.AppendError ("only scripting language supported for module importing is currently Python");
1474 result.SetStatus (eReturnStatusFailed);
1478 size_t argc = command.GetArgumentCount();
1482 result.AppendError ("'command script import' requires one argument");
1483 result.SetStatus (eReturnStatusFailed);
1487 std::string path = command.GetArgumentAtIndex(0);
1490 const bool init_session = true;
1491 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1492 // commands won't ever be recursively invoked, but it's actually possible to craft
1493 // a Python script that does other "command script imports" in __lldb_init_module
1494 // the real fix is to have recursive commands possible with a CommandInvocation object
1495 // separate from the CommandObject itself, so that recursive command invocations
1496 // won't stomp on each other (wrt to execution contents, options, and more)
1498 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
1499 m_options.m_allow_reload,
1503 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1507 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1508 result.SetStatus (eReturnStatusFailed);
1511 return result.Succeeded();
1514 CommandOptions m_options;
1518 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1520 { LLDB_OPT_SET_1, false, "allow-reload", 'r', no_argument, 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."},
1521 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1525 //-------------------------------------------------------------------------
1526 // CommandObjectCommandsScriptAdd
1527 //-------------------------------------------------------------------------
1529 class CommandObjectCommandsScriptAdd : public CommandObjectParsed
1532 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1533 CommandObjectParsed (interpreter,
1534 "command script add",
1535 "Add a scripted function as an LLDB command.",
1537 m_options (interpreter)
1539 CommandArgumentEntry arg1;
1540 CommandArgumentData cmd_arg;
1542 // Define the first (and only) variant of this arg.
1543 cmd_arg.arg_type = eArgTypeCommandName;
1544 cmd_arg.arg_repetition = eArgRepeatPlain;
1546 // There is only one variant this argument could be; put it into the argument entry.
1547 arg1.push_back (cmd_arg);
1549 // Push the data for the first argument into the m_arguments vector.
1550 m_arguments.push_back (arg1);
1553 ~CommandObjectCommandsScriptAdd ()
1565 class CommandOptions : public Options
1569 CommandOptions (CommandInterpreter &interpreter) :
1570 Options (interpreter)
1575 ~CommandOptions (){}
1578 SetOptionValue (uint32_t option_idx, const char *option_arg)
1581 const int short_option = m_getopt_table[option_idx].val;
1583 switch (short_option)
1586 m_funct_name = std::string(option_arg);
1589 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1590 if (!error.Success())
1591 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1594 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1602 OptionParsingStarting ()
1605 m_synchronous = eScriptedCommandSynchronicitySynchronous;
1608 const OptionDefinition*
1611 return g_option_table;
1614 // Options table: Required for subclasses of Options.
1616 static OptionDefinition g_option_table[];
1618 // Instance variables to hold the values for command options.
1620 std::string m_funct_name;
1621 ScriptedCommandSynchronicity m_synchronous;
1625 class PythonAliasReader : public InputReaderEZ
1628 CommandInterpreter& m_interpreter;
1629 std::string m_cmd_name;
1630 ScriptedCommandSynchronicity m_synchronous;
1631 StringList m_user_input;
1632 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1634 PythonAliasReader(Debugger& debugger,
1635 CommandInterpreter& interpreter,
1636 std::string cmd_name,
1637 ScriptedCommandSynchronicity synch) :
1638 InputReaderEZ(debugger),
1639 m_interpreter(interpreter),
1640 m_cmd_name(cmd_name),
1641 m_synchronous(synch),
1646 ~PythonAliasReader()
1650 virtual void ActivateHandler(HandlerData& data)
1652 StreamSP out_stream = data.GetOutStream();
1653 bool batch_mode = data.GetBatchMode();
1656 out_stream->Printf ("%s\n", g_python_command_instructions);
1657 if (data.reader.GetPrompt())
1658 out_stream->Printf ("%s", data.reader.GetPrompt());
1659 out_stream->Flush();
1663 virtual void ReactivateHandler(HandlerData& data)
1665 StreamSP out_stream = data.GetOutStream();
1666 bool batch_mode = data.GetBatchMode();
1667 if (data.reader.GetPrompt() && !batch_mode)
1669 out_stream->Printf ("%s", data.reader.GetPrompt());
1670 out_stream->Flush();
1673 virtual void GotTokenHandler(HandlerData& data)
1675 StreamSP out_stream = data.GetOutStream();
1676 bool batch_mode = data.GetBatchMode();
1677 if (data.bytes && data.bytes_len)
1679 m_user_input.AppendString(data.bytes, data.bytes_len);
1681 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1683 out_stream->Printf ("%s", data.reader.GetPrompt());
1684 out_stream->Flush();
1687 virtual void InterruptHandler(HandlerData& data)
1689 StreamSP out_stream = data.GetOutStream();
1690 bool batch_mode = data.GetBatchMode();
1691 data.reader.SetIsDone (true);
1694 out_stream->Printf ("Warning: No script attached.\n");
1695 out_stream->Flush();
1698 virtual void EOFHandler(HandlerData& data)
1700 data.reader.SetIsDone (true);
1702 virtual void DoneHandler(HandlerData& data)
1704 StreamSP out_stream = data.GetOutStream();
1706 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1709 out_stream->Printf ("Script interpreter missing: no script attached.\n");
1710 out_stream->Flush();
1713 std::string funct_name_str;
1714 if (!interpreter->GenerateScriptAliasFunction (m_user_input,
1717 out_stream->Printf ("Unable to create function: no script attached.\n");
1718 out_stream->Flush();
1721 if (funct_name_str.empty())
1723 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
1724 out_stream->Flush();
1727 // everything should be fine now, let's add this alias
1729 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1731 funct_name_str.c_str(),
1734 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1736 out_stream->Printf ("Unable to add selected command: no script attached.\n");
1737 out_stream->Flush();
1745 DoExecute (Args& command, CommandReturnObject &result)
1748 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1750 result.AppendError ("only scripting language supported for scripted commands is currently Python");
1751 result.SetStatus (eReturnStatusFailed);
1755 size_t argc = command.GetArgumentCount();
1759 result.AppendError ("'command script add' requires one argument");
1760 result.SetStatus (eReturnStatusFailed);
1764 std::string cmd_name = command.GetArgumentAtIndex(0);
1766 if (m_options.m_funct_name.empty())
1768 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1771 m_options.m_synchronous));
1776 InputReaderEZ::InitializationParameters ipr;
1778 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
1781 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1782 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1786 result.AppendError (err.AsCString());
1787 result.SetStatus (eReturnStatusFailed);
1792 result.AppendError("out of memory");
1793 result.SetStatus (eReturnStatusFailed);
1798 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1800 m_options.m_funct_name,
1801 m_options.m_synchronous));
1802 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
1804 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1808 result.AppendError("cannot add command");
1809 result.SetStatus (eReturnStatusFailed);
1813 return result.Succeeded();
1817 CommandOptions m_options;
1820 static OptionEnumValueElement g_script_synchro_type[] =
1822 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
1823 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
1824 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
1829 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1831 { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
1832 { LLDB_OPT_SET_1, false, "synchronicity", 's', required_argument, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
1833 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1836 //-------------------------------------------------------------------------
1837 // CommandObjectCommandsScriptList
1838 //-------------------------------------------------------------------------
1840 class CommandObjectCommandsScriptList : public CommandObjectParsed
1845 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
1846 CommandObjectParsed (interpreter,
1847 "command script list",
1848 "List defined scripted commands.",
1853 ~CommandObjectCommandsScriptList ()
1858 DoExecute (Args& command, CommandReturnObject &result)
1861 m_interpreter.GetHelp(result,
1862 CommandInterpreter::eCommandTypesUserDef);
1864 result.SetStatus (eReturnStatusSuccessFinishResult);
1872 //-------------------------------------------------------------------------
1873 // CommandObjectCommandsScriptClear
1874 //-------------------------------------------------------------------------
1876 class CommandObjectCommandsScriptClear : public CommandObjectParsed
1881 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
1882 CommandObjectParsed (interpreter,
1883 "command script clear",
1884 "Delete all scripted commands.",
1889 ~CommandObjectCommandsScriptClear ()
1895 DoExecute (Args& command, CommandReturnObject &result)
1898 m_interpreter.RemoveAllUser();
1900 result.SetStatus (eReturnStatusSuccessFinishResult);
1906 //-------------------------------------------------------------------------
1907 // CommandObjectCommandsScriptDelete
1908 //-------------------------------------------------------------------------
1910 class CommandObjectCommandsScriptDelete : public CommandObjectParsed
1913 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
1914 CommandObjectParsed (interpreter,
1915 "command script delete",
1916 "Delete a scripted command.",
1919 CommandArgumentEntry arg1;
1920 CommandArgumentData cmd_arg;
1922 // Define the first (and only) variant of this arg.
1923 cmd_arg.arg_type = eArgTypeCommandName;
1924 cmd_arg.arg_repetition = eArgRepeatPlain;
1926 // There is only one variant this argument could be; put it into the argument entry.
1927 arg1.push_back (cmd_arg);
1929 // Push the data for the first argument into the m_arguments vector.
1930 m_arguments.push_back (arg1);
1933 ~CommandObjectCommandsScriptDelete ()
1939 DoExecute (Args& command, CommandReturnObject &result)
1942 size_t argc = command.GetArgumentCount();
1946 result.AppendError ("'command script delete' requires one argument");
1947 result.SetStatus (eReturnStatusFailed);
1951 const char* cmd_name = command.GetArgumentAtIndex(0);
1953 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1955 m_interpreter.RemoveUser(cmd_name);
1956 result.SetStatus (eReturnStatusSuccessFinishResult);
1960 result.AppendErrorWithFormat ("command %s not found", cmd_name);
1961 result.SetStatus (eReturnStatusFailed);
1964 return result.Succeeded();
1969 #pragma mark CommandObjectMultiwordCommandsScript
1971 //-------------------------------------------------------------------------
1972 // CommandObjectMultiwordCommandsScript
1973 //-------------------------------------------------------------------------
1975 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1978 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1979 CommandObjectMultiword (interpreter,
1981 "A set of commands for managing or customizing script commands.",
1982 "command script <subcommand> [<subcommand-options>]")
1984 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1985 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1986 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1987 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1988 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
1991 ~CommandObjectMultiwordCommandsScript ()
1998 #pragma mark CommandObjectMultiwordCommands
2000 //-------------------------------------------------------------------------
2001 // CommandObjectMultiwordCommands
2002 //-------------------------------------------------------------------------
2004 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
2005 CommandObjectMultiword (interpreter,
2007 "A set of commands for managing or customizing the debugger commands.",
2008 "command <subcommand> [<subcommand-options>]")
2010 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2011 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2012 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2013 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2014 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2015 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2018 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()