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