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