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.GetErrorData() && result.GetErrorData()[0]) 1332 result.SetStatus(eReturnStatusFailed); 1333 else if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1334 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1335 else 1336 result.SetStatus(eReturnStatusSuccessFinishResult); 1337 } 1338 } 1339 1340 return result.Succeeded(); 1341 } 1342 1343 }; 1344 1345 //------------------------------------------------------------------------- 1346 // CommandObjectCommandsScriptImport 1347 //------------------------------------------------------------------------- 1348 1349 class CommandObjectCommandsScriptImport : public CommandObjectParsed 1350 { 1351 public: 1352 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 1353 CommandObjectParsed (interpreter, 1354 "command script import", 1355 "Import a scripting module in LLDB.", 1356 NULL), 1357 m_options(interpreter) 1358 { 1359 CommandArgumentEntry arg1; 1360 CommandArgumentData cmd_arg; 1361 1362 // Define the first (and only) variant of this arg. 1363 cmd_arg.arg_type = eArgTypeFilename; 1364 cmd_arg.arg_repetition = eArgRepeatPlain; 1365 1366 // There is only one variant this argument could be; put it into the argument entry. 1367 arg1.push_back (cmd_arg); 1368 1369 // Push the data for the first argument into the m_arguments vector. 1370 m_arguments.push_back (arg1); 1371 } 1372 1373 ~CommandObjectCommandsScriptImport () 1374 { 1375 } 1376 1377 virtual int 1378 HandleArgumentCompletion (Args &input, 1379 int &cursor_index, 1380 int &cursor_char_position, 1381 OptionElementVector &opt_element_vector, 1382 int match_start_point, 1383 int max_return_elements, 1384 bool &word_complete, 1385 StringList &matches) 1386 { 1387 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1388 completion_str.erase (cursor_char_position); 1389 1390 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1391 CommandCompletions::eDiskFileCompletion, 1392 completion_str.c_str(), 1393 match_start_point, 1394 max_return_elements, 1395 NULL, 1396 word_complete, 1397 matches); 1398 return matches.GetSize(); 1399 } 1400 1401 virtual Options * 1402 GetOptions () 1403 { 1404 return &m_options; 1405 } 1406 1407 protected: 1408 1409 class CommandOptions : public Options 1410 { 1411 public: 1412 1413 CommandOptions (CommandInterpreter &interpreter) : 1414 Options (interpreter) 1415 { 1416 } 1417 1418 virtual 1419 ~CommandOptions (){} 1420 1421 virtual Error 1422 SetOptionValue (uint32_t option_idx, const char *option_arg) 1423 { 1424 Error error; 1425 const int short_option = m_getopt_table[option_idx].val; 1426 1427 switch (short_option) 1428 { 1429 case 'r': 1430 m_allow_reload = true; 1431 break; 1432 default: 1433 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1434 break; 1435 } 1436 1437 return error; 1438 } 1439 1440 void 1441 OptionParsingStarting () 1442 { 1443 m_allow_reload = true; 1444 } 1445 1446 const OptionDefinition* 1447 GetDefinitions () 1448 { 1449 return g_option_table; 1450 } 1451 1452 // Options table: Required for subclasses of Options. 1453 1454 static OptionDefinition g_option_table[]; 1455 1456 // Instance variables to hold the values for command options. 1457 1458 bool m_allow_reload; 1459 }; 1460 1461 bool 1462 DoExecute (Args& command, CommandReturnObject &result) 1463 { 1464 1465 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1466 { 1467 result.AppendError ("only scripting language supported for module importing is currently Python"); 1468 result.SetStatus (eReturnStatusFailed); 1469 return false; 1470 } 1471 1472 size_t argc = command.GetArgumentCount(); 1473 1474 if (argc != 1) 1475 { 1476 result.AppendError ("'command script import' requires one argument"); 1477 result.SetStatus (eReturnStatusFailed); 1478 return false; 1479 } 1480 1481 std::string path = command.GetArgumentAtIndex(0); 1482 Error error; 1483 1484 const bool init_session = true; 1485 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1486 // commands won't ever be recursively invoked, but it's actually possible to craft 1487 // a Python script that does other "command script imports" in __lldb_init_module 1488 // the real fix is to have recursive commands possible with a CommandInvocation object 1489 // separate from the CommandObject itself, so that recursive command invocations 1490 // won't stomp on each other (wrt to execution contents, options, and more) 1491 m_exe_ctx.Clear(); 1492 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 1493 m_options.m_allow_reload, 1494 init_session, 1495 error)) 1496 { 1497 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1498 } 1499 else 1500 { 1501 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1502 result.SetStatus (eReturnStatusFailed); 1503 } 1504 1505 return result.Succeeded(); 1506 } 1507 1508 CommandOptions m_options; 1509 }; 1510 1511 OptionDefinition 1512 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 1513 { 1514 { 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."}, 1515 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1516 }; 1517 1518 1519 //------------------------------------------------------------------------- 1520 // CommandObjectCommandsScriptAdd 1521 //------------------------------------------------------------------------- 1522 1523 class CommandObjectCommandsScriptAdd : public CommandObjectParsed 1524 { 1525 public: 1526 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 1527 CommandObjectParsed (interpreter, 1528 "command script add", 1529 "Add a scripted function as an LLDB command.", 1530 NULL), 1531 m_options (interpreter) 1532 { 1533 CommandArgumentEntry arg1; 1534 CommandArgumentData cmd_arg; 1535 1536 // Define the first (and only) variant of this arg. 1537 cmd_arg.arg_type = eArgTypeCommandName; 1538 cmd_arg.arg_repetition = eArgRepeatPlain; 1539 1540 // There is only one variant this argument could be; put it into the argument entry. 1541 arg1.push_back (cmd_arg); 1542 1543 // Push the data for the first argument into the m_arguments vector. 1544 m_arguments.push_back (arg1); 1545 } 1546 1547 ~CommandObjectCommandsScriptAdd () 1548 { 1549 } 1550 1551 virtual Options * 1552 GetOptions () 1553 { 1554 return &m_options; 1555 } 1556 1557 protected: 1558 1559 class CommandOptions : public Options 1560 { 1561 public: 1562 1563 CommandOptions (CommandInterpreter &interpreter) : 1564 Options (interpreter) 1565 { 1566 } 1567 1568 virtual 1569 ~CommandOptions (){} 1570 1571 virtual Error 1572 SetOptionValue (uint32_t option_idx, const char *option_arg) 1573 { 1574 Error error; 1575 const int short_option = m_getopt_table[option_idx].val; 1576 1577 switch (short_option) 1578 { 1579 case 'f': 1580 m_funct_name = std::string(option_arg); 1581 break; 1582 case 's': 1583 m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1584 if (!error.Success()) 1585 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 1586 break; 1587 default: 1588 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1589 break; 1590 } 1591 1592 return error; 1593 } 1594 1595 void 1596 OptionParsingStarting () 1597 { 1598 m_funct_name = ""; 1599 m_synchronous = eScriptedCommandSynchronicitySynchronous; 1600 } 1601 1602 const OptionDefinition* 1603 GetDefinitions () 1604 { 1605 return g_option_table; 1606 } 1607 1608 // Options table: Required for subclasses of Options. 1609 1610 static OptionDefinition g_option_table[]; 1611 1612 // Instance variables to hold the values for command options. 1613 1614 std::string m_funct_name; 1615 ScriptedCommandSynchronicity m_synchronous; 1616 }; 1617 1618 private: 1619 class PythonAliasReader : public InputReaderEZ 1620 { 1621 private: 1622 CommandInterpreter& m_interpreter; 1623 std::string m_cmd_name; 1624 ScriptedCommandSynchronicity m_synchronous; 1625 StringList m_user_input; 1626 DISALLOW_COPY_AND_ASSIGN (PythonAliasReader); 1627 public: 1628 PythonAliasReader(Debugger& debugger, 1629 CommandInterpreter& interpreter, 1630 std::string cmd_name, 1631 ScriptedCommandSynchronicity synch) : 1632 InputReaderEZ(debugger), 1633 m_interpreter(interpreter), 1634 m_cmd_name(cmd_name), 1635 m_synchronous(synch), 1636 m_user_input() 1637 {} 1638 1639 virtual 1640 ~PythonAliasReader() 1641 { 1642 } 1643 1644 virtual void ActivateHandler(HandlerData& data) 1645 { 1646 StreamSP out_stream = data.GetOutStream(); 1647 bool batch_mode = data.GetBatchMode(); 1648 if (!batch_mode) 1649 { 1650 out_stream->Printf ("%s\n", g_python_command_instructions); 1651 if (data.reader.GetPrompt()) 1652 out_stream->Printf ("%s", data.reader.GetPrompt()); 1653 out_stream->Flush(); 1654 } 1655 } 1656 1657 virtual void ReactivateHandler(HandlerData& data) 1658 { 1659 StreamSP out_stream = data.GetOutStream(); 1660 bool batch_mode = data.GetBatchMode(); 1661 if (data.reader.GetPrompt() && !batch_mode) 1662 { 1663 out_stream->Printf ("%s", data.reader.GetPrompt()); 1664 out_stream->Flush(); 1665 } 1666 } 1667 virtual void GotTokenHandler(HandlerData& data) 1668 { 1669 StreamSP out_stream = data.GetOutStream(); 1670 bool batch_mode = data.GetBatchMode(); 1671 if (data.bytes && data.bytes_len) 1672 { 1673 m_user_input.AppendString(data.bytes, data.bytes_len); 1674 } 1675 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) 1676 { 1677 out_stream->Printf ("%s", data.reader.GetPrompt()); 1678 out_stream->Flush(); 1679 } 1680 } 1681 virtual void InterruptHandler(HandlerData& data) 1682 { 1683 StreamSP out_stream = data.GetOutStream(); 1684 bool batch_mode = data.GetBatchMode(); 1685 data.reader.SetIsDone (true); 1686 if (!batch_mode) 1687 { 1688 out_stream->Printf ("Warning: No script attached.\n"); 1689 out_stream->Flush(); 1690 } 1691 } 1692 virtual void EOFHandler(HandlerData& data) 1693 { 1694 data.reader.SetIsDone (true); 1695 } 1696 virtual void DoneHandler(HandlerData& data) 1697 { 1698 StreamSP out_stream = data.GetOutStream(); 1699 1700 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1701 if (!interpreter) 1702 { 1703 out_stream->Printf ("Script interpreter missing: no script attached.\n"); 1704 out_stream->Flush(); 1705 return; 1706 } 1707 std::string funct_name_str; 1708 if (!interpreter->GenerateScriptAliasFunction (m_user_input, 1709 funct_name_str)) 1710 { 1711 out_stream->Printf ("Unable to create function: no script attached.\n"); 1712 out_stream->Flush(); 1713 return; 1714 } 1715 if (funct_name_str.empty()) 1716 { 1717 out_stream->Printf ("Unable to obtain a function name: no script attached.\n"); 1718 out_stream->Flush(); 1719 return; 1720 } 1721 // everything should be fine now, let's add this alias 1722 1723 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, 1724 m_cmd_name, 1725 funct_name_str.c_str(), 1726 m_synchronous)); 1727 1728 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1729 { 1730 out_stream->Printf ("Unable to add selected command: no script attached.\n"); 1731 out_stream->Flush(); 1732 return; 1733 } 1734 } 1735 }; 1736 1737 protected: 1738 bool 1739 DoExecute (Args& command, CommandReturnObject &result) 1740 { 1741 1742 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1743 { 1744 result.AppendError ("only scripting language supported for scripted commands is currently Python"); 1745 result.SetStatus (eReturnStatusFailed); 1746 return false; 1747 } 1748 1749 size_t argc = command.GetArgumentCount(); 1750 1751 if (argc != 1) 1752 { 1753 result.AppendError ("'command script add' requires one argument"); 1754 result.SetStatus (eReturnStatusFailed); 1755 return false; 1756 } 1757 1758 std::string cmd_name = command.GetArgumentAtIndex(0); 1759 1760 if (m_options.m_funct_name.empty()) 1761 { 1762 InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(), 1763 m_interpreter, 1764 cmd_name, 1765 m_options.m_synchronous)); 1766 1767 if (reader_sp) 1768 { 1769 1770 InputReaderEZ::InitializationParameters ipr; 1771 1772 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" "))); 1773 if (err.Success()) 1774 { 1775 m_interpreter.GetDebugger().PushInputReader (reader_sp); 1776 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1777 } 1778 else 1779 { 1780 result.AppendError (err.AsCString()); 1781 result.SetStatus (eReturnStatusFailed); 1782 } 1783 } 1784 else 1785 { 1786 result.AppendError("out of memory"); 1787 result.SetStatus (eReturnStatusFailed); 1788 } 1789 } 1790 else 1791 { 1792 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 1793 cmd_name, 1794 m_options.m_funct_name, 1795 m_options.m_synchronous)); 1796 if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true)) 1797 { 1798 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1799 } 1800 else 1801 { 1802 result.AppendError("cannot add command"); 1803 result.SetStatus (eReturnStatusFailed); 1804 } 1805 } 1806 1807 return result.Succeeded(); 1808 1809 } 1810 1811 CommandOptions m_options; 1812 }; 1813 1814 static OptionEnumValueElement g_script_synchro_type[] = 1815 { 1816 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 1817 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 1818 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 1819 { 0, NULL, NULL } 1820 }; 1821 1822 OptionDefinition 1823 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 1824 { 1825 { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 1826 { 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."}, 1827 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1828 }; 1829 1830 //------------------------------------------------------------------------- 1831 // CommandObjectCommandsScriptList 1832 //------------------------------------------------------------------------- 1833 1834 class CommandObjectCommandsScriptList : public CommandObjectParsed 1835 { 1836 private: 1837 1838 public: 1839 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 1840 CommandObjectParsed (interpreter, 1841 "command script list", 1842 "List defined scripted commands.", 1843 NULL) 1844 { 1845 } 1846 1847 ~CommandObjectCommandsScriptList () 1848 { 1849 } 1850 1851 bool 1852 DoExecute (Args& command, CommandReturnObject &result) 1853 { 1854 1855 m_interpreter.GetHelp(result, 1856 CommandInterpreter::eCommandTypesUserDef); 1857 1858 result.SetStatus (eReturnStatusSuccessFinishResult); 1859 1860 return true; 1861 1862 1863 } 1864 }; 1865 1866 //------------------------------------------------------------------------- 1867 // CommandObjectCommandsScriptClear 1868 //------------------------------------------------------------------------- 1869 1870 class CommandObjectCommandsScriptClear : public CommandObjectParsed 1871 { 1872 private: 1873 1874 public: 1875 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 1876 CommandObjectParsed (interpreter, 1877 "command script clear", 1878 "Delete all scripted commands.", 1879 NULL) 1880 { 1881 } 1882 1883 ~CommandObjectCommandsScriptClear () 1884 { 1885 } 1886 1887 protected: 1888 bool 1889 DoExecute (Args& command, CommandReturnObject &result) 1890 { 1891 1892 m_interpreter.RemoveAllUser(); 1893 1894 result.SetStatus (eReturnStatusSuccessFinishResult); 1895 1896 return true; 1897 } 1898 }; 1899 1900 //------------------------------------------------------------------------- 1901 // CommandObjectCommandsScriptDelete 1902 //------------------------------------------------------------------------- 1903 1904 class CommandObjectCommandsScriptDelete : public CommandObjectParsed 1905 { 1906 public: 1907 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 1908 CommandObjectParsed (interpreter, 1909 "command script delete", 1910 "Delete a scripted command.", 1911 NULL) 1912 { 1913 CommandArgumentEntry arg1; 1914 CommandArgumentData cmd_arg; 1915 1916 // Define the first (and only) variant of this arg. 1917 cmd_arg.arg_type = eArgTypeCommandName; 1918 cmd_arg.arg_repetition = eArgRepeatPlain; 1919 1920 // There is only one variant this argument could be; put it into the argument entry. 1921 arg1.push_back (cmd_arg); 1922 1923 // Push the data for the first argument into the m_arguments vector. 1924 m_arguments.push_back (arg1); 1925 } 1926 1927 ~CommandObjectCommandsScriptDelete () 1928 { 1929 } 1930 1931 protected: 1932 bool 1933 DoExecute (Args& command, CommandReturnObject &result) 1934 { 1935 1936 size_t argc = command.GetArgumentCount(); 1937 1938 if (argc != 1) 1939 { 1940 result.AppendError ("'command script delete' requires one argument"); 1941 result.SetStatus (eReturnStatusFailed); 1942 return false; 1943 } 1944 1945 const char* cmd_name = command.GetArgumentAtIndex(0); 1946 1947 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 1948 { 1949 m_interpreter.RemoveUser(cmd_name); 1950 result.SetStatus (eReturnStatusSuccessFinishResult); 1951 } 1952 else 1953 { 1954 result.AppendErrorWithFormat ("command %s not found", cmd_name); 1955 result.SetStatus (eReturnStatusFailed); 1956 } 1957 1958 return result.Succeeded(); 1959 1960 } 1961 }; 1962 1963 #pragma mark CommandObjectMultiwordCommandsScript 1964 1965 //------------------------------------------------------------------------- 1966 // CommandObjectMultiwordCommandsScript 1967 //------------------------------------------------------------------------- 1968 1969 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 1970 { 1971 public: 1972 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 1973 CommandObjectMultiword (interpreter, 1974 "command script", 1975 "A set of commands for managing or customizing script commands.", 1976 "command script <subcommand> [<subcommand-options>]") 1977 { 1978 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 1979 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 1980 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 1981 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 1982 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 1983 } 1984 1985 ~CommandObjectMultiwordCommandsScript () 1986 { 1987 } 1988 1989 }; 1990 1991 1992 #pragma mark CommandObjectMultiwordCommands 1993 1994 //------------------------------------------------------------------------- 1995 // CommandObjectMultiwordCommands 1996 //------------------------------------------------------------------------- 1997 1998 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 1999 CommandObjectMultiword (interpreter, 2000 "command", 2001 "A set of commands for managing or customizing the debugger commands.", 2002 "command <subcommand> [<subcommand-options>]") 2003 { 2004 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 2005 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 2006 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 2007 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 2008 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 2009 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 2010 } 2011 2012 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 2013 { 2014 } 2015 2016