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