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 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 427 OptionDefinition 428 CommandObjectCommandsSource::CommandOptions::g_option_table[] = 429 { 430 { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 431 { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 432 { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."}, 433 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 434 }; 435 436 #pragma mark CommandObjectCommandsAlias 437 //------------------------------------------------------------------------- 438 // CommandObjectCommandsAlias 439 //------------------------------------------------------------------------- 440 441 static 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 446 class CommandObjectCommandsAlias : public CommandObjectRaw 447 { 448 449 450 public: 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 551 protected: 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 791 class CommandObjectCommandsUnalias : public CommandObjectParsed 792 { 793 public: 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 818 protected: 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 876 class CommandObjectCommandsAddRegex : 877 public CommandObjectParsed, 878 public IOHandlerDelegate 879 { 880 public: 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 expression 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 921 protected: 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-regex", // Name of input reader for history 1038 "\033[K> ", // Prompt and clear line 1039 multiple_lines, 1040 0, // Don't show line numbers 1041 *this)); 1042 1043 if (io_handler_sp) 1044 { 1045 debugger.PushIOHandler(io_handler_sp); 1046 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1047 } 1048 } 1049 else 1050 { 1051 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 1052 { 1053 llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 1054 bool check_only = false; 1055 error = AppendRegexSubstitution (arg_strref, check_only); 1056 if (error.Fail()) 1057 break; 1058 } 1059 1060 if (error.Success()) 1061 { 1062 AddRegexCommandToInterpreter(); 1063 } 1064 } 1065 if (error.Fail()) 1066 { 1067 result.AppendError (error.AsCString()); 1068 result.SetStatus (eReturnStatusFailed); 1069 } 1070 } 1071 1072 return result.Succeeded(); 1073 } 1074 1075 Error 1076 AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only) 1077 { 1078 Error error; 1079 1080 if (m_regex_cmd_ap.get() == NULL) 1081 { 1082 error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 1083 (int)regex_sed.size(), 1084 regex_sed.data()); 1085 return error; 1086 } 1087 1088 size_t regex_sed_size = regex_sed.size(); 1089 1090 if (regex_sed_size <= 1) 1091 { 1092 error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 1093 (int)regex_sed.size(), 1094 regex_sed.data()); 1095 return error; 1096 } 1097 1098 if (regex_sed[0] != 's') 1099 { 1100 error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 1101 (int)regex_sed.size(), 1102 regex_sed.data()); 1103 return error; 1104 } 1105 const size_t first_separator_char_pos = 1; 1106 // use the char that follows 's' as the regex separator character 1107 // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 1108 const char separator_char = regex_sed[first_separator_char_pos]; 1109 const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 1110 1111 if (second_separator_char_pos == std::string::npos) 1112 { 1113 error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'", 1114 separator_char, 1115 (int)(regex_sed.size() - first_separator_char_pos - 1), 1116 regex_sed.data() + (first_separator_char_pos + 1)); 1117 return error; 1118 } 1119 1120 const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 1121 1122 if (third_separator_char_pos == std::string::npos) 1123 { 1124 error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'", 1125 separator_char, 1126 (int)(regex_sed.size() - second_separator_char_pos - 1), 1127 regex_sed.data() + (second_separator_char_pos + 1)); 1128 return error; 1129 } 1130 1131 if (third_separator_char_pos != regex_sed_size - 1) 1132 { 1133 // Make sure that everything that follows the last regex 1134 // separator char 1135 if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 1136 { 1137 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 1138 (int)third_separator_char_pos + 1, 1139 regex_sed.data(), 1140 (int)(regex_sed.size() - third_separator_char_pos - 1), 1141 regex_sed.data() + (third_separator_char_pos + 1)); 1142 return error; 1143 } 1144 1145 } 1146 else if (first_separator_char_pos + 1 == second_separator_char_pos) 1147 { 1148 error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 1149 separator_char, 1150 separator_char, 1151 separator_char, 1152 (int)regex_sed.size(), 1153 regex_sed.data()); 1154 return error; 1155 } 1156 else if (second_separator_char_pos + 1 == third_separator_char_pos) 1157 { 1158 error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 1159 separator_char, 1160 separator_char, 1161 separator_char, 1162 (int)regex_sed.size(), 1163 regex_sed.data()); 1164 return error; 1165 } 1166 1167 if (check_only == false) 1168 { 1169 std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 1170 std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 1171 m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 1172 subst.c_str()); 1173 } 1174 return error; 1175 } 1176 1177 void 1178 AddRegexCommandToInterpreter() 1179 { 1180 if (m_regex_cmd_ap.get()) 1181 { 1182 if (m_regex_cmd_ap->HasRegexEntries()) 1183 { 1184 CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 1185 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 1186 } 1187 } 1188 } 1189 1190 private: 1191 std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1192 1193 class CommandOptions : public Options 1194 { 1195 public: 1196 1197 CommandOptions (CommandInterpreter &interpreter) : 1198 Options (interpreter) 1199 { 1200 } 1201 1202 virtual 1203 ~CommandOptions (){} 1204 1205 virtual Error 1206 SetOptionValue (uint32_t option_idx, const char *option_arg) 1207 { 1208 Error error; 1209 const int short_option = m_getopt_table[option_idx].val; 1210 1211 switch (short_option) 1212 { 1213 case 'h': 1214 m_help.assign (option_arg); 1215 break; 1216 case 's': 1217 m_syntax.assign (option_arg); 1218 break; 1219 1220 default: 1221 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1222 break; 1223 } 1224 1225 return error; 1226 } 1227 1228 void 1229 OptionParsingStarting () 1230 { 1231 m_help.clear(); 1232 m_syntax.clear(); 1233 } 1234 1235 const OptionDefinition* 1236 GetDefinitions () 1237 { 1238 return g_option_table; 1239 } 1240 1241 // Options table: Required for subclasses of Options. 1242 1243 static OptionDefinition g_option_table[]; 1244 1245 const char * 1246 GetHelp () 1247 { 1248 if (m_help.empty()) 1249 return NULL; 1250 return m_help.c_str(); 1251 } 1252 const char * 1253 GetSyntax () 1254 { 1255 if (m_syntax.empty()) 1256 return NULL; 1257 return m_syntax.c_str(); 1258 } 1259 // Instance variables to hold the values for command options. 1260 protected: 1261 std::string m_help; 1262 std::string m_syntax; 1263 }; 1264 1265 virtual Options * 1266 GetOptions () 1267 { 1268 return &m_options; 1269 } 1270 1271 CommandOptions m_options; 1272 }; 1273 1274 OptionDefinition 1275 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1276 { 1277 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1278 { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1279 { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL } 1280 }; 1281 1282 1283 class CommandObjectPythonFunction : public CommandObjectRaw 1284 { 1285 private: 1286 std::string m_function_name; 1287 ScriptedCommandSynchronicity m_synchro; 1288 bool m_fetched_help_long; 1289 1290 public: 1291 1292 CommandObjectPythonFunction (CommandInterpreter &interpreter, 1293 std::string name, 1294 std::string funct, 1295 std::string help, 1296 ScriptedCommandSynchronicity synch) : 1297 CommandObjectRaw (interpreter, 1298 name.c_str(), 1299 NULL, 1300 NULL), 1301 m_function_name(funct), 1302 m_synchro(synch), 1303 m_fetched_help_long(false) 1304 { 1305 if (!help.empty()) 1306 SetHelp(help.c_str()); 1307 else 1308 { 1309 StreamString stream; 1310 stream.Printf("For more information run 'help %s'",name.c_str()); 1311 SetHelp(stream.GetData()); 1312 } 1313 } 1314 1315 virtual 1316 ~CommandObjectPythonFunction () 1317 { 1318 } 1319 1320 virtual bool 1321 IsRemovable () const 1322 { 1323 return true; 1324 } 1325 1326 const std::string& 1327 GetFunctionName () 1328 { 1329 return m_function_name; 1330 } 1331 1332 ScriptedCommandSynchronicity 1333 GetSynchronicity () 1334 { 1335 return m_synchro; 1336 } 1337 1338 virtual const char * 1339 GetHelpLong () 1340 { 1341 if (!m_fetched_help_long) 1342 { 1343 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1344 if (scripter) 1345 { 1346 std::string docstring; 1347 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1348 if (!docstring.empty()) 1349 SetHelpLong(docstring); 1350 } 1351 } 1352 return CommandObjectRaw::GetHelpLong(); 1353 } 1354 1355 protected: 1356 virtual bool 1357 DoExecute (const char *raw_command_line, CommandReturnObject &result) 1358 { 1359 ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1360 1361 Error error; 1362 1363 result.SetStatus(eReturnStatusInvalid); 1364 1365 if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1366 raw_command_line, 1367 m_synchro, 1368 result, 1369 error, 1370 m_exe_ctx) == false) 1371 { 1372 result.AppendError(error.AsCString()); 1373 result.SetStatus(eReturnStatusFailed); 1374 } 1375 else 1376 { 1377 // Don't change the status if the command already set it... 1378 if (result.GetStatus() == eReturnStatusInvalid) 1379 { 1380 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1381 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1382 else 1383 result.SetStatus(eReturnStatusSuccessFinishResult); 1384 } 1385 } 1386 1387 return result.Succeeded(); 1388 } 1389 1390 }; 1391 1392 //------------------------------------------------------------------------- 1393 // CommandObjectCommandsScriptImport 1394 //------------------------------------------------------------------------- 1395 1396 class CommandObjectCommandsScriptImport : public CommandObjectParsed 1397 { 1398 public: 1399 CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 1400 CommandObjectParsed (interpreter, 1401 "command script import", 1402 "Import a scripting module in LLDB.", 1403 NULL), 1404 m_options(interpreter) 1405 { 1406 CommandArgumentEntry arg1; 1407 CommandArgumentData cmd_arg; 1408 1409 // Define the first (and only) variant of this arg. 1410 cmd_arg.arg_type = eArgTypeFilename; 1411 cmd_arg.arg_repetition = eArgRepeatPlain; 1412 1413 // There is only one variant this argument could be; put it into the argument entry. 1414 arg1.push_back (cmd_arg); 1415 1416 // Push the data for the first argument into the m_arguments vector. 1417 m_arguments.push_back (arg1); 1418 } 1419 1420 ~CommandObjectCommandsScriptImport () 1421 { 1422 } 1423 1424 virtual int 1425 HandleArgumentCompletion (Args &input, 1426 int &cursor_index, 1427 int &cursor_char_position, 1428 OptionElementVector &opt_element_vector, 1429 int match_start_point, 1430 int max_return_elements, 1431 bool &word_complete, 1432 StringList &matches) 1433 { 1434 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1435 completion_str.erase (cursor_char_position); 1436 1437 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1438 CommandCompletions::eDiskFileCompletion, 1439 completion_str.c_str(), 1440 match_start_point, 1441 max_return_elements, 1442 NULL, 1443 word_complete, 1444 matches); 1445 return matches.GetSize(); 1446 } 1447 1448 virtual Options * 1449 GetOptions () 1450 { 1451 return &m_options; 1452 } 1453 1454 protected: 1455 1456 class CommandOptions : public Options 1457 { 1458 public: 1459 1460 CommandOptions (CommandInterpreter &interpreter) : 1461 Options (interpreter) 1462 { 1463 } 1464 1465 virtual 1466 ~CommandOptions (){} 1467 1468 virtual Error 1469 SetOptionValue (uint32_t option_idx, const char *option_arg) 1470 { 1471 Error error; 1472 const int short_option = m_getopt_table[option_idx].val; 1473 1474 switch (short_option) 1475 { 1476 case 'r': 1477 m_allow_reload = true; 1478 break; 1479 default: 1480 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1481 break; 1482 } 1483 1484 return error; 1485 } 1486 1487 void 1488 OptionParsingStarting () 1489 { 1490 m_allow_reload = true; 1491 } 1492 1493 const OptionDefinition* 1494 GetDefinitions () 1495 { 1496 return g_option_table; 1497 } 1498 1499 // Options table: Required for subclasses of Options. 1500 1501 static OptionDefinition g_option_table[]; 1502 1503 // Instance variables to hold the values for command options. 1504 1505 bool m_allow_reload; 1506 }; 1507 1508 bool 1509 DoExecute (Args& command, CommandReturnObject &result) 1510 { 1511 1512 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1513 { 1514 result.AppendError ("only scripting language supported for module importing is currently Python"); 1515 result.SetStatus (eReturnStatusFailed); 1516 return false; 1517 } 1518 1519 size_t argc = command.GetArgumentCount(); 1520 1521 if (argc != 1) 1522 { 1523 result.AppendError ("'command script import' requires one argument"); 1524 result.SetStatus (eReturnStatusFailed); 1525 return false; 1526 } 1527 1528 std::string path = command.GetArgumentAtIndex(0); 1529 Error error; 1530 1531 const bool init_session = true; 1532 // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1533 // commands won't ever be recursively invoked, but it's actually possible to craft 1534 // a Python script that does other "command script imports" in __lldb_init_module 1535 // the real fix is to have recursive commands possible with a CommandInvocation object 1536 // separate from the CommandObject itself, so that recursive command invocations 1537 // won't stomp on each other (wrt to execution contents, options, and more) 1538 m_exe_ctx.Clear(); 1539 if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 1540 m_options.m_allow_reload, 1541 init_session, 1542 error)) 1543 { 1544 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1545 } 1546 else 1547 { 1548 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1549 result.SetStatus (eReturnStatusFailed); 1550 } 1551 1552 return result.Succeeded(); 1553 } 1554 1555 CommandOptions m_options; 1556 }; 1557 1558 OptionDefinition 1559 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 1560 { 1561 { 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."}, 1562 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1563 }; 1564 1565 1566 //------------------------------------------------------------------------- 1567 // CommandObjectCommandsScriptAdd 1568 //------------------------------------------------------------------------- 1569 1570 class CommandObjectCommandsScriptAdd : 1571 public CommandObjectParsed, 1572 public IOHandlerDelegateMultiline 1573 { 1574 public: 1575 CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 1576 CommandObjectParsed (interpreter, 1577 "command script add", 1578 "Add a scripted function as an LLDB command.", 1579 NULL), 1580 IOHandlerDelegateMultiline ("DONE"), 1581 m_options (interpreter) 1582 { 1583 CommandArgumentEntry arg1; 1584 CommandArgumentData cmd_arg; 1585 1586 // Define the first (and only) variant of this arg. 1587 cmd_arg.arg_type = eArgTypeCommandName; 1588 cmd_arg.arg_repetition = eArgRepeatPlain; 1589 1590 // There is only one variant this argument could be; put it into the argument entry. 1591 arg1.push_back (cmd_arg); 1592 1593 // Push the data for the first argument into the m_arguments vector. 1594 m_arguments.push_back (arg1); 1595 } 1596 1597 ~CommandObjectCommandsScriptAdd () 1598 { 1599 } 1600 1601 virtual Options * 1602 GetOptions () 1603 { 1604 return &m_options; 1605 } 1606 1607 protected: 1608 1609 class CommandOptions : public Options 1610 { 1611 public: 1612 1613 CommandOptions (CommandInterpreter &interpreter) : 1614 Options (interpreter) 1615 { 1616 } 1617 1618 virtual 1619 ~CommandOptions (){} 1620 1621 virtual Error 1622 SetOptionValue (uint32_t option_idx, const char *option_arg) 1623 { 1624 Error error; 1625 const int short_option = m_getopt_table[option_idx].val; 1626 1627 switch (short_option) 1628 { 1629 case 'f': 1630 if (option_arg) 1631 m_funct_name.assign(option_arg); 1632 break; 1633 case 'h': 1634 if (option_arg) 1635 m_short_help.assign(option_arg); 1636 break; 1637 case 's': 1638 m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1639 if (!error.Success()) 1640 error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 1641 break; 1642 default: 1643 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1644 break; 1645 } 1646 1647 return error; 1648 } 1649 1650 void 1651 OptionParsingStarting () 1652 { 1653 m_funct_name.clear(); 1654 m_short_help.clear(); 1655 m_synchronicity = eScriptedCommandSynchronicitySynchronous; 1656 } 1657 1658 const OptionDefinition* 1659 GetDefinitions () 1660 { 1661 return g_option_table; 1662 } 1663 1664 // Options table: Required for subclasses of Options. 1665 1666 static OptionDefinition g_option_table[]; 1667 1668 // Instance variables to hold the values for command options. 1669 1670 std::string m_funct_name; 1671 std::string m_short_help; 1672 ScriptedCommandSynchronicity m_synchronicity; 1673 }; 1674 1675 virtual void 1676 IOHandlerActivated (IOHandler &io_handler) 1677 { 1678 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 1679 if (output_sp) 1680 { 1681 output_sp->PutCString(g_python_command_instructions); 1682 output_sp->Flush(); 1683 } 1684 } 1685 1686 1687 virtual void 1688 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) 1689 { 1690 StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 1691 1692 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 1693 if (interpreter) 1694 { 1695 1696 StringList lines; 1697 lines.SplitIntoLines(data); 1698 if (lines.GetSize() > 0) 1699 { 1700 std::string funct_name_str; 1701 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str)) 1702 { 1703 if (funct_name_str.empty()) 1704 { 1705 error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n"); 1706 error_sp->Flush(); 1707 } 1708 else 1709 { 1710 // everything should be fine now, let's add this alias 1711 1712 CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter, 1713 m_cmd_name, 1714 funct_name_str.c_str(), 1715 m_short_help, 1716 m_synchronicity)); 1717 1718 if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1719 { 1720 error_sp->Printf ("error: unable to add selected command, didn't add python command.\n"); 1721 error_sp->Flush(); 1722 } 1723 } 1724 } 1725 else 1726 { 1727 error_sp->Printf ("error: unable to create function, didn't add python command.\n"); 1728 error_sp->Flush(); 1729 } 1730 } 1731 else 1732 { 1733 error_sp->Printf ("error: empty function, didn't add python command.\n"); 1734 error_sp->Flush(); 1735 } 1736 } 1737 else 1738 { 1739 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 1740 error_sp->Flush(); 1741 } 1742 1743 io_handler.SetIsDone(true); 1744 1745 1746 } 1747 1748 protected: 1749 bool 1750 DoExecute (Args& command, CommandReturnObject &result) 1751 { 1752 1753 if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1754 { 1755 result.AppendError ("only scripting language supported for scripted commands is currently Python"); 1756 result.SetStatus (eReturnStatusFailed); 1757 return false; 1758 } 1759 1760 size_t argc = command.GetArgumentCount(); 1761 1762 if (argc != 1) 1763 { 1764 result.AppendError ("'command script add' requires one argument"); 1765 result.SetStatus (eReturnStatusFailed); 1766 return false; 1767 } 1768 1769 // Store the options in case we get multi-line input 1770 m_cmd_name = command.GetArgumentAtIndex(0); 1771 m_short_help.assign(m_options.m_short_help); 1772 m_synchronicity = m_options.m_synchronicity; 1773 1774 if (m_options.m_funct_name.empty()) 1775 { 1776 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 1777 *this, // IOHandlerDelegate 1778 true, // Run IOHandler in async mode 1779 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 1780 } 1781 else 1782 { 1783 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 1784 m_cmd_name, 1785 m_options.m_funct_name, 1786 m_options.m_short_help, 1787 m_synchronicity)); 1788 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 1789 { 1790 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1791 } 1792 else 1793 { 1794 result.AppendError("cannot add command"); 1795 result.SetStatus (eReturnStatusFailed); 1796 } 1797 } 1798 1799 return result.Succeeded(); 1800 1801 } 1802 1803 CommandOptions m_options; 1804 std::string m_cmd_name; 1805 std::string m_short_help; 1806 ScriptedCommandSynchronicity m_synchronicity; 1807 }; 1808 1809 static OptionEnumValueElement g_script_synchro_type[] = 1810 { 1811 { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 1812 { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 1813 { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 1814 { 0, NULL, NULL } 1815 }; 1816 1817 OptionDefinition 1818 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 1819 { 1820 { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 1821 { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."}, 1822 { 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."}, 1823 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1824 }; 1825 1826 //------------------------------------------------------------------------- 1827 // CommandObjectCommandsScriptList 1828 //------------------------------------------------------------------------- 1829 1830 class CommandObjectCommandsScriptList : public CommandObjectParsed 1831 { 1832 private: 1833 1834 public: 1835 CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 1836 CommandObjectParsed (interpreter, 1837 "command script list", 1838 "List defined scripted commands.", 1839 NULL) 1840 { 1841 } 1842 1843 ~CommandObjectCommandsScriptList () 1844 { 1845 } 1846 1847 bool 1848 DoExecute (Args& command, CommandReturnObject &result) 1849 { 1850 1851 m_interpreter.GetHelp(result, 1852 CommandInterpreter::eCommandTypesUserDef); 1853 1854 result.SetStatus (eReturnStatusSuccessFinishResult); 1855 1856 return true; 1857 1858 1859 } 1860 }; 1861 1862 //------------------------------------------------------------------------- 1863 // CommandObjectCommandsScriptClear 1864 //------------------------------------------------------------------------- 1865 1866 class CommandObjectCommandsScriptClear : public CommandObjectParsed 1867 { 1868 private: 1869 1870 public: 1871 CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 1872 CommandObjectParsed (interpreter, 1873 "command script clear", 1874 "Delete all scripted commands.", 1875 NULL) 1876 { 1877 } 1878 1879 ~CommandObjectCommandsScriptClear () 1880 { 1881 } 1882 1883 protected: 1884 bool 1885 DoExecute (Args& command, CommandReturnObject &result) 1886 { 1887 1888 m_interpreter.RemoveAllUser(); 1889 1890 result.SetStatus (eReturnStatusSuccessFinishResult); 1891 1892 return true; 1893 } 1894 }; 1895 1896 //------------------------------------------------------------------------- 1897 // CommandObjectCommandsScriptDelete 1898 //------------------------------------------------------------------------- 1899 1900 class CommandObjectCommandsScriptDelete : public CommandObjectParsed 1901 { 1902 public: 1903 CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 1904 CommandObjectParsed (interpreter, 1905 "command script delete", 1906 "Delete a scripted command.", 1907 NULL) 1908 { 1909 CommandArgumentEntry arg1; 1910 CommandArgumentData cmd_arg; 1911 1912 // Define the first (and only) variant of this arg. 1913 cmd_arg.arg_type = eArgTypeCommandName; 1914 cmd_arg.arg_repetition = eArgRepeatPlain; 1915 1916 // There is only one variant this argument could be; put it into the argument entry. 1917 arg1.push_back (cmd_arg); 1918 1919 // Push the data for the first argument into the m_arguments vector. 1920 m_arguments.push_back (arg1); 1921 } 1922 1923 ~CommandObjectCommandsScriptDelete () 1924 { 1925 } 1926 1927 protected: 1928 bool 1929 DoExecute (Args& command, CommandReturnObject &result) 1930 { 1931 1932 size_t argc = command.GetArgumentCount(); 1933 1934 if (argc != 1) 1935 { 1936 result.AppendError ("'command script delete' requires one argument"); 1937 result.SetStatus (eReturnStatusFailed); 1938 return false; 1939 } 1940 1941 const char* cmd_name = command.GetArgumentAtIndex(0); 1942 1943 if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 1944 { 1945 m_interpreter.RemoveUser(cmd_name); 1946 result.SetStatus (eReturnStatusSuccessFinishResult); 1947 } 1948 else 1949 { 1950 result.AppendErrorWithFormat ("command %s not found", cmd_name); 1951 result.SetStatus (eReturnStatusFailed); 1952 } 1953 1954 return result.Succeeded(); 1955 1956 } 1957 }; 1958 1959 #pragma mark CommandObjectMultiwordCommandsScript 1960 1961 //------------------------------------------------------------------------- 1962 // CommandObjectMultiwordCommandsScript 1963 //------------------------------------------------------------------------- 1964 1965 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 1966 { 1967 public: 1968 CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 1969 CommandObjectMultiword (interpreter, 1970 "command script", 1971 "A set of commands for managing or customizing script commands.", 1972 "command script <subcommand> [<subcommand-options>]") 1973 { 1974 LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 1975 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 1976 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 1977 LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 1978 LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 1979 } 1980 1981 ~CommandObjectMultiwordCommandsScript () 1982 { 1983 } 1984 1985 }; 1986 1987 1988 #pragma mark CommandObjectMultiwordCommands 1989 1990 //------------------------------------------------------------------------- 1991 // CommandObjectMultiwordCommands 1992 //------------------------------------------------------------------------- 1993 1994 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 1995 CommandObjectMultiword (interpreter, 1996 "command", 1997 "A set of commands for managing or customizing the debugger commands.", 1998 "command <subcommand> [<subcommand-options>]") 1999 { 2000 LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 2001 LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 2002 LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 2003 LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 2004 LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 2005 LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 2006 } 2007 2008 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 2009 { 2010 } 2011 2012