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 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ 334 // command. \n\ 335 'command 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 'command 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 'command 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 command 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) command 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) command 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 command 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: 'command 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 ScriptedCommandSynchronicity m_synchro; 1157 1158 public: 1159 1160 CommandObjectPythonFunction (CommandInterpreter &interpreter, 1161 std::string name, 1162 std::string funct, 1163 ScriptedCommandSynchronicity synch) : 1164 CommandObject (interpreter, 1165 name.c_str(), 1166 (std::string("Run Python function ") + funct).c_str(), 1167 NULL), 1168 m_function_name(funct), 1169 m_synchro(synch) 1170 { 1171 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1172 if (scripter) 1173 { 1174 std::string docstring = scripter->GetDocumentationForItem(funct.c_str()); 1175 if (!docstring.empty()) 1176 SetHelpLong(docstring); 1177 } 1178 } 1179 1180 virtual 1181 ~CommandObjectPythonFunction () 1182 { 1183 } 1184 1185 virtual bool 1186 ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result) 1187 { 1188 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1189 1190 Error error; 1191 1192 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1193 raw_command_line, 1194 m_synchro, 1195 result, 1196 error) == false) 1197 { 1198 result.AppendError(error.AsCString()); 1199 result.SetStatus(eReturnStatusFailed); 1200 } 1201 else 1202 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1203 1204 return result.Succeeded(); 1205 } 1206 1207 virtual bool 1208 WantsRawCommandString () 1209 { 1210 return true; 1211 } 1212 1213 bool 1214 Execute (Args& command, 1215 CommandReturnObject &result) 1216 { 1217 std::string cmd_string; 1218 command.GetCommandString(cmd_string); 1219 return ExecuteRawCommandString(cmd_string.c_str(), result); 1220 } 1221 1222 virtual bool 1223 IsRemovable () 1224 { 1225 return true; 1226 } 1227 1228 const std::string& 1229 GetFunctionName () 1230 { 1231 return m_function_name; 1232 } 1233 1234 ScriptedCommandSynchronicity 1235 GetSynchronicity () 1236 { 1237 return m_synchro; 1238 } 1239 1240 }; 1241 1242 //------------------------------------------------------------------------- 1243 // CommandObjectCommandsScriptImport 1244 //------------------------------------------------------------------------- 1245 1246 class CommandObjectCommandsScriptImport : public CommandObject 1247 { 1248 private: 1249 1250 class CommandOptions : public Options 1251 { 1252 public: 1253 1254 CommandOptions (CommandInterpreter &interpreter) : 1255 Options (interpreter) 1256 { 1257 } 1258 1259 virtual 1260 ~CommandOptions (){} 1261 1262 virtual Error 1263 SetOptionValue (uint32_t option_idx, const char *option_arg) 1264 { 1265 Error error; 1266 char short_option = (char) m_getopt_table[option_idx].val; 1267 1268 switch (short_option) 1269 { 1270 case 'r': 1271 m_allow_reload = true; 1272 break; 1273 default: 1274 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1275 break; 1276 } 1277 1278 return error; 1279 } 1280 1281 void 1282 OptionParsingStarting () 1283 { 1284 m_allow_reload = false; 1285 } 1286 1287 const OptionDefinition* 1288 GetDefinitions () 1289 { 1290 return g_option_table; 1291 } 1292 1293 // Options table: Required for subclasses of Options. 1294 1295 static OptionDefinition g_option_table[]; 1296 1297 // Instance variables to hold the values for command options. 1298 1299 bool m_allow_reload; 1300 }; 1301 1302 CommandOptions m_options; 1303 1304 virtual Options * 1305 GetOptions () 1306 { 1307 return &m_options; 1308 } 1309 1310 public: 1311 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 1312 CommandObject (interpreter, 1313 "command script import", 1314 "Import a scripting module in LLDB.", 1315 NULL), 1316 m_options(interpreter) 1317 { 1318 CommandArgumentEntry arg1; 1319 CommandArgumentData cmd_arg; 1320 1321 // Define the first (and only) variant of this arg. 1322 cmd_arg.arg_type = eArgTypeFilename; 1323 cmd_arg.arg_repetition = eArgRepeatPlain; 1324 1325 // There is only one variant this argument could be; put it into the argument entry. 1326 arg1.push_back (cmd_arg); 1327 1328 // Push the data for the first argument into the m_arguments vector. 1329 m_arguments.push_back (arg1); 1330 } 1331 1332 ~CommandObjectCommandsScriptImport () 1333 { 1334 } 1335 1336 bool 1337 Execute 1338 ( 1339 Args& args, 1340 CommandReturnObject &result 1341 ) 1342 { 1343 1344 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1345 { 1346 result.AppendError ("only scripting language supported for module importing is currently Python"); 1347 result.SetStatus (eReturnStatusFailed); 1348 return false; 1349 } 1350 1351 size_t argc = args.GetArgumentCount(); 1352 1353 if (argc != 1) 1354 { 1355 result.AppendError ("'command script import' requires one argument"); 1356 result.SetStatus (eReturnStatusFailed); 1357 return false; 1358 } 1359 1360 std::string path = args.GetArgumentAtIndex(0); 1361 Error error; 1362 1363 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 1364 m_options.m_allow_reload, 1365 error)) 1366 { 1367 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1368 } 1369 else 1370 { 1371 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1372 result.SetStatus (eReturnStatusFailed); 1373 } 1374 1375 return result.Succeeded(); 1376 } 1377 1378 int 1379 HandleArgumentCompletion (Args &input, 1380 int &cursor_index, 1381 int &cursor_char_position, 1382 OptionElementVector &opt_element_vector, 1383 int match_start_point, 1384 int max_return_elements, 1385 bool &word_complete, 1386 StringList &matches) 1387 { 1388 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1389 completion_str.erase (cursor_char_position); 1390 1391 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1392 CommandCompletions::eDiskFileCompletion, 1393 completion_str.c_str(), 1394 match_start_point, 1395 max_return_elements, 1396 NULL, 1397 word_complete, 1398 matches); 1399 return matches.GetSize(); 1400 } 1401 }; 1402 1403 OptionDefinition 1404 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 1405 { 1406 { LLDB_OPT_SET_1, false, "allow-reload", 'r', no_argument, NULL, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before (for Python, the __lldb_init_module function will be called again, but the module will not be reloaded from disk)."}, 1407 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1408 }; 1409 1410 1411 //------------------------------------------------------------------------- 1412 // CommandObjectCommandsScriptAdd 1413 //------------------------------------------------------------------------- 1414 1415 class CommandObjectCommandsScriptAdd : public CommandObject 1416 { 1417 private: 1418 1419 class CommandOptions : public Options 1420 { 1421 public: 1422 1423 CommandOptions (CommandInterpreter &interpreter) : 1424 Options (interpreter) 1425 { 1426 } 1427 1428 virtual 1429 ~CommandOptions (){} 1430 1431 virtual Error 1432 SetOptionValue (uint32_t option_idx, const char *option_arg) 1433 { 1434 Error error; 1435 char short_option = (char) m_getopt_table[option_idx].val; 1436 1437 switch (short_option) 1438 { 1439 case 'f': 1440 m_funct_name = std::string(option_arg); 1441 break; 1442 case 's': 1443 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1444 if (!error.Success()) 1445 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 1446 break; 1447 default: 1448 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1449 break; 1450 } 1451 1452 return error; 1453 } 1454 1455 void 1456 OptionParsingStarting () 1457 { 1458 m_funct_name = ""; 1459 m_synchronous = eScriptedCommandSynchronicitySynchronous; 1460 } 1461 1462 const OptionDefinition* 1463 GetDefinitions () 1464 { 1465 return g_option_table; 1466 } 1467 1468 // Options table: Required for subclasses of Options. 1469 1470 static OptionDefinition g_option_table[]; 1471 1472 // Instance variables to hold the values for command options. 1473 1474 std::string m_funct_name; 1475 ScriptedCommandSynchronicity m_synchronous; 1476 }; 1477 1478 CommandOptions m_options; 1479 1480 virtual Options * 1481 GetOptions () 1482 { 1483 return &m_options; 1484 } 1485 1486 class PythonAliasReader : public InputReaderEZ 1487 { 1488 private: 1489 CommandInterpreter& m_interpreter; 1490 std::string m_cmd_name; 1491 ScriptedCommandSynchronicity m_synchronous; 1492 StringList m_user_input; 1493 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader); 1494 public: 1495 PythonAliasReader(Debugger& debugger, 1496 CommandInterpreter& interpreter, 1497 std::string cmd_name, 1498 ScriptedCommandSynchronicity synch) : 1499 InputReaderEZ(debugger), 1500 m_interpreter(interpreter), 1501 m_cmd_name(cmd_name), 1502 m_synchronous(synch), 1503 m_user_input() 1504 {} 1505 1506 virtual 1507 ~PythonAliasReader() 1508 { 1509 } 1510 1511 virtual void ActivateHandler(HandlerData& data) 1512 { 1513 StreamSP out_stream = data.GetOutStream(); 1514 bool batch_mode = data.GetBatchMode(); 1515 if (!batch_mode) 1516 { 1517 out_stream->Printf ("%s\n", g_python_command_instructions); 1518 if (data.reader.GetPrompt()) 1519 out_stream->Printf ("%s", data.reader.GetPrompt()); 1520 out_stream->Flush(); 1521 } 1522 } 1523 1524 virtual void ReactivateHandler(HandlerData& data) 1525 { 1526 StreamSP out_stream = data.GetOutStream(); 1527 bool batch_mode = data.GetBatchMode(); 1528 if (data.reader.GetPrompt() && !batch_mode) 1529 { 1530 out_stream->Printf ("%s", data.reader.GetPrompt()); 1531 out_stream->Flush(); 1532 } 1533 } 1534 virtual void GotTokenHandler(HandlerData& data) 1535 { 1536 StreamSP out_stream = data.GetOutStream(); 1537 bool batch_mode = data.GetBatchMode(); 1538 if (data.bytes && data.bytes_len) 1539 { 1540 m_user_input.AppendString(data.bytes, data.bytes_len); 1541 } 1542 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) 1543 { 1544 out_stream->Printf ("%s", data.reader.GetPrompt()); 1545 out_stream->Flush(); 1546 } 1547 } 1548 virtual void InterruptHandler(HandlerData& data) 1549 { 1550 StreamSP out_stream = data.GetOutStream(); 1551 bool batch_mode = data.GetBatchMode(); 1552 data.reader.SetIsDone (true); 1553 if (!batch_mode) 1554 { 1555 out_stream->Printf ("Warning: No script attached.\n"); 1556 out_stream->Flush(); 1557 } 1558 } 1559 virtual void EOFHandler(HandlerData& data) 1560 { 1561 data.reader.SetIsDone (true); 1562 } 1563 virtual void DoneHandler(HandlerData& data) 1564 { 1565 StreamSP out_stream = data.GetOutStream(); 1566 1567 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1568 if (!interpreter) 1569 { 1570 out_stream->Printf ("Script interpreter missing: no script attached.\n"); 1571 out_stream->Flush(); 1572 return; 1573 } 1574 std::string funct_name_str; 1575 if (!interpreter->GenerateScriptAliasFunction (m_user_input, 1576 funct_name_str)) 1577 { 1578 out_stream->Printf ("Unable to create function: no script attached.\n"); 1579 out_stream->Flush(); 1580 return; 1581 } 1582 if (funct_name_str.empty()) 1583 { 1584 out_stream->Printf ("Unable to obtain a function name: no script attached.\n"); 1585 out_stream->Flush(); 1586 return; 1587 } 1588 // everything should be fine now, let's add this alias 1589 1590 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, 1591 m_cmd_name, 1592 funct_name_str.c_str(), 1593 m_synchronous)); 1594 1595 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1596 { 1597 out_stream->Printf ("Unable to add selected command: no script attached.\n"); 1598 out_stream->Flush(); 1599 return; 1600 } 1601 } 1602 }; 1603 1604 public: 1605 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 1606 CommandObject (interpreter, 1607 "command script add", 1608 "Add a scripted function as an LLDB command.", 1609 NULL), 1610 m_options (interpreter) 1611 { 1612 CommandArgumentEntry arg1; 1613 CommandArgumentData cmd_arg; 1614 1615 // Define the first (and only) variant of this arg. 1616 cmd_arg.arg_type = eArgTypeCommandName; 1617 cmd_arg.arg_repetition = eArgRepeatPlain; 1618 1619 // There is only one variant this argument could be; put it into the argument entry. 1620 arg1.push_back (cmd_arg); 1621 1622 // Push the data for the first argument into the m_arguments vector. 1623 m_arguments.push_back (arg1); 1624 } 1625 1626 ~CommandObjectCommandsScriptAdd () 1627 { 1628 } 1629 1630 bool 1631 Execute 1632 ( 1633 Args& args, 1634 CommandReturnObject &result 1635 ) 1636 { 1637 1638 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1639 { 1640 result.AppendError ("only scripting language supported for scripted commands is currently Python"); 1641 result.SetStatus (eReturnStatusFailed); 1642 return false; 1643 } 1644 1645 size_t argc = args.GetArgumentCount(); 1646 1647 if (argc != 1) 1648 { 1649 result.AppendError ("'command script add' requires one argument"); 1650 result.SetStatus (eReturnStatusFailed); 1651 return false; 1652 } 1653 1654 std::string cmd_name = args.GetArgumentAtIndex(0); 1655 1656 if (m_options.m_funct_name.empty()) 1657 { 1658 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(), 1659 m_interpreter, 1660 cmd_name, 1661 m_options.m_synchronous)); 1662 1663 if (reader_sp) 1664 { 1665 1666 InputReaderEZ::InitializationParameters ipr; 1667 1668 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" "))); 1669 if (err.Success()) 1670 { 1671 m_interpreter.GetDebugger().PushInputReader (reader_sp); 1672 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1673 } 1674 else 1675 { 1676 result.AppendError (err.AsCString()); 1677 result.SetStatus (eReturnStatusFailed); 1678 } 1679 } 1680 else 1681 { 1682 result.AppendError("out of memory"); 1683 result.SetStatus (eReturnStatusFailed); 1684 } 1685 } 1686 else 1687 { 1688 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 1689 cmd_name, 1690 m_options.m_funct_name, 1691 m_options.m_synchronous)); 1692 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true)) 1693 { 1694 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1695 } 1696 else 1697 { 1698 result.AppendError("cannot add command"); 1699 result.SetStatus (eReturnStatusFailed); 1700 } 1701 } 1702 1703 return result.Succeeded(); 1704 1705 } 1706 }; 1707 1708 static OptionEnumValueElement g_script_synchro_type[] = 1709 { 1710 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 1711 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 1712 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 1713 { 0, NULL, NULL } 1714 }; 1715 1716 OptionDefinition 1717 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 1718 { 1719 { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 1720 { LLDB_OPT_SET_1, false, "synchronicity", 's', required_argument, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."}, 1721 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1722 }; 1723 1724 //------------------------------------------------------------------------- 1725 // CommandObjectCommandsScriptList 1726 //------------------------------------------------------------------------- 1727 1728 class CommandObjectCommandsScriptList : public CommandObject 1729 { 1730 private: 1731 1732 public: 1733 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 1734 CommandObject (interpreter, 1735 "command script list", 1736 "List defined scripted commands.", 1737 NULL) 1738 { 1739 } 1740 1741 ~CommandObjectCommandsScriptList () 1742 { 1743 } 1744 1745 bool 1746 Execute 1747 ( 1748 Args& args, 1749 CommandReturnObject &result 1750 ) 1751 { 1752 1753 m_interpreter.GetHelp(result, 1754 CommandInterpreter::eCommandTypesUserDef); 1755 1756 result.SetStatus (eReturnStatusSuccessFinishResult); 1757 1758 return true; 1759 1760 1761 } 1762 }; 1763 1764 //------------------------------------------------------------------------- 1765 // CommandObjectCommandsScriptClear 1766 //------------------------------------------------------------------------- 1767 1768 class CommandObjectCommandsScriptClear : public CommandObject 1769 { 1770 private: 1771 1772 public: 1773 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 1774 CommandObject (interpreter, 1775 "command script clear", 1776 "Delete all scripted commands.", 1777 NULL) 1778 { 1779 } 1780 1781 ~CommandObjectCommandsScriptClear () 1782 { 1783 } 1784 1785 bool 1786 Execute 1787 ( 1788 Args& args, 1789 CommandReturnObject &result 1790 ) 1791 { 1792 1793 m_interpreter.RemoveAllUser(); 1794 1795 result.SetStatus (eReturnStatusSuccessFinishResult); 1796 1797 return true; 1798 1799 1800 } 1801 }; 1802 1803 //------------------------------------------------------------------------- 1804 // CommandObjectCommandsScriptDelete 1805 //------------------------------------------------------------------------- 1806 1807 class CommandObjectCommandsScriptDelete : public CommandObject 1808 { 1809 private: 1810 1811 public: 1812 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 1813 CommandObject (interpreter, 1814 "command script delete", 1815 "Delete a scripted command.", 1816 NULL) 1817 { 1818 CommandArgumentEntry arg1; 1819 CommandArgumentData cmd_arg; 1820 1821 // Define the first (and only) variant of this arg. 1822 cmd_arg.arg_type = eArgTypeCommandName; 1823 cmd_arg.arg_repetition = eArgRepeatPlain; 1824 1825 // There is only one variant this argument could be; put it into the argument entry. 1826 arg1.push_back (cmd_arg); 1827 1828 // Push the data for the first argument into the m_arguments vector. 1829 m_arguments.push_back (arg1); 1830 } 1831 1832 ~CommandObjectCommandsScriptDelete () 1833 { 1834 } 1835 1836 bool 1837 Execute 1838 ( 1839 Args& args, 1840 CommandReturnObject &result 1841 ) 1842 { 1843 1844 size_t argc = args.GetArgumentCount(); 1845 1846 if (argc != 1) 1847 { 1848 result.AppendError ("'command script delete' requires one argument"); 1849 result.SetStatus (eReturnStatusFailed); 1850 return false; 1851 } 1852 1853 const char* cmd_name = args.GetArgumentAtIndex(0); 1854 1855 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 1856 { 1857 m_interpreter.RemoveUser(cmd_name); 1858 result.SetStatus (eReturnStatusSuccessFinishResult); 1859 } 1860 else 1861 { 1862 result.AppendErrorWithFormat ("command %s not found", cmd_name); 1863 result.SetStatus (eReturnStatusFailed); 1864 } 1865 1866 return result.Succeeded(); 1867 1868 } 1869 }; 1870 1871 #pragma mark CommandObjectMultiwordCommandsScript 1872 1873 //------------------------------------------------------------------------- 1874 // CommandObjectMultiwordCommandsScript 1875 //------------------------------------------------------------------------- 1876 1877 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 1878 { 1879 public: 1880 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 1881 CommandObjectMultiword (interpreter, 1882 "command script", 1883 "A set of commands for managing or customizing script commands.", 1884 "command script <subcommand> [<subcommand-options>]") 1885 { 1886 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 1887 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 1888 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 1889 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 1890 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 1891 } 1892 1893 ~CommandObjectMultiwordCommandsScript () 1894 { 1895 } 1896 1897 }; 1898 1899 1900 #pragma mark CommandObjectMultiwordCommands 1901 1902 //------------------------------------------------------------------------- 1903 // CommandObjectMultiwordCommands 1904 //------------------------------------------------------------------------- 1905 1906 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 1907 CommandObjectMultiword (interpreter, 1908 "command", 1909 "A set of commands for managing or customizing the debugger commands.", 1910 "command <subcommand> [<subcommand-options>]") 1911 { 1912 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 1913 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 1914 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 1915 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 1916 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 1917 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 1918 } 1919 1920 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 1921 { 1922 } 1923 1924