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