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