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/IOHandler.h" 22 #include "lldb/Core/StringList.h" 23 #include "lldb/Interpreter/Args.h" 24 #include "lldb/Interpreter/CommandHistory.h" 25 #include "lldb/Interpreter/CommandInterpreter.h" 26 #include "lldb/Interpreter/CommandObjectRegexCommand.h" 27 #include "lldb/Interpreter/CommandReturnObject.h" 28 #include "lldb/Interpreter/OptionValueBoolean.h" 29 #include "lldb/Interpreter/OptionValueUInt64.h" 30 #include "lldb/Interpreter/Options.h" 31 #include "lldb/Interpreter/ScriptInterpreter.h" 32 #include "lldb/Interpreter/ScriptInterpreterPython.h" 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 //------------------------------------------------------------------------- 38 // CommandObjectCommandsSource 39 //------------------------------------------------------------------------- 40 41 class CommandObjectCommandsHistory : public CommandObjectParsed 42 { 43 public: 44 CommandObjectCommandsHistory(CommandInterpreter &interpreter) : 45 CommandObjectParsed (interpreter, 46 "command history", 47 "Dump the history of commands in this session.", 48 NULL), 49 m_options (interpreter) 50 { 51 } 52 53 ~CommandObjectCommandsHistory () {} 54 55 virtual Options * 56 GetOptions () 57 { 58 return &m_options; 59 } 60 61 protected: 62 63 class CommandOptions : public Options 64 { 65 public: 66 67 CommandOptions (CommandInterpreter &interpreter) : 68 Options (interpreter), 69 m_start_idx(0), 70 m_stop_idx(0), 71 m_count(0), 72 m_clear(false) 73 { 74 } 75 76 virtual 77 ~CommandOptions (){} 78 79 virtual Error 80 SetOptionValue (uint32_t option_idx, const char *option_arg) 81 { 82 Error error; 83 const int short_option = m_getopt_table[option_idx].val; 84 85 switch (short_option) 86 { 87 case 'c': 88 error = m_count.SetValueFromCString(option_arg,eVarSetOperationAssign); 89 break; 90 case 's': 91 if (option_arg && strcmp("end", option_arg) == 0) 92 { 93 m_start_idx.SetCurrentValue(UINT64_MAX); 94 m_start_idx.SetOptionWasSet(); 95 } 96 else 97 error = m_start_idx.SetValueFromCString(option_arg,eVarSetOperationAssign); 98 break; 99 case 'e': 100 error = m_stop_idx.SetValueFromCString(option_arg,eVarSetOperationAssign); 101 break; 102 case 'C': 103 m_clear.SetCurrentValue(true); 104 m_clear.SetOptionWasSet(); 105 break; 106 default: 107 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 108 break; 109 } 110 111 return error; 112 } 113 114 void 115 OptionParsingStarting () 116 { 117 m_start_idx.Clear(); 118 m_stop_idx.Clear(); 119 m_count.Clear(); 120 m_clear.Clear(); 121 } 122 123 const OptionDefinition* 124 GetDefinitions () 125 { 126 return g_option_table; 127 } 128 129 // Options table: Required for subclasses of Options. 130 131 static OptionDefinition g_option_table[]; 132 133 // Instance variables to hold the values for command options. 134 135 OptionValueUInt64 m_start_idx; 136 OptionValueUInt64 m_stop_idx; 137 OptionValueUInt64 m_count; 138 OptionValueBoolean m_clear; 139 }; 140 141 bool 142 DoExecute (Args& command, CommandReturnObject &result) 143 { 144 if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet()) 145 { 146 m_interpreter.GetCommandHistory().Clear(); 147 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); 148 } 149 else 150 { 151 if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet()) 152 { 153 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation"); 154 result.SetStatus(lldb::eReturnStatusFailed); 155 } 156 else 157 { 158 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue()); 159 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue()); 160 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue()); 161 162 const CommandHistory& history(m_interpreter.GetCommandHistory()); 163 164 if (start_idx.first && start_idx.second == UINT64_MAX) 165 { 166 if (count.first) 167 { 168 start_idx.second = history.GetSize() - count.second; 169 stop_idx.second = history.GetSize() - 1; 170 } 171 else if (stop_idx.first) 172 { 173 start_idx.second = stop_idx.second; 174 stop_idx.second = history.GetSize() - 1; 175 } 176 else 177 { 178 start_idx.second = 0; 179 stop_idx.second = history.GetSize() - 1; 180 } 181 } 182 else 183 { 184 if (!start_idx.first && !stop_idx.first && !count.first) 185 { 186 start_idx.second = 0; 187 stop_idx.second = history.GetSize() - 1; 188 } 189 else if (start_idx.first) 190 { 191 if (count.first) 192 { 193 stop_idx.second = start_idx.second + count.second - 1; 194 } 195 else if (!stop_idx.first) 196 { 197 stop_idx.second = history.GetSize() - 1; 198 } 199 } 200 else if (stop_idx.first) 201 { 202 if (count.first) 203 { 204 if (stop_idx.second >= count.second) 205 start_idx.second = stop_idx.second - count.second + 1; 206 else 207 start_idx.second = 0; 208 } 209 } 210 else /* if (count.first) */ 211 { 212 start_idx.second = 0; 213 stop_idx.second = count.second - 1; 214 } 215 } 216 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second); 217 } 218 } 219 return result.Succeeded(); 220 221 } 222 223 CommandOptions m_options; 224 }; 225 226 OptionDefinition 227 CommandObjectCommandsHistory::CommandOptions::g_option_table[] = 228 { 229 { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, 230 { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."}, 231 { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, 232 { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, 0, eArgTypeBoolean, "Clears the current command history."}, 233 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 234 }; 235 236 237 //------------------------------------------------------------------------- 238 // CommandObjectCommandsSource 239 //------------------------------------------------------------------------- 240 241 class CommandObjectCommandsSource : public CommandObjectParsed 242 { 243 public: 244 CommandObjectCommandsSource(CommandInterpreter &interpreter) : 245 CommandObjectParsed (interpreter, 246 "command source", 247 "Read in debugger commands from the file <filename> and execute them.", 248 NULL), 249 m_options (interpreter) 250 { 251 CommandArgumentEntry arg; 252 CommandArgumentData file_arg; 253 254 // Define the first (and only) variant of this arg. 255 file_arg.arg_type = eArgTypeFilename; 256 file_arg.arg_repetition = eArgRepeatPlain; 257 258 // There is only one variant this argument could be; put it into the argument entry. 259 arg.push_back (file_arg); 260 261 // Push the data for the first argument into the m_arguments vector. 262 m_arguments.push_back (arg); 263 } 264 265 ~CommandObjectCommandsSource () {} 266 267 virtual const char* 268 GetRepeatCommand (Args ¤t_command_args, uint32_t index) 269 { 270 return ""; 271 } 272 273 virtual int 274 HandleArgumentCompletion (Args &input, 275 int &cursor_index, 276 int &cursor_char_position, 277 OptionElementVector &opt_element_vector, 278 int match_start_point, 279 int max_return_elements, 280 bool &word_complete, 281 StringList &matches) 282 { 283 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 284 completion_str.erase (cursor_char_position); 285 286 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 287 CommandCompletions::eDiskFileCompletion, 288 completion_str.c_str(), 289 match_start_point, 290 max_return_elements, 291 NULL, 292 word_complete, 293 matches); 294 return matches.GetSize(); 295 } 296 297 virtual Options * 298 GetOptions () 299 { 300 return &m_options; 301 } 302 303 protected: 304 305 class CommandOptions : public Options 306 { 307 public: 308 309 CommandOptions (CommandInterpreter &interpreter) : 310 Options (interpreter), 311 m_stop_on_error (true) 312 { 313 } 314 315 virtual 316 ~CommandOptions (){} 317 318 virtual Error 319 SetOptionValue (uint32_t option_idx, const char *option_arg) 320 { 321 Error error; 322 const int short_option = m_getopt_table[option_idx].val; 323 bool success; 324 325 switch (short_option) 326 { 327 case 'e': 328 error = m_stop_on_error.SetValueFromCString(option_arg); 329 break; 330 case 'c': 331 m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success); 332 if (!success) 333 error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg); 334 break; 335 case 's': 336 m_silent_run = Args::StringToBoolean(option_arg, true, &success); 337 if (!success) 338 error.SetErrorStringWithFormat("invalid value for silent-run: %s", option_arg); 339 break; 340 default: 341 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 342 break; 343 } 344 345 return error; 346 } 347 348 void 349 OptionParsingStarting () 350 { 351 m_stop_on_error.Clear(); 352 m_silent_run = false; 353 m_stop_on_continue = true; 354 } 355 356 const OptionDefinition* 357 GetDefinitions () 358 { 359 return g_option_table; 360 } 361 362 // Options table: Required for subclasses of Options. 363 364 static OptionDefinition g_option_table[]; 365 366 // Instance variables to hold the values for command options. 367 368 OptionValueBoolean m_stop_on_error; 369 bool m_silent_run; 370 bool m_stop_on_continue; 371 }; 372 373 bool 374 DoExecute(Args& command, CommandReturnObject &result) 375 { 376 const size_t argc = command.GetArgumentCount(); 377 if (argc == 1) 378 { 379 const char *filename = command.GetArgumentAtIndex(0); 380 381 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) 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', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 414 { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 415 { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, 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):\n"; 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 : 860 public CommandObjectParsed, 861 public IOHandlerDelegate 862 { 863 public: 864 CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 865 CommandObjectParsed (interpreter, 866 "command regex", 867 "Allow the user to create a regular expression command.", 868 "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 869 IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand), 870 m_options (interpreter) 871 { 872 SetHelpLong( 873 "This command allows the user to create powerful regular expression commands\n" 874 "with substitutions. The regular expressions and substitutions are specified\n" 875 "using the regular exression substitution format of:\n" 876 "\n" 877 " s/<regex>/<subst>/\n" 878 "\n" 879 "<regex> is a regular expression that can use parenthesis to capture regular\n" 880 "expression input and substitute the captured matches in the output using %1\n" 881 "for the first match, %2 for the second, and so on.\n" 882 "\n" 883 "The regular expressions can all be specified on the command line if more than\n" 884 "one argument is provided. If just the command name is provided on the command\n" 885 "line, then the regular expressions and substitutions can be entered on separate\n" 886 " lines, followed by an empty line to terminate the command definition.\n" 887 "\n" 888 "EXAMPLES\n" 889 "\n" 890 "The following example will define a regular expression command named 'f' that\n" 891 "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n" 892 "a number follows 'f':\n" 893 "\n" 894 " (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n" 895 "\n" 896 ); 897 } 898 899 ~CommandObjectCommandsAddRegex() 900 { 901 } 902 903 904 protected: 905 906 virtual void 907 IOHandlerActivated (IOHandler &io_handler) 908 { 909 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 910 if (output_sp) 911 { 912 output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n"); 913 output_sp->Flush(); 914 } 915 } 916 917 virtual void 918 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) 919 { 920 io_handler.SetIsDone(true); 921 if (m_regex_cmd_ap.get()) 922 { 923 StringList lines; 924 if (lines.SplitIntoLines (data)) 925 { 926 const size_t num_lines = lines.GetSize(); 927 bool check_only = false; 928 for (size_t i=0; i<num_lines; ++i) 929 { 930 printf ("regex[%zu] = %s\n", i, lines[i].c_str()); 931 llvm::StringRef bytes_strref (lines[i]); 932 Error error = AppendRegexSubstitution (bytes_strref, check_only); 933 if (error.Fail()) 934 { 935 if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) 936 { 937 StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream(); 938 out_stream->Printf("error: %s\n", error.AsCString()); 939 } 940 } 941 } 942 } 943 if (m_regex_cmd_ap->HasRegexEntries()) 944 { 945 CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 946 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 947 } 948 } 949 } 950 951 virtual LineStatus 952 IOHandlerLinesUpdated (IOHandler &io_handler, 953 StringList &lines, 954 uint32_t line_idx, 955 Error &error) 956 { 957 if (line_idx == UINT32_MAX) 958 { 959 // Return true to indicate we are done getting lines (this 960 // is a "fake" line - the real terminating blank line was 961 // removed during a previous call with the code below) 962 error.Clear(); 963 return LineStatus::Done; 964 } 965 else 966 { 967 const size_t num_lines = lines.GetSize(); 968 if (line_idx + 1 == num_lines) 969 { 970 // The last line was edited, if this line is empty, then we are done 971 // getting our multiple lines. 972 if (lines[line_idx].empty()) 973 { 974 // Remove the last empty line from "lines" so it doesn't appear 975 // in our final expression and return true to indicate we are done 976 // getting lines 977 lines.PopBack(); 978 return LineStatus::Done; 979 } 980 } 981 // Check the current line to make sure it is formatted correctly 982 bool check_only = true; 983 llvm::StringRef regex_sed(lines[line_idx]); 984 error = AppendRegexSubstitution (regex_sed, check_only); 985 if (error.Fail()) 986 { 987 return LineStatus::Error; 988 } 989 else 990 { 991 return LineStatus::Success; 992 } 993 } 994 } 995 996 bool 997 DoExecute (Args& command, CommandReturnObject &result) 998 { 999 const size_t argc = command.GetArgumentCount(); 1000 if (argc == 0) 1001 { 1002 result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 1003 result.SetStatus (eReturnStatusFailed); 1004 } 1005 else 1006 { 1007 Error error; 1008 const char *name = command.GetArgumentAtIndex(0); 1009 m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 1010 name, 1011 m_options.GetHelp (), 1012 m_options.GetSyntax (), 1013 10)); 1014 1015 if (argc == 1) 1016 { 1017 Debugger &debugger = m_interpreter.GetDebugger(); 1018 const bool multiple_lines = true; // Get multiple lines 1019 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 1020 "lldb", // Name of input reader for history 1021 "\033[K> ", // Prompt and clear line 1022 multiple_lines, 1023 *this)); 1024 1025 if (io_handler_sp) 1026 { 1027 debugger.PushIOHandler(io_handler_sp); 1028 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1029 } 1030 } 1031 else 1032 { 1033 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 1034 { 1035 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 1036 bool check_only = false; 1037 error = AppendRegexSubstitution (arg_strref, check_only); 1038 if (error.Fail()) 1039 break; 1040 } 1041 1042 if (error.Success()) 1043 { 1044 AddRegexCommandToInterpreter(); 1045 } 1046 } 1047 if (error.Fail()) 1048 { 1049 result.AppendError (error.AsCString()); 1050 result.SetStatus (eReturnStatusFailed); 1051 } 1052 } 1053 1054 return result.Succeeded(); 1055 } 1056 1057 Error 1058 AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only) 1059 { 1060 Error error; 1061 1062 if (m_regex_cmd_ap.get() == NULL) 1063 { 1064 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 1065 (int)regex_sed.size(), 1066 regex_sed.data()); 1067 return error; 1068 } 1069 1070 size_t regex_sed_size = regex_sed.size(); 1071 1072 if (regex_sed_size <= 1) 1073 { 1074 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 1075 (int)regex_sed.size(), 1076 regex_sed.data()); 1077 return error; 1078 } 1079 1080 if (regex_sed[0] != 's') 1081 { 1082 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 1083 (int)regex_sed.size(), 1084 regex_sed.data()); 1085 return error; 1086 } 1087 const size_t first_separator_char_pos = 1; 1088 // use the char that follows 's' as the regex separator character 1089 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 1090 const char separator_char = regex_sed[first_separator_char_pos]; 1091 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 1092 1093 if (second_separator_char_pos == std::string::npos) 1094 { 1095 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'", 1096 separator_char, 1097 (int)(regex_sed.size() - first_separator_char_pos - 1), 1098 regex_sed.data() + (first_separator_char_pos + 1)); 1099 return error; 1100 } 1101 1102 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 1103 1104 if (third_separator_char_pos == std::string::npos) 1105 { 1106 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'", 1107 separator_char, 1108 (int)(regex_sed.size() - second_separator_char_pos - 1), 1109 regex_sed.data() + (second_separator_char_pos + 1)); 1110 return error; 1111 } 1112 1113 if (third_separator_char_pos != regex_sed_size - 1) 1114 { 1115 // Make sure that everything that follows the last regex 1116 // separator char 1117 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 1118 { 1119 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 1120 (int)third_separator_char_pos + 1, 1121 regex_sed.data(), 1122 (int)(regex_sed.size() - third_separator_char_pos - 1), 1123 regex_sed.data() + (third_separator_char_pos + 1)); 1124 return error; 1125 } 1126 1127 } 1128 else if (first_separator_char_pos + 1 == second_separator_char_pos) 1129 { 1130 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 1131 separator_char, 1132 separator_char, 1133 separator_char, 1134 (int)regex_sed.size(), 1135 regex_sed.data()); 1136 return error; 1137 } 1138 else if (second_separator_char_pos + 1 == third_separator_char_pos) 1139 { 1140 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 1141 separator_char, 1142 separator_char, 1143 separator_char, 1144 (int)regex_sed.size(), 1145 regex_sed.data()); 1146 return error; 1147 } 1148 1149 if (check_only == false) 1150 { 1151 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 1152 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 1153 m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 1154 subst.c_str()); 1155 } 1156 return error; 1157 } 1158 1159 void 1160 AddRegexCommandToInterpreter() 1161 { 1162 if (m_regex_cmd_ap.get()) 1163 { 1164 if (m_regex_cmd_ap->HasRegexEntries()) 1165 { 1166 CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 1167 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 1168 } 1169 } 1170 } 1171 1172 private: 1173 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1174 1175 class CommandOptions : public Options 1176 { 1177 public: 1178 1179 CommandOptions (CommandInterpreter &interpreter) : 1180 Options (interpreter) 1181 { 1182 } 1183 1184 virtual 1185 ~CommandOptions (){} 1186 1187 virtual Error 1188 SetOptionValue (uint32_t option_idx, const char *option_arg) 1189 { 1190 Error error; 1191 const int short_option = m_getopt_table[option_idx].val; 1192 1193 switch (short_option) 1194 { 1195 case 'h': 1196 m_help.assign (option_arg); 1197 break; 1198 case 's': 1199 m_syntax.assign (option_arg); 1200 break; 1201 1202 default: 1203 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1204 break; 1205 } 1206 1207 return error; 1208 } 1209 1210 void 1211 OptionParsingStarting () 1212 { 1213 m_help.clear(); 1214 m_syntax.clear(); 1215 } 1216 1217 const OptionDefinition* 1218 GetDefinitions () 1219 { 1220 return g_option_table; 1221 } 1222 1223 // Options table: Required for subclasses of Options. 1224 1225 static OptionDefinition g_option_table[]; 1226 1227 const char * 1228 GetHelp () 1229 { 1230 if (m_help.empty()) 1231 return NULL; 1232 return m_help.c_str(); 1233 } 1234 const char * 1235 GetSyntax () 1236 { 1237 if (m_syntax.empty()) 1238 return NULL; 1239 return m_syntax.c_str(); 1240 } 1241 // Instance variables to hold the values for command options. 1242 protected: 1243 std::string m_help; 1244 std::string m_syntax; 1245 }; 1246 1247 virtual Options * 1248 GetOptions () 1249 { 1250 return &m_options; 1251 } 1252 1253 CommandOptions m_options; 1254 }; 1255 1256 OptionDefinition 1257 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1258 { 1259 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1260 { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1261 { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL } 1262 }; 1263 1264 1265 class CommandObjectPythonFunction : public CommandObjectRaw 1266 { 1267 private: 1268 std::string m_function_name; 1269 ScriptedCommandSynchronicity m_synchro; 1270 bool m_fetched_help_long; 1271 1272 public: 1273 1274 CommandObjectPythonFunction (CommandInterpreter &interpreter, 1275 std::string name, 1276 std::string funct, 1277 ScriptedCommandSynchronicity synch) : 1278 CommandObjectRaw (interpreter, 1279 name.c_str(), 1280 (std::string("Run Python function ") + funct).c_str(), 1281 NULL), 1282 m_function_name(funct), 1283 m_synchro(synch), 1284 m_fetched_help_long(false) 1285 { 1286 } 1287 1288 virtual 1289 ~CommandObjectPythonFunction () 1290 { 1291 } 1292 1293 virtual bool 1294 IsRemovable () const 1295 { 1296 return true; 1297 } 1298 1299 const std::string& 1300 GetFunctionName () 1301 { 1302 return m_function_name; 1303 } 1304 1305 ScriptedCommandSynchronicity 1306 GetSynchronicity () 1307 { 1308 return m_synchro; 1309 } 1310 1311 virtual const char * 1312 GetHelpLong () 1313 { 1314 if (!m_fetched_help_long) 1315 { 1316 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1317 if (scripter) 1318 { 1319 std::string docstring; 1320 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1321 if (!docstring.empty()) 1322 SetHelpLong(docstring); 1323 } 1324 } 1325 return CommandObjectRaw::GetHelpLong(); 1326 } 1327 1328 protected: 1329 virtual bool 1330 DoExecute (const char *raw_command_line, CommandReturnObject &result) 1331 { 1332 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1333 1334 Error error; 1335 1336 result.SetStatus(eReturnStatusInvalid); 1337 1338 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1339 raw_command_line, 1340 m_synchro, 1341 result, 1342 error) == false) 1343 { 1344 result.AppendError(error.AsCString()); 1345 result.SetStatus(eReturnStatusFailed); 1346 } 1347 else 1348 { 1349 // Don't change the status if the command already set it... 1350 if (result.GetStatus() == eReturnStatusInvalid) 1351 { 1352 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1353 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1354 else 1355 result.SetStatus(eReturnStatusSuccessFinishResult); 1356 } 1357 } 1358 1359 return result.Succeeded(); 1360 } 1361 1362 }; 1363 1364 //------------------------------------------------------------------------- 1365 // CommandObjectCommandsScriptImport 1366 //------------------------------------------------------------------------- 1367 1368 class CommandObjectCommandsScriptImport : public CommandObjectParsed 1369 { 1370 public: 1371 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 1372 CommandObjectParsed (interpreter, 1373 "command script import", 1374 "Import a scripting module in LLDB.", 1375 NULL), 1376 m_options(interpreter) 1377 { 1378 CommandArgumentEntry arg1; 1379 CommandArgumentData cmd_arg; 1380 1381 // Define the first (and only) variant of this arg. 1382 cmd_arg.arg_type = eArgTypeFilename; 1383 cmd_arg.arg_repetition = eArgRepeatPlain; 1384 1385 // There is only one variant this argument could be; put it into the argument entry. 1386 arg1.push_back (cmd_arg); 1387 1388 // Push the data for the first argument into the m_arguments vector. 1389 m_arguments.push_back (arg1); 1390 } 1391 1392 ~CommandObjectCommandsScriptImport () 1393 { 1394 } 1395 1396 virtual int 1397 HandleArgumentCompletion (Args &input, 1398 int &cursor_index, 1399 int &cursor_char_position, 1400 OptionElementVector &opt_element_vector, 1401 int match_start_point, 1402 int max_return_elements, 1403 bool &word_complete, 1404 StringList &matches) 1405 { 1406 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1407 completion_str.erase (cursor_char_position); 1408 1409 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1410 CommandCompletions::eDiskFileCompletion, 1411 completion_str.c_str(), 1412 match_start_point, 1413 max_return_elements, 1414 NULL, 1415 word_complete, 1416 matches); 1417 return matches.GetSize(); 1418 } 1419 1420 virtual Options * 1421 GetOptions () 1422 { 1423 return &m_options; 1424 } 1425 1426 protected: 1427 1428 class CommandOptions : public Options 1429 { 1430 public: 1431 1432 CommandOptions (CommandInterpreter &interpreter) : 1433 Options (interpreter) 1434 { 1435 } 1436 1437 virtual 1438 ~CommandOptions (){} 1439 1440 virtual Error 1441 SetOptionValue (uint32_t option_idx, const char *option_arg) 1442 { 1443 Error error; 1444 const int short_option = m_getopt_table[option_idx].val; 1445 1446 switch (short_option) 1447 { 1448 case 'r': 1449 m_allow_reload = true; 1450 break; 1451 default: 1452 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1453 break; 1454 } 1455 1456 return error; 1457 } 1458 1459 void 1460 OptionParsingStarting () 1461 { 1462 m_allow_reload = true; 1463 } 1464 1465 const OptionDefinition* 1466 GetDefinitions () 1467 { 1468 return g_option_table; 1469 } 1470 1471 // Options table: Required for subclasses of Options. 1472 1473 static OptionDefinition g_option_table[]; 1474 1475 // Instance variables to hold the values for command options. 1476 1477 bool m_allow_reload; 1478 }; 1479 1480 bool 1481 DoExecute (Args& command, CommandReturnObject &result) 1482 { 1483 1484 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1485 { 1486 result.AppendError ("only scripting language supported for module importing is currently Python"); 1487 result.SetStatus (eReturnStatusFailed); 1488 return false; 1489 } 1490 1491 size_t argc = command.GetArgumentCount(); 1492 1493 if (argc != 1) 1494 { 1495 result.AppendError ("'command script import' requires one argument"); 1496 result.SetStatus (eReturnStatusFailed); 1497 return false; 1498 } 1499 1500 std::string path = command.GetArgumentAtIndex(0); 1501 Error error; 1502 1503 const bool init_session = true; 1504 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1505 // commands won't ever be recursively invoked, but it's actually possible to craft 1506 // a Python script that does other "command script imports" in __lldb_init_module 1507 // the real fix is to have recursive commands possible with a CommandInvocation object 1508 // separate from the CommandObject itself, so that recursive command invocations 1509 // won't stomp on each other (wrt to execution contents, options, and more) 1510 m_exe_ctx.Clear(); 1511 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 1512 m_options.m_allow_reload, 1513 init_session, 1514 error)) 1515 { 1516 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1517 } 1518 else 1519 { 1520 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1521 result.SetStatus (eReturnStatusFailed); 1522 } 1523 1524 return result.Succeeded(); 1525 } 1526 1527 CommandOptions m_options; 1528 }; 1529 1530 OptionDefinition 1531 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 1532 { 1533 { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, 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."}, 1534 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1535 }; 1536 1537 1538 //------------------------------------------------------------------------- 1539 // CommandObjectCommandsScriptAdd 1540 //------------------------------------------------------------------------- 1541 1542 class CommandObjectCommandsScriptAdd : 1543 public CommandObjectParsed, 1544 public IOHandlerDelegateMultiline 1545 { 1546 public: 1547 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 1548 CommandObjectParsed (interpreter, 1549 "command script add", 1550 "Add a scripted function as an LLDB command.", 1551 NULL), 1552 IOHandlerDelegateMultiline ("DONE"), 1553 m_options (interpreter) 1554 { 1555 CommandArgumentEntry arg1; 1556 CommandArgumentData cmd_arg; 1557 1558 // Define the first (and only) variant of this arg. 1559 cmd_arg.arg_type = eArgTypeCommandName; 1560 cmd_arg.arg_repetition = eArgRepeatPlain; 1561 1562 // There is only one variant this argument could be; put it into the argument entry. 1563 arg1.push_back (cmd_arg); 1564 1565 // Push the data for the first argument into the m_arguments vector. 1566 m_arguments.push_back (arg1); 1567 } 1568 1569 ~CommandObjectCommandsScriptAdd () 1570 { 1571 } 1572 1573 virtual Options * 1574 GetOptions () 1575 { 1576 return &m_options; 1577 } 1578 1579 protected: 1580 1581 class CommandOptions : public Options 1582 { 1583 public: 1584 1585 CommandOptions (CommandInterpreter &interpreter) : 1586 Options (interpreter) 1587 { 1588 } 1589 1590 virtual 1591 ~CommandOptions (){} 1592 1593 virtual Error 1594 SetOptionValue (uint32_t option_idx, const char *option_arg) 1595 { 1596 Error error; 1597 const int short_option = m_getopt_table[option_idx].val; 1598 1599 switch (short_option) 1600 { 1601 case 'f': 1602 m_funct_name = std::string(option_arg); 1603 break; 1604 case 's': 1605 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1606 if (!error.Success()) 1607 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 1608 break; 1609 default: 1610 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1611 break; 1612 } 1613 1614 return error; 1615 } 1616 1617 void 1618 OptionParsingStarting () 1619 { 1620 m_funct_name = ""; 1621 m_synchronicity = eScriptedCommandSynchronicitySynchronous; 1622 } 1623 1624 const OptionDefinition* 1625 GetDefinitions () 1626 { 1627 return g_option_table; 1628 } 1629 1630 // Options table: Required for subclasses of Options. 1631 1632 static OptionDefinition g_option_table[]; 1633 1634 // Instance variables to hold the values for command options. 1635 1636 std::string m_funct_name; 1637 ScriptedCommandSynchronicity m_synchronicity; 1638 }; 1639 1640 virtual void 1641 IOHandlerActivated (IOHandler &io_handler) 1642 { 1643 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 1644 if (output_sp) 1645 { 1646 output_sp->PutCString(g_python_command_instructions); 1647 output_sp->Flush(); 1648 } 1649 } 1650 1651 1652 virtual void 1653 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) 1654 { 1655 StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 1656 1657 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 1658 if (interpreter) 1659 { 1660 1661 StringList lines; 1662 lines.SplitIntoLines(data); 1663 if (lines.GetSize() > 0) 1664 { 1665 std::string funct_name_str; 1666 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str)) 1667 { 1668 if (funct_name_str.empty()) 1669 { 1670 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n"); 1671 error_sp->Flush(); 1672 } 1673 else 1674 { 1675 // everything should be fine now, let's add this alias 1676 1677 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter, 1678 m_cmd_name, 1679 funct_name_str.c_str(), 1680 m_synchronicity)); 1681 1682 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1683 { 1684 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n"); 1685 error_sp->Flush(); 1686 } 1687 } 1688 } 1689 else 1690 { 1691 error_sp->Printf ("error: unable to create function, didn't add python command.\n"); 1692 error_sp->Flush(); 1693 } 1694 } 1695 else 1696 { 1697 error_sp->Printf ("error: empty function, didn't add python command.\n"); 1698 error_sp->Flush(); 1699 } 1700 } 1701 else 1702 { 1703 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 1704 error_sp->Flush(); 1705 } 1706 1707 io_handler.SetIsDone(true); 1708 1709 1710 } 1711 1712 protected: 1713 bool 1714 DoExecute (Args& command, CommandReturnObject &result) 1715 { 1716 1717 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1718 { 1719 result.AppendError ("only scripting language supported for scripted commands is currently Python"); 1720 result.SetStatus (eReturnStatusFailed); 1721 return false; 1722 } 1723 1724 size_t argc = command.GetArgumentCount(); 1725 1726 if (argc != 1) 1727 { 1728 result.AppendError ("'command script add' requires one argument"); 1729 result.SetStatus (eReturnStatusFailed); 1730 return false; 1731 } 1732 1733 // Store the command name and synchronicity in case we get multi-line input 1734 m_cmd_name = command.GetArgumentAtIndex(0); 1735 m_synchronicity = m_options.m_synchronicity; 1736 1737 if (m_options.m_funct_name.empty()) 1738 { 1739 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 1740 *this, // IOHandlerDelegate 1741 true, // Run IOHandler in async mode 1742 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 1743 } 1744 else 1745 { 1746 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 1747 m_cmd_name, 1748 m_options.m_funct_name, 1749 m_synchronicity)); 1750 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 1751 { 1752 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1753 } 1754 else 1755 { 1756 result.AppendError("cannot add command"); 1757 result.SetStatus (eReturnStatusFailed); 1758 } 1759 } 1760 1761 return result.Succeeded(); 1762 1763 } 1764 1765 CommandOptions m_options; 1766 std::string m_cmd_name; 1767 ScriptedCommandSynchronicity m_synchronicity; 1768 }; 1769 1770 static OptionEnumValueElement g_script_synchro_type[] = 1771 { 1772 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 1773 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 1774 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 1775 { 0, NULL, NULL } 1776 }; 1777 1778 OptionDefinition 1779 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 1780 { 1781 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 1782 { LLDB_OPT_SET_1, false, "synchronicity", 's', OptionParser::eRequiredArgument, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."}, 1783 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1784 }; 1785 1786 //------------------------------------------------------------------------- 1787 // CommandObjectCommandsScriptList 1788 //------------------------------------------------------------------------- 1789 1790 class CommandObjectCommandsScriptList : public CommandObjectParsed 1791 { 1792 private: 1793 1794 public: 1795 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 1796 CommandObjectParsed (interpreter, 1797 "command script list", 1798 "List defined scripted commands.", 1799 NULL) 1800 { 1801 } 1802 1803 ~CommandObjectCommandsScriptList () 1804 { 1805 } 1806 1807 bool 1808 DoExecute (Args& command, CommandReturnObject &result) 1809 { 1810 1811 m_interpreter.GetHelp(result, 1812 CommandInterpreter::eCommandTypesUserDef); 1813 1814 result.SetStatus (eReturnStatusSuccessFinishResult); 1815 1816 return true; 1817 1818 1819 } 1820 }; 1821 1822 //------------------------------------------------------------------------- 1823 // CommandObjectCommandsScriptClear 1824 //------------------------------------------------------------------------- 1825 1826 class CommandObjectCommandsScriptClear : public CommandObjectParsed 1827 { 1828 private: 1829 1830 public: 1831 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 1832 CommandObjectParsed (interpreter, 1833 "command script clear", 1834 "Delete all scripted commands.", 1835 NULL) 1836 { 1837 } 1838 1839 ~CommandObjectCommandsScriptClear () 1840 { 1841 } 1842 1843 protected: 1844 bool 1845 DoExecute (Args& command, CommandReturnObject &result) 1846 { 1847 1848 m_interpreter.RemoveAllUser(); 1849 1850 result.SetStatus (eReturnStatusSuccessFinishResult); 1851 1852 return true; 1853 } 1854 }; 1855 1856 //------------------------------------------------------------------------- 1857 // CommandObjectCommandsScriptDelete 1858 //------------------------------------------------------------------------- 1859 1860 class CommandObjectCommandsScriptDelete : public CommandObjectParsed 1861 { 1862 public: 1863 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 1864 CommandObjectParsed (interpreter, 1865 "command script delete", 1866 "Delete a scripted command.", 1867 NULL) 1868 { 1869 CommandArgumentEntry arg1; 1870 CommandArgumentData cmd_arg; 1871 1872 // Define the first (and only) variant of this arg. 1873 cmd_arg.arg_type = eArgTypeCommandName; 1874 cmd_arg.arg_repetition = eArgRepeatPlain; 1875 1876 // There is only one variant this argument could be; put it into the argument entry. 1877 arg1.push_back (cmd_arg); 1878 1879 // Push the data for the first argument into the m_arguments vector. 1880 m_arguments.push_back (arg1); 1881 } 1882 1883 ~CommandObjectCommandsScriptDelete () 1884 { 1885 } 1886 1887 protected: 1888 bool 1889 DoExecute (Args& command, CommandReturnObject &result) 1890 { 1891 1892 size_t argc = command.GetArgumentCount(); 1893 1894 if (argc != 1) 1895 { 1896 result.AppendError ("'command script delete' requires one argument"); 1897 result.SetStatus (eReturnStatusFailed); 1898 return false; 1899 } 1900 1901 const char* cmd_name = command.GetArgumentAtIndex(0); 1902 1903 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 1904 { 1905 m_interpreter.RemoveUser(cmd_name); 1906 result.SetStatus (eReturnStatusSuccessFinishResult); 1907 } 1908 else 1909 { 1910 result.AppendErrorWithFormat ("command %s not found", cmd_name); 1911 result.SetStatus (eReturnStatusFailed); 1912 } 1913 1914 return result.Succeeded(); 1915 1916 } 1917 }; 1918 1919 #pragma mark CommandObjectMultiwordCommandsScript 1920 1921 //------------------------------------------------------------------------- 1922 // CommandObjectMultiwordCommandsScript 1923 //------------------------------------------------------------------------- 1924 1925 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 1926 { 1927 public: 1928 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 1929 CommandObjectMultiword (interpreter, 1930 "command script", 1931 "A set of commands for managing or customizing script commands.", 1932 "command script <subcommand> [<subcommand-options>]") 1933 { 1934 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 1935 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 1936 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 1937 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 1938 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 1939 } 1940 1941 ~CommandObjectMultiwordCommandsScript () 1942 { 1943 } 1944 1945 }; 1946 1947 1948 #pragma mark CommandObjectMultiwordCommands 1949 1950 //------------------------------------------------------------------------- 1951 // CommandObjectMultiwordCommands 1952 //------------------------------------------------------------------------- 1953 1954 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 1955 CommandObjectMultiword (interpreter, 1956 "command", 1957 "A set of commands for managing or customizing the debugger commands.", 1958 "command <subcommand> [<subcommand-options>]") 1959 { 1960 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 1961 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 1962 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 1963 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 1964 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 1965 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 1966 } 1967 1968 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 1969 { 1970 } 1971 1972