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