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