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