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