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