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