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/CommandObjectPlatform.h" 29 #include "../Commands/CommandObjectProcess.h" 30 #include "../Commands/CommandObjectQuit.h" 31 #include "lldb/Interpreter/CommandObjectRegexCommand.h" 32 #include "../Commands/CommandObjectRegister.h" 33 #include "CommandObjectScript.h" 34 #include "../Commands/CommandObjectSettings.h" 35 #include "../Commands/CommandObjectSource.h" 36 #include "../Commands/CommandObjectCommands.h" 37 #include "../Commands/CommandObjectSyntax.h" 38 #include "../Commands/CommandObjectTarget.h" 39 #include "../Commands/CommandObjectThread.h" 40 #include "../Commands/CommandObjectVersion.h" 41 42 #include "lldb/Interpreter/Args.h" 43 #include "lldb/Core/Debugger.h" 44 #include "lldb/Core/InputReader.h" 45 #include "lldb/Core/Stream.h" 46 #include "lldb/Core/Timer.h" 47 #include "lldb/Host/Host.h" 48 #include "lldb/Target/Process.h" 49 #include "lldb/Target/Thread.h" 50 #include "lldb/Target/TargetList.h" 51 #include "lldb/Utility/CleanUp.h" 52 53 #include "lldb/Interpreter/CommandReturnObject.h" 54 #include "lldb/Interpreter/CommandInterpreter.h" 55 #include "lldb/Interpreter/ScriptInterpreterNone.h" 56 #include "lldb/Interpreter/ScriptInterpreterPython.h" 57 58 using namespace lldb; 59 using namespace lldb_private; 60 61 CommandInterpreter::CommandInterpreter 62 ( 63 Debugger &debugger, 64 ScriptLanguage script_language, 65 bool synchronous_execution 66 ) : 67 Broadcaster ("lldb.command-interpreter"), 68 m_debugger (debugger), 69 m_synchronous_execution (synchronous_execution), 70 m_skip_lldbinit_files (false), 71 m_script_interpreter_ap (), 72 m_comment_char ('#') 73 { 74 const char *dbg_name = debugger.GetInstanceName().AsCString(); 75 std::string lang_name = ScriptInterpreter::LanguageToString (script_language); 76 StreamString var_name; 77 var_name.Printf ("[%s].script-lang", dbg_name); 78 debugger.GetSettingsController()->SetVariable (var_name.GetData(), lang_name.c_str(), 79 eVarSetOperationAssign, false, 80 m_debugger.GetInstanceName().AsCString()); 81 SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit"); 82 SetEventName (eBroadcastBitResetPrompt, "reset-prompt"); 83 SetEventName (eBroadcastBitQuitCommandReceived, "quit"); 84 } 85 86 void 87 CommandInterpreter::Initialize () 88 { 89 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 90 91 CommandReturnObject result; 92 93 LoadCommandDictionary (); 94 95 // Set up some initial aliases. 96 HandleCommand ("command alias q quit", false, result); 97 HandleCommand ("command alias run process launch --", false, result); 98 HandleCommand ("command alias r process launch --", false, result); 99 HandleCommand ("command alias c process continue", false, result); 100 HandleCommand ("command alias continue process continue", false, result); 101 HandleCommand ("command alias expr expression", false, result); 102 HandleCommand ("command alias exit quit", false, result); 103 HandleCommand ("command alias b _regexp-break", false, result); 104 HandleCommand ("command alias bt thread backtrace", false, result); 105 HandleCommand ("command alias si thread step-inst", false, result); 106 HandleCommand ("command alias step thread step-in", false, result); 107 HandleCommand ("command alias s thread step-in", false, result); 108 HandleCommand ("command alias next thread step-over", false, result); 109 HandleCommand ("command alias n thread step-over", false, result); 110 HandleCommand ("command alias f thread step-out", false, result); 111 HandleCommand ("command alias finish thread step-out", false, result); 112 HandleCommand ("command alias x memory read", false, result); 113 HandleCommand ("command alias l source list", false, result); 114 HandleCommand ("command alias list source list", false, result); 115 HandleCommand ("command alias p expression --", false, result); 116 HandleCommand ("command alias print expression --", false, result); 117 HandleCommand ("command alias po expression -o --", false, result); 118 HandleCommand ("command alias up _regexp-up", false, result); 119 HandleCommand ("command alias down _regexp-down", false, result); 120 121 } 122 123 const char * 124 CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg) 125 { 126 // This function has not yet been implemented. 127 128 // Look for any embedded script command 129 // If found, 130 // get interpreter object from the command dictionary, 131 // call execute_one_command on it, 132 // get the results as a string, 133 // substitute that string for current stuff. 134 135 return arg; 136 } 137 138 139 void 140 CommandInterpreter::LoadCommandDictionary () 141 { 142 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); 143 144 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT *** 145 // 146 // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref) 147 // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use 148 // the cross-referencing stuff) are created!!! 149 // 150 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT *** 151 152 153 // Command objects that inherit from CommandObjectCrossref must be created before other command objects 154 // are created. This is so that when another command is created that needs to go into a crossref object, 155 // the crossref object exists and is ready to take the cross reference. Put the cross referencing command 156 // objects into the CommandDictionary now, so they are ready for use when the other commands get created. 157 158 // Non-CommandObjectCrossref commands can now be created. 159 160 lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage(); 161 162 m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this)); 163 m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this)); 164 //m_command_dict["call"] = CommandObjectSP (new CommandObjectCall (*this)); 165 m_command_dict["commands"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this)); 166 m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this)); 167 m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this)); 168 m_command_dict["file"] = CommandObjectSP (new CommandObjectFile (*this)); 169 m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this)); 170 m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this)); 171 m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (*this)); 172 m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this)); 173 m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this)); 174 m_command_dict["platform"] = CommandObjectSP (new CommandObjectPlatform (*this)); 175 m_command_dict["process"] = CommandObjectSP (new CommandObjectMultiwordProcess (*this)); 176 m_command_dict["quit"] = CommandObjectSP (new CommandObjectQuit (*this)); 177 m_command_dict["register"] = CommandObjectSP (new CommandObjectRegister (*this)); 178 m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (*this, script_language)); 179 m_command_dict["settings"] = CommandObjectSP (new CommandObjectMultiwordSettings (*this)); 180 m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this)); 181 m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); 182 m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); 183 m_command_dict["version"] = CommandObjectSP (new CommandObjectVersion (*this)); 184 185 std::auto_ptr<CommandObjectRegexCommand> 186 break_regex_cmd_ap(new CommandObjectRegexCommand (*this, 187 "_regexp-break", 188 "Set a breakpoint using a regular expression to specify the location.", 189 "_regexp-break [<filename>:<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2)); 190 if (break_regex_cmd_ap.get()) 191 { 192 if (break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2") && 193 break_regex_cmd_ap->AddRegexCommand("^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1") && 194 break_regex_cmd_ap->AddRegexCommand("^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'") && 195 break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full") && 196 break_regex_cmd_ap->AddRegexCommand("^(-.*)$", "breakpoint set %1") && 197 break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'") && 198 break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'")) 199 { 200 CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release()); 201 m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp; 202 } 203 } 204 205 std::auto_ptr<CommandObjectRegexCommand> 206 down_regex_cmd_ap(new CommandObjectRegexCommand (*this, 207 "_regexp-down", 208 "Go down \"n\" frames in the stack (1 frame by default).", 209 "_regexp-down [n]", 2)); 210 if (down_regex_cmd_ap.get()) 211 { 212 if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") && 213 down_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r -%1")) 214 { 215 CommandObjectSP down_regex_cmd_sp(down_regex_cmd_ap.release()); 216 m_command_dict[down_regex_cmd_sp->GetCommandName ()] = down_regex_cmd_sp; 217 } 218 } 219 220 std::auto_ptr<CommandObjectRegexCommand> 221 up_regex_cmd_ap(new CommandObjectRegexCommand (*this, 222 "_regexp-up", 223 "Go up \"n\" frames in the stack (1 frame by default).", 224 "_regexp-up [n]", 2)); 225 if (up_regex_cmd_ap.get()) 226 { 227 if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") && 228 up_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r %1")) 229 { 230 CommandObjectSP up_regex_cmd_sp(up_regex_cmd_ap.release()); 231 m_command_dict[up_regex_cmd_sp->GetCommandName ()] = up_regex_cmd_sp; 232 } 233 } 234 } 235 236 int 237 CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases, 238 StringList &matches) 239 { 240 CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches); 241 242 if (include_aliases) 243 { 244 CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches); 245 } 246 247 return matches.GetSize(); 248 } 249 250 CommandObjectSP 251 CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches) 252 { 253 CommandObject::CommandMap::iterator pos; 254 CommandObjectSP ret_val; 255 256 std::string cmd(cmd_cstr); 257 258 if (HasCommands()) 259 { 260 pos = m_command_dict.find(cmd); 261 if (pos != m_command_dict.end()) 262 ret_val = pos->second; 263 } 264 265 if (include_aliases && HasAliases()) 266 { 267 pos = m_alias_dict.find(cmd); 268 if (pos != m_alias_dict.end()) 269 ret_val = pos->second; 270 } 271 272 if (HasUserCommands()) 273 { 274 pos = m_user_dict.find(cmd); 275 if (pos != m_user_dict.end()) 276 ret_val = pos->second; 277 } 278 279 if (!exact && ret_val == NULL) 280 { 281 // We will only get into here if we didn't find any exact matches. 282 283 CommandObjectSP user_match_sp, alias_match_sp, real_match_sp; 284 285 StringList local_matches; 286 if (matches == NULL) 287 matches = &local_matches; 288 289 unsigned int num_cmd_matches = 0; 290 unsigned int num_alias_matches = 0; 291 unsigned int num_user_matches = 0; 292 293 // Look through the command dictionaries one by one, and if we get only one match from any of 294 // them in toto, then return that, otherwise return an empty CommandObjectSP and the list of matches. 295 296 if (HasCommands()) 297 { 298 num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches); 299 } 300 301 if (num_cmd_matches == 1) 302 { 303 cmd.assign(matches->GetStringAtIndex(0)); 304 pos = m_command_dict.find(cmd); 305 if (pos != m_command_dict.end()) 306 real_match_sp = pos->second; 307 } 308 309 if (include_aliases && HasAliases()) 310 { 311 num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches); 312 313 } 314 315 if (num_alias_matches == 1) 316 { 317 cmd.assign(matches->GetStringAtIndex (num_cmd_matches)); 318 pos = m_alias_dict.find(cmd); 319 if (pos != m_alias_dict.end()) 320 alias_match_sp = pos->second; 321 } 322 323 if (HasUserCommands()) 324 { 325 num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches); 326 } 327 328 if (num_user_matches == 1) 329 { 330 cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches)); 331 332 pos = m_user_dict.find (cmd); 333 if (pos != m_user_dict.end()) 334 user_match_sp = pos->second; 335 } 336 337 // If we got exactly one match, return that, otherwise return the match list. 338 339 if (num_user_matches + num_cmd_matches + num_alias_matches == 1) 340 { 341 if (num_cmd_matches) 342 return real_match_sp; 343 else if (num_alias_matches) 344 return alias_match_sp; 345 else 346 return user_match_sp; 347 } 348 } 349 else if (matches && ret_val != NULL) 350 { 351 matches->AppendString (cmd_cstr); 352 } 353 354 355 return ret_val; 356 } 357 358 CommandObjectSP 359 CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases) 360 { 361 Args cmd_words (cmd_cstr); // Break up the command string into words, in case it's a multi-word command. 362 CommandObjectSP ret_val; // Possibly empty return value. 363 364 if (cmd_cstr == NULL) 365 return ret_val; 366 367 if (cmd_words.GetArgumentCount() == 1) 368 return GetCommandSP(cmd_cstr, include_aliases, true, NULL); 369 else 370 { 371 // We have a multi-word command (seemingly), so we need to do more work. 372 // First, get the cmd_obj_sp for the first word in the command. 373 CommandObjectSP cmd_obj_sp = GetCommandSP (cmd_words.GetArgumentAtIndex (0), include_aliases, true, NULL); 374 if (cmd_obj_sp.get() != NULL) 375 { 376 // Loop through the rest of the words in the command (everything passed in was supposed to be part of a 377 // command name), and find the appropriate sub-command SP for each command word.... 378 size_t end = cmd_words.GetArgumentCount(); 379 for (size_t j= 1; j < end; ++j) 380 { 381 if (cmd_obj_sp->IsMultiwordObject()) 382 { 383 cmd_obj_sp = ((CommandObjectMultiword *) cmd_obj_sp.get())->GetSubcommandSP 384 (cmd_words.GetArgumentAtIndex (j)); 385 if (cmd_obj_sp.get() == NULL) 386 // The sub-command name was invalid. Fail and return the empty 'ret_val'. 387 return ret_val; 388 } 389 else 390 // We have more words in the command name, but we don't have a multiword object. Fail and return 391 // empty 'ret_val'. 392 return ret_val; 393 } 394 // We successfully looped through all the command words and got valid command objects for them. Assign the 395 // last object retrieved to 'ret_val'. 396 ret_val = cmd_obj_sp; 397 } 398 } 399 return ret_val; 400 } 401 402 CommandObject * 403 CommandInterpreter::GetCommandObjectExact (const char *cmd_cstr, bool include_aliases) 404 { 405 return GetCommandSPExact (cmd_cstr, include_aliases).get(); 406 } 407 408 CommandObject * 409 CommandInterpreter::GetCommandObject (const char *cmd_cstr, StringList *matches) 410 { 411 CommandObject *command_obj = GetCommandSP (cmd_cstr, false, true, matches).get(); 412 413 // If we didn't find an exact match to the command string in the commands, look in 414 // the aliases. 415 416 if (command_obj == NULL) 417 { 418 command_obj = GetCommandSP (cmd_cstr, true, true, matches).get(); 419 } 420 421 // Finally, if there wasn't an exact match among the aliases, look for an inexact match 422 // in both the commands and the aliases. 423 424 if (command_obj == NULL) 425 command_obj = GetCommandSP(cmd_cstr, true, false, matches).get(); 426 427 return command_obj; 428 } 429 430 bool 431 CommandInterpreter::CommandExists (const char *cmd) 432 { 433 return m_command_dict.find(cmd) != m_command_dict.end(); 434 } 435 436 bool 437 CommandInterpreter::AliasExists (const char *cmd) 438 { 439 return m_alias_dict.find(cmd) != m_alias_dict.end(); 440 } 441 442 bool 443 CommandInterpreter::UserCommandExists (const char *cmd) 444 { 445 return m_user_dict.find(cmd) != m_user_dict.end(); 446 } 447 448 void 449 CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp) 450 { 451 command_obj_sp->SetIsAlias (true); 452 m_alias_dict[alias_name] = command_obj_sp; 453 } 454 455 bool 456 CommandInterpreter::RemoveAlias (const char *alias_name) 457 { 458 CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name); 459 if (pos != m_alias_dict.end()) 460 { 461 m_alias_dict.erase(pos); 462 return true; 463 } 464 return false; 465 } 466 bool 467 CommandInterpreter::RemoveUser (const char *alias_name) 468 { 469 CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name); 470 if (pos != m_user_dict.end()) 471 { 472 m_user_dict.erase(pos); 473 return true; 474 } 475 return false; 476 } 477 478 void 479 CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string) 480 { 481 help_string.Printf ("'%s", command_name); 482 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 483 484 if (option_arg_vector_sp != NULL) 485 { 486 OptionArgVector *options = option_arg_vector_sp.get(); 487 for (int i = 0; i < options->size(); ++i) 488 { 489 OptionArgPair cur_option = (*options)[i]; 490 std::string opt = cur_option.first; 491 OptionArgValue value_pair = cur_option.second; 492 std::string value = value_pair.second; 493 if (opt.compare("<argument>") == 0) 494 { 495 help_string.Printf (" %s", value.c_str()); 496 } 497 else 498 { 499 help_string.Printf (" %s", opt.c_str()); 500 if ((value.compare ("<no-argument>") != 0) 501 && (value.compare ("<need-argument") != 0)) 502 { 503 help_string.Printf (" %s", value.c_str()); 504 } 505 } 506 } 507 } 508 509 help_string.Printf ("'"); 510 } 511 512 size_t 513 CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict) 514 { 515 CommandObject::CommandMap::const_iterator pos; 516 CommandObject::CommandMap::const_iterator end = dict.end(); 517 size_t max_len = 0; 518 519 for (pos = dict.begin(); pos != end; ++pos) 520 { 521 size_t len = pos->first.size(); 522 if (max_len < len) 523 max_len = len; 524 } 525 return max_len; 526 } 527 528 void 529 CommandInterpreter::GetHelp (CommandReturnObject &result) 530 { 531 CommandObject::CommandMap::const_iterator pos; 532 result.AppendMessage("The following is a list of built-in, permanent debugger commands:"); 533 result.AppendMessage(""); 534 uint32_t max_len = FindLongestCommandWord (m_command_dict); 535 536 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 537 { 538 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), 539 max_len); 540 } 541 result.AppendMessage(""); 542 543 if (m_alias_dict.size() > 0) 544 { 545 result.AppendMessage("The following is a list of your current command abbreviations " 546 "(see 'help commands alias' for more info):"); 547 result.AppendMessage(""); 548 max_len = FindLongestCommandWord (m_alias_dict); 549 550 for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos) 551 { 552 StreamString sstr; 553 StreamString translation_and_help; 554 std::string entry_name = pos->first; 555 std::string second_entry = pos->second.get()->GetCommandName(); 556 GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr); 557 558 translation_and_help.Printf ("(%s) %s", sstr.GetData(), pos->second->GetHelp()); 559 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", 560 translation_and_help.GetData(), max_len); 561 } 562 result.AppendMessage(""); 563 } 564 565 if (m_user_dict.size() > 0) 566 { 567 result.AppendMessage ("The following is a list of your current user-defined commands:"); 568 result.AppendMessage(""); 569 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) 570 { 571 result.AppendMessageWithFormat ("%s -- %s\n", pos->first.c_str(), pos->second->GetHelp()); 572 } 573 result.AppendMessage(""); 574 } 575 576 result.AppendMessage("For more information on any particular command, try 'help <command-name>'."); 577 } 578 579 CommandObject * 580 CommandInterpreter::GetCommandObjectForCommand (std::string &command_string) 581 { 582 // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will 583 // eventually be invoked by the given command line. 584 585 CommandObject *cmd_obj = NULL; 586 std::string white_space (" \t\v"); 587 size_t start = command_string.find_first_not_of (white_space); 588 size_t end = 0; 589 bool done = false; 590 while (!done) 591 { 592 if (start != std::string::npos) 593 { 594 // Get the next word from command_string. 595 end = command_string.find_first_of (white_space, start); 596 if (end == std::string::npos) 597 end = command_string.size(); 598 std::string cmd_word = command_string.substr (start, end - start); 599 600 if (cmd_obj == NULL) 601 // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid 602 // command or alias. 603 cmd_obj = GetCommandObject (cmd_word.c_str()); 604 else if (cmd_obj->IsMultiwordObject ()) 605 { 606 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object. 607 CommandObject *sub_cmd_obj = 608 ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (cmd_word.c_str()); 609 if (sub_cmd_obj) 610 cmd_obj = sub_cmd_obj; 611 else // cmd_word was not a valid sub-command word, so we are donee 612 done = true; 613 } 614 else 615 // We have a cmd_obj and it is not a multi-word object, so we are done. 616 done = true; 617 618 // If we didn't find a valid command object, or our command object is not a multi-word object, or 619 // we are at the end of the command_string, then we are done. Otherwise, find the start of the 620 // next word. 621 622 if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size()) 623 done = true; 624 else 625 start = command_string.find_first_not_of (white_space, end); 626 } 627 else 628 // Unable to find any more words. 629 done = true; 630 } 631 632 if (end == command_string.size()) 633 command_string.clear(); 634 else 635 command_string = command_string.substr(end); 636 637 return cmd_obj; 638 } 639 640 bool 641 CommandInterpreter::StripFirstWord (std::string &command_string, std::string &word) 642 { 643 std::string white_space (" \t\v"); 644 size_t start; 645 size_t end; 646 647 start = command_string.find_first_not_of (white_space); 648 if (start != std::string::npos) 649 { 650 end = command_string.find_first_of (white_space, start); 651 if (end != std::string::npos) 652 { 653 word = command_string.substr (start, end - start); 654 command_string = command_string.substr (end); 655 size_t pos = command_string.find_first_not_of (white_space); 656 if ((pos != 0) && (pos != std::string::npos)) 657 command_string = command_string.substr (pos); 658 } 659 else 660 { 661 word = command_string.substr (start); 662 command_string.erase(); 663 } 664 665 } 666 return true; 667 } 668 669 void 670 CommandInterpreter::BuildAliasResult (const char *alias_name, std::string &raw_input_string, std::string &alias_result, 671 CommandObject *&alias_cmd_obj, CommandReturnObject &result) 672 { 673 Args cmd_args (raw_input_string.c_str()); 674 alias_cmd_obj = GetCommandObject (alias_name); 675 StreamString result_str; 676 677 if (alias_cmd_obj) 678 { 679 std::string alias_name_str = alias_name; 680 if ((cmd_args.GetArgumentCount() == 0) 681 || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)) 682 cmd_args.Unshift (alias_name); 683 684 result_str.Printf ("%s", alias_cmd_obj->GetCommandName ()); 685 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 686 687 if (option_arg_vector_sp.get()) 688 { 689 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 690 691 for (int i = 0; i < option_arg_vector->size(); ++i) 692 { 693 OptionArgPair option_pair = (*option_arg_vector)[i]; 694 OptionArgValue value_pair = option_pair.second; 695 int value_type = value_pair.first; 696 std::string option = option_pair.first; 697 std::string value = value_pair.second; 698 if (option.compare ("<argument>") == 0) 699 result_str.Printf (" %s", value.c_str()); 700 else 701 { 702 result_str.Printf (" %s", option.c_str()); 703 if (value_type != optional_argument) 704 result_str.Printf (" "); 705 if (value.compare ("<no_argument>") != 0) 706 { 707 int index = GetOptionArgumentPosition (value.c_str()); 708 if (index == 0) 709 result_str.Printf ("%s", value.c_str()); 710 else if (index >= cmd_args.GetArgumentCount()) 711 { 712 713 result.AppendErrorWithFormat 714 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 715 index); 716 result.SetStatus (eReturnStatusFailed); 717 return; 718 } 719 else 720 { 721 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); 722 if (strpos != std::string::npos) 723 raw_input_string = raw_input_string.erase (strpos, 724 strlen (cmd_args.GetArgumentAtIndex (index))); 725 result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index)); 726 } 727 } 728 } 729 } 730 } 731 732 alias_result = result_str.GetData(); 733 } 734 } 735 736 bool 737 CommandInterpreter::HandleCommand (const char *command_line, 738 bool add_to_history, 739 CommandReturnObject &result, 740 ExecutionContext *override_context, 741 bool repeat_on_empty_command) 742 743 { 744 745 bool done = false; 746 CommandObject *cmd_obj = NULL; 747 std::string next_word; 748 bool wants_raw_input = false; 749 std::string command_string (command_line); 750 751 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS)); 752 Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line); 753 754 // Make a scoped cleanup object that will clear the crash description string 755 // on exit of this function. 756 lldb_utility::CleanUp <const char *, void> crash_description_cleanup(NULL, Host::SetCrashDescription); 757 758 if (log) 759 log->Printf ("Processing command: %s", command_line); 760 761 Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line); 762 763 UpdateExecutionContext (override_context); 764 765 bool empty_command = false; 766 bool comment_command = false; 767 if (command_string.empty()) 768 empty_command = true; 769 else 770 { 771 const char *k_space_characters = "\t\n\v\f\r "; 772 773 size_t non_space = command_string.find_first_not_of (k_space_characters); 774 // Check for empty line or comment line (lines whose first 775 // non-space character is the comment character for this interpreter) 776 if (non_space == std::string::npos) 777 empty_command = true; 778 else if (command_string[non_space] == m_comment_char) 779 comment_command = true; 780 } 781 782 if (empty_command) 783 { 784 if (repeat_on_empty_command) 785 { 786 if (m_command_history.empty()) 787 { 788 result.AppendError ("empty command"); 789 result.SetStatus(eReturnStatusFailed); 790 return false; 791 } 792 else 793 { 794 command_line = m_repeat_command.c_str(); 795 command_string = command_line; 796 if (m_repeat_command.empty()) 797 { 798 result.AppendErrorWithFormat("No auto repeat.\n"); 799 result.SetStatus (eReturnStatusFailed); 800 return false; 801 } 802 } 803 add_to_history = false; 804 } 805 else 806 { 807 result.SetStatus (eReturnStatusSuccessFinishNoResult); 808 return true; 809 } 810 } 811 else if (comment_command) 812 { 813 result.SetStatus (eReturnStatusSuccessFinishNoResult); 814 return true; 815 } 816 817 // Phase 1. 818 819 // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object 820 // is for the specified command, and whether or not it wants raw input. This gets complicated by the fact that 821 // the user could have specified an alias, and in translating the alias there may also be command options and/or 822 // even data (including raw text strings) that need to be found and inserted into the command line as part of 823 // the translation. So this first step is plain look-up & replacement, resulting in three things: 1). the command 824 // object whose Execute method will actually be called; 2). a revised command string, with all substitutions & 825 // replacements taken care of; 3). whether or not the Execute function wants raw input or not. 826 827 StreamString revised_command_line; 828 size_t actual_cmd_name_len = 0; 829 while (!done) 830 { 831 StripFirstWord (command_string, next_word); 832 if (!cmd_obj && AliasExists (next_word.c_str())) 833 { 834 std::string alias_result; 835 BuildAliasResult (next_word.c_str(), command_string, alias_result, cmd_obj, result); 836 revised_command_line.Printf ("%s", alias_result.c_str()); 837 if (cmd_obj) 838 { 839 wants_raw_input = cmd_obj->WantsRawCommandString (); 840 actual_cmd_name_len = strlen (cmd_obj->GetCommandName()); 841 } 842 } 843 else if (!cmd_obj) 844 { 845 cmd_obj = GetCommandObject (next_word.c_str()); 846 if (cmd_obj) 847 { 848 actual_cmd_name_len += next_word.length(); 849 revised_command_line.Printf ("%s", next_word.c_str()); 850 wants_raw_input = cmd_obj->WantsRawCommandString (); 851 } 852 else 853 { 854 revised_command_line.Printf ("%s", next_word.c_str()); 855 } 856 } 857 else if (cmd_obj->IsMultiwordObject ()) 858 { 859 CommandObject *sub_cmd_obj = ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (next_word.c_str()); 860 if (sub_cmd_obj) 861 { 862 actual_cmd_name_len += next_word.length() + 1; 863 revised_command_line.Printf (" %s", next_word.c_str()); 864 cmd_obj = sub_cmd_obj; 865 wants_raw_input = cmd_obj->WantsRawCommandString (); 866 } 867 else 868 { 869 revised_command_line.Printf (" %s", next_word.c_str()); 870 done = true; 871 } 872 } 873 else 874 { 875 revised_command_line.Printf (" %s", next_word.c_str()); 876 done = true; 877 } 878 879 if (cmd_obj == NULL) 880 { 881 result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str()); 882 result.SetStatus (eReturnStatusFailed); 883 return false; 884 } 885 886 next_word.erase (); 887 if (command_string.length() == 0) 888 done = true; 889 890 } 891 892 if (command_string.size() > 0) 893 revised_command_line.Printf (" %s", command_string.c_str()); 894 895 // End of Phase 1. 896 // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command 897 // specified was valid; revised_command_line contains the complete command line (including command name(s)), 898 // fully translated with all substitutions & translations taken care of (still in raw text format); and 899 // wants_raw_input specifies whether the Execute method expects raw input or not. 900 901 902 if (log) 903 { 904 log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>"); 905 log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData()); 906 log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False"); 907 } 908 909 // Phase 2. 910 // Take care of things like setting up the history command & calling the appropriate Execute method on the 911 // CommandObject, with the appropriate arguments. 912 913 if (cmd_obj != NULL) 914 { 915 if (add_to_history) 916 { 917 Args command_args (revised_command_line.GetData()); 918 const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); 919 if (repeat_command != NULL) 920 m_repeat_command.assign(repeat_command); 921 else 922 m_repeat_command.assign(command_line); 923 924 m_command_history.push_back (command_line); 925 } 926 927 command_string = revised_command_line.GetData(); 928 std::string command_name (cmd_obj->GetCommandName()); 929 std::string remainder; 930 if (actual_cmd_name_len < command_string.length()) 931 remainder = command_string.substr (actual_cmd_name_len); // Note: 'actual_cmd_name_len' may be considerably shorter 932 // than cmd_obj->GetCommandName(), because name completion 933 // allows users to enter short versions of the names, 934 // e.g. 'br s' for 'breakpoint set'. 935 936 // Remove any initial spaces 937 std::string white_space (" \t\v"); 938 size_t pos = remainder.find_first_not_of (white_space); 939 if (pos != 0 && pos != std::string::npos) 940 remainder = remainder.substr (pos); 941 942 if (log) 943 log->Printf ("HandleCommand, command line after removing command name(s): '%s'\n", remainder.c_str()); 944 945 946 if (wants_raw_input) 947 cmd_obj->ExecuteRawCommandString (remainder.c_str(), result); 948 else 949 { 950 Args cmd_args (remainder.c_str()); 951 cmd_obj->ExecuteWithOptions (cmd_args, result); 952 } 953 } 954 else 955 { 956 // We didn't find the first command object, so complete the first argument. 957 Args command_args (revised_command_line.GetData()); 958 StringList matches; 959 int num_matches; 960 int cursor_index = 0; 961 int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0)); 962 bool word_complete; 963 num_matches = HandleCompletionMatches (command_args, 964 cursor_index, 965 cursor_char_position, 966 0, 967 -1, 968 word_complete, 969 matches); 970 971 if (num_matches > 0) 972 { 973 std::string error_msg; 974 error_msg.assign ("ambiguous command '"); 975 error_msg.append(command_args.GetArgumentAtIndex(0)); 976 error_msg.append ("'."); 977 978 error_msg.append (" Possible completions:"); 979 for (int i = 0; i < num_matches; i++) 980 { 981 error_msg.append ("\n\t"); 982 error_msg.append (matches.GetStringAtIndex (i)); 983 } 984 error_msg.append ("\n"); 985 result.AppendRawError (error_msg.c_str(), error_msg.size()); 986 } 987 else 988 result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0)); 989 990 result.SetStatus (eReturnStatusFailed); 991 } 992 993 return result.Succeeded(); 994 } 995 996 int 997 CommandInterpreter::HandleCompletionMatches (Args &parsed_line, 998 int &cursor_index, 999 int &cursor_char_position, 1000 int match_start_point, 1001 int max_return_elements, 1002 bool &word_complete, 1003 StringList &matches) 1004 { 1005 int num_command_matches = 0; 1006 bool look_for_subcommand = false; 1007 1008 // For any of the command completions a unique match will be a complete word. 1009 word_complete = true; 1010 1011 if (cursor_index == -1) 1012 { 1013 // We got nothing on the command line, so return the list of commands 1014 bool include_aliases = true; 1015 num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches); 1016 } 1017 else if (cursor_index == 0) 1018 { 1019 // The cursor is in the first argument, so just do a lookup in the dictionary. 1020 CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches); 1021 num_command_matches = matches.GetSize(); 1022 1023 if (num_command_matches == 1 1024 && cmd_obj && cmd_obj->IsMultiwordObject() 1025 && matches.GetStringAtIndex(0) != NULL 1026 && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0) 1027 { 1028 look_for_subcommand = true; 1029 num_command_matches = 0; 1030 matches.DeleteStringAtIndex(0); 1031 parsed_line.AppendArgument (""); 1032 cursor_index++; 1033 cursor_char_position = 0; 1034 } 1035 } 1036 1037 if (cursor_index > 0 || look_for_subcommand) 1038 { 1039 // We are completing further on into a commands arguments, so find the command and tell it 1040 // to complete the command. 1041 // First see if there is a matching initial command: 1042 CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0)); 1043 if (command_object == NULL) 1044 { 1045 return 0; 1046 } 1047 else 1048 { 1049 parsed_line.Shift(); 1050 cursor_index--; 1051 num_command_matches = command_object->HandleCompletion (parsed_line, 1052 cursor_index, 1053 cursor_char_position, 1054 match_start_point, 1055 max_return_elements, 1056 word_complete, 1057 matches); 1058 } 1059 } 1060 1061 return num_command_matches; 1062 1063 } 1064 1065 int 1066 CommandInterpreter::HandleCompletion (const char *current_line, 1067 const char *cursor, 1068 const char *last_char, 1069 int match_start_point, 1070 int max_return_elements, 1071 StringList &matches) 1072 { 1073 // We parse the argument up to the cursor, so the last argument in parsed_line is 1074 // the one containing the cursor, and the cursor is after the last character. 1075 1076 Args parsed_line(current_line, last_char - current_line); 1077 Args partial_parsed_line(current_line, cursor - current_line); 1078 1079 int num_args = partial_parsed_line.GetArgumentCount(); 1080 int cursor_index = partial_parsed_line.GetArgumentCount() - 1; 1081 int cursor_char_position; 1082 1083 if (cursor_index == -1) 1084 cursor_char_position = 0; 1085 else 1086 cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index)); 1087 1088 if (cursor > current_line && cursor[-1] == ' ') 1089 { 1090 // We are just after a space. If we are in an argument, then we will continue 1091 // parsing, but if we are between arguments, then we have to complete whatever the next 1092 // element would be. 1093 // We can distinguish the two cases because if we are in an argument (e.g. because the space is 1094 // protected by a quote) then the space will also be in the parsed argument... 1095 1096 const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index); 1097 if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ') 1098 { 1099 parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '"'); 1100 cursor_index++; 1101 cursor_char_position = 0; 1102 } 1103 } 1104 1105 int num_command_matches; 1106 1107 matches.Clear(); 1108 1109 // Only max_return_elements == -1 is supported at present: 1110 assert (max_return_elements == -1); 1111 bool word_complete; 1112 num_command_matches = HandleCompletionMatches (parsed_line, 1113 cursor_index, 1114 cursor_char_position, 1115 match_start_point, 1116 max_return_elements, 1117 word_complete, 1118 matches); 1119 1120 if (num_command_matches <= 0) 1121 return num_command_matches; 1122 1123 if (num_args == 0) 1124 { 1125 // If we got an empty string, insert nothing. 1126 matches.InsertStringAtIndex(0, ""); 1127 } 1128 else 1129 { 1130 // Now figure out if there is a common substring, and if so put that in element 0, otherwise 1131 // put an empty string in element 0. 1132 std::string command_partial_str; 1133 if (cursor_index >= 0) 1134 command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index), 1135 parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position); 1136 1137 std::string common_prefix; 1138 matches.LongestCommonPrefix (common_prefix); 1139 int partial_name_len = command_partial_str.size(); 1140 1141 // If we matched a unique single command, add a space... 1142 // Only do this if the completer told us this was a complete word, however... 1143 if (num_command_matches == 1 && word_complete) 1144 { 1145 char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index); 1146 if (quote_char != '\0') 1147 common_prefix.push_back(quote_char); 1148 1149 common_prefix.push_back(' '); 1150 } 1151 common_prefix.erase (0, partial_name_len); 1152 matches.InsertStringAtIndex(0, common_prefix.c_str()); 1153 } 1154 return num_command_matches; 1155 } 1156 1157 1158 CommandInterpreter::~CommandInterpreter () 1159 { 1160 } 1161 1162 const char * 1163 CommandInterpreter::GetPrompt () 1164 { 1165 return m_debugger.GetPrompt(); 1166 } 1167 1168 void 1169 CommandInterpreter::SetPrompt (const char *new_prompt) 1170 { 1171 m_debugger.SetPrompt (new_prompt); 1172 } 1173 1174 size_t 1175 CommandInterpreter::GetConfirmationInputReaderCallback 1176 ( 1177 void *baton, 1178 InputReader &reader, 1179 lldb::InputReaderAction action, 1180 const char *bytes, 1181 size_t bytes_len 1182 ) 1183 { 1184 File &out_file = reader.GetDebugger().GetOutputFile(); 1185 bool *response_ptr = (bool *) baton; 1186 1187 switch (action) 1188 { 1189 case eInputReaderActivate: 1190 if (out_file.IsValid()) 1191 { 1192 if (reader.GetPrompt()) 1193 { 1194 out_file.Printf ("%s", reader.GetPrompt()); 1195 out_file.Flush (); 1196 } 1197 } 1198 break; 1199 1200 case eInputReaderDeactivate: 1201 break; 1202 1203 case eInputReaderReactivate: 1204 if (out_file.IsValid() && reader.GetPrompt()) 1205 { 1206 out_file.Printf ("%s", reader.GetPrompt()); 1207 out_file.Flush (); 1208 } 1209 break; 1210 1211 case eInputReaderGotToken: 1212 if (bytes_len == 0) 1213 { 1214 reader.SetIsDone(true); 1215 } 1216 else if (bytes[0] == 'y') 1217 { 1218 *response_ptr = true; 1219 reader.SetIsDone(true); 1220 } 1221 else if (bytes[0] == 'n') 1222 { 1223 *response_ptr = false; 1224 reader.SetIsDone(true); 1225 } 1226 else 1227 { 1228 if (out_file.IsValid() && !reader.IsDone() && reader.GetPrompt()) 1229 { 1230 out_file.Printf ("Please answer \"y\" or \"n\"\n%s", reader.GetPrompt()); 1231 out_file.Flush (); 1232 } 1233 } 1234 break; 1235 1236 case eInputReaderInterrupt: 1237 case eInputReaderEndOfFile: 1238 *response_ptr = false; // Assume ^C or ^D means cancel the proposed action 1239 reader.SetIsDone (true); 1240 break; 1241 1242 case eInputReaderDone: 1243 break; 1244 } 1245 1246 return bytes_len; 1247 1248 } 1249 1250 bool 1251 CommandInterpreter::Confirm (const char *message, bool default_answer) 1252 { 1253 // Check AutoConfirm first: 1254 if (m_debugger.GetAutoConfirm()) 1255 return default_answer; 1256 1257 InputReaderSP reader_sp (new InputReader(GetDebugger())); 1258 bool response = default_answer; 1259 if (reader_sp) 1260 { 1261 std::string prompt(message); 1262 prompt.append(": ["); 1263 if (default_answer) 1264 prompt.append ("Y/n] "); 1265 else 1266 prompt.append ("y/N] "); 1267 1268 Error err (reader_sp->Initialize (CommandInterpreter::GetConfirmationInputReaderCallback, 1269 &response, // baton 1270 eInputReaderGranularityLine, // token size, to pass to callback function 1271 NULL, // end token 1272 prompt.c_str(), // prompt 1273 true)); // echo input 1274 if (err.Success()) 1275 { 1276 GetDebugger().PushInputReader (reader_sp); 1277 } 1278 reader_sp->WaitOnReaderIsDone(); 1279 } 1280 return response; 1281 } 1282 1283 1284 void 1285 CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type) 1286 { 1287 CommandObjectSP cmd_obj_sp = GetCommandSPExact (dest_cmd, true); 1288 1289 if (cmd_obj_sp != NULL) 1290 { 1291 CommandObject *cmd_obj = cmd_obj_sp.get(); 1292 if (cmd_obj->IsCrossRefObject ()) 1293 cmd_obj->AddObject (object_type); 1294 } 1295 } 1296 1297 OptionArgVectorSP 1298 CommandInterpreter::GetAliasOptions (const char *alias_name) 1299 { 1300 OptionArgMap::iterator pos; 1301 OptionArgVectorSP ret_val; 1302 1303 std::string alias (alias_name); 1304 1305 if (HasAliasOptions()) 1306 { 1307 pos = m_alias_options.find (alias); 1308 if (pos != m_alias_options.end()) 1309 ret_val = pos->second; 1310 } 1311 1312 return ret_val; 1313 } 1314 1315 void 1316 CommandInterpreter::RemoveAliasOptions (const char *alias_name) 1317 { 1318 OptionArgMap::iterator pos = m_alias_options.find(alias_name); 1319 if (pos != m_alias_options.end()) 1320 { 1321 m_alias_options.erase (pos); 1322 } 1323 } 1324 1325 void 1326 CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp) 1327 { 1328 m_alias_options[alias_name] = option_arg_vector_sp; 1329 } 1330 1331 bool 1332 CommandInterpreter::HasCommands () 1333 { 1334 return (!m_command_dict.empty()); 1335 } 1336 1337 bool 1338 CommandInterpreter::HasAliases () 1339 { 1340 return (!m_alias_dict.empty()); 1341 } 1342 1343 bool 1344 CommandInterpreter::HasUserCommands () 1345 { 1346 return (!m_user_dict.empty()); 1347 } 1348 1349 bool 1350 CommandInterpreter::HasAliasOptions () 1351 { 1352 return (!m_alias_options.empty()); 1353 } 1354 1355 void 1356 CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj, 1357 const char *alias_name, 1358 Args &cmd_args, 1359 std::string &raw_input_string, 1360 CommandReturnObject &result) 1361 { 1362 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name); 1363 1364 bool wants_raw_input = alias_cmd_obj->WantsRawCommandString(); 1365 1366 // Make sure that the alias name is the 0th element in cmd_args 1367 std::string alias_name_str = alias_name; 1368 if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0) 1369 cmd_args.Unshift (alias_name); 1370 1371 Args new_args (alias_cmd_obj->GetCommandName()); 1372 if (new_args.GetArgumentCount() == 2) 1373 new_args.Shift(); 1374 1375 if (option_arg_vector_sp.get()) 1376 { 1377 if (wants_raw_input) 1378 { 1379 // We have a command that both has command options and takes raw input. Make *sure* it has a 1380 // " -- " in the right place in the raw_input_string. 1381 size_t pos = raw_input_string.find(" -- "); 1382 if (pos == std::string::npos) 1383 { 1384 // None found; assume it goes at the beginning of the raw input string 1385 raw_input_string.insert (0, " -- "); 1386 } 1387 } 1388 1389 OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 1390 int old_size = cmd_args.GetArgumentCount(); 1391 std::vector<bool> used (old_size + 1, false); 1392 1393 used[0] = true; 1394 1395 for (int i = 0; i < option_arg_vector->size(); ++i) 1396 { 1397 OptionArgPair option_pair = (*option_arg_vector)[i]; 1398 OptionArgValue value_pair = option_pair.second; 1399 int value_type = value_pair.first; 1400 std::string option = option_pair.first; 1401 std::string value = value_pair.second; 1402 if (option.compare ("<argument>") == 0) 1403 { 1404 if (!wants_raw_input 1405 || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice 1406 new_args.AppendArgument (value.c_str()); 1407 } 1408 else 1409 { 1410 if (value_type != optional_argument) 1411 new_args.AppendArgument (option.c_str()); 1412 if (value.compare ("<no-argument>") != 0) 1413 { 1414 int index = GetOptionArgumentPosition (value.c_str()); 1415 if (index == 0) 1416 { 1417 // value was NOT a positional argument; must be a real value 1418 if (value_type != optional_argument) 1419 new_args.AppendArgument (value.c_str()); 1420 else 1421 { 1422 char buffer[255]; 1423 ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str()); 1424 new_args.AppendArgument (buffer); 1425 } 1426 1427 } 1428 else if (index >= cmd_args.GetArgumentCount()) 1429 { 1430 result.AppendErrorWithFormat 1431 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n", 1432 index); 1433 result.SetStatus (eReturnStatusFailed); 1434 return; 1435 } 1436 else 1437 { 1438 // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string 1439 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index)); 1440 if (strpos != std::string::npos) 1441 { 1442 raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index))); 1443 } 1444 1445 if (value_type != optional_argument) 1446 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index)); 1447 else 1448 { 1449 char buffer[255]; 1450 ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(), 1451 cmd_args.GetArgumentAtIndex (index)); 1452 new_args.AppendArgument (buffer); 1453 } 1454 used[index] = true; 1455 } 1456 } 1457 } 1458 } 1459 1460 for (int j = 0; j < cmd_args.GetArgumentCount(); ++j) 1461 { 1462 if (!used[j] && !wants_raw_input) 1463 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j)); 1464 } 1465 1466 cmd_args.Clear(); 1467 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 1468 } 1469 else 1470 { 1471 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1472 // This alias was not created with any options; nothing further needs to be done, unless it is a command that 1473 // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw 1474 // input string. 1475 if (wants_raw_input) 1476 { 1477 cmd_args.Clear(); 1478 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector()); 1479 } 1480 return; 1481 } 1482 1483 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1484 return; 1485 } 1486 1487 1488 int 1489 CommandInterpreter::GetOptionArgumentPosition (const char *in_string) 1490 { 1491 int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position 1492 // of zero. 1493 1494 char *cptr = (char *) in_string; 1495 1496 // Does it start with '%' 1497 if (cptr[0] == '%') 1498 { 1499 ++cptr; 1500 1501 // Is the rest of it entirely digits? 1502 if (isdigit (cptr[0])) 1503 { 1504 const char *start = cptr; 1505 while (isdigit (cptr[0])) 1506 ++cptr; 1507 1508 // We've gotten to the end of the digits; are we at the end of the string? 1509 if (cptr[0] == '\0') 1510 position = atoi (start); 1511 } 1512 } 1513 1514 return position; 1515 } 1516 1517 void 1518 CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result) 1519 { 1520 // Don't parse any .lldbinit files if we were asked not to 1521 if (m_skip_lldbinit_files) 1522 return; 1523 1524 const char *init_file_path = in_cwd ? "./.lldbinit" : "~/.lldbinit"; 1525 FileSpec init_file (init_file_path, true); 1526 // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting 1527 // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details). 1528 1529 if (init_file.Exists()) 1530 { 1531 ExecutionContext *exe_ctx = NULL; // We don't have any context yet. 1532 bool stop_on_continue = true; 1533 bool stop_on_error = false; 1534 bool echo_commands = false; 1535 bool print_results = false; 1536 1537 HandleCommandsFromFile (init_file, exe_ctx, stop_on_continue, stop_on_error, echo_commands, print_results, result); 1538 } 1539 else 1540 { 1541 // nothing to be done if the file doesn't exist 1542 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1543 } 1544 } 1545 1546 PlatformSP 1547 CommandInterpreter::GetPlatform (bool prefer_target_platform) 1548 { 1549 PlatformSP platform_sp; 1550 if (prefer_target_platform && m_exe_ctx.target) 1551 platform_sp = m_exe_ctx.target->GetPlatform(); 1552 1553 if (!platform_sp) 1554 platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform(); 1555 return platform_sp; 1556 } 1557 1558 void 1559 CommandInterpreter::HandleCommands (const StringList &commands, 1560 ExecutionContext *override_context, 1561 bool stop_on_continue, 1562 bool stop_on_error, 1563 bool echo_commands, 1564 bool print_results, 1565 CommandReturnObject &result) 1566 { 1567 size_t num_lines = commands.GetSize(); 1568 1569 // If we are going to continue past a "continue" then we need to run the commands synchronously. 1570 // Make sure you reset this value anywhere you return from the function. 1571 1572 bool old_async_execution = m_debugger.GetAsyncExecution(); 1573 1574 // If we've been given an execution context, set it at the start, but don't keep resetting it or we will 1575 // cause series of commands that change the context, then do an operation that relies on that context to fail. 1576 1577 if (override_context != NULL) 1578 UpdateExecutionContext (override_context); 1579 1580 if (!stop_on_continue) 1581 { 1582 m_debugger.SetAsyncExecution (false); 1583 } 1584 1585 for (int idx = 0; idx < num_lines; idx++) 1586 { 1587 const char *cmd = commands.GetStringAtIndex(idx); 1588 if (cmd[0] == '\0') 1589 continue; 1590 1591 if (echo_commands) 1592 { 1593 result.AppendMessageWithFormat ("%s %s\n", 1594 GetPrompt(), 1595 cmd); 1596 } 1597 1598 CommandReturnObject tmp_result; 1599 bool success = HandleCommand(cmd, false, tmp_result, NULL); 1600 1601 if (print_results) 1602 { 1603 if (tmp_result.Succeeded()) 1604 result.AppendMessageWithFormat("%s", tmp_result.GetOutputData()); 1605 } 1606 1607 if (!success || !tmp_result.Succeeded()) 1608 { 1609 if (stop_on_error) 1610 { 1611 result.AppendErrorWithFormat("Aborting reading of commands after command #%d: '%s' failed.\n", 1612 idx, cmd); 1613 result.SetStatus (eReturnStatusFailed); 1614 m_debugger.SetAsyncExecution (old_async_execution); 1615 return; 1616 } 1617 else if (print_results) 1618 { 1619 result.AppendMessageWithFormat ("Command #%d '%s' failed with error: %s.\n", 1620 idx + 1, 1621 cmd, 1622 tmp_result.GetErrorData()); 1623 } 1624 } 1625 1626 // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution 1627 // could be running (for instance in Breakpoint Commands. 1628 // So we check the return value to see if it is has running in it. 1629 if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult) 1630 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult)) 1631 { 1632 if (stop_on_continue) 1633 { 1634 // If we caused the target to proceed, and we're going to stop in that case, set the 1635 // status in our real result before returning. This is an error if the continue was not the 1636 // last command in the set of commands to be run. 1637 if (idx != num_lines - 1) 1638 result.AppendErrorWithFormat("Aborting reading of commands after command #%d: '%s' continued the target.\n", 1639 idx + 1, cmd); 1640 else 1641 result.AppendMessageWithFormat ("Command #%d '%s' continued the target.\n", idx + 1, cmd); 1642 1643 result.SetStatus(tmp_result.GetStatus()); 1644 m_debugger.SetAsyncExecution (old_async_execution); 1645 1646 return; 1647 } 1648 } 1649 1650 } 1651 1652 result.SetStatus (eReturnStatusSuccessFinishResult); 1653 m_debugger.SetAsyncExecution (old_async_execution); 1654 1655 return; 1656 } 1657 1658 void 1659 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file, 1660 ExecutionContext *context, 1661 bool stop_on_continue, 1662 bool stop_on_error, 1663 bool echo_command, 1664 bool print_result, 1665 CommandReturnObject &result) 1666 { 1667 if (cmd_file.Exists()) 1668 { 1669 bool success; 1670 StringList commands; 1671 success = commands.ReadFileLines(cmd_file); 1672 if (!success) 1673 { 1674 result.AppendErrorWithFormat ("Error reading commands from file: %s.\n", cmd_file.GetFilename().AsCString()); 1675 result.SetStatus (eReturnStatusFailed); 1676 return; 1677 } 1678 HandleCommands (commands, context, stop_on_continue, stop_on_error, echo_command, print_result, result); 1679 } 1680 else 1681 { 1682 result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n", 1683 cmd_file.GetFilename().AsCString()); 1684 result.SetStatus (eReturnStatusFailed); 1685 return; 1686 } 1687 } 1688 1689 ScriptInterpreter * 1690 CommandInterpreter::GetScriptInterpreter () 1691 { 1692 if (m_script_interpreter_ap.get() != NULL) 1693 return m_script_interpreter_ap.get(); 1694 1695 lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage(); 1696 switch (script_lang) 1697 { 1698 case eScriptLanguageNone: 1699 m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this)); 1700 break; 1701 case eScriptLanguagePython: 1702 m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this)); 1703 break; 1704 default: 1705 break; 1706 }; 1707 1708 return m_script_interpreter_ap.get(); 1709 } 1710 1711 1712 1713 bool 1714 CommandInterpreter::GetSynchronous () 1715 { 1716 return m_synchronous_execution; 1717 } 1718 1719 void 1720 CommandInterpreter::SetSynchronous (bool value) 1721 { 1722 m_synchronous_execution = value; 1723 } 1724 1725 void 1726 CommandInterpreter::OutputFormattedHelpText (Stream &strm, 1727 const char *word_text, 1728 const char *separator, 1729 const char *help_text, 1730 uint32_t max_word_len) 1731 { 1732 const uint32_t max_columns = m_debugger.GetTerminalWidth(); 1733 1734 int indent_size = max_word_len + strlen (separator) + 2; 1735 1736 strm.IndentMore (indent_size); 1737 1738 StreamString text_strm; 1739 text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text); 1740 1741 size_t len = text_strm.GetSize(); 1742 const char *text = text_strm.GetData(); 1743 if (text[len - 1] == '\n') 1744 { 1745 text_strm.EOL(); 1746 len = text_strm.GetSize(); 1747 } 1748 1749 if (len < max_columns) 1750 { 1751 // Output it as a single line. 1752 strm.Printf ("%s", text); 1753 } 1754 else 1755 { 1756 // We need to break it up into multiple lines. 1757 bool first_line = true; 1758 int text_width; 1759 int start = 0; 1760 int end = start; 1761 int final_end = strlen (text); 1762 int sub_len; 1763 1764 while (end < final_end) 1765 { 1766 if (first_line) 1767 text_width = max_columns - 1; 1768 else 1769 text_width = max_columns - indent_size - 1; 1770 1771 // Don't start the 'text' on a space, since we're already outputting the indentation. 1772 if (!first_line) 1773 { 1774 while ((start < final_end) && (text[start] == ' ')) 1775 start++; 1776 } 1777 1778 end = start + text_width; 1779 if (end > final_end) 1780 end = final_end; 1781 else 1782 { 1783 // If we're not at the end of the text, make sure we break the line on white space. 1784 while (end > start 1785 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') 1786 end--; 1787 } 1788 1789 sub_len = end - start; 1790 if (start != 0) 1791 strm.EOL(); 1792 if (!first_line) 1793 strm.Indent(); 1794 else 1795 first_line = false; 1796 assert (start <= final_end); 1797 assert (start + sub_len <= final_end); 1798 if (sub_len > 0) 1799 strm.Write (text + start, sub_len); 1800 start = end + 1; 1801 } 1802 } 1803 strm.EOL(); 1804 strm.IndentLess(indent_size); 1805 } 1806 1807 void 1808 CommandInterpreter::AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word, 1809 StringList &commands_found, StringList &commands_help) 1810 { 1811 CommandObject::CommandMap::const_iterator pos; 1812 CommandObject::CommandMap sub_cmd_dict = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict; 1813 CommandObject *sub_cmd_obj; 1814 1815 for (pos = sub_cmd_dict.begin(); pos != sub_cmd_dict.end(); ++pos) 1816 { 1817 const char * command_name = pos->first.c_str(); 1818 sub_cmd_obj = pos->second.get(); 1819 StreamString complete_command_name; 1820 1821 complete_command_name.Printf ("%s %s", prefix, command_name); 1822 1823 if (sub_cmd_obj->HelpTextContainsWord (search_word)) 1824 { 1825 commands_found.AppendString (complete_command_name.GetData()); 1826 commands_help.AppendString (sub_cmd_obj->GetHelp()); 1827 } 1828 1829 if (sub_cmd_obj->IsMultiwordObject()) 1830 AproposAllSubCommands (sub_cmd_obj, complete_command_name.GetData(), search_word, commands_found, 1831 commands_help); 1832 } 1833 1834 } 1835 1836 void 1837 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found, 1838 StringList &commands_help) 1839 { 1840 CommandObject::CommandMap::const_iterator pos; 1841 1842 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) 1843 { 1844 const char *command_name = pos->first.c_str(); 1845 CommandObject *cmd_obj = pos->second.get(); 1846 1847 if (cmd_obj->HelpTextContainsWord (search_word)) 1848 { 1849 commands_found.AppendString (command_name); 1850 commands_help.AppendString (cmd_obj->GetHelp()); 1851 } 1852 1853 if (cmd_obj->IsMultiwordObject()) 1854 AproposAllSubCommands (cmd_obj, command_name, search_word, commands_found, commands_help); 1855 1856 } 1857 } 1858 1859 1860 void 1861 CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context) 1862 { 1863 m_exe_ctx.Clear(); 1864 1865 if (override_context != NULL) 1866 { 1867 m_exe_ctx.target = override_context->target; 1868 m_exe_ctx.process = override_context->process; 1869 m_exe_ctx.thread = override_context->thread; 1870 m_exe_ctx.frame = override_context->frame; 1871 } 1872 else 1873 { 1874 TargetSP target_sp (m_debugger.GetSelectedTarget()); 1875 if (target_sp) 1876 { 1877 m_exe_ctx.target = target_sp.get(); 1878 m_exe_ctx.process = target_sp->GetProcessSP().get(); 1879 if (m_exe_ctx.process && m_exe_ctx.process->IsAlive() && !m_exe_ctx.process->IsRunning()) 1880 { 1881 m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetSelectedThread().get(); 1882 if (m_exe_ctx.thread == NULL) 1883 { 1884 m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get(); 1885 // If we didn't have a selected thread, select one here. 1886 if (m_exe_ctx.thread != NULL) 1887 m_exe_ctx.process->GetThreadList().SetSelectedThreadByID(m_exe_ctx.thread->GetID()); 1888 } 1889 if (m_exe_ctx.thread) 1890 { 1891 m_exe_ctx.frame = m_exe_ctx.thread->GetSelectedFrame().get(); 1892 if (m_exe_ctx.frame == NULL) 1893 { 1894 m_exe_ctx.frame = m_exe_ctx.thread->GetStackFrameAtIndex (0).get(); 1895 // If we didn't have a selected frame select one here. 1896 if (m_exe_ctx.frame != NULL) 1897 m_exe_ctx.thread->SetSelectedFrame(m_exe_ctx.frame); 1898 } 1899 } 1900 } 1901 } 1902 } 1903 } 1904 1905