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