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