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