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 "CommandObjectCommands.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 #include "llvm/ADT/StringRef.h" 16 17 // Project includes 18 #include "lldb/Core/Debugger.h" 19 #include "lldb/Core/InputReader.h" 20 #include "lldb/Core/InputReaderEZ.h" 21 #include "lldb/Core/StringList.h" 22 #include "lldb/Interpreter/Args.h" 23 #include "lldb/Interpreter/CommandInterpreter.h" 24 #include "lldb/Interpreter/CommandObjectRegexCommand.h" 25 #include "lldb/Interpreter/CommandReturnObject.h" 26 #include "lldb/Interpreter/Options.h" 27 #include "lldb/Interpreter/ScriptInterpreter.h" 28 #include "lldb/Interpreter/ScriptInterpreterPython.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 //------------------------------------------------------------------------- 34 // CommandObjectCommandsSource 35 //------------------------------------------------------------------------- 36 37 class CommandObjectCommandsHistory : public CommandObject 38 { 39 private: 40 41 class CommandOptions : public Options 42 { 43 public: 44 45 CommandOptions (CommandInterpreter &interpreter) : 46 Options (interpreter) 47 { 48 } 49 50 virtual 51 ~CommandOptions (){} 52 53 virtual Error 54 SetOptionValue (uint32_t option_idx, const char *option_arg) 55 { 56 Error error; 57 char short_option = (char) m_getopt_table[option_idx].val; 58 bool success; 59 60 switch (short_option) 61 { 62 case 'c': 63 m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success); 64 if (!success) 65 error.SetErrorStringWithFormat("invalid value for count: %s", option_arg); 66 if (m_end_idx != 0) 67 m_end_idx--; 68 m_start_idx = 0; 69 break; 70 case 'e': 71 m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success); 72 if (!success) 73 error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg); 74 break; 75 case 's': 76 m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success); 77 if (!success) 78 error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg); 79 break; 80 default: 81 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 82 break; 83 } 84 85 return error; 86 } 87 88 void 89 OptionParsingStarting () 90 { 91 m_start_idx = 0; 92 m_end_idx = UINT_MAX; 93 } 94 95 const OptionDefinition* 96 GetDefinitions () 97 { 98 return g_option_table; 99 } 100 101 // Options table: Required for subclasses of Options. 102 103 static OptionDefinition g_option_table[]; 104 105 // Instance variables to hold the values for command options. 106 107 uint32_t m_start_idx; 108 uint32_t m_end_idx; 109 }; 110 111 CommandOptions m_options; 112 113 virtual Options * 114 GetOptions () 115 { 116 return &m_options; 117 } 118 119 public: 120 CommandObjectCommandsHistory(CommandInterpreter &interpreter) : 121 CommandObject (interpreter, 122 "command history", 123 "Dump the history of commands in this session.", 124 NULL), 125 m_options (interpreter) 126 { 127 } 128 129 ~CommandObjectCommandsHistory () 130 { 131 } 132 133 bool 134 Execute 135 ( 136 Args& args, 137 CommandReturnObject &result 138 ) 139 { 140 141 m_interpreter.DumpHistory (result.GetOutputStream(), 142 m_options.m_start_idx, 143 m_options.m_end_idx); 144 return result.Succeeded(); 145 146 } 147 }; 148 149 OptionDefinition 150 CommandObjectCommandsHistory::CommandOptions::g_option_table[] = 151 { 152 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, 153 { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands."}, 154 { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, 155 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 156 }; 157 158 159 //------------------------------------------------------------------------- 160 // CommandObjectCommandsSource 161 //------------------------------------------------------------------------- 162 163 class CommandObjectCommandsSource : public CommandObject 164 { 165 private: 166 167 class CommandOptions : public Options 168 { 169 public: 170 171 CommandOptions (CommandInterpreter &interpreter) : 172 Options (interpreter) 173 { 174 } 175 176 virtual 177 ~CommandOptions (){} 178 179 virtual Error 180 SetOptionValue (uint32_t option_idx, const char *option_arg) 181 { 182 Error error; 183 char short_option = (char) m_getopt_table[option_idx].val; 184 bool success; 185 186 switch (short_option) 187 { 188 case 'e': 189 m_stop_on_error = Args::StringToBoolean(option_arg, true, &success); 190 if (!success) 191 error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg); 192 break; 193 case 'c': 194 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success); 195 if (!success) 196 error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg); 197 break; 198 default: 199 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 200 break; 201 } 202 203 return error; 204 } 205 206 void 207 OptionParsingStarting () 208 { 209 m_stop_on_error = true; 210 m_stop_on_continue = true; 211 } 212 213 const OptionDefinition* 214 GetDefinitions () 215 { 216 return g_option_table; 217 } 218 219 // Options table: Required for subclasses of Options. 220 221 static OptionDefinition g_option_table[]; 222 223 // Instance variables to hold the values for command options. 224 225 bool m_stop_on_error; 226 bool m_stop_on_continue; 227 }; 228 229 CommandOptions m_options; 230 231 virtual Options * 232 GetOptions () 233 { 234 return &m_options; 235 } 236 237 public: 238 CommandObjectCommandsSource(CommandInterpreter &interpreter) : 239 CommandObject (interpreter, 240 "command source", 241 "Read in debugger commands from the file <filename> and execute them.", 242 NULL), 243 m_options (interpreter) 244 { 245 CommandArgumentEntry arg; 246 CommandArgumentData file_arg; 247 248 // Define the first (and only) variant of this arg. 249 file_arg.arg_type = eArgTypeFilename; 250 file_arg.arg_repetition = eArgRepeatPlain; 251 252 // There is only one variant this argument could be; put it into the argument entry. 253 arg.push_back (file_arg); 254 255 // Push the data for the first argument into the m_arguments vector. 256 m_arguments.push_back (arg); 257 } 258 259 ~CommandObjectCommandsSource () 260 { 261 } 262 263 bool 264 Execute 265 ( 266 Args& args, 267 CommandReturnObject &result 268 ) 269 { 270 const int argc = args.GetArgumentCount(); 271 if (argc == 1) 272 { 273 const char *filename = args.GetArgumentAtIndex(0); 274 275 result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename); 276 277 FileSpec cmd_file (filename, true); 278 ExecutionContext *exe_ctx = NULL; // Just use the default context. 279 bool echo_commands = true; 280 bool print_results = true; 281 282 m_interpreter.HandleCommandsFromFile (cmd_file, 283 exe_ctx, 284 m_options.m_stop_on_continue, 285 m_options.m_stop_on_error, 286 echo_commands, 287 print_results, 288 result); 289 } 290 else 291 { 292 result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName()); 293 result.SetStatus (eReturnStatusFailed); 294 } 295 return result.Succeeded(); 296 297 } 298 }; 299 300 OptionDefinition 301 CommandObjectCommandsSource::CommandOptions::g_option_table[] = 302 { 303 { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 304 { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 305 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 306 }; 307 308 #pragma mark CommandObjectCommandsAlias 309 //------------------------------------------------------------------------- 310 // CommandObjectCommandsAlias 311 //------------------------------------------------------------------------- 312 313 static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 314 "You must define a Python function with this signature:\n" 315 "def my_command_impl(debugger, args, result, dict):"; 316 317 318 class CommandObjectCommandsAlias : public CommandObject 319 { 320 321 322 public: 323 CommandObjectCommandsAlias (CommandInterpreter &interpreter) : 324 CommandObject (interpreter, 325 "command alias", 326 "Allow users to define their own debugger command abbreviations.", 327 NULL) 328 { 329 SetHelpLong( 330 "'alias' allows the user to create a short-cut or abbreviation for long \n\ 331 commands, multi-word commands, and commands that take particular options. \n\ 332 Below are some simple examples of how one might use the 'alias' command: \n\ 333 \n 'commands alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ 334 // command. \n\ 335 'commands alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ 336 // command. Since breakpoint commands are two-word \n\ 337 // commands, the user will still need to enter the \n\ 338 // second word after 'bp', e.g. 'bp enable' or \n\ 339 // 'bp delete'. \n\ 340 'commands alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\ 341 // two-word command 'breakpoint list'. \n\ 342 \nAn alias can include some options for the command, with the values either \n\ 343 filled in at the time the alias is created, or specified as positional \n\ 344 arguments, to be filled in when the alias is invoked. The following example \n\ 345 shows how to create aliases with options: \n\ 346 \n\ 347 'commands alias bfl breakpoint set -f %1 -l %2' \n\ 348 \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\ 349 options already part of the alias. So if the user wants to set a breakpoint \n\ 350 by file and line without explicitly having to use the -f and -l options, the \n\ 351 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\ 352 for the actual arguments that will be passed when the alias command is used. \n\ 353 The number in the placeholder refers to the position/order the actual value \n\ 354 occupies when the alias is used. All the occurrences of '%1' in the alias \n\ 355 will be replaced with the first argument, all the occurrences of '%2' in the \n\ 356 alias will be replaced with the second argument, and so on. This also allows \n\ 357 actual arguments to be used multiple times within an alias (see 'process \n\ 358 launch' example below). \n\ 359 Note: the positional arguments must substitute as whole words in the resultant\n\ 360 command, so you can't at present do something like:\n\ 361 \n\ 362 commands alias bcppfl breakpoint set -f %1.cpp -l %2\n\ 363 \n\ 364 to get the file extension \".cpp\" automatically appended. For more complex\n\ 365 aliasing, use the \"command regex\" command instead.\n\ 366 \nSo in the 'bfl' case, the actual file value will be \n\ 367 filled in with the first argument following 'bfl' and the actual line number \n\ 368 value will be filled in with the second argument. The user would use this \n\ 369 alias as follows: \n\ 370 \n (lldb) commands alias bfl breakpoint set -f %1 -l %2 \n\ 371 <... some time later ...> \n\ 372 (lldb) bfl my-file.c 137 \n\ 373 \nThis would be the same as if the user had entered \n\ 374 'breakpoint set -f my-file.c -l 137'. \n\ 375 \nAnother example: \n\ 376 \n (lldb) commands alias pltty process launch -s -o %1 -e %1 \n\ 377 (lldb) pltty /dev/tty0 \n\ 378 // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\ 379 \nIf the user always wanted to pass the same value to a particular option, the \n\ 380 alias could be defined with that value directly in the alias as a constant, \n\ 381 rather than using a positional placeholder: \n\ 382 \n commands alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\ 383 // 3 of whatever file is indicated. \n"); 384 385 CommandArgumentEntry arg1; 386 CommandArgumentEntry arg2; 387 CommandArgumentEntry arg3; 388 CommandArgumentData alias_arg; 389 CommandArgumentData cmd_arg; 390 CommandArgumentData options_arg; 391 392 // Define the first (and only) variant of this arg. 393 alias_arg.arg_type = eArgTypeAliasName; 394 alias_arg.arg_repetition = eArgRepeatPlain; 395 396 // There is only one variant this argument could be; put it into the argument entry. 397 arg1.push_back (alias_arg); 398 399 // Define the first (and only) variant of this arg. 400 cmd_arg.arg_type = eArgTypeCommandName; 401 cmd_arg.arg_repetition = eArgRepeatPlain; 402 403 // There is only one variant this argument could be; put it into the argument entry. 404 arg2.push_back (cmd_arg); 405 406 // Define the first (and only) variant of this arg. 407 options_arg.arg_type = eArgTypeAliasOptions; 408 options_arg.arg_repetition = eArgRepeatOptional; 409 410 // There is only one variant this argument could be; put it into the argument entry. 411 arg3.push_back (options_arg); 412 413 // Push the data for the first argument into the m_arguments vector. 414 m_arguments.push_back (arg1); 415 m_arguments.push_back (arg2); 416 m_arguments.push_back (arg3); 417 } 418 419 ~CommandObjectCommandsAlias () 420 { 421 } 422 423 bool 424 WantsRawCommandString () 425 { 426 return true; 427 } 428 429 bool 430 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result) 431 { 432 Args args (raw_command_line); 433 std::string raw_command_string (raw_command_line); 434 435 size_t argc = args.GetArgumentCount(); 436 437 if (argc < 2) 438 { 439 result.AppendError ("'alias' requires at least two arguments"); 440 result.SetStatus (eReturnStatusFailed); 441 return false; 442 } 443 444 // Get the alias command. 445 446 const std::string alias_command = args.GetArgumentAtIndex (0); 447 448 // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which 449 // does the stripping itself. 450 size_t pos = raw_command_string.find (alias_command); 451 if (pos == 0) 452 { 453 raw_command_string = raw_command_string.substr (alias_command.size()); 454 pos = raw_command_string.find_first_not_of (' '); 455 if ((pos != std::string::npos) && (pos > 0)) 456 raw_command_string = raw_command_string.substr (pos); 457 } 458 else 459 { 460 result.AppendError ("Error parsing command string. No alias created."); 461 result.SetStatus (eReturnStatusFailed); 462 return false; 463 } 464 465 466 // Verify that the command is alias-able. 467 if (m_interpreter.CommandExists (alias_command.c_str())) 468 { 469 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 470 alias_command.c_str()); 471 result.SetStatus (eReturnStatusFailed); 472 return false; 473 } 474 475 // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. 476 // raw_command_string is returned with the name of the command object stripped off the front. 477 CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); 478 479 if (!cmd_obj) 480 { 481 result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command." 482 " No alias created.", raw_command_string.c_str()); 483 result.SetStatus (eReturnStatusFailed); 484 return false; 485 } 486 else if (!cmd_obj->WantsRawCommandString ()) 487 { 488 // Note that args was initialized with the original command, and has not been updated to this point. 489 // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. 490 return Execute (args, result); 491 } 492 else 493 { 494 // Verify & handle any options/arguments passed to the alias command 495 496 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 497 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 498 499 CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 500 501 if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp)) 502 { 503 result.AppendError ("Unable to create requested alias.\n"); 504 result.SetStatus (eReturnStatusFailed); 505 return false; 506 } 507 508 // Create the alias 509 if (m_interpreter.AliasExists (alias_command.c_str()) 510 || m_interpreter.UserCommandExists (alias_command.c_str())) 511 { 512 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 513 if (temp_option_arg_sp.get()) 514 { 515 if (option_arg_vector->size() == 0) 516 m_interpreter.RemoveAliasOptions (alias_command.c_str()); 517 } 518 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 519 alias_command.c_str()); 520 } 521 522 if (cmd_obj_sp) 523 { 524 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp); 525 if (option_arg_vector->size() > 0) 526 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 527 result.SetStatus (eReturnStatusSuccessFinishNoResult); 528 } 529 else 530 { 531 result.AppendError ("Unable to create requested alias.\n"); 532 result.SetStatus (eReturnStatusFailed); 533 } 534 } 535 return result.Succeeded(); 536 } 537 538 bool 539 Execute 540 ( 541 Args& args, 542 CommandReturnObject &result 543 ) 544 { 545 size_t argc = args.GetArgumentCount(); 546 547 if (argc < 2) 548 { 549 result.AppendError ("'alias' requires at least two arguments"); 550 result.SetStatus (eReturnStatusFailed); 551 return false; 552 } 553 554 const std::string alias_command = args.GetArgumentAtIndex(0); 555 const std::string actual_command = args.GetArgumentAtIndex(1); 556 557 args.Shift(); // Shift the alias command word off the argument vector. 558 args.Shift(); // Shift the old command word off the argument vector. 559 560 // Verify that the command is alias'able, and get the appropriate command object. 561 562 if (m_interpreter.CommandExists (alias_command.c_str())) 563 { 564 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 565 alias_command.c_str()); 566 result.SetStatus (eReturnStatusFailed); 567 } 568 else 569 { 570 CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true)); 571 CommandObjectSP subcommand_obj_sp; 572 bool use_subcommand = false; 573 if (command_obj_sp.get()) 574 { 575 CommandObject *cmd_obj = command_obj_sp.get(); 576 CommandObject *sub_cmd_obj = NULL; 577 OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 578 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 579 580 while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) 581 { 582 if (argc >= 3) 583 { 584 const std::string sub_command = args.GetArgumentAtIndex(0); 585 assert (sub_command.length() != 0); 586 subcommand_obj_sp = 587 (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str())); 588 if (subcommand_obj_sp.get()) 589 { 590 sub_cmd_obj = subcommand_obj_sp.get(); 591 use_subcommand = true; 592 args.Shift(); // Shift the sub_command word off the argument vector. 593 cmd_obj = sub_cmd_obj; 594 } 595 else 596 { 597 result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. " 598 "Unable to create alias.\n", 599 sub_command.c_str(), actual_command.c_str()); 600 result.SetStatus (eReturnStatusFailed); 601 return false; 602 } 603 } 604 } 605 606 // Verify & handle any options/arguments passed to the alias command 607 608 if (args.GetArgumentCount () > 0) 609 { 610 CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 611 if (use_subcommand) 612 tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); 613 614 std::string args_string; 615 args.GetCommandString (args_string); 616 617 if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp)) 618 { 619 result.AppendError ("Unable to create requested alias.\n"); 620 result.SetStatus (eReturnStatusFailed); 621 return false; 622 } 623 } 624 625 // Create the alias. 626 627 if (m_interpreter.AliasExists (alias_command.c_str()) 628 || m_interpreter.UserCommandExists (alias_command.c_str())) 629 { 630 OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 631 if (tmp_option_arg_sp.get()) 632 { 633 if (option_arg_vector->size() == 0) 634 m_interpreter.RemoveAliasOptions (alias_command.c_str()); 635 } 636 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 637 alias_command.c_str()); 638 } 639 640 if (use_subcommand) 641 m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp); 642 else 643 m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp); 644 if (option_arg_vector->size() > 0) 645 m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 646 result.SetStatus (eReturnStatusSuccessFinishNoResult); 647 } 648 else 649 { 650 result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str()); 651 result.SetStatus (eReturnStatusFailed); 652 return false; 653 } 654 } 655 656 return result.Succeeded(); 657 } 658 }; 659 660 #pragma mark CommandObjectCommandsUnalias 661 //------------------------------------------------------------------------- 662 // CommandObjectCommandsUnalias 663 //------------------------------------------------------------------------- 664 665 class CommandObjectCommandsUnalias : public CommandObject 666 { 667 public: 668 CommandObjectCommandsUnalias (CommandInterpreter &interpreter) : 669 CommandObject (interpreter, 670 "command unalias", 671 "Allow the user to remove/delete a user-defined command abbreviation.", 672 NULL) 673 { 674 CommandArgumentEntry arg; 675 CommandArgumentData alias_arg; 676 677 // Define the first (and only) variant of this arg. 678 alias_arg.arg_type = eArgTypeAliasName; 679 alias_arg.arg_repetition = eArgRepeatPlain; 680 681 // There is only one variant this argument could be; put it into the argument entry. 682 arg.push_back (alias_arg); 683 684 // Push the data for the first argument into the m_arguments vector. 685 m_arguments.push_back (arg); 686 } 687 688 ~CommandObjectCommandsUnalias() 689 { 690 } 691 692 693 bool 694 Execute 695 ( 696 Args& args, 697 CommandReturnObject &result 698 ) 699 { 700 CommandObject::CommandMap::iterator pos; 701 CommandObject *cmd_obj; 702 703 if (args.GetArgumentCount() != 0) 704 { 705 const char *command_name = args.GetArgumentAtIndex(0); 706 cmd_obj = m_interpreter.GetCommandObject(command_name); 707 if (cmd_obj) 708 { 709 if (m_interpreter.CommandExists (command_name)) 710 { 711 result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 712 command_name); 713 result.SetStatus (eReturnStatusFailed); 714 } 715 else 716 { 717 718 if (m_interpreter.RemoveAlias (command_name) == false) 719 { 720 if (m_interpreter.AliasExists (command_name)) 721 result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n", 722 command_name); 723 else 724 result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name); 725 result.SetStatus (eReturnStatusFailed); 726 } 727 else 728 result.SetStatus (eReturnStatusSuccessFinishNoResult); 729 } 730 } 731 else 732 { 733 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a " 734 "current list of commands.\n", 735 command_name); 736 result.SetStatus (eReturnStatusFailed); 737 } 738 } 739 else 740 { 741 result.AppendError ("must call 'unalias' with a valid alias"); 742 result.SetStatus (eReturnStatusFailed); 743 } 744 745 return result.Succeeded(); 746 } 747 }; 748 749 #pragma mark CommandObjectCommandsAddRegex 750 //------------------------------------------------------------------------- 751 // CommandObjectCommandsAddRegex 752 //------------------------------------------------------------------------- 753 754 class CommandObjectCommandsAddRegex : public CommandObject 755 { 756 public: 757 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 758 CommandObject (interpreter, 759 "command regex", 760 "Allow the user to create a regular expression command.", 761 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 762 m_options (interpreter) 763 { 764 SetHelpLong( 765 "This command allows the user to create powerful regular expression commands\n" 766 "with substitutions. The regular expressions and substitutions are specified\n" 767 "using the regular exression substitution format of:\n" 768 "\n" 769 " s/<regex>/<subst>/\n" 770 "\n" 771 "<regex> is a regular expression that can use parenthesis to capture regular\n" 772 "expression input and substitute the captured matches in the output using %1\n" 773 "for the first match, %2 for the second, and so on.\n" 774 "\n" 775 "The regular expressions can all be specified on the command line if more than\n" 776 "one argument is provided. If just the command name is provided on the command\n" 777 "line, then the regular expressions and substitutions can be entered on separate\n" 778 " lines, followed by an empty line to terminate the command definition.\n" 779 "\n" 780 "EXAMPLES\n" 781 "\n" 782 "The following example with define a regular expression command named 'f' that\n" 783 "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n" 784 "a number follows 'f':\n" 785 "(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n" 786 ); 787 } 788 789 ~CommandObjectCommandsAddRegex() 790 { 791 } 792 793 794 bool 795 Execute (Args& args, CommandReturnObject &result) 796 { 797 const size_t argc = args.GetArgumentCount(); 798 if (argc == 0) 799 { 800 result.AppendError ("usage: 'commands regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 801 result.SetStatus (eReturnStatusFailed); 802 } 803 else 804 { 805 Error error; 806 const char *name = args.GetArgumentAtIndex(0); 807 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 808 name, 809 m_options.GetHelp (), 810 m_options.GetSyntax (), 811 10)); 812 813 if (argc == 1) 814 { 815 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 816 if (reader_sp) 817 { 818 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback, 819 this, // baton 820 eInputReaderGranularityLine, // token size, to pass to callback function 821 NULL, // end token 822 "> ", // prompt 823 true); // echo input 824 if (error.Success()) 825 { 826 m_interpreter.GetDebugger().PushInputReader (reader_sp); 827 result.SetStatus (eReturnStatusSuccessFinishNoResult); 828 return true; 829 } 830 } 831 } 832 else 833 { 834 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 835 { 836 llvm::StringRef arg_strref (args.GetArgumentAtIndex(arg_idx)); 837 error = AppendRegexSubstitution (arg_strref); 838 if (error.Fail()) 839 break; 840 } 841 842 if (error.Success()) 843 { 844 AddRegexCommandToInterpreter(); 845 } 846 } 847 if (error.Fail()) 848 { 849 result.AppendError (error.AsCString()); 850 result.SetStatus (eReturnStatusFailed); 851 } 852 } 853 854 return result.Succeeded(); 855 } 856 857 Error 858 AppendRegexSubstitution (const llvm::StringRef ®ex_sed) 859 { 860 Error error; 861 862 if (m_regex_cmd_ap.get() == NULL) 863 { 864 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 865 (int)regex_sed.size(), 866 regex_sed.data()); 867 return error; 868 } 869 870 size_t regex_sed_size = regex_sed.size(); 871 872 if (regex_sed_size <= 1) 873 { 874 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 875 (int)regex_sed.size(), 876 regex_sed.data()); 877 return error; 878 } 879 880 if (regex_sed[0] != 's') 881 { 882 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 883 (int)regex_sed.size(), 884 regex_sed.data()); 885 return error; 886 } 887 const size_t first_separator_char_pos = 1; 888 // use the char that follows 's' as the regex separator character 889 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 890 const char separator_char = regex_sed[first_separator_char_pos]; 891 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 892 893 if (second_separator_char_pos == std::string::npos) 894 { 895 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'", 896 separator_char, 897 (int)(regex_sed.size() - first_separator_char_pos - 1), 898 regex_sed.data() + (first_separator_char_pos + 1)); 899 return error; 900 } 901 902 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 903 904 if (third_separator_char_pos == std::string::npos) 905 { 906 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'", 907 separator_char, 908 (int)(regex_sed.size() - second_separator_char_pos - 1), 909 regex_sed.data() + (second_separator_char_pos + 1)); 910 return error; 911 } 912 913 if (third_separator_char_pos != regex_sed_size - 1) 914 { 915 // Make sure that everything that follows the last regex 916 // separator char 917 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 918 { 919 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 920 (int)third_separator_char_pos + 1, 921 regex_sed.data(), 922 (int)(regex_sed.size() - third_separator_char_pos - 1), 923 regex_sed.data() + (third_separator_char_pos + 1)); 924 return error; 925 } 926 927 } 928 else if (first_separator_char_pos + 1 == second_separator_char_pos) 929 { 930 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 931 separator_char, 932 separator_char, 933 separator_char, 934 (int)regex_sed.size(), 935 regex_sed.data()); 936 return error; 937 } 938 else if (second_separator_char_pos + 1 == third_separator_char_pos) 939 { 940 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 941 separator_char, 942 separator_char, 943 separator_char, 944 (int)regex_sed.size(), 945 regex_sed.data()); 946 return error; 947 } 948 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 949 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 950 m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 951 subst.c_str()); 952 return error; 953 } 954 955 void 956 AddRegexCommandToInterpreter() 957 { 958 if (m_regex_cmd_ap.get()) 959 { 960 if (m_regex_cmd_ap->HasRegexEntries()) 961 { 962 CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 963 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 964 } 965 } 966 } 967 968 void 969 InputReaderDidCancel() 970 { 971 m_regex_cmd_ap.reset(); 972 } 973 974 static size_t 975 InputReaderCallback (void *baton, 976 InputReader &reader, 977 lldb::InputReaderAction notification, 978 const char *bytes, 979 size_t bytes_len); 980 private: 981 std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 982 983 class CommandOptions : public Options 984 { 985 public: 986 987 CommandOptions (CommandInterpreter &interpreter) : 988 Options (interpreter) 989 { 990 } 991 992 virtual 993 ~CommandOptions (){} 994 995 virtual Error 996 SetOptionValue (uint32_t option_idx, const char *option_arg) 997 { 998 Error error; 999 char short_option = (char) m_getopt_table[option_idx].val; 1000 1001 switch (short_option) 1002 { 1003 case 'h': 1004 m_help.assign (option_arg); 1005 break; 1006 case 's': 1007 m_syntax.assign (option_arg); 1008 break; 1009 1010 default: 1011 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1012 break; 1013 } 1014 1015 return error; 1016 } 1017 1018 void 1019 OptionParsingStarting () 1020 { 1021 m_help.clear(); 1022 m_syntax.clear(); 1023 } 1024 1025 const OptionDefinition* 1026 GetDefinitions () 1027 { 1028 return g_option_table; 1029 } 1030 1031 // Options table: Required for subclasses of Options. 1032 1033 static OptionDefinition g_option_table[]; 1034 1035 const char * 1036 GetHelp () 1037 { 1038 if (m_help.empty()) 1039 return NULL; 1040 return m_help.c_str(); 1041 } 1042 const char * 1043 GetSyntax () 1044 { 1045 if (m_syntax.empty()) 1046 return NULL; 1047 return m_syntax.c_str(); 1048 } 1049 // Instance variables to hold the values for command options. 1050 protected: 1051 std::string m_help; 1052 std::string m_syntax; 1053 }; 1054 1055 CommandOptions m_options; 1056 1057 virtual Options * 1058 GetOptions () 1059 { 1060 return &m_options; 1061 } 1062 1063 }; 1064 1065 size_t 1066 CommandObjectCommandsAddRegex::InputReaderCallback (void *baton, 1067 InputReader &reader, 1068 lldb::InputReaderAction notification, 1069 const char *bytes, 1070 size_t bytes_len) 1071 { 1072 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton; 1073 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 1074 1075 switch (notification) 1076 { 1077 case eInputReaderActivate: 1078 if (!batch_mode) 1079 { 1080 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream (); 1081 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:"); 1082 out_stream->Flush(); 1083 } 1084 break; 1085 case eInputReaderReactivate: 1086 break; 1087 1088 case eInputReaderDeactivate: 1089 break; 1090 1091 case eInputReaderAsynchronousOutputWritten: 1092 break; 1093 1094 case eInputReaderGotToken: 1095 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n')) 1096 --bytes_len; 1097 if (bytes_len == 0) 1098 reader.SetIsDone(true); 1099 else if (bytes) 1100 { 1101 llvm::StringRef bytes_strref (bytes, bytes_len); 1102 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref)); 1103 if (error.Fail()) 1104 { 1105 if (!batch_mode) 1106 { 1107 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 1108 out_stream->Printf("error: %s\n", error.AsCString()); 1109 out_stream->Flush(); 1110 } 1111 add_regex_cmd->InputReaderDidCancel (); 1112 reader.SetIsDone (true); 1113 } 1114 } 1115 break; 1116 1117 case eInputReaderInterrupt: 1118 { 1119 reader.SetIsDone (true); 1120 if (!batch_mode) 1121 { 1122 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 1123 out_stream->PutCString("Regular expression command creations was cancelled.\n"); 1124 out_stream->Flush(); 1125 } 1126 add_regex_cmd->InputReaderDidCancel (); 1127 } 1128 break; 1129 1130 case eInputReaderEndOfFile: 1131 reader.SetIsDone (true); 1132 break; 1133 1134 case eInputReaderDone: 1135 add_regex_cmd->AddRegexCommandToInterpreter(); 1136 break; 1137 } 1138 1139 return bytes_len; 1140 } 1141 1142 1143 OptionDefinition 1144 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1145 { 1146 { LLDB_OPT_SET_1, false, "help" , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1147 { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1148 { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL } 1149 }; 1150 1151 1152 class CommandObjectPythonFunction : public CommandObject 1153 { 1154 private: 1155 std::string m_function_name; 1156 1157 public: 1158 1159 CommandObjectPythonFunction (CommandInterpreter &interpreter, 1160 std::string name, 1161 std::string funct) : 1162 CommandObject (interpreter, 1163 name.c_str(), 1164 (std::string("Run Python function ") + funct).c_str(), 1165 NULL), 1166 m_function_name(funct) 1167 { 1168 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1169 if (scripter) 1170 { 1171 std::string docstring = scripter->GetDocumentationForItem(funct.c_str()); 1172 if (!docstring.empty()) 1173 SetHelpLong(docstring); 1174 } 1175 } 1176 1177 virtual 1178 ~CommandObjectPythonFunction () 1179 { 1180 } 1181 1182 virtual bool 1183 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result) 1184 { 1185 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1186 1187 Error error; 1188 1189 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1190 raw_command_line, 1191 result, 1192 error) == false) 1193 { 1194 result.AppendError(error.AsCString()); 1195 result.SetStatus(eReturnStatusFailed); 1196 } 1197 else 1198 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1199 1200 return result.Succeeded(); 1201 } 1202 1203 virtual bool 1204 WantsRawCommandString () 1205 { 1206 return true; 1207 } 1208 1209 bool 1210 Execute (Args& command, 1211 CommandReturnObject &result) 1212 { 1213 std::string cmd_string; 1214 command.GetCommandString(cmd_string); 1215 return ExecuteRawCommandString(cmd_string.c_str(), result); 1216 } 1217 1218 virtual bool 1219 IsRemovable() { return true; } 1220 1221 }; 1222 1223 //------------------------------------------------------------------------- 1224 // CommandObjectCommandsScriptImport 1225 //------------------------------------------------------------------------- 1226 1227 class CommandObjectCommandsScriptImport : public CommandObject 1228 { 1229 public: 1230 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 1231 CommandObject (interpreter, 1232 "command script import", 1233 "Import a scripting module in LLDB.", 1234 NULL) 1235 { 1236 CommandArgumentEntry arg1; 1237 CommandArgumentData cmd_arg; 1238 1239 // Define the first (and only) variant of this arg. 1240 cmd_arg.arg_type = eArgTypePath; 1241 cmd_arg.arg_repetition = eArgRepeatPlain; 1242 1243 // There is only one variant this argument could be; put it into the argument entry. 1244 arg1.push_back (cmd_arg); 1245 1246 // Push the data for the first argument into the m_arguments vector. 1247 m_arguments.push_back (arg1); 1248 } 1249 1250 ~CommandObjectCommandsScriptImport () 1251 { 1252 } 1253 1254 bool 1255 Execute 1256 ( 1257 Args& args, 1258 CommandReturnObject &result 1259 ) 1260 { 1261 1262 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1263 { 1264 result.AppendError ("only scripting language supported for module importing is currently Python"); 1265 result.SetStatus (eReturnStatusFailed); 1266 return false; 1267 } 1268 1269 size_t argc = args.GetArgumentCount(); 1270 1271 if (argc != 1) 1272 { 1273 result.AppendError ("'command script import' requires one argument"); 1274 result.SetStatus (eReturnStatusFailed); 1275 return false; 1276 } 1277 1278 std::string path = args.GetArgumentAtIndex(0); 1279 Error error; 1280 1281 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 1282 error)) 1283 { 1284 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1285 } 1286 else 1287 { 1288 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1289 result.SetStatus (eReturnStatusFailed); 1290 } 1291 1292 return result.Succeeded(); 1293 } 1294 }; 1295 1296 //------------------------------------------------------------------------- 1297 // CommandObjectCommandsScriptAdd 1298 //------------------------------------------------------------------------- 1299 1300 class CommandObjectCommandsScriptAdd : public CommandObject 1301 { 1302 private: 1303 1304 class CommandOptions : public Options 1305 { 1306 public: 1307 1308 CommandOptions (CommandInterpreter &interpreter) : 1309 Options (interpreter) 1310 { 1311 } 1312 1313 virtual 1314 ~CommandOptions (){} 1315 1316 virtual Error 1317 SetOptionValue (uint32_t option_idx, const char *option_arg) 1318 { 1319 Error error; 1320 char short_option = (char) m_getopt_table[option_idx].val; 1321 1322 switch (short_option) 1323 { 1324 case 'f': 1325 m_funct_name = std::string(option_arg); 1326 break; 1327 default: 1328 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1329 break; 1330 } 1331 1332 return error; 1333 } 1334 1335 void 1336 OptionParsingStarting () 1337 { 1338 m_funct_name = ""; 1339 } 1340 1341 const OptionDefinition* 1342 GetDefinitions () 1343 { 1344 return g_option_table; 1345 } 1346 1347 // Options table: Required for subclasses of Options. 1348 1349 static OptionDefinition g_option_table[]; 1350 1351 // Instance variables to hold the values for command options. 1352 1353 std::string m_funct_name; 1354 }; 1355 1356 CommandOptions m_options; 1357 1358 virtual Options * 1359 GetOptions () 1360 { 1361 return &m_options; 1362 } 1363 1364 class PythonAliasReader : public InputReaderEZ 1365 { 1366 private: 1367 CommandInterpreter& m_interpreter; 1368 std::string m_cmd_name; 1369 StringList m_user_input; 1370 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader); 1371 public: 1372 PythonAliasReader(Debugger& debugger, 1373 CommandInterpreter& interpreter, 1374 std::string cmd_name) : 1375 InputReaderEZ(debugger), 1376 m_interpreter(interpreter), 1377 m_cmd_name(cmd_name), 1378 m_user_input() 1379 {} 1380 1381 virtual 1382 ~PythonAliasReader() 1383 { 1384 } 1385 1386 virtual void ActivateHandler(HandlerData& data) 1387 { 1388 StreamSP out_stream = data.GetOutStream(); 1389 bool batch_mode = data.GetBatchMode(); 1390 if (!batch_mode) 1391 { 1392 out_stream->Printf ("%s\n", g_python_command_instructions); 1393 if (data.reader.GetPrompt()) 1394 out_stream->Printf ("%s", data.reader.GetPrompt()); 1395 out_stream->Flush(); 1396 } 1397 } 1398 1399 virtual void ReactivateHandler(HandlerData& data) 1400 { 1401 StreamSP out_stream = data.GetOutStream(); 1402 bool batch_mode = data.GetBatchMode(); 1403 if (data.reader.GetPrompt() && !batch_mode) 1404 { 1405 out_stream->Printf ("%s", data.reader.GetPrompt()); 1406 out_stream->Flush(); 1407 } 1408 } 1409 virtual void GotTokenHandler(HandlerData& data) 1410 { 1411 StreamSP out_stream = data.GetOutStream(); 1412 bool batch_mode = data.GetBatchMode(); 1413 if (data.bytes && data.bytes_len) 1414 { 1415 m_user_input.AppendString(data.bytes, data.bytes_len); 1416 } 1417 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) 1418 { 1419 out_stream->Printf ("%s", data.reader.GetPrompt()); 1420 out_stream->Flush(); 1421 } 1422 } 1423 virtual void InterruptHandler(HandlerData& data) 1424 { 1425 StreamSP out_stream = data.GetOutStream(); 1426 bool batch_mode = data.GetBatchMode(); 1427 data.reader.SetIsDone (true); 1428 if (!batch_mode) 1429 { 1430 out_stream->Printf ("Warning: No command attached to breakpoint.\n"); 1431 out_stream->Flush(); 1432 } 1433 } 1434 virtual void EOFHandler(HandlerData& data) 1435 { 1436 data.reader.SetIsDone (true); 1437 } 1438 virtual void DoneHandler(HandlerData& data) 1439 { 1440 StreamSP out_stream = data.GetOutStream(); 1441 1442 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1443 if (!interpreter) 1444 { 1445 out_stream->Printf ("Internal error #1: no script attached.\n"); 1446 out_stream->Flush(); 1447 return; 1448 } 1449 StringList funct_name_sl; 1450 if (!interpreter->GenerateScriptAliasFunction (m_user_input, 1451 funct_name_sl)) 1452 { 1453 out_stream->Printf ("Internal error #2: no script attached.\n"); 1454 out_stream->Flush(); 1455 return; 1456 } 1457 if (funct_name_sl.GetSize() == 0) 1458 { 1459 out_stream->Printf ("Internal error #3: no script attached.\n"); 1460 out_stream->Flush(); 1461 return; 1462 } 1463 const char *funct_name = funct_name_sl.GetStringAtIndex(0); 1464 if (!funct_name || !funct_name[0]) 1465 { 1466 out_stream->Printf ("Internal error #4: no script attached.\n"); 1467 out_stream->Flush(); 1468 return; 1469 } 1470 1471 // everything should be fine now, let's add this alias 1472 1473 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, 1474 m_cmd_name, 1475 funct_name)); 1476 1477 if (!m_interpreter.AddUserCommand(m_cmd_name.c_str(), command_obj_sp, true)) 1478 { 1479 out_stream->Printf ("Internal error #5: no script attached.\n"); 1480 out_stream->Flush(); 1481 return; 1482 } 1483 } 1484 }; 1485 1486 public: 1487 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 1488 CommandObject (interpreter, 1489 "command script add", 1490 "Add a scripted function as an LLDB command.", 1491 NULL), 1492 m_options (interpreter) 1493 { 1494 CommandArgumentEntry arg1; 1495 CommandArgumentData cmd_arg; 1496 1497 // Define the first (and only) variant of this arg. 1498 cmd_arg.arg_type = eArgTypeCommandName; 1499 cmd_arg.arg_repetition = eArgRepeatPlain; 1500 1501 // There is only one variant this argument could be; put it into the argument entry. 1502 arg1.push_back (cmd_arg); 1503 1504 // Push the data for the first argument into the m_arguments vector. 1505 m_arguments.push_back (arg1); 1506 } 1507 1508 ~CommandObjectCommandsScriptAdd () 1509 { 1510 } 1511 1512 bool 1513 Execute 1514 ( 1515 Args& args, 1516 CommandReturnObject &result 1517 ) 1518 { 1519 1520 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1521 { 1522 result.AppendError ("only scripting language supported for scripted commands is currently Python"); 1523 result.SetStatus (eReturnStatusFailed); 1524 return false; 1525 } 1526 1527 size_t argc = args.GetArgumentCount(); 1528 1529 if (argc != 1) 1530 { 1531 result.AppendError ("'command script add' requires one argument"); 1532 result.SetStatus (eReturnStatusFailed); 1533 return false; 1534 } 1535 1536 std::string cmd_name = args.GetArgumentAtIndex(0); 1537 1538 if (m_options.m_funct_name.empty()) 1539 { 1540 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(), 1541 m_interpreter, 1542 cmd_name)); 1543 1544 if (reader_sp) 1545 { 1546 1547 InputReaderEZ::InitializationParameters ipr; 1548 1549 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" "))); 1550 if (err.Success()) 1551 { 1552 m_interpreter.GetDebugger().PushInputReader (reader_sp); 1553 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1554 } 1555 else 1556 { 1557 result.AppendError (err.AsCString()); 1558 result.SetStatus (eReturnStatusFailed); 1559 } 1560 } 1561 else 1562 { 1563 result.AppendError("out of memory"); 1564 result.SetStatus (eReturnStatusFailed); 1565 } 1566 } 1567 else 1568 { 1569 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, cmd_name, m_options.m_funct_name)); 1570 if (m_interpreter.AddUserCommand(cmd_name.c_str(), new_cmd, true)) 1571 { 1572 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1573 } 1574 else 1575 { 1576 result.AppendError("cannot add command"); 1577 result.SetStatus (eReturnStatusFailed); 1578 } 1579 } 1580 1581 return result.Succeeded(); 1582 1583 } 1584 }; 1585 1586 OptionDefinition 1587 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 1588 { 1589 { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 1590 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1591 }; 1592 1593 //------------------------------------------------------------------------- 1594 // CommandObjectCommandsScriptList 1595 //------------------------------------------------------------------------- 1596 1597 class CommandObjectCommandsScriptList : public CommandObject 1598 { 1599 private: 1600 1601 public: 1602 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 1603 CommandObject (interpreter, 1604 "command script list", 1605 "List defined scripted commands.", 1606 NULL) 1607 { 1608 } 1609 1610 ~CommandObjectCommandsScriptList () 1611 { 1612 } 1613 1614 bool 1615 Execute 1616 ( 1617 Args& args, 1618 CommandReturnObject &result 1619 ) 1620 { 1621 1622 m_interpreter.GetHelp(result, 1623 CommandInterpreter::eCommandTypesUserDef); 1624 1625 result.SetStatus (eReturnStatusSuccessFinishResult); 1626 1627 return true; 1628 1629 1630 } 1631 }; 1632 1633 //------------------------------------------------------------------------- 1634 // CommandObjectCommandsScriptClear 1635 //------------------------------------------------------------------------- 1636 1637 class CommandObjectCommandsScriptClear : public CommandObject 1638 { 1639 private: 1640 1641 public: 1642 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 1643 CommandObject (interpreter, 1644 "command script clear", 1645 "Delete all scripted commands.", 1646 NULL) 1647 { 1648 } 1649 1650 ~CommandObjectCommandsScriptClear () 1651 { 1652 } 1653 1654 bool 1655 Execute 1656 ( 1657 Args& args, 1658 CommandReturnObject &result 1659 ) 1660 { 1661 1662 m_interpreter.RemoveAllUser(); 1663 1664 result.SetStatus (eReturnStatusSuccessFinishResult); 1665 1666 return true; 1667 1668 1669 } 1670 }; 1671 1672 //------------------------------------------------------------------------- 1673 // CommandObjectCommandsScriptDelete 1674 //------------------------------------------------------------------------- 1675 1676 class CommandObjectCommandsScriptDelete : public CommandObject 1677 { 1678 private: 1679 1680 public: 1681 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 1682 CommandObject (interpreter, 1683 "command script delete", 1684 "Delete a scripted command.", 1685 NULL) 1686 { 1687 CommandArgumentEntry arg1; 1688 CommandArgumentData cmd_arg; 1689 1690 // Define the first (and only) variant of this arg. 1691 cmd_arg.arg_type = eArgTypeCommandName; 1692 cmd_arg.arg_repetition = eArgRepeatPlain; 1693 1694 // There is only one variant this argument could be; put it into the argument entry. 1695 arg1.push_back (cmd_arg); 1696 1697 // Push the data for the first argument into the m_arguments vector. 1698 m_arguments.push_back (arg1); 1699 } 1700 1701 ~CommandObjectCommandsScriptDelete () 1702 { 1703 } 1704 1705 bool 1706 Execute 1707 ( 1708 Args& args, 1709 CommandReturnObject &result 1710 ) 1711 { 1712 1713 size_t argc = args.GetArgumentCount(); 1714 1715 if (argc != 1) 1716 { 1717 result.AppendError ("'command script delete' requires one argument"); 1718 result.SetStatus (eReturnStatusFailed); 1719 return false; 1720 } 1721 1722 const char* cmd_name = args.GetArgumentAtIndex(0); 1723 1724 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 1725 { 1726 m_interpreter.RemoveUser(cmd_name); 1727 result.SetStatus (eReturnStatusSuccessFinishResult); 1728 } 1729 else 1730 { 1731 result.AppendErrorWithFormat ("command %s not found", cmd_name); 1732 result.SetStatus (eReturnStatusFailed); 1733 } 1734 1735 return result.Succeeded(); 1736 1737 } 1738 }; 1739 1740 #pragma mark CommandObjectMultiwordCommandsScript 1741 1742 //------------------------------------------------------------------------- 1743 // CommandObjectMultiwordCommandsScript 1744 //------------------------------------------------------------------------- 1745 1746 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 1747 { 1748 public: 1749 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 1750 CommandObjectMultiword (interpreter, 1751 "command script", 1752 "A set of commands for managing or customizing script commands.", 1753 "command script <subcommand> [<subcommand-options>]") 1754 { 1755 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 1756 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 1757 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 1758 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 1759 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 1760 } 1761 1762 ~CommandObjectMultiwordCommandsScript () 1763 { 1764 } 1765 1766 }; 1767 1768 1769 #pragma mark CommandObjectMultiwordCommands 1770 1771 //------------------------------------------------------------------------- 1772 // CommandObjectMultiwordCommands 1773 //------------------------------------------------------------------------- 1774 1775 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 1776 CommandObjectMultiword (interpreter, 1777 "command", 1778 "A set of commands for managing or customizing the debugger commands.", 1779 "command <subcommand> [<subcommand-options>]") 1780 { 1781 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 1782 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 1783 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 1784 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 1785 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 1786 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 1787 } 1788 1789 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 1790 { 1791 } 1792 1793