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