1 //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/lldb-python.h" 11 12 #include "CommandObjectCommands.h" 13 14 // C Includes 15 // C++ Includes 16 // Other libraries and framework includes 17 #include "llvm/ADT/StringRef.h" 18 19 // Project includes 20 #include "lldb/Core/Debugger.h" 21 #include "lldb/Core/IOHandler.h" 22 #include "lldb/Core/StringList.h" 23 #include "lldb/Interpreter/Args.h" 24 #include "lldb/Interpreter/CommandHistory.h" 25 #include "lldb/Interpreter/CommandInterpreter.h" 26 #include "lldb/Interpreter/CommandObjectRegexCommand.h" 27 #include "lldb/Interpreter/CommandReturnObject.h" 28 #include "lldb/Interpreter/OptionValueBoolean.h" 29 #include "lldb/Interpreter/OptionValueUInt64.h" 30 #include "lldb/Interpreter/Options.h" 31 #include "lldb/Interpreter/ScriptInterpreter.h" 32 33 using namespace lldb; 34 using namespace lldb_private; 35 36 //------------------------------------------------------------------------- 37 // CommandObjectCommandsSource 38 //------------------------------------------------------------------------- 39 40 class CommandObjectCommandsHistory : public CommandObjectParsed 41 { 42 public: 43 CommandObjectCommandsHistory(CommandInterpreter &interpreter) : 44 CommandObjectParsed (interpreter, 45 "command history", 46 "Dump the history of commands in this session.", 47 NULL), 48 m_options (interpreter) 49 { 50 } 51 52 ~CommandObjectCommandsHistory () {} 53 54 virtual Options * 55 GetOptions () 56 { 57 return &m_options; 58 } 59 60 protected: 61 62 class CommandOptions : public Options 63 { 64 public: 65 66 CommandOptions (CommandInterpreter &interpreter) : 67 Options (interpreter), 68 m_start_idx(0), 69 m_stop_idx(0), 70 m_count(0), 71 m_clear(false) 72 { 73 } 74 75 virtual 76 ~CommandOptions (){} 77 78 virtual Error 79 SetOptionValue (uint32_t option_idx, const char *option_arg) 80 { 81 Error error; 82 const int short_option = m_getopt_table[option_idx].val; 83 84 switch (short_option) 85 { 86 case 'c': 87 error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign); 88 break; 89 case 's': 90 if (option_arg && strcmp("end", option_arg) == 0) 91 { 92 m_start_idx.SetCurrentValue(UINT64_MAX); 93 m_start_idx.SetOptionWasSet(); 94 } 95 else 96 error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign); 97 break; 98 case 'e': 99 error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign); 100 break; 101 case 'C': 102 m_clear.SetCurrentValue(true); 103 m_clear.SetOptionWasSet(); 104 break; 105 default: 106 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 107 break; 108 } 109 110 return error; 111 } 112 113 void 114 OptionParsingStarting () 115 { 116 m_start_idx.Clear(); 117 m_stop_idx.Clear(); 118 m_count.Clear(); 119 m_clear.Clear(); 120 } 121 122 const OptionDefinition* 123 GetDefinitions () 124 { 125 return g_option_table; 126 } 127 128 // Options table: Required for subclasses of Options. 129 130 static OptionDefinition g_option_table[]; 131 132 // Instance variables to hold the values for command options. 133 134 OptionValueUInt64 m_start_idx; 135 OptionValueUInt64 m_stop_idx; 136 OptionValueUInt64 m_count; 137 OptionValueBoolean m_clear; 138 }; 139 140 bool 141 DoExecute (Args& command, CommandReturnObject &result) 142 { 143 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet()) 144 { 145 m_interpreter.GetCommandHistory().Clear(); 146 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); 147 } 148 else 149 { 150 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet()) 151 { 152 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation"); 153 result.SetStatus(lldb::eReturnStatusFailed); 154 } 155 else 156 { 157 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue()); 158 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue()); 159 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue()); 160 161 const CommandHistory& history(m_interpreter.GetCommandHistory()); 162 163 if (start_idx.first && start_idx.second == UINT64_MAX) 164 { 165 if (count.first) 166 { 167 start_idx.second = history.GetSize() - count.second; 168 stop_idx.second = history.GetSize() - 1; 169 } 170 else if (stop_idx.first) 171 { 172 start_idx.second = stop_idx.second; 173 stop_idx.second = history.GetSize() - 1; 174 } 175 else 176 { 177 start_idx.second = 0; 178 stop_idx.second = history.GetSize() - 1; 179 } 180 } 181 else 182 { 183 if (!start_idx.first && !stop_idx.first && !count.first) 184 { 185 start_idx.second = 0; 186 stop_idx.second = history.GetSize() - 1; 187 } 188 else if (start_idx.first) 189 { 190 if (count.first) 191 { 192 stop_idx.second = start_idx.second + count.second - 1; 193 } 194 else if (!stop_idx.first) 195 { 196 stop_idx.second = history.GetSize() - 1; 197 } 198 } 199 else if (stop_idx.first) 200 { 201 if (count.first) 202 { 203 if (stop_idx.second >= count.second) 204 start_idx.second = stop_idx.second - count.second + 1; 205 else 206 start_idx.second = 0; 207 } 208 } 209 else /* if (count.first) */ 210 { 211 start_idx.second = 0; 212 stop_idx.second = count.second - 1; 213 } 214 } 215 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second); 216 } 217 } 218 return result.Succeeded(); 219 220 } 221 222 CommandOptions m_options; 223 }; 224 225 OptionDefinition 226 CommandObjectCommandsHistory::CommandOptions::g_option_table[] = 227 { 228 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, 229 { 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)."}, 230 { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, 231 { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean, "Clears the current command history."}, 232 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 233 }; 234 235 236 //------------------------------------------------------------------------- 237 // CommandObjectCommandsSource 238 //------------------------------------------------------------------------- 239 240 class CommandObjectCommandsSource : public CommandObjectParsed 241 { 242 public: 243 CommandObjectCommandsSource(CommandInterpreter &interpreter) : 244 CommandObjectParsed (interpreter, 245 "command source", 246 "Read in debugger commands from the file <filename> and execute them.", 247 NULL), 248 m_options (interpreter) 249 { 250 CommandArgumentEntry arg; 251 CommandArgumentData file_arg; 252 253 // Define the first (and only) variant of this arg. 254 file_arg.arg_type = eArgTypeFilename; 255 file_arg.arg_repetition = eArgRepeatPlain; 256 257 // There is only one variant this argument could be; put it into the argument entry. 258 arg.push_back (file_arg); 259 260 // Push the data for the first argument into the m_arguments vector. 261 m_arguments.push_back (arg); 262 } 263 264 ~CommandObjectCommandsSource () {} 265 266 virtual const char* 267 GetRepeatCommand (Args ¤t_command_args, uint32_t index) 268 { 269 return ""; 270 } 271 272 virtual int 273 HandleArgumentCompletion (Args &input, 274 int &cursor_index, 275 int &cursor_char_position, 276 OptionElementVector &opt_element_vector, 277 int match_start_point, 278 int max_return_elements, 279 bool &word_complete, 280 StringList &matches) 281 { 282 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 283 completion_str.erase (cursor_char_position); 284 285 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 286 CommandCompletions::eDiskFileCompletion, 287 completion_str.c_str(), 288 match_start_point, 289 max_return_elements, 290 NULL, 291 word_complete, 292 matches); 293 return matches.GetSize(); 294 } 295 296 virtual Options * 297 GetOptions () 298 { 299 return &m_options; 300 } 301 302 protected: 303 304 class CommandOptions : public Options 305 { 306 public: 307 308 CommandOptions (CommandInterpreter &interpreter) : 309 Options (interpreter), 310 m_stop_on_error (true), 311 m_silent_run (false), 312 m_stop_on_continue (true) 313 { 314 } 315 316 virtual 317 ~CommandOptions (){} 318 319 virtual Error 320 SetOptionValue (uint32_t option_idx, const char *option_arg) 321 { 322 Error error; 323 const int short_option = m_getopt_table[option_idx].val; 324 325 switch (short_option) 326 { 327 case 'e': 328 error = m_stop_on_error.SetValueFromString(option_arg); 329 break; 330 331 case 'c': 332 error = m_stop_on_continue.SetValueFromString(option_arg); 333 break; 334 335 case 's': 336 error = m_silent_run.SetValueFromString(option_arg); 337 break; 338 339 default: 340 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 341 break; 342 } 343 344 return error; 345 } 346 347 void 348 OptionParsingStarting () 349 { 350 m_stop_on_error.Clear(); 351 m_silent_run.Clear(); 352 m_stop_on_continue.Clear(); 353 } 354 355 const OptionDefinition* 356 GetDefinitions () 357 { 358 return g_option_table; 359 } 360 361 // Options table: Required for subclasses of Options. 362 363 static OptionDefinition g_option_table[]; 364 365 // Instance variables to hold the values for command options. 366 367 OptionValueBoolean m_stop_on_error; 368 OptionValueBoolean m_silent_run; 369 OptionValueBoolean m_stop_on_continue; 370 }; 371 372 bool 373 DoExecute(Args& command, CommandReturnObject &result) 374 { 375 const size_t argc = command.GetArgumentCount(); 376 if (argc == 1) 377 { 378 const char *filename = command.GetArgumentAtIndex(0); 379 380 FileSpec cmd_file (filename, true); 381 ExecutionContext *exe_ctx = NULL; // Just use the default context. 382 383 // If any options were set, then use them 384 if (m_options.m_stop_on_error.OptionWasSet() || 385 m_options.m_silent_run.OptionWasSet() || 386 m_options.m_stop_on_continue.OptionWasSet()) 387 { 388 // Use user set settings 389 CommandInterpreterRunOptions options; 390 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue()); 391 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue()); 392 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue()); 393 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue()); 394 395 m_interpreter.HandleCommandsFromFile (cmd_file, 396 exe_ctx, 397 options, 398 result); 399 400 } 401 else 402 { 403 // No options were set, inherit any settings from nested "command source" commands, 404 // or set to sane default settings... 405 CommandInterpreterRunOptions options; 406 m_interpreter.HandleCommandsFromFile (cmd_file, 407 exe_ctx, 408 options, 409 result); 410 411 } 412 } 413 else 414 { 415 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName()); 416 result.SetStatus (eReturnStatusFailed); 417 } 418 return result.Succeeded(); 419 420 } 421 CommandOptions m_options; 422 }; 423 424 OptionDefinition 425 CommandObjectCommandsSource::CommandOptions::g_option_table[] = 426 { 427 { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 428 { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 429 { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."}, 430 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 431 }; 432 433 #pragma mark CommandObjectCommandsAlias 434 //------------------------------------------------------------------------- 435 // CommandObjectCommandsAlias 436 //------------------------------------------------------------------------- 437 438 static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 439 "You must define a Python function with this signature:\n" 440 "def my_command_impl(debugger, args, result, internal_dict):\n"; 441 442 443 class CommandObjectCommandsAlias : public CommandObjectRaw 444 { 445 446 447 public: 448 CommandObjectCommandsAlias (CommandInterpreter &interpreter) : 449 CommandObjectRaw (interpreter, 450 "command alias", 451 "Allow users to define their own debugger command abbreviations.", 452 NULL) 453 { 454 SetHelpLong( 455 "'alias' allows the user to create a short-cut or abbreviation for long \n\ 456 commands, multi-word commands, and commands that take particular options. \n\ 457 Below are some simple examples of how one might use the 'alias' command: \n\ 458 \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ 459 // command. \n\ 460 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ 461 // command. Since breakpoint commands are two-word \n\ 462 // commands, the user will still need to enter the \n\ 463 // second word after 'bp', e.g. 'bp enable' or \n\ 464 // 'bp delete'. \n\ 465 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\ 466 // two-word command 'breakpoint list'. \n\ 467 \nAn alias can include some options for the command, with the values either \n\ 468 filled in at the time the alias is created, or specified as positional \n\ 469 arguments, to be filled in when the alias is invoked. The following example \n\ 470 shows how to create aliases with options: \n\ 471 \n\ 472 'command alias bfl breakpoint set -f %1 -l %2' \n\ 473 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\ 474 options already part of the alias. So if the user wants to set a breakpoint \n\ 475 by file and line without explicitly having to use the -f and -l options, the \n\ 476 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\ 477 for the actual arguments that will be passed when the alias command is used. \n\ 478 The number in the placeholder refers to the position/order the actual value \n\ 479 occupies when the alias is used. All the occurrences of '%1' in the alias \n\ 480 will be replaced with the first argument, all the occurrences of '%2' in the \n\ 481 alias will be replaced with the second argument, and so on. This also allows \n\ 482 actual arguments to be used multiple times within an alias (see 'process \n\ 483 launch' example below). \n\ 484 Note: the positional arguments must substitute as whole words in the resultant\n\ 485 command, so you can't at present do something like:\n\ 486 \n\ 487 command alias bcppfl breakpoint set -f %1.cpp -l %2\n\ 488 \n\ 489 to get the file extension \".cpp\" automatically appended. For more complex\n\ 490 aliasing, use the \"command regex\" command instead.\n\ 491 \nSo in the 'bfl' case, the actual file value will be \n\ 492 filled in with the first argument following 'bfl' and the actual line number \n\ 493 value will be filled in with the second argument. The user would use this \n\ 494 alias as follows: \n\ 495 \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\ 496 <... some time later ...> \n\ 497 (lldb) bfl my-file.c 137 \n\ 498 \nThis would be the same as if the user had entered \n\ 499 'breakpoint set -f my-file.c -l 137'. \n\ 500 \nAnother example: \n\ 501 \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\ 502 (lldb) pltty /dev/tty0 \n\ 503 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\ 504 \nIf the user always wanted to pass the same value to a particular option, the \n\ 505 alias could be defined with that value directly in the alias as a constant, \n\ 506 rather than using a positional placeholder: \n\ 507 \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\ 508 // 3 of whatever file is indicated. \n"); 509 510 CommandArgumentEntry arg1; 511 CommandArgumentEntry arg2; 512 CommandArgumentEntry arg3; 513 CommandArgumentData alias_arg; 514 CommandArgumentData cmd_arg; 515 CommandArgumentData options_arg; 516 517 // Define the first (and only) variant of this arg. 518 alias_arg.arg_type = eArgTypeAliasName; 519 alias_arg.arg_repetition = eArgRepeatPlain; 520 521 // There is only one variant this argument could be; put it into the argument entry. 522 arg1.push_back (alias_arg); 523 524 // Define the first (and only) variant of this arg. 525 cmd_arg.arg_type = eArgTypeCommandName; 526 cmd_arg.arg_repetition = eArgRepeatPlain; 527 528 // There is only one variant this argument could be; put it into the argument entry. 529 arg2.push_back (cmd_arg); 530 531 // Define the first (and only) variant of this arg. 532 options_arg.arg_type = eArgTypeAliasOptions; 533 options_arg.arg_repetition = eArgRepeatOptional; 534 535 // There is only one variant this argument could be; put it into the argument entry. 536 arg3.push_back (options_arg); 537 538 // Push the data for the first argument into the m_arguments vector. 539 m_arguments.push_back (arg1); 540 m_arguments.push_back (arg2); 541 m_arguments.push_back (arg3); 542 } 543 544 ~CommandObjectCommandsAlias () 545 { 546 } 547 548 protected: 549 virtual bool 550 DoExecute (const char *raw_command_line, CommandReturnObject &result) 551 { 552 Args args (raw_command_line); 553 std::string raw_command_string (raw_command_line); 554 555 size_t argc = args.GetArgumentCount(); 556 557 if (argc < 2) 558 { 559 result.AppendError ("'alias' requires at least two arguments"); 560 result.SetStatus (eReturnStatusFailed); 561 return false; 562 } 563 564 // Get the alias command. 565 566 const std::string alias_command = args.GetArgumentAtIndex (0); 567 568 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which 569 // does the stripping itself. 570 size_t pos = raw_command_string.find (alias_command); 571 if (pos == 0) 572 { 573 raw_command_string = raw_command_string.substr (alias_command.size()); 574 pos = raw_command_string.find_first_not_of (' '); 575 if ((pos != std::string::npos) && (pos > 0)) 576 raw_command_string = raw_command_string.substr (pos); 577 } 578 else 579 { 580 result.AppendError ("Error parsing command string. No alias created."); 581 result.SetStatus (eReturnStatusFailed); 582 return false; 583 } 584 585 586 // Verify that the command is alias-able. 587 if (m_interpreter.CommandExists (alias_command.c_str())) 588 { 589 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 590 alias_command.c_str()); 591 result.SetStatus (eReturnStatusFailed); 592 return false; 593 } 594 595 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. 596 // raw_command_string is returned with the name of the command object stripped off the front. 597 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); 598 599 if (!cmd_obj) 600 { 601 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command." 602 " No alias created.", raw_command_string.c_str()); 603 result.SetStatus (eReturnStatusFailed); 604 return false; 605 } 606 else if (!cmd_obj->WantsRawCommandString ()) 607 { 608 // Note that args was initialized with the original command, and has not been updated to this point. 609 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. 610 return HandleAliasingNormalCommand (args, result); 611 } 612 else 613 { 614 return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result); 615 } 616 return result.Succeeded(); 617 } 618 619 bool 620 HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result) 621 { 622 // Verify & handle any options/arguments passed to the alias command 623 624 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 625 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 626 627 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false); 628 629 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp)) 630 { 631 result.AppendError ("Unable to create requested alias.\n"); 632 result.SetStatus (eReturnStatusFailed); 633 return false; 634 } 635 636 // Create the alias 637 if (m_interpreter.AliasExists (alias_command.c_str()) 638 || m_interpreter.UserCommandExists (alias_command.c_str())) 639 { 640 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 641 if (temp_option_arg_sp.get()) 642 { 643 if (option_arg_vector->size() == 0) 644 m_interpreter.RemoveAliasOptions (alias_command.c_str()); 645 } 646 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 647 alias_command.c_str()); 648 } 649 650 if (cmd_obj_sp) 651 { 652 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp); 653 if (option_arg_vector->size() > 0) 654 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 655 result.SetStatus (eReturnStatusSuccessFinishNoResult); 656 } 657 else 658 { 659 result.AppendError ("Unable to create requested alias.\n"); 660 result.SetStatus (eReturnStatusFailed); 661 } 662 return result.Succeeded (); 663 } 664 665 bool 666 HandleAliasingNormalCommand (Args& args, CommandReturnObject &result) 667 { 668 size_t argc = args.GetArgumentCount(); 669 670 if (argc < 2) 671 { 672 result.AppendError ("'alias' requires at least two arguments"); 673 result.SetStatus (eReturnStatusFailed); 674 return false; 675 } 676 677 const std::string alias_command = args.GetArgumentAtIndex(0); 678 const std::string actual_command = args.GetArgumentAtIndex(1); 679 680 args.Shift(); // Shift the alias command word off the argument vector. 681 args.Shift(); // Shift the old command word off the argument vector. 682 683 // Verify that the command is alias'able, and get the appropriate command object. 684 685 if (m_interpreter.CommandExists (alias_command.c_str())) 686 { 687 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 688 alias_command.c_str()); 689 result.SetStatus (eReturnStatusFailed); 690 } 691 else 692 { 693 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true)); 694 CommandObjectSP subcommand_obj_sp; 695 bool use_subcommand = false; 696 if (command_obj_sp.get()) 697 { 698 CommandObject *cmd_obj = command_obj_sp.get(); 699 CommandObject *sub_cmd_obj = NULL; 700 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 701 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 702 703 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) 704 { 705 if (argc >= 3) 706 { 707 const std::string sub_command = args.GetArgumentAtIndex(0); 708 assert (sub_command.length() != 0); 709 subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str()); 710 if (subcommand_obj_sp.get()) 711 { 712 sub_cmd_obj = subcommand_obj_sp.get(); 713 use_subcommand = true; 714 args.Shift(); // Shift the sub_command word off the argument vector. 715 cmd_obj = sub_cmd_obj; 716 } 717 else 718 { 719 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. " 720 "Unable to create alias.\n", 721 sub_command.c_str(), actual_command.c_str()); 722 result.SetStatus (eReturnStatusFailed); 723 return false; 724 } 725 } 726 } 727 728 // Verify & handle any options/arguments passed to the alias command 729 730 if (args.GetArgumentCount () > 0) 731 { 732 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 733 if (use_subcommand) 734 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); 735 736 std::string args_string; 737 args.GetCommandString (args_string); 738 739 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp)) 740 { 741 result.AppendError ("Unable to create requested alias.\n"); 742 result.SetStatus (eReturnStatusFailed); 743 return false; 744 } 745 } 746 747 // Create the alias. 748 749 if (m_interpreter.AliasExists (alias_command.c_str()) 750 || m_interpreter.UserCommandExists (alias_command.c_str())) 751 { 752 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 753 if (tmp_option_arg_sp.get()) 754 { 755 if (option_arg_vector->size() == 0) 756 m_interpreter.RemoveAliasOptions (alias_command.c_str()); 757 } 758 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 759 alias_command.c_str()); 760 } 761 762 if (use_subcommand) 763 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp); 764 else 765 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp); 766 if (option_arg_vector->size() > 0) 767 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 768 result.SetStatus (eReturnStatusSuccessFinishNoResult); 769 } 770 else 771 { 772 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str()); 773 result.SetStatus (eReturnStatusFailed); 774 return false; 775 } 776 } 777 778 return result.Succeeded(); 779 } 780 781 }; 782 783 #pragma mark CommandObjectCommandsUnalias 784 //------------------------------------------------------------------------- 785 // CommandObjectCommandsUnalias 786 //------------------------------------------------------------------------- 787 788 class CommandObjectCommandsUnalias : public CommandObjectParsed 789 { 790 public: 791 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) : 792 CommandObjectParsed (interpreter, 793 "command unalias", 794 "Allow the user to remove/delete a user-defined command abbreviation.", 795 NULL) 796 { 797 CommandArgumentEntry arg; 798 CommandArgumentData alias_arg; 799 800 // Define the first (and only) variant of this arg. 801 alias_arg.arg_type = eArgTypeAliasName; 802 alias_arg.arg_repetition = eArgRepeatPlain; 803 804 // There is only one variant this argument could be; put it into the argument entry. 805 arg.push_back (alias_arg); 806 807 // Push the data for the first argument into the m_arguments vector. 808 m_arguments.push_back (arg); 809 } 810 811 ~CommandObjectCommandsUnalias() 812 { 813 } 814 815 protected: 816 bool 817 DoExecute (Args& args, CommandReturnObject &result) 818 { 819 CommandObject::CommandMap::iterator pos; 820 CommandObject *cmd_obj; 821 822 if (args.GetArgumentCount() != 0) 823 { 824 const char *command_name = args.GetArgumentAtIndex(0); 825 cmd_obj = m_interpreter.GetCommandObject(command_name); 826 if (cmd_obj) 827 { 828 if (m_interpreter.CommandExists (command_name)) 829 { 830 if (cmd_obj->IsRemovable()) 831 { 832 result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n", 833 command_name); 834 } 835 else 836 { 837 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 838 command_name); 839 } 840 result.SetStatus (eReturnStatusFailed); 841 } 842 else 843 { 844 845 if (m_interpreter.RemoveAlias (command_name) == false) 846 { 847 if (m_interpreter.AliasExists (command_name)) 848 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n", 849 command_name); 850 else 851 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name); 852 result.SetStatus (eReturnStatusFailed); 853 } 854 else 855 result.SetStatus (eReturnStatusSuccessFinishNoResult); 856 } 857 } 858 else 859 { 860 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a " 861 "current list of commands.\n", 862 command_name); 863 result.SetStatus (eReturnStatusFailed); 864 } 865 } 866 else 867 { 868 result.AppendError ("must call 'unalias' with a valid alias"); 869 result.SetStatus (eReturnStatusFailed); 870 } 871 872 return result.Succeeded(); 873 } 874 }; 875 876 #pragma mark CommandObjectCommandsDelete 877 //------------------------------------------------------------------------- 878 // CommandObjectCommandsDelete 879 //------------------------------------------------------------------------- 880 881 class CommandObjectCommandsDelete : public CommandObjectParsed 882 { 883 public: 884 CommandObjectCommandsDelete (CommandInterpreter &interpreter) : 885 CommandObjectParsed (interpreter, 886 "command delete", 887 "Allow the user to delete user-defined regular expression, python or multi-word commands.", 888 NULL) 889 { 890 CommandArgumentEntry arg; 891 CommandArgumentData alias_arg; 892 893 // Define the first (and only) variant of this arg. 894 alias_arg.arg_type = eArgTypeCommandName; 895 alias_arg.arg_repetition = eArgRepeatPlain; 896 897 // There is only one variant this argument could be; put it into the argument entry. 898 arg.push_back (alias_arg); 899 900 // Push the data for the first argument into the m_arguments vector. 901 m_arguments.push_back (arg); 902 } 903 904 ~CommandObjectCommandsDelete() 905 { 906 } 907 908 protected: 909 bool 910 DoExecute (Args& args, CommandReturnObject &result) 911 { 912 CommandObject::CommandMap::iterator pos; 913 914 if (args.GetArgumentCount() != 0) 915 { 916 const char *command_name = args.GetArgumentAtIndex(0); 917 if (m_interpreter.CommandExists (command_name)) 918 { 919 if (m_interpreter.RemoveCommand (command_name)) 920 { 921 result.SetStatus (eReturnStatusSuccessFinishNoResult); 922 } 923 else 924 { 925 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 926 command_name); 927 result.SetStatus (eReturnStatusFailed); 928 } 929 } 930 else 931 { 932 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n", 933 command_name); 934 result.SetStatus (eReturnStatusFailed); 935 } 936 } 937 else 938 { 939 result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ()); 940 result.SetStatus (eReturnStatusFailed); 941 } 942 943 return result.Succeeded(); 944 } 945 }; 946 947 //------------------------------------------------------------------------- 948 // CommandObjectCommandsAddRegex 949 //------------------------------------------------------------------------- 950 #pragma mark CommandObjectCommandsAddRegex 951 952 class CommandObjectCommandsAddRegex : 953 public CommandObjectParsed, 954 public IOHandlerDelegateMultiline 955 { 956 public: 957 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 958 CommandObjectParsed (interpreter, 959 "command regex", 960 "Allow the user to create a regular expression command.", 961 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 962 IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand), 963 m_options (interpreter) 964 { 965 SetHelpLong( 966 "This command allows the user to create powerful regular expression commands\n" 967 "with substitutions. The regular expressions and substitutions are specified\n" 968 "using the regular expression substitution format of:\n" 969 "\n" 970 " s/<regex>/<subst>/\n" 971 "\n" 972 "<regex> is a regular expression that can use parenthesis to capture regular\n" 973 "expression input and substitute the captured matches in the output using %1\n" 974 "for the first match, %2 for the second, and so on.\n" 975 "\n" 976 "The regular expressions can all be specified on the command line if more than\n" 977 "one argument is provided. If just the command name is provided on the command\n" 978 "line, then the regular expressions and substitutions can be entered on separate\n" 979 " lines, followed by an empty line to terminate the command definition.\n" 980 "\n" 981 "EXAMPLES\n" 982 "\n" 983 "The following example will define a regular expression command named 'f' that\n" 984 "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n" 985 "a number follows 'f':\n" 986 "\n" 987 " (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n" 988 "\n" 989 ); 990 } 991 992 ~CommandObjectCommandsAddRegex() 993 { 994 } 995 996 997 protected: 998 999 void 1000 IOHandlerActivated (IOHandler &io_handler) override 1001 { 1002 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 1003 if (output_sp) 1004 { 1005 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"); 1006 output_sp->Flush(); 1007 } 1008 } 1009 1010 void 1011 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override 1012 { 1013 io_handler.SetIsDone(true); 1014 if (m_regex_cmd_ap.get()) 1015 { 1016 StringList lines; 1017 if (lines.SplitIntoLines (data)) 1018 { 1019 const size_t num_lines = lines.GetSize(); 1020 bool check_only = false; 1021 for (size_t i=0; i<num_lines; ++i) 1022 { 1023 llvm::StringRef bytes_strref (lines[i]); 1024 Error error = AppendRegexSubstitution (bytes_strref, check_only); 1025 if (error.Fail()) 1026 { 1027 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) 1028 { 1029 StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream(); 1030 out_stream->Printf("error: %s\n", error.AsCString()); 1031 } 1032 } 1033 } 1034 } 1035 if (m_regex_cmd_ap->HasRegexEntries()) 1036 { 1037 CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 1038 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 1039 } 1040 } 1041 } 1042 1043 bool 1044 DoExecute (Args& command, CommandReturnObject &result) override 1045 { 1046 const size_t argc = command.GetArgumentCount(); 1047 if (argc == 0) 1048 { 1049 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 1050 result.SetStatus (eReturnStatusFailed); 1051 } 1052 else 1053 { 1054 Error error; 1055 const char *name = command.GetArgumentAtIndex(0); 1056 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 1057 name, 1058 m_options.GetHelp (), 1059 m_options.GetSyntax (), 1060 10, 1061 0, 1062 true)); 1063 1064 if (argc == 1) 1065 { 1066 Debugger &debugger = m_interpreter.GetDebugger(); 1067 bool color_prompt = debugger.GetUseColor(); 1068 const bool multiple_lines = true; // Get multiple lines 1069 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 1070 IOHandler::Type::Other, 1071 "lldb-regex", // Name of input reader for history 1072 "> ", // Prompt 1073 NULL, // Continuation prompt 1074 multiple_lines, 1075 color_prompt, 1076 0, // Don't show line numbers 1077 *this)); 1078 1079 if (io_handler_sp) 1080 { 1081 debugger.PushIOHandler(io_handler_sp); 1082 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1083 } 1084 } 1085 else 1086 { 1087 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 1088 { 1089 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 1090 bool check_only = false; 1091 error = AppendRegexSubstitution (arg_strref, check_only); 1092 if (error.Fail()) 1093 break; 1094 } 1095 1096 if (error.Success()) 1097 { 1098 AddRegexCommandToInterpreter(); 1099 } 1100 } 1101 if (error.Fail()) 1102 { 1103 result.AppendError (error.AsCString()); 1104 result.SetStatus (eReturnStatusFailed); 1105 } 1106 } 1107 1108 return result.Succeeded(); 1109 } 1110 1111 Error 1112 AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only) 1113 { 1114 Error error; 1115 1116 if (m_regex_cmd_ap.get() == NULL) 1117 { 1118 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 1119 (int)regex_sed.size(), 1120 regex_sed.data()); 1121 return error; 1122 } 1123 1124 size_t regex_sed_size = regex_sed.size(); 1125 1126 if (regex_sed_size <= 1) 1127 { 1128 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 1129 (int)regex_sed.size(), 1130 regex_sed.data()); 1131 return error; 1132 } 1133 1134 if (regex_sed[0] != 's') 1135 { 1136 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 1137 (int)regex_sed.size(), 1138 regex_sed.data()); 1139 return error; 1140 } 1141 const size_t first_separator_char_pos = 1; 1142 // use the char that follows 's' as the regex separator character 1143 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 1144 const char separator_char = regex_sed[first_separator_char_pos]; 1145 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 1146 1147 if (second_separator_char_pos == std::string::npos) 1148 { 1149 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'", 1150 separator_char, 1151 (int)(regex_sed.size() - first_separator_char_pos - 1), 1152 regex_sed.data() + (first_separator_char_pos + 1), 1153 (int)regex_sed.size(), 1154 regex_sed.data()); 1155 return error; 1156 } 1157 1158 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 1159 1160 if (third_separator_char_pos == std::string::npos) 1161 { 1162 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'", 1163 separator_char, 1164 (int)(regex_sed.size() - second_separator_char_pos - 1), 1165 regex_sed.data() + (second_separator_char_pos + 1), 1166 (int)regex_sed.size(), 1167 regex_sed.data()); 1168 return error; 1169 } 1170 1171 if (third_separator_char_pos != regex_sed_size - 1) 1172 { 1173 // Make sure that everything that follows the last regex 1174 // separator char 1175 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 1176 { 1177 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 1178 (int)third_separator_char_pos + 1, 1179 regex_sed.data(), 1180 (int)(regex_sed.size() - third_separator_char_pos - 1), 1181 regex_sed.data() + (third_separator_char_pos + 1)); 1182 return error; 1183 } 1184 1185 } 1186 else if (first_separator_char_pos + 1 == second_separator_char_pos) 1187 { 1188 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 1189 separator_char, 1190 separator_char, 1191 separator_char, 1192 (int)regex_sed.size(), 1193 regex_sed.data()); 1194 return error; 1195 } 1196 else if (second_separator_char_pos + 1 == third_separator_char_pos) 1197 { 1198 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 1199 separator_char, 1200 separator_char, 1201 separator_char, 1202 (int)regex_sed.size(), 1203 regex_sed.data()); 1204 return error; 1205 } 1206 1207 if (check_only == false) 1208 { 1209 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 1210 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 1211 m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 1212 subst.c_str()); 1213 } 1214 return error; 1215 } 1216 1217 void 1218 AddRegexCommandToInterpreter() 1219 { 1220 if (m_regex_cmd_ap.get()) 1221 { 1222 if (m_regex_cmd_ap->HasRegexEntries()) 1223 { 1224 CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 1225 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 1226 } 1227 } 1228 } 1229 1230 private: 1231 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1232 1233 class CommandOptions : public Options 1234 { 1235 public: 1236 1237 CommandOptions (CommandInterpreter &interpreter) : 1238 Options (interpreter) 1239 { 1240 } 1241 1242 virtual 1243 ~CommandOptions (){} 1244 1245 virtual Error 1246 SetOptionValue (uint32_t option_idx, const char *option_arg) 1247 { 1248 Error error; 1249 const int short_option = m_getopt_table[option_idx].val; 1250 1251 switch (short_option) 1252 { 1253 case 'h': 1254 m_help.assign (option_arg); 1255 break; 1256 case 's': 1257 m_syntax.assign (option_arg); 1258 break; 1259 1260 default: 1261 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1262 break; 1263 } 1264 1265 return error; 1266 } 1267 1268 void 1269 OptionParsingStarting () 1270 { 1271 m_help.clear(); 1272 m_syntax.clear(); 1273 } 1274 1275 const OptionDefinition* 1276 GetDefinitions () 1277 { 1278 return g_option_table; 1279 } 1280 1281 // Options table: Required for subclasses of Options. 1282 1283 static OptionDefinition g_option_table[]; 1284 1285 const char * 1286 GetHelp () 1287 { 1288 if (m_help.empty()) 1289 return NULL; 1290 return m_help.c_str(); 1291 } 1292 const char * 1293 GetSyntax () 1294 { 1295 if (m_syntax.empty()) 1296 return NULL; 1297 return m_syntax.c_str(); 1298 } 1299 // Instance variables to hold the values for command options. 1300 protected: 1301 std::string m_help; 1302 std::string m_syntax; 1303 }; 1304 1305 Options * 1306 GetOptions () override 1307 { 1308 return &m_options; 1309 } 1310 1311 CommandOptions m_options; 1312 }; 1313 1314 OptionDefinition 1315 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1316 { 1317 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1318 { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1319 { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL } 1320 }; 1321 1322 1323 class CommandObjectPythonFunction : public CommandObjectRaw 1324 { 1325 private: 1326 std::string m_function_name; 1327 ScriptedCommandSynchronicity m_synchro; 1328 bool m_fetched_help_long; 1329 1330 public: 1331 1332 CommandObjectPythonFunction (CommandInterpreter &interpreter, 1333 std::string name, 1334 std::string funct, 1335 std::string help, 1336 ScriptedCommandSynchronicity synch) : 1337 CommandObjectRaw (interpreter, 1338 name.c_str(), 1339 NULL, 1340 NULL), 1341 m_function_name(funct), 1342 m_synchro(synch), 1343 m_fetched_help_long(false) 1344 { 1345 if (!help.empty()) 1346 SetHelp(help.c_str()); 1347 else 1348 { 1349 StreamString stream; 1350 stream.Printf("For more information run 'help %s'",name.c_str()); 1351 SetHelp(stream.GetData()); 1352 } 1353 } 1354 1355 virtual 1356 ~CommandObjectPythonFunction () 1357 { 1358 } 1359 1360 virtual bool 1361 IsRemovable () const 1362 { 1363 return true; 1364 } 1365 1366 const std::string& 1367 GetFunctionName () 1368 { 1369 return m_function_name; 1370 } 1371 1372 ScriptedCommandSynchronicity 1373 GetSynchronicity () 1374 { 1375 return m_synchro; 1376 } 1377 1378 virtual const char * 1379 GetHelpLong () 1380 { 1381 if (!m_fetched_help_long) 1382 { 1383 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1384 if (scripter) 1385 { 1386 std::string docstring; 1387 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1388 if (!docstring.empty()) 1389 SetHelpLong(docstring); 1390 } 1391 } 1392 return CommandObjectRaw::GetHelpLong(); 1393 } 1394 1395 protected: 1396 virtual bool 1397 DoExecute (const char *raw_command_line, CommandReturnObject &result) 1398 { 1399 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1400 1401 Error error; 1402 1403 result.SetStatus(eReturnStatusInvalid); 1404 1405 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1406 raw_command_line, 1407 m_synchro, 1408 result, 1409 error, 1410 m_exe_ctx) == false) 1411 { 1412 result.AppendError(error.AsCString()); 1413 result.SetStatus(eReturnStatusFailed); 1414 } 1415 else 1416 { 1417 // Don't change the status if the command already set it... 1418 if (result.GetStatus() == eReturnStatusInvalid) 1419 { 1420 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1421 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1422 else 1423 result.SetStatus(eReturnStatusSuccessFinishResult); 1424 } 1425 } 1426 1427 return result.Succeeded(); 1428 } 1429 1430 }; 1431 1432 class CommandObjectScriptingObject : public CommandObjectRaw 1433 { 1434 private: 1435 StructuredData::GenericSP m_cmd_obj_sp; 1436 ScriptedCommandSynchronicity m_synchro; 1437 bool m_fetched_help_short:1; 1438 bool m_fetched_help_long:1; 1439 1440 public: 1441 1442 CommandObjectScriptingObject (CommandInterpreter &interpreter, 1443 std::string name, 1444 StructuredData::GenericSP cmd_obj_sp, 1445 ScriptedCommandSynchronicity synch) : 1446 CommandObjectRaw (interpreter, 1447 name.c_str(), 1448 NULL, 1449 NULL), 1450 m_cmd_obj_sp(cmd_obj_sp), 1451 m_synchro(synch), 1452 m_fetched_help_short(false), 1453 m_fetched_help_long(false) 1454 { 1455 StreamString stream; 1456 stream.Printf("For more information run 'help %s'",name.c_str()); 1457 SetHelp(stream.GetData()); 1458 } 1459 1460 virtual 1461 ~CommandObjectScriptingObject () 1462 { 1463 } 1464 1465 virtual bool 1466 IsRemovable () const 1467 { 1468 return true; 1469 } 1470 1471 StructuredData::GenericSP 1472 GetImplementingObject () 1473 { 1474 return m_cmd_obj_sp; 1475 } 1476 1477 ScriptedCommandSynchronicity 1478 GetSynchronicity () 1479 { 1480 return m_synchro; 1481 } 1482 1483 virtual const char * 1484 GetHelp () 1485 { 1486 if (!m_fetched_help_short) 1487 { 1488 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1489 if (scripter) 1490 { 1491 std::string docstring; 1492 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring); 1493 if (!docstring.empty()) 1494 SetHelp(docstring); 1495 } 1496 } 1497 return CommandObjectRaw::GetHelp(); 1498 } 1499 1500 virtual const char * 1501 GetHelpLong () 1502 { 1503 if (!m_fetched_help_long) 1504 { 1505 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1506 if (scripter) 1507 { 1508 std::string docstring; 1509 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring); 1510 if (!docstring.empty()) 1511 SetHelpLong(docstring); 1512 } 1513 } 1514 return CommandObjectRaw::GetHelpLong(); 1515 } 1516 1517 protected: 1518 virtual bool 1519 DoExecute (const char *raw_command_line, CommandReturnObject &result) 1520 { 1521 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1522 1523 Error error; 1524 1525 result.SetStatus(eReturnStatusInvalid); 1526 1527 if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp, 1528 raw_command_line, 1529 m_synchro, 1530 result, 1531 error, 1532 m_exe_ctx) == false) 1533 { 1534 result.AppendError(error.AsCString()); 1535 result.SetStatus(eReturnStatusFailed); 1536 } 1537 else 1538 { 1539 // Don't change the status if the command already set it... 1540 if (result.GetStatus() == eReturnStatusInvalid) 1541 { 1542 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1543 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1544 else 1545 result.SetStatus(eReturnStatusSuccessFinishResult); 1546 } 1547 } 1548 1549 return result.Succeeded(); 1550 } 1551 1552 }; 1553 1554 //------------------------------------------------------------------------- 1555 // CommandObjectCommandsScriptImport 1556 //------------------------------------------------------------------------- 1557 1558 class CommandObjectCommandsScriptImport : public CommandObjectParsed 1559 { 1560 public: 1561 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 1562 CommandObjectParsed (interpreter, 1563 "command script import", 1564 "Import a scripting module in LLDB.", 1565 NULL), 1566 m_options(interpreter) 1567 { 1568 CommandArgumentEntry arg1; 1569 CommandArgumentData cmd_arg; 1570 1571 // Define the first (and only) variant of this arg. 1572 cmd_arg.arg_type = eArgTypeFilename; 1573 cmd_arg.arg_repetition = eArgRepeatPlain; 1574 1575 // There is only one variant this argument could be; put it into the argument entry. 1576 arg1.push_back (cmd_arg); 1577 1578 // Push the data for the first argument into the m_arguments vector. 1579 m_arguments.push_back (arg1); 1580 } 1581 1582 ~CommandObjectCommandsScriptImport () 1583 { 1584 } 1585 1586 virtual int 1587 HandleArgumentCompletion (Args &input, 1588 int &cursor_index, 1589 int &cursor_char_position, 1590 OptionElementVector &opt_element_vector, 1591 int match_start_point, 1592 int max_return_elements, 1593 bool &word_complete, 1594 StringList &matches) 1595 { 1596 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1597 completion_str.erase (cursor_char_position); 1598 1599 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1600 CommandCompletions::eDiskFileCompletion, 1601 completion_str.c_str(), 1602 match_start_point, 1603 max_return_elements, 1604 NULL, 1605 word_complete, 1606 matches); 1607 return matches.GetSize(); 1608 } 1609 1610 virtual Options * 1611 GetOptions () 1612 { 1613 return &m_options; 1614 } 1615 1616 protected: 1617 1618 class CommandOptions : public Options 1619 { 1620 public: 1621 1622 CommandOptions (CommandInterpreter &interpreter) : 1623 Options (interpreter) 1624 { 1625 } 1626 1627 virtual 1628 ~CommandOptions (){} 1629 1630 virtual Error 1631 SetOptionValue (uint32_t option_idx, const char *option_arg) 1632 { 1633 Error error; 1634 const int short_option = m_getopt_table[option_idx].val; 1635 1636 switch (short_option) 1637 { 1638 case 'r': 1639 m_allow_reload = true; 1640 break; 1641 default: 1642 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1643 break; 1644 } 1645 1646 return error; 1647 } 1648 1649 void 1650 OptionParsingStarting () 1651 { 1652 m_allow_reload = true; 1653 } 1654 1655 const OptionDefinition* 1656 GetDefinitions () 1657 { 1658 return g_option_table; 1659 } 1660 1661 // Options table: Required for subclasses of Options. 1662 1663 static OptionDefinition g_option_table[]; 1664 1665 // Instance variables to hold the values for command options. 1666 1667 bool m_allow_reload; 1668 }; 1669 1670 bool 1671 DoExecute (Args& command, CommandReturnObject &result) 1672 { 1673 1674 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1675 { 1676 result.AppendError ("only scripting language supported for module importing is currently Python"); 1677 result.SetStatus (eReturnStatusFailed); 1678 return false; 1679 } 1680 1681 size_t argc = command.GetArgumentCount(); 1682 1683 if (argc != 1) 1684 { 1685 result.AppendError ("'command script import' requires one argument"); 1686 result.SetStatus (eReturnStatusFailed); 1687 return false; 1688 } 1689 1690 std::string path = command.GetArgumentAtIndex(0); 1691 Error error; 1692 1693 const bool init_session = true; 1694 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1695 // commands won't ever be recursively invoked, but it's actually possible to craft 1696 // a Python script that does other "command script imports" in __lldb_init_module 1697 // the real fix is to have recursive commands possible with a CommandInvocation object 1698 // separate from the CommandObject itself, so that recursive command invocations 1699 // won't stomp on each other (wrt to execution contents, options, and more) 1700 m_exe_ctx.Clear(); 1701 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 1702 m_options.m_allow_reload, 1703 init_session, 1704 error)) 1705 { 1706 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1707 } 1708 else 1709 { 1710 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1711 result.SetStatus (eReturnStatusFailed); 1712 } 1713 1714 return result.Succeeded(); 1715 } 1716 1717 CommandOptions m_options; 1718 }; 1719 1720 OptionDefinition 1721 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 1722 { 1723 { 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."}, 1724 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1725 }; 1726 1727 1728 //------------------------------------------------------------------------- 1729 // CommandObjectCommandsScriptAdd 1730 //------------------------------------------------------------------------- 1731 1732 class CommandObjectCommandsScriptAdd : 1733 public CommandObjectParsed, 1734 public IOHandlerDelegateMultiline 1735 { 1736 public: 1737 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 1738 CommandObjectParsed (interpreter, 1739 "command script add", 1740 "Add a scripted function as an LLDB command.", 1741 NULL), 1742 IOHandlerDelegateMultiline ("DONE"), 1743 m_options (interpreter) 1744 { 1745 CommandArgumentEntry arg1; 1746 CommandArgumentData cmd_arg; 1747 1748 // Define the first (and only) variant of this arg. 1749 cmd_arg.arg_type = eArgTypeCommandName; 1750 cmd_arg.arg_repetition = eArgRepeatPlain; 1751 1752 // There is only one variant this argument could be; put it into the argument entry. 1753 arg1.push_back (cmd_arg); 1754 1755 // Push the data for the first argument into the m_arguments vector. 1756 m_arguments.push_back (arg1); 1757 } 1758 1759 ~CommandObjectCommandsScriptAdd () 1760 { 1761 } 1762 1763 virtual Options * 1764 GetOptions () 1765 { 1766 return &m_options; 1767 } 1768 1769 protected: 1770 1771 class CommandOptions : public Options 1772 { 1773 public: 1774 1775 CommandOptions (CommandInterpreter &interpreter) : 1776 Options (interpreter), 1777 m_class_name(), 1778 m_funct_name(), 1779 m_short_help(), 1780 m_synchronicity(eScriptedCommandSynchronicitySynchronous) 1781 { 1782 } 1783 1784 virtual 1785 ~CommandOptions (){} 1786 1787 virtual Error 1788 SetOptionValue (uint32_t option_idx, const char *option_arg) 1789 { 1790 Error error; 1791 const int short_option = m_getopt_table[option_idx].val; 1792 1793 switch (short_option) 1794 { 1795 case 'f': 1796 if (option_arg) 1797 m_funct_name.assign(option_arg); 1798 break; 1799 case 'c': 1800 if (option_arg) 1801 m_class_name.assign(option_arg); 1802 break; 1803 case 'h': 1804 if (option_arg) 1805 m_short_help.assign(option_arg); 1806 break; 1807 case 's': 1808 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1809 if (!error.Success()) 1810 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 1811 break; 1812 default: 1813 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1814 break; 1815 } 1816 1817 return error; 1818 } 1819 1820 void 1821 OptionParsingStarting () 1822 { 1823 m_class_name.clear(); 1824 m_funct_name.clear(); 1825 m_short_help.clear(); 1826 m_synchronicity = eScriptedCommandSynchronicitySynchronous; 1827 } 1828 1829 const OptionDefinition* 1830 GetDefinitions () 1831 { 1832 return g_option_table; 1833 } 1834 1835 // Options table: Required for subclasses of Options. 1836 1837 static OptionDefinition g_option_table[]; 1838 1839 // Instance variables to hold the values for command options. 1840 1841 std::string m_class_name; 1842 std::string m_funct_name; 1843 std::string m_short_help; 1844 ScriptedCommandSynchronicity m_synchronicity; 1845 }; 1846 1847 virtual void 1848 IOHandlerActivated (IOHandler &io_handler) 1849 { 1850 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 1851 if (output_sp) 1852 { 1853 output_sp->PutCString(g_python_command_instructions); 1854 output_sp->Flush(); 1855 } 1856 } 1857 1858 1859 virtual void 1860 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) 1861 { 1862 StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 1863 1864 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 1865 if (interpreter) 1866 { 1867 1868 StringList lines; 1869 lines.SplitIntoLines(data); 1870 if (lines.GetSize() > 0) 1871 { 1872 std::string funct_name_str; 1873 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str)) 1874 { 1875 if (funct_name_str.empty()) 1876 { 1877 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n"); 1878 error_sp->Flush(); 1879 } 1880 else 1881 { 1882 // everything should be fine now, let's add this alias 1883 1884 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter, 1885 m_cmd_name, 1886 funct_name_str.c_str(), 1887 m_short_help, 1888 m_synchronicity)); 1889 1890 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1891 { 1892 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n"); 1893 error_sp->Flush(); 1894 } 1895 } 1896 } 1897 else 1898 { 1899 error_sp->Printf ("error: unable to create function, didn't add python command.\n"); 1900 error_sp->Flush(); 1901 } 1902 } 1903 else 1904 { 1905 error_sp->Printf ("error: empty function, didn't add python command.\n"); 1906 error_sp->Flush(); 1907 } 1908 } 1909 else 1910 { 1911 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 1912 error_sp->Flush(); 1913 } 1914 1915 io_handler.SetIsDone(true); 1916 1917 1918 } 1919 1920 protected: 1921 bool 1922 DoExecute (Args& command, CommandReturnObject &result) 1923 { 1924 1925 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1926 { 1927 result.AppendError ("only scripting language supported for scripted commands is currently Python"); 1928 result.SetStatus (eReturnStatusFailed); 1929 return false; 1930 } 1931 1932 size_t argc = command.GetArgumentCount(); 1933 1934 if (argc != 1) 1935 { 1936 result.AppendError ("'command script add' requires one argument"); 1937 result.SetStatus (eReturnStatusFailed); 1938 return false; 1939 } 1940 1941 // Store the options in case we get multi-line input 1942 m_cmd_name = command.GetArgumentAtIndex(0); 1943 m_short_help.assign(m_options.m_short_help); 1944 m_synchronicity = m_options.m_synchronicity; 1945 1946 if (m_options.m_class_name.empty()) 1947 { 1948 if (m_options.m_funct_name.empty()) 1949 { 1950 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 1951 *this, // IOHandlerDelegate 1952 true, // Run IOHandler in async mode 1953 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 1954 } 1955 else 1956 { 1957 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 1958 m_cmd_name, 1959 m_options.m_funct_name, 1960 m_options.m_short_help, 1961 m_synchronicity)); 1962 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 1963 { 1964 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1965 } 1966 else 1967 { 1968 result.AppendError("cannot add command"); 1969 result.SetStatus (eReturnStatusFailed); 1970 } 1971 } 1972 } 1973 else 1974 { 1975 ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter(); 1976 if (!interpreter) 1977 { 1978 result.AppendError("cannot find ScriptInterpreter"); 1979 result.SetStatus(eReturnStatusFailed); 1980 return false; 1981 } 1982 1983 auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str()); 1984 if (!cmd_obj_sp) 1985 { 1986 result.AppendError("cannot create helper object"); 1987 result.SetStatus(eReturnStatusFailed); 1988 return false; 1989 } 1990 1991 CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter, 1992 m_cmd_name, 1993 cmd_obj_sp, 1994 m_synchronicity)); 1995 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 1996 { 1997 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1998 } 1999 else 2000 { 2001 result.AppendError("cannot add command"); 2002 result.SetStatus (eReturnStatusFailed); 2003 } 2004 } 2005 2006 return result.Succeeded(); 2007 2008 } 2009 2010 CommandOptions m_options; 2011 std::string m_cmd_name; 2012 std::string m_short_help; 2013 ScriptedCommandSynchronicity m_synchronicity; 2014 }; 2015 2016 static OptionEnumValueElement g_script_synchro_type[] = 2017 { 2018 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 2019 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 2020 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 2021 { 0, NULL, NULL } 2022 }; 2023 2024 OptionDefinition 2025 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 2026 { 2027 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 2028 { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."}, 2029 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."}, 2030 { 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."}, 2031 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2032 }; 2033 2034 //------------------------------------------------------------------------- 2035 // CommandObjectCommandsScriptList 2036 //------------------------------------------------------------------------- 2037 2038 class CommandObjectCommandsScriptList : public CommandObjectParsed 2039 { 2040 private: 2041 2042 public: 2043 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 2044 CommandObjectParsed (interpreter, 2045 "command script list", 2046 "List defined scripted commands.", 2047 NULL) 2048 { 2049 } 2050 2051 ~CommandObjectCommandsScriptList () 2052 { 2053 } 2054 2055 bool 2056 DoExecute (Args& command, CommandReturnObject &result) 2057 { 2058 2059 m_interpreter.GetHelp(result, 2060 CommandInterpreter::eCommandTypesUserDef); 2061 2062 result.SetStatus (eReturnStatusSuccessFinishResult); 2063 2064 return true; 2065 2066 2067 } 2068 }; 2069 2070 //------------------------------------------------------------------------- 2071 // CommandObjectCommandsScriptClear 2072 //------------------------------------------------------------------------- 2073 2074 class CommandObjectCommandsScriptClear : public CommandObjectParsed 2075 { 2076 private: 2077 2078 public: 2079 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 2080 CommandObjectParsed (interpreter, 2081 "command script clear", 2082 "Delete all scripted commands.", 2083 NULL) 2084 { 2085 } 2086 2087 ~CommandObjectCommandsScriptClear () 2088 { 2089 } 2090 2091 protected: 2092 bool 2093 DoExecute (Args& command, CommandReturnObject &result) 2094 { 2095 2096 m_interpreter.RemoveAllUser(); 2097 2098 result.SetStatus (eReturnStatusSuccessFinishResult); 2099 2100 return true; 2101 } 2102 }; 2103 2104 //------------------------------------------------------------------------- 2105 // CommandObjectCommandsScriptDelete 2106 //------------------------------------------------------------------------- 2107 2108 class CommandObjectCommandsScriptDelete : public CommandObjectParsed 2109 { 2110 public: 2111 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 2112 CommandObjectParsed (interpreter, 2113 "command script delete", 2114 "Delete a scripted command.", 2115 NULL) 2116 { 2117 CommandArgumentEntry arg1; 2118 CommandArgumentData cmd_arg; 2119 2120 // Define the first (and only) variant of this arg. 2121 cmd_arg.arg_type = eArgTypeCommandName; 2122 cmd_arg.arg_repetition = eArgRepeatPlain; 2123 2124 // There is only one variant this argument could be; put it into the argument entry. 2125 arg1.push_back (cmd_arg); 2126 2127 // Push the data for the first argument into the m_arguments vector. 2128 m_arguments.push_back (arg1); 2129 } 2130 2131 ~CommandObjectCommandsScriptDelete () 2132 { 2133 } 2134 2135 protected: 2136 bool 2137 DoExecute (Args& command, CommandReturnObject &result) 2138 { 2139 2140 size_t argc = command.GetArgumentCount(); 2141 2142 if (argc != 1) 2143 { 2144 result.AppendError ("'command script delete' requires one argument"); 2145 result.SetStatus (eReturnStatusFailed); 2146 return false; 2147 } 2148 2149 const char* cmd_name = command.GetArgumentAtIndex(0); 2150 2151 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 2152 { 2153 m_interpreter.RemoveUser(cmd_name); 2154 result.SetStatus (eReturnStatusSuccessFinishResult); 2155 } 2156 else 2157 { 2158 result.AppendErrorWithFormat ("command %s not found", cmd_name); 2159 result.SetStatus (eReturnStatusFailed); 2160 } 2161 2162 return result.Succeeded(); 2163 2164 } 2165 }; 2166 2167 #pragma mark CommandObjectMultiwordCommandsScript 2168 2169 //------------------------------------------------------------------------- 2170 // CommandObjectMultiwordCommandsScript 2171 //------------------------------------------------------------------------- 2172 2173 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 2174 { 2175 public: 2176 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 2177 CommandObjectMultiword (interpreter, 2178 "command script", 2179 "A set of commands for managing or customizing script commands.", 2180 "command script <subcommand> [<subcommand-options>]") 2181 { 2182 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 2183 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 2184 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 2185 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 2186 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 2187 } 2188 2189 ~CommandObjectMultiwordCommandsScript () 2190 { 2191 } 2192 2193 }; 2194 2195 2196 #pragma mark CommandObjectMultiwordCommands 2197 2198 //------------------------------------------------------------------------- 2199 // CommandObjectMultiwordCommands 2200 //------------------------------------------------------------------------- 2201 2202 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 2203 CommandObjectMultiword (interpreter, 2204 "command", 2205 "A set of commands for managing or customizing the debugger commands.", 2206 "command <subcommand> [<subcommand-options>]") 2207 { 2208 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 2209 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 2210 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 2211 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter))); 2212 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 2213 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 2214 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 2215 } 2216 2217 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 2218 { 2219 } 2220 2221