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