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, 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 with 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 "(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n" 799 ); 800 } 801 802 ~CommandObjectCommandsAddRegex() 803 { 804 } 805 806 807 protected: 808 bool 809 DoExecute (Args& command, CommandReturnObject &result) 810 { 811 const size_t argc = command.GetArgumentCount(); 812 if (argc == 0) 813 { 814 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 815 result.SetStatus (eReturnStatusFailed); 816 } 817 else 818 { 819 Error error; 820 const char *name = command.GetArgumentAtIndex(0); 821 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 822 name, 823 m_options.GetHelp (), 824 m_options.GetSyntax (), 825 10)); 826 827 if (argc == 1) 828 { 829 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 830 if (reader_sp) 831 { 832 error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback, 833 this, // baton 834 eInputReaderGranularityLine, // token size, to pass to callback function 835 NULL, // end token 836 "> ", // prompt 837 true); // echo input 838 if (error.Success()) 839 { 840 m_interpreter.GetDebugger().PushInputReader (reader_sp); 841 result.SetStatus (eReturnStatusSuccessFinishNoResult); 842 return true; 843 } 844 } 845 } 846 else 847 { 848 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 849 { 850 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 851 error = AppendRegexSubstitution (arg_strref); 852 if (error.Fail()) 853 break; 854 } 855 856 if (error.Success()) 857 { 858 AddRegexCommandToInterpreter(); 859 } 860 } 861 if (error.Fail()) 862 { 863 result.AppendError (error.AsCString()); 864 result.SetStatus (eReturnStatusFailed); 865 } 866 } 867 868 return result.Succeeded(); 869 } 870 871 Error 872 AppendRegexSubstitution (const llvm::StringRef ®ex_sed) 873 { 874 Error error; 875 876 if (m_regex_cmd_ap.get() == NULL) 877 { 878 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 879 (int)regex_sed.size(), 880 regex_sed.data()); 881 return error; 882 } 883 884 size_t regex_sed_size = regex_sed.size(); 885 886 if (regex_sed_size <= 1) 887 { 888 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 889 (int)regex_sed.size(), 890 regex_sed.data()); 891 return error; 892 } 893 894 if (regex_sed[0] != 's') 895 { 896 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 897 (int)regex_sed.size(), 898 regex_sed.data()); 899 return error; 900 } 901 const size_t first_separator_char_pos = 1; 902 // use the char that follows 's' as the regex separator character 903 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 904 const char separator_char = regex_sed[first_separator_char_pos]; 905 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 906 907 if (second_separator_char_pos == std::string::npos) 908 { 909 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'", 910 separator_char, 911 (int)(regex_sed.size() - first_separator_char_pos - 1), 912 regex_sed.data() + (first_separator_char_pos + 1)); 913 return error; 914 } 915 916 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 917 918 if (third_separator_char_pos == std::string::npos) 919 { 920 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'", 921 separator_char, 922 (int)(regex_sed.size() - second_separator_char_pos - 1), 923 regex_sed.data() + (second_separator_char_pos + 1)); 924 return error; 925 } 926 927 if (third_separator_char_pos != regex_sed_size - 1) 928 { 929 // Make sure that everything that follows the last regex 930 // separator char 931 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 932 { 933 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 934 (int)third_separator_char_pos + 1, 935 regex_sed.data(), 936 (int)(regex_sed.size() - third_separator_char_pos - 1), 937 regex_sed.data() + (third_separator_char_pos + 1)); 938 return error; 939 } 940 941 } 942 else if (first_separator_char_pos + 1 == second_separator_char_pos) 943 { 944 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 945 separator_char, 946 separator_char, 947 separator_char, 948 (int)regex_sed.size(), 949 regex_sed.data()); 950 return error; 951 } 952 else if (second_separator_char_pos + 1 == third_separator_char_pos) 953 { 954 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 955 separator_char, 956 separator_char, 957 separator_char, 958 (int)regex_sed.size(), 959 regex_sed.data()); 960 return error; 961 } 962 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 963 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 964 m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 965 subst.c_str()); 966 return error; 967 } 968 969 void 970 AddRegexCommandToInterpreter() 971 { 972 if (m_regex_cmd_ap.get()) 973 { 974 if (m_regex_cmd_ap->HasRegexEntries()) 975 { 976 CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 977 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 978 } 979 } 980 } 981 982 void 983 InputReaderDidCancel() 984 { 985 m_regex_cmd_ap.reset(); 986 } 987 988 static size_t 989 InputReaderCallback (void *baton, 990 InputReader &reader, 991 lldb::InputReaderAction notification, 992 const char *bytes, 993 size_t bytes_len) 994 { 995 CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton; 996 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 997 998 switch (notification) 999 { 1000 case eInputReaderActivate: 1001 if (!batch_mode) 1002 { 1003 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream (); 1004 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:"); 1005 out_stream->Flush(); 1006 } 1007 break; 1008 case eInputReaderReactivate: 1009 break; 1010 1011 case eInputReaderDeactivate: 1012 break; 1013 1014 case eInputReaderAsynchronousOutputWritten: 1015 break; 1016 1017 case eInputReaderGotToken: 1018 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n')) 1019 --bytes_len; 1020 if (bytes_len == 0) 1021 reader.SetIsDone(true); 1022 else if (bytes) 1023 { 1024 llvm::StringRef bytes_strref (bytes, bytes_len); 1025 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref)); 1026 if (error.Fail()) 1027 { 1028 if (!batch_mode) 1029 { 1030 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 1031 out_stream->Printf("error: %s\n", error.AsCString()); 1032 out_stream->Flush(); 1033 } 1034 add_regex_cmd->InputReaderDidCancel (); 1035 reader.SetIsDone (true); 1036 } 1037 } 1038 break; 1039 1040 case eInputReaderInterrupt: 1041 { 1042 reader.SetIsDone (true); 1043 if (!batch_mode) 1044 { 1045 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 1046 out_stream->PutCString("Regular expression command creations was cancelled.\n"); 1047 out_stream->Flush(); 1048 } 1049 add_regex_cmd->InputReaderDidCancel (); 1050 } 1051 break; 1052 1053 case eInputReaderEndOfFile: 1054 reader.SetIsDone (true); 1055 break; 1056 1057 case eInputReaderDone: 1058 add_regex_cmd->AddRegexCommandToInterpreter(); 1059 break; 1060 } 1061 1062 return bytes_len; 1063 } 1064 1065 private: 1066 std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1067 1068 class CommandOptions : public Options 1069 { 1070 public: 1071 1072 CommandOptions (CommandInterpreter &interpreter) : 1073 Options (interpreter) 1074 { 1075 } 1076 1077 virtual 1078 ~CommandOptions (){} 1079 1080 virtual Error 1081 SetOptionValue (uint32_t option_idx, const char *option_arg) 1082 { 1083 Error error; 1084 char short_option = (char) m_getopt_table[option_idx].val; 1085 1086 switch (short_option) 1087 { 1088 case 'h': 1089 m_help.assign (option_arg); 1090 break; 1091 case 's': 1092 m_syntax.assign (option_arg); 1093 break; 1094 1095 default: 1096 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1097 break; 1098 } 1099 1100 return error; 1101 } 1102 1103 void 1104 OptionParsingStarting () 1105 { 1106 m_help.clear(); 1107 m_syntax.clear(); 1108 } 1109 1110 const OptionDefinition* 1111 GetDefinitions () 1112 { 1113 return g_option_table; 1114 } 1115 1116 // Options table: Required for subclasses of Options. 1117 1118 static OptionDefinition g_option_table[]; 1119 1120 const char * 1121 GetHelp () 1122 { 1123 if (m_help.empty()) 1124 return NULL; 1125 return m_help.c_str(); 1126 } 1127 const char * 1128 GetSyntax () 1129 { 1130 if (m_syntax.empty()) 1131 return NULL; 1132 return m_syntax.c_str(); 1133 } 1134 // Instance variables to hold the values for command options. 1135 protected: 1136 std::string m_help; 1137 std::string m_syntax; 1138 }; 1139 1140 virtual Options * 1141 GetOptions () 1142 { 1143 return &m_options; 1144 } 1145 1146 CommandOptions m_options; 1147 }; 1148 1149 OptionDefinition 1150 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1151 { 1152 { LLDB_OPT_SET_1, false, "help" , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1153 { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1154 { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL } 1155 }; 1156 1157 1158 class CommandObjectPythonFunction : public CommandObjectRaw 1159 { 1160 private: 1161 std::string m_function_name; 1162 ScriptedCommandSynchronicity m_synchro; 1163 1164 public: 1165 1166 CommandObjectPythonFunction (CommandInterpreter &interpreter, 1167 std::string name, 1168 std::string funct, 1169 ScriptedCommandSynchronicity synch) : 1170 CommandObjectRaw (interpreter, 1171 name.c_str(), 1172 (std::string("Run Python function ") + funct).c_str(), 1173 NULL), 1174 m_function_name(funct), 1175 m_synchro(synch) 1176 { 1177 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1178 if (scripter) 1179 { 1180 std::string docstring = scripter->GetDocumentationForItem(funct.c_str()); 1181 if (!docstring.empty()) 1182 SetHelpLong(docstring); 1183 } 1184 } 1185 1186 virtual 1187 ~CommandObjectPythonFunction () 1188 { 1189 } 1190 1191 virtual bool 1192 IsRemovable () 1193 { 1194 return true; 1195 } 1196 1197 const std::string& 1198 GetFunctionName () 1199 { 1200 return m_function_name; 1201 } 1202 1203 ScriptedCommandSynchronicity 1204 GetSynchronicity () 1205 { 1206 return m_synchro; 1207 } 1208 1209 protected: 1210 virtual bool 1211 DoExecute (const char *raw_command_line, CommandReturnObject &result) 1212 { 1213 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1214 1215 Error error; 1216 1217 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1218 raw_command_line, 1219 m_synchro, 1220 result, 1221 error) == false) 1222 { 1223 result.AppendError(error.AsCString()); 1224 result.SetStatus(eReturnStatusFailed); 1225 } 1226 else 1227 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1228 1229 return result.Succeeded(); 1230 } 1231 1232 }; 1233 1234 //------------------------------------------------------------------------- 1235 // CommandObjectCommandsScriptImport 1236 //------------------------------------------------------------------------- 1237 1238 class CommandObjectCommandsScriptImport : public CommandObjectParsed 1239 { 1240 public: 1241 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 1242 CommandObjectParsed (interpreter, 1243 "command script import", 1244 "Import a scripting module in LLDB.", 1245 NULL), 1246 m_options(interpreter) 1247 { 1248 CommandArgumentEntry arg1; 1249 CommandArgumentData cmd_arg; 1250 1251 // Define the first (and only) variant of this arg. 1252 cmd_arg.arg_type = eArgTypeFilename; 1253 cmd_arg.arg_repetition = eArgRepeatPlain; 1254 1255 // There is only one variant this argument could be; put it into the argument entry. 1256 arg1.push_back (cmd_arg); 1257 1258 // Push the data for the first argument into the m_arguments vector. 1259 m_arguments.push_back (arg1); 1260 } 1261 1262 ~CommandObjectCommandsScriptImport () 1263 { 1264 } 1265 1266 int 1267 HandleArgumentCompletion (Args &input, 1268 int &cursor_index, 1269 int &cursor_char_position, 1270 OptionElementVector &opt_element_vector, 1271 int match_start_point, 1272 int max_return_elements, 1273 bool &word_complete, 1274 StringList &matches) 1275 { 1276 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1277 completion_str.erase (cursor_char_position); 1278 1279 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1280 CommandCompletions::eDiskFileCompletion, 1281 completion_str.c_str(), 1282 match_start_point, 1283 max_return_elements, 1284 NULL, 1285 word_complete, 1286 matches); 1287 return matches.GetSize(); 1288 } 1289 1290 virtual Options * 1291 GetOptions () 1292 { 1293 return &m_options; 1294 } 1295 1296 protected: 1297 1298 class CommandOptions : public Options 1299 { 1300 public: 1301 1302 CommandOptions (CommandInterpreter &interpreter) : 1303 Options (interpreter) 1304 { 1305 } 1306 1307 virtual 1308 ~CommandOptions (){} 1309 1310 virtual Error 1311 SetOptionValue (uint32_t option_idx, const char *option_arg) 1312 { 1313 Error error; 1314 char short_option = (char) m_getopt_table[option_idx].val; 1315 1316 switch (short_option) 1317 { 1318 case 'r': 1319 m_allow_reload = true; 1320 break; 1321 default: 1322 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1323 break; 1324 } 1325 1326 return error; 1327 } 1328 1329 void 1330 OptionParsingStarting () 1331 { 1332 m_allow_reload = false; 1333 } 1334 1335 const OptionDefinition* 1336 GetDefinitions () 1337 { 1338 return g_option_table; 1339 } 1340 1341 // Options table: Required for subclasses of Options. 1342 1343 static OptionDefinition g_option_table[]; 1344 1345 // Instance variables to hold the values for command options. 1346 1347 bool m_allow_reload; 1348 }; 1349 1350 bool 1351 DoExecute (Args& command, CommandReturnObject &result) 1352 { 1353 1354 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1355 { 1356 result.AppendError ("only scripting language supported for module importing is currently Python"); 1357 result.SetStatus (eReturnStatusFailed); 1358 return false; 1359 } 1360 1361 size_t argc = command.GetArgumentCount(); 1362 1363 if (argc != 1) 1364 { 1365 result.AppendError ("'command script import' requires one argument"); 1366 result.SetStatus (eReturnStatusFailed); 1367 return false; 1368 } 1369 1370 std::string path = command.GetArgumentAtIndex(0); 1371 Error error; 1372 1373 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 1374 m_options.m_allow_reload, 1375 error)) 1376 { 1377 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1378 } 1379 else 1380 { 1381 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1382 result.SetStatus (eReturnStatusFailed); 1383 } 1384 1385 return result.Succeeded(); 1386 } 1387 1388 CommandOptions m_options; 1389 }; 1390 1391 OptionDefinition 1392 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 1393 { 1394 { 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)."}, 1395 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1396 }; 1397 1398 1399 //------------------------------------------------------------------------- 1400 // CommandObjectCommandsScriptAdd 1401 //------------------------------------------------------------------------- 1402 1403 class CommandObjectCommandsScriptAdd : public CommandObjectParsed 1404 { 1405 public: 1406 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 1407 CommandObjectParsed (interpreter, 1408 "command script add", 1409 "Add a scripted function as an LLDB command.", 1410 NULL), 1411 m_options (interpreter) 1412 { 1413 CommandArgumentEntry arg1; 1414 CommandArgumentData cmd_arg; 1415 1416 // Define the first (and only) variant of this arg. 1417 cmd_arg.arg_type = eArgTypeCommandName; 1418 cmd_arg.arg_repetition = eArgRepeatPlain; 1419 1420 // There is only one variant this argument could be; put it into the argument entry. 1421 arg1.push_back (cmd_arg); 1422 1423 // Push the data for the first argument into the m_arguments vector. 1424 m_arguments.push_back (arg1); 1425 } 1426 1427 ~CommandObjectCommandsScriptAdd () 1428 { 1429 } 1430 1431 virtual Options * 1432 GetOptions () 1433 { 1434 return &m_options; 1435 } 1436 1437 protected: 1438 1439 class CommandOptions : public Options 1440 { 1441 public: 1442 1443 CommandOptions (CommandInterpreter &interpreter) : 1444 Options (interpreter) 1445 { 1446 } 1447 1448 virtual 1449 ~CommandOptions (){} 1450 1451 virtual Error 1452 SetOptionValue (uint32_t option_idx, const char *option_arg) 1453 { 1454 Error error; 1455 char short_option = (char) m_getopt_table[option_idx].val; 1456 1457 switch (short_option) 1458 { 1459 case 'f': 1460 m_funct_name = std::string(option_arg); 1461 break; 1462 case 's': 1463 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1464 if (!error.Success()) 1465 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 1466 break; 1467 default: 1468 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1469 break; 1470 } 1471 1472 return error; 1473 } 1474 1475 void 1476 OptionParsingStarting () 1477 { 1478 m_funct_name = ""; 1479 m_synchronous = eScriptedCommandSynchronicitySynchronous; 1480 } 1481 1482 const OptionDefinition* 1483 GetDefinitions () 1484 { 1485 return g_option_table; 1486 } 1487 1488 // Options table: Required for subclasses of Options. 1489 1490 static OptionDefinition g_option_table[]; 1491 1492 // Instance variables to hold the values for command options. 1493 1494 std::string m_funct_name; 1495 ScriptedCommandSynchronicity m_synchronous; 1496 }; 1497 1498 private: 1499 class PythonAliasReader : public InputReaderEZ 1500 { 1501 private: 1502 CommandInterpreter& m_interpreter; 1503 std::string m_cmd_name; 1504 ScriptedCommandSynchronicity m_synchronous; 1505 StringList m_user_input; 1506 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader); 1507 public: 1508 PythonAliasReader(Debugger& debugger, 1509 CommandInterpreter& interpreter, 1510 std::string cmd_name, 1511 ScriptedCommandSynchronicity synch) : 1512 InputReaderEZ(debugger), 1513 m_interpreter(interpreter), 1514 m_cmd_name(cmd_name), 1515 m_synchronous(synch), 1516 m_user_input() 1517 {} 1518 1519 virtual 1520 ~PythonAliasReader() 1521 { 1522 } 1523 1524 virtual void ActivateHandler(HandlerData& data) 1525 { 1526 StreamSP out_stream = data.GetOutStream(); 1527 bool batch_mode = data.GetBatchMode(); 1528 if (!batch_mode) 1529 { 1530 out_stream->Printf ("%s\n", g_python_command_instructions); 1531 if (data.reader.GetPrompt()) 1532 out_stream->Printf ("%s", data.reader.GetPrompt()); 1533 out_stream->Flush(); 1534 } 1535 } 1536 1537 virtual void ReactivateHandler(HandlerData& data) 1538 { 1539 StreamSP out_stream = data.GetOutStream(); 1540 bool batch_mode = data.GetBatchMode(); 1541 if (data.reader.GetPrompt() && !batch_mode) 1542 { 1543 out_stream->Printf ("%s", data.reader.GetPrompt()); 1544 out_stream->Flush(); 1545 } 1546 } 1547 virtual void GotTokenHandler(HandlerData& data) 1548 { 1549 StreamSP out_stream = data.GetOutStream(); 1550 bool batch_mode = data.GetBatchMode(); 1551 if (data.bytes && data.bytes_len) 1552 { 1553 m_user_input.AppendString(data.bytes, data.bytes_len); 1554 } 1555 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) 1556 { 1557 out_stream->Printf ("%s", data.reader.GetPrompt()); 1558 out_stream->Flush(); 1559 } 1560 } 1561 virtual void InterruptHandler(HandlerData& data) 1562 { 1563 StreamSP out_stream = data.GetOutStream(); 1564 bool batch_mode = data.GetBatchMode(); 1565 data.reader.SetIsDone (true); 1566 if (!batch_mode) 1567 { 1568 out_stream->Printf ("Warning: No script attached.\n"); 1569 out_stream->Flush(); 1570 } 1571 } 1572 virtual void EOFHandler(HandlerData& data) 1573 { 1574 data.reader.SetIsDone (true); 1575 } 1576 virtual void DoneHandler(HandlerData& data) 1577 { 1578 StreamSP out_stream = data.GetOutStream(); 1579 1580 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1581 if (!interpreter) 1582 { 1583 out_stream->Printf ("Script interpreter missing: no script attached.\n"); 1584 out_stream->Flush(); 1585 return; 1586 } 1587 std::string funct_name_str; 1588 if (!interpreter->GenerateScriptAliasFunction (m_user_input, 1589 funct_name_str)) 1590 { 1591 out_stream->Printf ("Unable to create function: no script attached.\n"); 1592 out_stream->Flush(); 1593 return; 1594 } 1595 if (funct_name_str.empty()) 1596 { 1597 out_stream->Printf ("Unable to obtain a function name: no script attached.\n"); 1598 out_stream->Flush(); 1599 return; 1600 } 1601 // everything should be fine now, let's add this alias 1602 1603 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, 1604 m_cmd_name, 1605 funct_name_str.c_str(), 1606 m_synchronous)); 1607 1608 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1609 { 1610 out_stream->Printf ("Unable to add selected command: no script attached.\n"); 1611 out_stream->Flush(); 1612 return; 1613 } 1614 } 1615 }; 1616 1617 protected: 1618 bool 1619 DoExecute (Args& command, CommandReturnObject &result) 1620 { 1621 1622 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1623 { 1624 result.AppendError ("only scripting language supported for scripted commands is currently Python"); 1625 result.SetStatus (eReturnStatusFailed); 1626 return false; 1627 } 1628 1629 size_t argc = command.GetArgumentCount(); 1630 1631 if (argc != 1) 1632 { 1633 result.AppendError ("'command script add' requires one argument"); 1634 result.SetStatus (eReturnStatusFailed); 1635 return false; 1636 } 1637 1638 std::string cmd_name = command.GetArgumentAtIndex(0); 1639 1640 if (m_options.m_funct_name.empty()) 1641 { 1642 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(), 1643 m_interpreter, 1644 cmd_name, 1645 m_options.m_synchronous)); 1646 1647 if (reader_sp) 1648 { 1649 1650 InputReaderEZ::InitializationParameters ipr; 1651 1652 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" "))); 1653 if (err.Success()) 1654 { 1655 m_interpreter.GetDebugger().PushInputReader (reader_sp); 1656 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1657 } 1658 else 1659 { 1660 result.AppendError (err.AsCString()); 1661 result.SetStatus (eReturnStatusFailed); 1662 } 1663 } 1664 else 1665 { 1666 result.AppendError("out of memory"); 1667 result.SetStatus (eReturnStatusFailed); 1668 } 1669 } 1670 else 1671 { 1672 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 1673 cmd_name, 1674 m_options.m_funct_name, 1675 m_options.m_synchronous)); 1676 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true)) 1677 { 1678 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1679 } 1680 else 1681 { 1682 result.AppendError("cannot add command"); 1683 result.SetStatus (eReturnStatusFailed); 1684 } 1685 } 1686 1687 return result.Succeeded(); 1688 1689 } 1690 1691 CommandOptions m_options; 1692 }; 1693 1694 static OptionEnumValueElement g_script_synchro_type[] = 1695 { 1696 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 1697 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 1698 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 1699 { 0, NULL, NULL } 1700 }; 1701 1702 OptionDefinition 1703 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 1704 { 1705 { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 1706 { 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."}, 1707 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1708 }; 1709 1710 //------------------------------------------------------------------------- 1711 // CommandObjectCommandsScriptList 1712 //------------------------------------------------------------------------- 1713 1714 class CommandObjectCommandsScriptList : public CommandObjectParsed 1715 { 1716 private: 1717 1718 public: 1719 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 1720 CommandObjectParsed (interpreter, 1721 "command script list", 1722 "List defined scripted commands.", 1723 NULL) 1724 { 1725 } 1726 1727 ~CommandObjectCommandsScriptList () 1728 { 1729 } 1730 1731 bool 1732 DoExecute (Args& command, CommandReturnObject &result) 1733 { 1734 1735 m_interpreter.GetHelp(result, 1736 CommandInterpreter::eCommandTypesUserDef); 1737 1738 result.SetStatus (eReturnStatusSuccessFinishResult); 1739 1740 return true; 1741 1742 1743 } 1744 }; 1745 1746 //------------------------------------------------------------------------- 1747 // CommandObjectCommandsScriptClear 1748 //------------------------------------------------------------------------- 1749 1750 class CommandObjectCommandsScriptClear : public CommandObjectParsed 1751 { 1752 private: 1753 1754 public: 1755 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 1756 CommandObjectParsed (interpreter, 1757 "command script clear", 1758 "Delete all scripted commands.", 1759 NULL) 1760 { 1761 } 1762 1763 ~CommandObjectCommandsScriptClear () 1764 { 1765 } 1766 1767 protected: 1768 bool 1769 DoExecute (Args& command, CommandReturnObject &result) 1770 { 1771 1772 m_interpreter.RemoveAllUser(); 1773 1774 result.SetStatus (eReturnStatusSuccessFinishResult); 1775 1776 return true; 1777 } 1778 }; 1779 1780 //------------------------------------------------------------------------- 1781 // CommandObjectCommandsScriptDelete 1782 //------------------------------------------------------------------------- 1783 1784 class CommandObjectCommandsScriptDelete : public CommandObjectParsed 1785 { 1786 public: 1787 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 1788 CommandObjectParsed (interpreter, 1789 "command script delete", 1790 "Delete a scripted command.", 1791 NULL) 1792 { 1793 CommandArgumentEntry arg1; 1794 CommandArgumentData cmd_arg; 1795 1796 // Define the first (and only) variant of this arg. 1797 cmd_arg.arg_type = eArgTypeCommandName; 1798 cmd_arg.arg_repetition = eArgRepeatPlain; 1799 1800 // There is only one variant this argument could be; put it into the argument entry. 1801 arg1.push_back (cmd_arg); 1802 1803 // Push the data for the first argument into the m_arguments vector. 1804 m_arguments.push_back (arg1); 1805 } 1806 1807 ~CommandObjectCommandsScriptDelete () 1808 { 1809 } 1810 1811 protected: 1812 bool 1813 DoExecute (Args& command, CommandReturnObject &result) 1814 { 1815 1816 size_t argc = command.GetArgumentCount(); 1817 1818 if (argc != 1) 1819 { 1820 result.AppendError ("'command script delete' requires one argument"); 1821 result.SetStatus (eReturnStatusFailed); 1822 return false; 1823 } 1824 1825 const char* cmd_name = command.GetArgumentAtIndex(0); 1826 1827 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 1828 { 1829 m_interpreter.RemoveUser(cmd_name); 1830 result.SetStatus (eReturnStatusSuccessFinishResult); 1831 } 1832 else 1833 { 1834 result.AppendErrorWithFormat ("command %s not found", cmd_name); 1835 result.SetStatus (eReturnStatusFailed); 1836 } 1837 1838 return result.Succeeded(); 1839 1840 } 1841 }; 1842 1843 #pragma mark CommandObjectMultiwordCommandsScript 1844 1845 //------------------------------------------------------------------------- 1846 // CommandObjectMultiwordCommandsScript 1847 //------------------------------------------------------------------------- 1848 1849 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 1850 { 1851 public: 1852 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 1853 CommandObjectMultiword (interpreter, 1854 "command script", 1855 "A set of commands for managing or customizing script commands.", 1856 "command script <subcommand> [<subcommand-options>]") 1857 { 1858 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 1859 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 1860 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 1861 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 1862 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 1863 } 1864 1865 ~CommandObjectMultiwordCommandsScript () 1866 { 1867 } 1868 1869 }; 1870 1871 1872 #pragma mark CommandObjectMultiwordCommands 1873 1874 //------------------------------------------------------------------------- 1875 // CommandObjectMultiwordCommands 1876 //------------------------------------------------------------------------- 1877 1878 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 1879 CommandObjectMultiword (interpreter, 1880 "command", 1881 "A set of commands for managing or customizing the debugger commands.", 1882 "command <subcommand> [<subcommand-options>]") 1883 { 1884 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 1885 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 1886 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 1887 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 1888 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 1889 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 1890 } 1891 1892 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 1893 { 1894 } 1895 1896