1 //===-- CommandInterpreter.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 <string> 11 12 #include <getopt.h> 13 #include <stdlib.h> 14 15 #include "../Commands/CommandObjectAlias.h" 16 #include "../Commands/CommandObjectAppend.h" 17 #include "../Commands/CommandObjectApropos.h" 18 #include "../Commands/CommandObjectArgs.h" 19 #include "../Commands/CommandObjectBreakpoint.h" 20 #include "../Commands/CommandObjectCall.h" 21 #include "../Commands/CommandObjectDelete.h" 22 #include "../Commands/CommandObjectDisassemble.h" 23 #include "../Commands/CommandObjectExpression.h" 24 #include "../Commands/CommandObjectFile.h" 25 #include "../Commands/CommandObjectFrame.h" 26 #include "../Commands/CommandObjectHelp.h" 27 #include "../Commands/CommandObjectImage.h" 28 #include "../Commands/CommandObjectInfo.h" 29 #include "../Commands/CommandObjectLog.h" 30 #include "../Commands/CommandObjectMemory.h" 31 #include "../Commands/CommandObjectProcess.h" 32 #include "../Commands/CommandObjectQuit.h" 33 #include "lldb/Interpreter/CommandObjectRegexCommand.h" 34 #include "../Commands/CommandObjectRegister.h" 35 #include "CommandObjectScript.h" 36 #include "../Commands/CommandObjectSelect.h" 37 #include "../Commands/CommandObjectSet.h" 38 #include "../Commands/CommandObjectSettings.h" 39 #include "../Commands/CommandObjectShow.h" 40 #include "../Commands/CommandObjectSource.h" 41 #include "../Commands/CommandObjectSourceFile.h" 42 #include "../Commands/CommandObjectSyntax.h" 43 #include "../Commands/CommandObjectTarget.h" 44 #include "../Commands/CommandObjectThread.h" 45 #include "../Commands/CommandObjectUnalias.h" 46 #include "../Commands/CommandObjectVariable.h" 47 48 #include "lldb/Interpreter/Args.h" 49 #include "lldb/Core/Debugger.h" 50 #include "lldb/Core/Stream.h" 51 #include "lldb/Core/Timer.h" 52 #include "lldb/Target/Process.h" 53 #include "lldb/Target/Thread.h" 54 #include "lldb/Target/TargetList.h" 55 56 #include "lldb/Interpreter/CommandReturnObject.h" 57 #include "lldb/Interpreter/CommandInterpreter.h" 58 59 using namespace lldb; 60 using namespace lldb_private; 61 62 CommandInterpreter::CommandInterpreter 63 ( 64 Debugger &debugger, 65 ScriptLanguage script_language, 66 bool synchronous_execution 67 ) : 68 Broadcaster ("CommandInterpreter"), 69 m_debugger (debugger), 70 m_script_language (script_language), 71 m_synchronous_execution (synchronous_execution) 72 { 73 } 74 75 void 76 CommandInterpreter::Initialize () 77 { 78 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 79 80 CommandReturnObject result; 81 82 LoadCommandDictionary (); 83 84 InitializeVariables (); 85 86 // Set up some initial aliases. 87 result.Clear(); HandleCommand ("alias q quit", false, result); 88 result.Clear(); HandleCommand ("alias run process launch", false, result); 89 result.Clear(); HandleCommand ("alias r process launch", false, result); 90 result.Clear(); HandleCommand ("alias c process continue", false, result); 91 result.Clear(); HandleCommand ("alias continue process continue", false, result); 92 result.Clear(); HandleCommand ("alias expr expression", false, result); 93 result.Clear(); HandleCommand ("alias exit quit", false, result); 94 result.Clear(); HandleCommand ("alias bt thread backtrace", false, result); 95 result.Clear(); HandleCommand ("alias si thread step-inst", false, result); 96 result.Clear(); HandleCommand ("alias step thread step-in", false, result); 97 result.Clear(); HandleCommand ("alias s thread step-in", false, result); 98 result.Clear(); HandleCommand ("alias next thread step-over", false, result); 99 result.Clear(); HandleCommand ("alias n thread step-over", false, result); 100 result.Clear(); HandleCommand ("alias finish thread step-out", false, result); 101 result.Clear(); HandleCommand ("alias x memory read", false, result); 102 result.Clear(); HandleCommand ("alias l source-file", false, result); 103 result.Clear(); HandleCommand ("alias list source-file", false, result); 104 } 105 106 void 107 CommandInterpreter::InitializeVariables () 108 { 109 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 110 111 m_variables["prompt"] = 112 StateVariableSP (new StateVariable ("prompt", 113 "(lldb) ", 114 false, 115 "The debugger prompt displayed for the user.", 116 StateVariable::BroadcastPromptChange)); 117 118 m_variables["run-args"] = 119 StateVariableSP (new StateVariable ("run-args", 120 (Args*)NULL, 121 "An argument list containing the arguments to be passed to the executable when it is launched.")); 122 123 124 m_variables["env-vars"] = 125 StateVariableSP (new StateVariable ("env-vars", 126 (Args*)NULL, 127 "A list of strings containing the environment variables to be passed to the executable's environment.")); 128 129 m_variables["input-path"] = 130 StateVariableSP (new StateVariable ("input-path", 131 "/dev/stdin", 132 false, 133 "The file/path to be used by the executable program for reading its input.")); 134 135 m_variables["output-path"] = 136 StateVariableSP (new StateVariable ( "output-path", 137 "/dev/stdout", 138 false, 139 "The file/path to be used by the executable program for writing its output.")); 140 141 m_variables["error-path"] = 142 StateVariableSP (new StateVariable ("error-path", 143 "/dev/stderr", 144 false, 145 "The file/path to be used by the executable program for writing its error messages.")); 146 147 m_variables["arch"] = 148 StateVariableSP (new StateVariable ("arch", 149 "", 150 false, 151 "The architecture to be used for running the executable (e.g. i386, x86_64, etc).")); 152 153 m_variables["script-lang"] = 154 StateVariableSP (new StateVariable ("script-lang", 155 "Python", 156 false, 157 "The script language to be used for evaluating user-written scripts.", 158 StateVariable::VerifyScriptLanguage)); 159 160 m_variables["term-width"] = 161 StateVariableSP (new StateVariable ("term-width", 162 80, 163 "The maximum number of columns to use for displaying text.")); 164 165 } 166 167 const char * 168 CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg) 169 { 170 // This function has not yet been implemented. 171 172 // Look for any embedded script command 173 // If found, 174 // get interpreter object from the command dictionary, 175 // call execute_one_command on it, 176 // get the results as a string, 177 // substitute that string for current stuff. 178 179 return arg; 180 } 181 182 183 void 184 CommandInterpreter::LoadCommandDictionary () 185 { 186 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 187 188 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT *** 189 // 190 // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref) 191 // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use 192 // the cross-referencing stuff) are created!!! 193 // 194 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT *** 195 196 197 // Command objects that inherit from CommandObjectCrossref must be created before other command objects 198 // are created. This is so that when another command is created that needs to go into a crossref object, 199 // the crossref object exists and is ready to take the cross reference. Put the cross referencing command 200 // objects into the CommandDictionary now, so they are ready for use when the other commands get created. 201 202 m_command_dict["select"] = CommandObjectSP (new CommandObjectSelect ()); 203 m_command_dict["info"] = CommandObjectSP (new CommandObjectInfo ()); 204 m_command_dict["delete"] = CommandObjectSP (new CommandObjectDelete ()); 205 206 // Non-CommandObjectCrossref commands can now be created. 207 208 m_command_dict["alias"] = CommandObjectSP (new CommandObjectAlias ()); 209 m_command_dict["append"] = CommandObjectSP (new CommandObjectAppend ()); 210 m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos ()); 211 m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this)); 212 m_command_dict["call"] = CommandObjectSP (new CommandObjectCall ()); 213 m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble ()); 214 m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression ()); 215 m_command_dict["file"] = CommandObjectSP (new CommandObjectFile ()); 216 m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this)); 217 m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp ()); 218 m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (*this)); 219 m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this)); 220 m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this)); 221 m_command_dict["process"] = CommandObjectSP (new CommandObjectMultiwordProcess (*this)); 222 m_command_dict["quit"] = CommandObjectSP (new CommandObjectQuit ()); 223 m_command_dict["register"] = CommandObjectSP (new CommandObjectRegister (*this)); 224 m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (m_script_language)); 225 m_command_dict["set"] = CommandObjectSP (new CommandObjectSet ()); 226 m_command_dict["settings"] = CommandObjectSP (new CommandObjectSettings ()); 227 m_command_dict["show"] = CommandObjectSP (new CommandObjectShow ()); 228 m_command_dict["source"] = CommandObjectSP (new CommandObjectSource ()); 229 m_command_dict["source-file"] = CommandObjectSP (new CommandObjectSourceFile ()); 230 m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); 231 m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); 232 m_command_dict["unalias"] = CommandObjectSP (new CommandObjectUnalias ()); 233 m_command_dict["variable"] = CommandObjectSP (new CommandObjectVariable (*this)); 234 235 std::auto_ptr<CommandObjectRegexCommand> 236 break_regex_cmd_ap(new CommandObjectRegexCommand ("regexp-break", 237 "Smart breakpoint command (using regular expressions).", 238 "regexp-break [<file>:<line>]\nregexp-break [<address>]\nregexp-break <...>", 2)); 239 if (break_regex_cmd_ap.get()) 240 { 241 if (break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2") && 242 break_regex_cmd_ap->AddRegexCommand("^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1") && 243 break_regex_cmd_ap->AddRegexCommand("^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'") && 244 break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list") && 245 break_regex_cmd_ap->AddRegexCommand("^(-.*)$", "breakpoint set %1") && 246 break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'")) 247 { 248 CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release()); 249 m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp; 250 } 251 } 252 } 253 254 int 255 CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases, 256 StringList &matches) 257 { 258 CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches); 259 260 if (include_aliases) 261 { 262 CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches); 263 } 264 265 return matches.GetSize(); 266 } 267 268 CommandObjectSP 269 CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches) 270 { 271 CommandObject::CommandMap::iterator pos; 272 CommandObjectSP ret_val; 273 274 std::string cmd(cmd_cstr); 275 276 if (HasCommands()) 277 { 278 pos = m_command_dict.find(cmd); 279 if (pos != m_command_dict.end()) 280 ret_val = pos->second; 281 } 282 283 if (include_aliases && HasAliases()) 284 { 285 pos = m_alias_dict.find(cmd); 286 if (pos != m_alias_dict.end()) 287 ret_val = pos->second; 288 } 289 290 if (HasUserCommands()) 291 { 292 pos = m_user_dict.find(cmd); 293 if (pos != m_user_dict.end()) 294 ret_val = pos->second; 295 } 296 297 if (!exact && ret_val == NULL) 298 { 299 StringList local_matches; 300 if (matches == NULL) 301 matches = &local_matches; 302 303 int num_cmd_matches = 0; 304 int num_alias_matches = 0; 305 int num_user_matches = 0; 306 if (HasCommands()) 307 { 308 num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches); 309 } 310 311 if (num_cmd_matches == 1) 312 { 313 cmd.assign(matches->GetStringAtIndex(0)); 314 pos = m_command_dict.find(cmd); 315 if (pos != m_command_dict.end()) 316 ret_val = pos->second; 317 } 318 319 if (include_aliases && HasAliases()) 320 { 321 num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches); 322 323 } 324 325 if (num_alias_matches == 1 && num_cmd_matches == 0) 326 { 327 cmd.assign(matches->GetStringAtIndex (num_cmd_matches)); 328 pos = m_alias_dict.find(cmd); 329 if (pos != m_alias_dict.end()) 330 { 331 matches->Clear(); 332 matches->AppendString (cmd.c_str()); 333 334 ret_val = pos->second; 335 } 336 } 337 338 if (HasUserCommands()) 339 { 340 num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches); 341 } 342 343 if (num_user_matches == 1 && num_alias_matches == 0 && num_cmd_matches == 0) 344 { 345 cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches)); 346 347 pos = m_user_dict.find (cmd); 348 if (pos != m_user_dict.end()) 349 { 350 matches->Clear(); 351 matches->AppendString (cmd.c_str()); 352 353 ret_val = pos->second; 354 } 355 } 356 } 357 else { 358 if (matches) 359 matches->AppendString (cmd_cstr); 360 } 361 362 363 return ret_val; 364 } 365 366 CommandObject * 367 CommandInterpreter::GetCommandObject (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches) 368 { 369 return GetCommandSP (cmd_cstr, include_aliases, exact, matches).get(); 370 } 371 372 bool 373 CommandInterpreter::CommandExists (const char *cmd) 374 { 375 return m_command_dict.find(cmd) != m_command_dict.end(); 376 } 377 378 bool 379 CommandInterpreter::AliasExists (const char *cmd) 380 { 381 return m_alias_dict.find(cmd) != m_alias_dict.end(); 382 } 383 384 bool 385 CommandInterpreter::UserCommandExists (const char *cmd) 386 { 387 return m_user_dict.find(cmd) != m_user_dict.end(); 388 } 389 390 void 391 CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp) 392 { 393 m_alias_dict[alias_name] = command_obj_sp; 394 } 395 396 bool 397 CommandInterpreter::RemoveAlias (const char *alias_name) 398 { 399 CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name); 400 if (pos != m_alias_dict.end()) 401 { 402 m_alias_dict.erase(pos); 403 return true; 404 } 405 return false; 406 } 407 bool 408 CommandInterpreter::RemoveUser (const char *alias_name) 409 { 410 CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name); 411 if (pos != m_user_dict.end()) 412 { 413 m_user_dict.erase(pos); 414 return true; 415 } 416 return false; 417 } 418 419 StateVariable * 420 CommandInterpreter::GetStateVariable(const char *name) 421 { 422 VariableMap::const_iterator pos = m_variables.find(name); 423 if (pos != m_variables.end()) 424 return pos->second.get(); 425 return NULL; 426 } 427 428 void 429 CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string) 430 { 431 help_string.Printf ("'%s", command_name); 432 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 433 434 if (option_arg_vector_sp != NULL) 435 { 436 OptionArgVector *options = option_arg_vector_sp.get(); 437 for (int i = 0; i < options->size(); ++i) 438 { 439 OptionArgPair cur_option = (*options)[i]; 440 std::string opt = cur_option.first; 441 std::string value = cur_option.second; 442 if (opt.compare("<argument>") == 0) 443 { 444 help_string.Printf (" %s", value.c_str()); 445 } 446 else 447 { 448 help_string.Printf (" %s", opt.c_str()); 449 if ((value.compare ("<no-argument>") != 0) 450 && (value.compare ("<need-argument") != 0)) 451 { 452 help_string.Printf (" %s", value.c_str()); 453 } 454 } 455 } 456 } 457 458 help_string.Printf ("'"); 459 } 460 461 std::string 462 CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict) 463 { 464 CommandObject::CommandMap::const_iterator pos; 465 int max_len = 0; 466 CommandObjectSP cmd_sp; 467 std::string longest_word; 468 469 for (pos = dict.begin(); pos != dict.end(); ++pos) 470 { 471 if ((max_len == 0) 472 || (strlen (pos->first.c_str()) > max_len)) 473 { 474 longest_word = pos->first; 475 max_len = strlen (longest_word.c_str()); 476 } 477 } 478 479 return longest_word; 480 } 481 482 void 483 CommandInterpreter::GetHelp (CommandReturnObject &result) 484 { 485 CommandObject::CommandMap::const_iterator pos; 486 result.AppendMessage("The following is a list of built-in, permanent debugger commands:"); 487 result.AppendMessage(""); 488 std::string longest_word = FindLongestCommandWord (m_command_dict); 489 uint32_t max_len = strlen (longest_word.c_str()); 490 491 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 492 { 493 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), 494 max_len); 495 } 496 result.AppendMessage(""); 497 498 if (m_alias_dict.size() > 0) 499 { 500 result.AppendMessage("The following is a list of your current command abbreviations (see 'alias' for more info):"); 501 result.AppendMessage(""); 502 longest_word = FindLongestCommandWord (m_alias_dict); 503 max_len = strlen (longest_word.c_str()); 504 for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos) 505 { 506 StreamString sstr; 507 StreamString translation_and_help; 508 std::string entry_name = pos->first; 509 std::string second_entry = pos->second.get()->GetCommandName(); 510 GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr); 511 512 translation_and_help.Printf ("(%s) %s", sstr.GetData(), pos->second->GetHelp()); 513 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", 514 translation_and_help.GetData(), max_len); 515 } 516 result.AppendMessage(""); 517 } 518 519 if (m_user_dict.size() > 0) 520 { 521 result.AppendMessage ("The following is a list of your current user-defined commands:"); 522 result.AppendMessage(""); 523 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) 524 { 525 result.AppendMessageWithFormat ("%s -- %s\n", pos->first.c_str(), pos->second->GetHelp()); 526 } 527 result.AppendMessage(""); 528 } 529 530 result.AppendMessage("For more information on any particular command, try 'help <command-name>'."); 531 } 532 533 void 534 CommandInterpreter::ShowVariableValues (CommandReturnObject &result) 535 { 536 result.AppendMessage ("Below is a list of all the debugger setting variables and their values:"); 537 538 for (VariableMap::const_iterator pos = m_variables.begin(); pos != m_variables.end(); ++pos) 539 { 540 StateVariable *var = pos->second.get(); 541 var->AppendVariableInformation (result); 542 } 543 } 544 545 void 546 CommandInterpreter::ShowVariableHelp (CommandReturnObject &result) 547 { 548 result.AppendMessage ("Below is a list of all the internal debugger variables that are settable:"); 549 for (VariableMap::const_iterator pos = m_variables.begin(); pos != m_variables.end(); ++pos) 550 { 551 StateVariable *var = pos->second.get(); 552 result.AppendMessageWithFormat (" %s -- %s \n", var->GetName(), var->GetHelp()); 553 } 554 } 555 556 // Main entry point into the command_interpreter; this function takes a text 557 // line containing a debugger command, with all its flags, options, etc, 558 // parses the line and takes the appropriate actions. 559 560 bool 561 CommandInterpreter::HandleCommand 562 ( 563 const char *command_line, 564 bool add_to_history, 565 CommandReturnObject &result, 566 ExecutionContext *override_context 567 ) 568 { 569 // FIXME: there should probably be a mutex to make sure only one thread can 570 // run the interpreter at a time. 571 572 // TODO: this should be a logging channel in lldb. 573 // if (DebugSelf()) 574 // { 575 // result.AppendMessageWithFormat ("Processing command: %s\n", command_line); 576 // } 577 578 m_debugger.UpdateExecutionContext (override_context); 579 580 if (command_line == NULL || command_line[0] == '\0') 581 { 582 if (m_command_history.empty()) 583 { 584 result.AppendError ("empty command"); 585 result.SetStatus(eReturnStatusFailed); 586 return false; 587 } 588 else 589 { 590 command_line = m_command_history.back().c_str(); 591 } 592 add_to_history = false; 593 } 594 595 Args command_args(command_line); 596 597 if (command_args.GetArgumentCount() > 0) 598 { 599 const char *command_cstr = command_args.GetArgumentAtIndex(0); 600 if (command_cstr) 601 { 602 603 // We're looking up the command object here. So first find an exact match to the 604 // command in the commands. 605 606 CommandObject *command_obj = GetCommandObject (command_cstr, false, true); 607 608 // If we didn't find an exact match to the command string in the commands, look in 609 // the aliases. 610 611 if (command_obj == NULL) 612 { 613 command_obj = GetCommandObject (command_cstr, true, true); 614 if (command_obj != NULL) 615 { 616 BuildAliasCommandArgs (command_obj, command_cstr, command_args, result); 617 if (!result.Succeeded()) 618 return false; 619 } 620 } 621 622 // Finally, if there wasn't an exact match among the aliases, look for an inexact match. 623 624 if (command_obj == NULL) 625 command_obj = GetCommandObject(command_cstr, false, false); 626 627 if (command_obj) 628 { 629 if (command_obj->WantsRawCommandString()) 630 { 631 const char *stripped_command = ::strstr (command_line, command_cstr); 632 if (stripped_command) 633 { 634 stripped_command += strlen(command_cstr); 635 while (isspace(*stripped_command)) 636 ++stripped_command; 637 command_obj->ExecuteRawCommandString (*this, stripped_command, result); 638 } 639 } 640 else 641 { 642 if (add_to_history) 643 m_command_history.push_back (command_line); 644 645 // Remove the command from the args. 646 command_args.Shift(); 647 command_obj->ExecuteWithOptions (*this, command_args, result); 648 } 649 } 650 else 651 { 652 StringList matches; 653 int num_matches; 654 int cursor_index = command_args.GetArgumentCount() - 1; 655 int cursor_char_position = strlen (command_args.GetArgumentAtIndex(command_args.GetArgumentCount() - 1)); 656 bool word_complete; 657 num_matches = HandleCompletionMatches (command_args, 658 cursor_index, 659 cursor_char_position, 660 0, 661 -1, 662 word_complete, 663 matches); 664 665 if (num_matches > 0) 666 { 667 std::string error_msg; 668 error_msg.assign ("ambiguous command '"); 669 error_msg.append(command_cstr); 670 error_msg.append ("'."); 671 672 error_msg.append (" Possible completions:"); 673 for (int i = 0; i < num_matches; i++) 674 { 675 error_msg.append ("\n\t"); 676 error_msg.append (matches.GetStringAtIndex (i)); 677 } 678 error_msg.append ("\n"); 679 result.AppendRawError (error_msg.c_str(), error_msg.size()); 680 } 681 else 682 result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_cstr); 683 684 result.SetStatus (eReturnStatusFailed); 685 } 686 } 687 } 688 return result.Succeeded(); 689 } 690 691 int 692 CommandInterpreter::HandleCompletionMatches (Args &parsed_line, 693 int &cursor_index, 694 int &cursor_char_position, 695 int match_start_point, 696 int max_return_elements, 697 bool &word_complete, 698 StringList &matches) 699 { 700 int num_command_matches = 0; 701 bool include_aliases = true; 702 bool look_for_subcommand = false; 703 704 // For any of the command completions a unique match will be a complete word. 705 word_complete = true; 706 707 if (cursor_index == -1) 708 { 709 // We got nothing on the command line, so return the list of commands 710 num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches); 711 } 712 else if (cursor_index == 0) 713 { 714 // The cursor is in the first argument, so just do a lookup in the dictionary. 715 CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), include_aliases, false, 716 &matches); 717 num_command_matches = matches.GetSize(); 718 719 if (num_command_matches == 1 720 && cmd_obj && cmd_obj->IsMultiwordObject() 721 && matches.GetStringAtIndex(0) != NULL 722 && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0) 723 { 724 look_for_subcommand = true; 725 num_command_matches = 0; 726 matches.DeleteStringAtIndex(0); 727 parsed_line.AppendArgument (""); 728 cursor_index++; 729 cursor_char_position = 0; 730 } 731 } 732 733 if (cursor_index > 0 || look_for_subcommand) 734 { 735 // We are completing further on into a commands arguments, so find the command and tell it 736 // to complete the command. 737 // First see if there is a matching initial command: 738 CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0), include_aliases, false); 739 if (command_object == NULL) 740 { 741 return 0; 742 } 743 else 744 { 745 parsed_line.Shift(); 746 cursor_index--; 747 num_command_matches = command_object->HandleCompletion (*this, 748 parsed_line, 749 cursor_index, 750 cursor_char_position, 751 match_start_point, 752 max_return_elements, 753 word_complete, 754 matches); 755 } 756 } 757 758 return num_command_matches; 759 760 } 761 762 int 763 CommandInterpreter::HandleCompletion (const char *current_line, 764 const char *cursor, 765 const char *last_char, 766 int match_start_point, 767 int max_return_elements, 768 StringList &matches) 769 { 770 // We parse the argument up to the cursor, so the last argument in parsed_line is 771 // the one containing the cursor, and the cursor is after the last character. 772 773 Args parsed_line(current_line, last_char - current_line); 774 Args partial_parsed_line(current_line, cursor - current_line); 775 776 int num_args = partial_parsed_line.GetArgumentCount(); 777 int cursor_index = partial_parsed_line.GetArgumentCount() - 1; 778 int cursor_char_position; 779 780 if (cursor_index == -1) 781 cursor_char_position = 0; 782 else 783 cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index)); 784 785 int num_command_matches; 786 787 matches.Clear(); 788 789 // Only max_return_elements == -1 is supported at present: 790 assert (max_return_elements == -1); 791 bool word_complete; 792 num_command_matches = HandleCompletionMatches (parsed_line, 793 cursor_index, 794 cursor_char_position, 795 match_start_point, 796 max_return_elements, 797 word_complete, 798 matches); 799 800 if (num_command_matches <= 0) 801 return num_command_matches; 802 803 if (num_args == 0) 804 { 805 // If we got an empty string, insert nothing. 806 matches.InsertStringAtIndex(0, ""); 807 } 808 else 809 { 810 // Now figure out if there is a common substring, and if so put that in element 0, otherwise 811 // put an empty string in element 0. 812 std::string command_partial_str; 813 if (cursor_index >= 0) 814 command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index), parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position); 815 816 std::string common_prefix; 817 matches.LongestCommonPrefix (common_prefix); 818 int partial_name_len = command_partial_str.size(); 819 820 // If we matched a unique single command, add a space... 821 // Only do this if the completer told us this was a complete word, however... 822 if (num_command_matches == 1 && word_complete) 823 { 824 char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index); 825 if (quote_char != '\0') 826 common_prefix.push_back(quote_char); 827 828 common_prefix.push_back(' '); 829 } 830 common_prefix.erase (0, partial_name_len); 831 matches.InsertStringAtIndex(0, common_prefix.c_str()); 832 } 833 return num_command_matches; 834 } 835 836 const Args * 837 CommandInterpreter::GetProgramArguments () 838 { 839 if (! HasInterpreterVariables()) 840 return NULL; 841 842 VariableMap::const_iterator pos = m_variables.find("run-args"); 843 if (pos == m_variables.end()) 844 return NULL; 845 846 StateVariable *var = pos->second.get(); 847 848 if (var) 849 return &var->GetArgs(); 850 return NULL; 851 } 852 853 const Args * 854 CommandInterpreter::GetEnvironmentVariables () 855 { 856 if (! HasInterpreterVariables()) 857 return NULL; 858 859 VariableMap::const_iterator pos = m_variables.find("env-vars"); 860 if (pos == m_variables.end()) 861 return NULL; 862 863 StateVariable *var = pos->second.get(); 864 if (var) 865 return &var->GetArgs(); 866 return NULL; 867 } 868 869 870 CommandInterpreter::~CommandInterpreter () 871 { 872 } 873 874 const char * 875 CommandInterpreter::GetPrompt () 876 { 877 VariableMap::iterator pos; 878 879 if (! HasInterpreterVariables()) 880 return NULL; 881 882 pos = m_variables.find("prompt"); 883 if (pos == m_variables.end()) 884 return NULL; 885 886 StateVariable *var = pos->second.get(); 887 888 return ((char *) var->GetStringValue()); 889 } 890 891 void 892 CommandInterpreter::SetPrompt (const char *new_prompt) 893 { 894 VariableMap::iterator pos; 895 CommandReturnObject result; 896 897 if (! HasInterpreterVariables()) 898 return; 899 900 pos = m_variables.find ("prompt"); 901 if (pos == m_variables.end()) 902 return; 903 904 StateVariable *var = pos->second.get(); 905 906 if (var->VerifyValue (this, (void *) new_prompt, result)) 907 var->SetStringValue (new_prompt); 908 } 909 910 void 911 CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type) 912 { 913 CommandObjectSP cmd_obj_sp = GetCommandSP (dest_cmd); 914 915 if (cmd_obj_sp != NULL) 916 { 917 CommandObject *cmd_obj = cmd_obj_sp.get(); 918 if (cmd_obj->IsCrossRefObject ()) 919 cmd_obj->AddObject (object_type); 920 } 921 } 922 923 void 924 CommandInterpreter::SetScriptLanguage (ScriptLanguage lang) 925 { 926 m_script_language = lang; 927 } 928 929 OptionArgVectorSP 930 CommandInterpreter::GetAliasOptions (const char *alias_name) 931 { 932 OptionArgMap::iterator pos; 933 OptionArgVectorSP ret_val; 934 935 std::string alias (alias_name); 936 937 if (HasAliasOptions()) 938 { 939 pos = m_alias_options.find (alias); 940 if (pos != m_alias_options.end()) 941 ret_val = pos->second; 942 } 943 944 return ret_val; 945 } 946 947 void 948 CommandInterpreter::RemoveAliasOptions (const char *alias_name) 949 { 950 OptionArgMap::iterator pos = m_alias_options.find(alias_name); 951 if (pos != m_alias_options.end()) 952 { 953 m_alias_options.erase (pos); 954 } 955 } 956 957 void 958 CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp) 959 { 960 m_alias_options[alias_name] = option_arg_vector_sp; 961 } 962 963 bool 964 CommandInterpreter::HasCommands () 965 { 966 return (!m_command_dict.empty()); 967 } 968 969 bool 970 CommandInterpreter::HasAliases () 971 { 972 return (!m_alias_dict.empty()); 973 } 974 975 bool 976 CommandInterpreter::HasUserCommands () 977 { 978 return (!m_user_dict.empty()); 979 } 980 981 bool 982 CommandInterpreter::HasAliasOptions () 983 { 984 return (!m_alias_options.empty()); 985 } 986 987 bool 988 CommandInterpreter::HasInterpreterVariables () 989 { 990 return (!m_variables.empty()); 991 } 992 993 void 994 CommandInterpreter::BuildAliasCommandArgs 995 ( 996 CommandObject *alias_cmd_obj, 997 const char *alias_name, 998 Args &cmd_args, 999 CommandReturnObject &result 1000 ) 1001 { 1002 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 1003 1004 if (option_arg_vector_sp.get()) 1005 { 1006 // Make sure that the alias name is the 0th element in cmd_args 1007 std::string alias_name_str = alias_name; 1008 if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0) 1009 cmd_args.Unshift (alias_name); 1010 1011 Args new_args (alias_cmd_obj->GetCommandName()); 1012 if (new_args.GetArgumentCount() == 2) 1013 new_args.Shift(); 1014 1015 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 1016 int old_size = cmd_args.GetArgumentCount(); 1017 int *used = (int *) malloc ((old_size + 1) * sizeof (int)); 1018 1019 memset (used, 0, (old_size + 1) * sizeof (int)); 1020 used[0] = 1; 1021 1022 for (int i = 0; i < option_arg_vector->size(); ++i) 1023 { 1024 OptionArgPair option_pair = (*option_arg_vector)[i]; 1025 std::string option = option_pair.first; 1026 std::string value = option_pair.second; 1027 if (option.compare ("<argument>") == 0) 1028 new_args.AppendArgument (value.c_str()); 1029 else 1030 { 1031 new_args.AppendArgument (option.c_str()); 1032 if (value.compare ("<no-argument>") != 0) 1033 { 1034 int index = GetOptionArgumentPosition (value.c_str()); 1035 if (index == 0) 1036 // value was NOT a positional argument; must be a real value 1037 new_args.AppendArgument (value.c_str()); 1038 else if (index >= cmd_args.GetArgumentCount()) 1039 { 1040 result.AppendErrorWithFormat 1041 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 1042 index); 1043 result.SetStatus (eReturnStatusFailed); 1044 return; 1045 } 1046 else 1047 { 1048 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index)); 1049 used[index] = 1; 1050 } 1051 } 1052 } 1053 } 1054 1055 for (int j = 0; j < cmd_args.GetArgumentCount(); ++j) 1056 { 1057 if (!used[j]) 1058 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j)); 1059 } 1060 1061 cmd_args.Clear(); 1062 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 1063 } 1064 else 1065 { 1066 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1067 // This alias was not created with any options; nothing further needs to be done. 1068 return; 1069 } 1070 1071 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1072 return; 1073 } 1074 1075 1076 int 1077 CommandInterpreter::GetOptionArgumentPosition (const char *in_string) 1078 { 1079 int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position 1080 // of zero. 1081 1082 char *cptr = (char *) in_string; 1083 1084 // Does it start with '%' 1085 if (cptr[0] == '%') 1086 { 1087 ++cptr; 1088 1089 // Is the rest of it entirely digits? 1090 if (isdigit (cptr[0])) 1091 { 1092 const char *start = cptr; 1093 while (isdigit (cptr[0])) 1094 ++cptr; 1095 1096 // We've gotten to the end of the digits; are we at the end of the string? 1097 if (cptr[0] == '\0') 1098 position = atoi (start); 1099 } 1100 } 1101 1102 return position; 1103 } 1104 1105 void 1106 CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result) 1107 { 1108 const char *init_file_path = in_cwd ? "./.lldbinit" : "~/.lldbinit"; 1109 FileSpec init_file (init_file_path); 1110 // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting 1111 // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details). 1112 1113 if (init_file.Exists()) 1114 { 1115 char path[PATH_MAX]; 1116 init_file.GetPath(path, sizeof(path)); 1117 StreamString source_command; 1118 source_command.Printf ("source '%s'", path); 1119 HandleCommand (source_command.GetData(), false, result); 1120 } 1121 else 1122 { 1123 // nothing to be done if the file doesn't exist 1124 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1125 } 1126 } 1127 1128 ScriptInterpreter * 1129 CommandInterpreter::GetScriptInterpreter () 1130 { 1131 CommandObject::CommandMap::iterator pos; 1132 1133 pos = m_command_dict.find ("script"); 1134 if (pos != m_command_dict.end()) 1135 { 1136 CommandObject *script_cmd_obj = pos->second.get(); 1137 return ((CommandObjectScript *) script_cmd_obj)->GetInterpreter (*this); 1138 } 1139 return NULL; 1140 } 1141 1142 1143 1144 bool 1145 CommandInterpreter::GetSynchronous () 1146 { 1147 return m_synchronous_execution; 1148 } 1149 1150 void 1151 CommandInterpreter::SetSynchronous (bool value) 1152 { 1153 static bool value_set_once = false; 1154 if (!value_set_once) 1155 { 1156 value_set_once = true; 1157 m_synchronous_execution = value; 1158 } 1159 } 1160 1161 void 1162 CommandInterpreter::OutputFormattedHelpText (Stream &strm, 1163 const char *word_text, 1164 const char *separator, 1165 const char *help_text, 1166 uint32_t max_word_len) 1167 { 1168 StateVariable *var = GetStateVariable ("term-width"); 1169 int max_columns = var->GetIntValue(); 1170 // Sanity check max_columns, to cope with emacs shell mode with TERM=dumb 1171 // (0 rows; 0 columns;). 1172 if (max_columns <= 0) max_columns = 80; 1173 1174 int indent_size = max_word_len + strlen (separator) + 2; 1175 1176 strm.IndentMore (indent_size); 1177 1178 int len = indent_size + strlen (help_text) + 1; 1179 char *text = (char *) malloc (len); 1180 sprintf (text, "%-*s %s %s", max_word_len, word_text, separator, help_text); 1181 if (text[len - 1] == '\n') 1182 text[--len] = '\0'; 1183 1184 if (len < max_columns) 1185 { 1186 // Output it as a single line. 1187 strm.Printf ("%s", text); 1188 } 1189 else 1190 { 1191 // We need to break it up into multiple lines. 1192 bool first_line = true; 1193 int text_width; 1194 int start = 0; 1195 int end = start; 1196 int final_end = strlen (text); 1197 int sub_len; 1198 1199 while (end < final_end) 1200 { 1201 if (first_line) 1202 text_width = max_columns - 1; 1203 else 1204 text_width = max_columns - indent_size - 1; 1205 1206 // Don't start the 'text' on a space, since we're already outputting the indentation. 1207 if (!first_line) 1208 { 1209 while ((start < final_end) && (text[start] == ' ')) 1210 start++; 1211 } 1212 1213 end = start + text_width; 1214 if (end > final_end) 1215 end = final_end; 1216 else 1217 { 1218 // If we're not at the end of the text, make sure we break the line on white space. 1219 while (end > start 1220 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') 1221 end--; 1222 } 1223 1224 sub_len = end - start; 1225 if (start != 0) 1226 strm.EOL(); 1227 if (!first_line) 1228 strm.Indent(); 1229 else 1230 first_line = false; 1231 assert (start <= final_end); 1232 assert (start + sub_len <= final_end); 1233 if (sub_len > 0) 1234 strm.Write (text + start, sub_len); 1235 start = end + 1; 1236 } 1237 } 1238 strm.EOL(); 1239 strm.IndentLess(indent_size); 1240 free (text); 1241 } 1242 1243 void 1244 CommandInterpreter::AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word, 1245 StringList &commands_found, StringList &commands_help) 1246 { 1247 CommandObject::CommandMap::const_iterator pos; 1248 CommandObject::CommandMap sub_cmd_dict = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict; 1249 CommandObject *sub_cmd_obj; 1250 1251 for (pos = sub_cmd_dict.begin(); pos != sub_cmd_dict.end(); ++pos) 1252 { 1253 const char * command_name = pos->first.c_str(); 1254 sub_cmd_obj = pos->second.get(); 1255 StreamString complete_command_name; 1256 1257 complete_command_name.Printf ("%s %s", prefix, command_name); 1258 1259 if (sub_cmd_obj->HelpTextContainsWord (search_word)) 1260 { 1261 commands_found.AppendString (complete_command_name.GetData()); 1262 commands_help.AppendString (sub_cmd_obj->GetHelp()); 1263 } 1264 1265 if (sub_cmd_obj->IsMultiwordObject()) 1266 AproposAllSubCommands (sub_cmd_obj, complete_command_name.GetData(), search_word, commands_found, 1267 commands_help); 1268 } 1269 1270 } 1271 1272 void 1273 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found, 1274 StringList &commands_help) 1275 { 1276 CommandObject::CommandMap::const_iterator pos; 1277 1278 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 1279 { 1280 const char *command_name = pos->first.c_str(); 1281 CommandObject *cmd_obj = pos->second.get(); 1282 1283 if (cmd_obj->HelpTextContainsWord (search_word)) 1284 { 1285 commands_found.AppendString (command_name); 1286 commands_help.AppendString (cmd_obj->GetHelp()); 1287 } 1288 1289 if (cmd_obj->IsMultiwordObject()) 1290 AproposAllSubCommands (cmd_obj, command_name, search_word, commands_found, commands_help); 1291 1292 } 1293 } 1294