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