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