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 "lldb/lldb-python.h"
11 
12 #include <string>
13 #include <vector>
14 
15 #include <getopt.h>
16 #include <stdlib.h>
17 
18 #include "CommandObjectScript.h"
19 #include "lldb/Interpreter/CommandObjectRegexCommand.h"
20 
21 #include "../Commands/CommandObjectApropos.h"
22 #include "../Commands/CommandObjectArgs.h"
23 #include "../Commands/CommandObjectBreakpoint.h"
24 #include "../Commands/CommandObjectDisassemble.h"
25 #include "../Commands/CommandObjectExpression.h"
26 #include "../Commands/CommandObjectFrame.h"
27 #include "../Commands/CommandObjectHelp.h"
28 #include "../Commands/CommandObjectLog.h"
29 #include "../Commands/CommandObjectMemory.h"
30 #include "../Commands/CommandObjectPlatform.h"
31 #include "../Commands/CommandObjectPlugin.h"
32 #include "../Commands/CommandObjectProcess.h"
33 #include "../Commands/CommandObjectQuit.h"
34 #include "../Commands/CommandObjectRegister.h"
35 #include "../Commands/CommandObjectSettings.h"
36 #include "../Commands/CommandObjectSource.h"
37 #include "../Commands/CommandObjectCommands.h"
38 #include "../Commands/CommandObjectSyntax.h"
39 #include "../Commands/CommandObjectTarget.h"
40 #include "../Commands/CommandObjectThread.h"
41 #include "../Commands/CommandObjectType.h"
42 #include "../Commands/CommandObjectVersion.h"
43 #include "../Commands/CommandObjectWatchpoint.h"
44 
45 #include "lldb/Core/Debugger.h"
46 #include "lldb/Core/InputReader.h"
47 #include "lldb/Core/Log.h"
48 #include "lldb/Core/Stream.h"
49 #include "lldb/Core/Timer.h"
50 
51 #include "lldb/Host/Host.h"
52 
53 #include "lldb/Interpreter/Args.h"
54 #include "lldb/Interpreter/CommandReturnObject.h"
55 #include "lldb/Interpreter/CommandInterpreter.h"
56 #include "lldb/Interpreter/Options.h"
57 #include "lldb/Interpreter/ScriptInterpreterNone.h"
58 #include "lldb/Interpreter/ScriptInterpreterPython.h"
59 
60 
61 #include "lldb/Target/Process.h"
62 #include "lldb/Target/Thread.h"
63 #include "lldb/Target/TargetList.h"
64 
65 #include "lldb/Utility/CleanUp.h"
66 
67 using namespace lldb;
68 using namespace lldb_private;
69 
70 
71 static PropertyDefinition
72 g_properties[] =
73 {
74     { "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." },
75     { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." },
76     { NULL                  , OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
77 };
78 
79 enum
80 {
81     ePropertyExpandRegexAliases = 0,
82     ePropertyPromptOnQuit = 1
83 };
84 
85 ConstString &
86 CommandInterpreter::GetStaticBroadcasterClass ()
87 {
88     static ConstString class_name ("lldb.commandInterpreter");
89     return class_name;
90 }
91 
92 CommandInterpreter::CommandInterpreter
93 (
94     Debugger &debugger,
95     ScriptLanguage script_language,
96     bool synchronous_execution
97 ) :
98     Broadcaster (&debugger, "lldb.command-interpreter"),
99     Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))),
100     m_debugger (debugger),
101     m_synchronous_execution (synchronous_execution),
102     m_skip_lldbinit_files (false),
103     m_skip_app_init_files (false),
104     m_script_interpreter_ap (),
105     m_comment_char ('#'),
106     m_repeat_char ('!'),
107     m_batch_command_mode (false),
108     m_truncation_warning(eNoTruncation),
109     m_command_source_depth (0)
110 {
111     debugger.SetScriptLanguage (script_language);
112     SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit");
113     SetEventName (eBroadcastBitResetPrompt, "reset-prompt");
114     SetEventName (eBroadcastBitQuitCommandReceived, "quit");
115     CheckInWithManager ();
116     m_collection_sp->Initialize (g_properties);
117 }
118 
119 bool
120 CommandInterpreter::GetExpandRegexAliases () const
121 {
122     const uint32_t idx = ePropertyExpandRegexAliases;
123     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
124 }
125 
126 bool
127 CommandInterpreter::GetPromptOnQuit () const
128 {
129     const uint32_t idx = ePropertyPromptOnQuit;
130     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
131 }
132 
133 void
134 CommandInterpreter::Initialize ()
135 {
136     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
137 
138     CommandReturnObject result;
139 
140     LoadCommandDictionary ();
141 
142     // Set up some initial aliases.
143     CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false);
144     if (cmd_obj_sp)
145     {
146         AddAlias ("q", cmd_obj_sp);
147         AddAlias ("exit", cmd_obj_sp);
148     }
149 
150     cmd_obj_sp = GetCommandSPExact ("_regexp-attach",false);
151     if (cmd_obj_sp)
152     {
153         AddAlias ("attach", cmd_obj_sp);
154     }
155 
156     cmd_obj_sp = GetCommandSPExact ("process detach",false);
157     if (cmd_obj_sp)
158     {
159         AddAlias ("detach", cmd_obj_sp);
160     }
161 
162     cmd_obj_sp = GetCommandSPExact ("process continue", false);
163     if (cmd_obj_sp)
164     {
165         AddAlias ("c", cmd_obj_sp);
166         AddAlias ("continue", cmd_obj_sp);
167     }
168 
169     cmd_obj_sp = GetCommandSPExact ("_regexp-break",false);
170     if (cmd_obj_sp)
171         AddAlias ("b", cmd_obj_sp);
172 
173     cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false);
174     if (cmd_obj_sp)
175         AddAlias ("tbreak", cmd_obj_sp);
176 
177     cmd_obj_sp = GetCommandSPExact ("thread step-inst", false);
178     if (cmd_obj_sp)
179     {
180         AddAlias ("stepi", cmd_obj_sp);
181         AddAlias ("si", cmd_obj_sp);
182     }
183 
184     cmd_obj_sp = GetCommandSPExact ("thread step-inst-over", false);
185     if (cmd_obj_sp)
186     {
187         AddAlias ("nexti", cmd_obj_sp);
188         AddAlias ("ni", cmd_obj_sp);
189     }
190 
191     cmd_obj_sp = GetCommandSPExact ("thread step-in", false);
192     if (cmd_obj_sp)
193     {
194         AddAlias ("s", cmd_obj_sp);
195         AddAlias ("step", cmd_obj_sp);
196     }
197 
198     cmd_obj_sp = GetCommandSPExact ("thread step-over", false);
199     if (cmd_obj_sp)
200     {
201         AddAlias ("n", cmd_obj_sp);
202         AddAlias ("next", cmd_obj_sp);
203     }
204 
205     cmd_obj_sp = GetCommandSPExact ("thread step-out", false);
206     if (cmd_obj_sp)
207     {
208         AddAlias ("finish", cmd_obj_sp);
209     }
210 
211     cmd_obj_sp = GetCommandSPExact ("frame select", false);
212     if (cmd_obj_sp)
213     {
214         AddAlias ("f", cmd_obj_sp);
215     }
216 
217     cmd_obj_sp = GetCommandSPExact ("thread select", false);
218     if (cmd_obj_sp)
219     {
220         AddAlias ("t", cmd_obj_sp);
221     }
222 
223     cmd_obj_sp = GetCommandSPExact ("source list", false);
224     if (cmd_obj_sp)
225     {
226         AddAlias ("l", cmd_obj_sp);
227         AddAlias ("list", cmd_obj_sp);
228     }
229 
230     cmd_obj_sp = GetCommandSPExact ("memory read", false);
231     if (cmd_obj_sp)
232         AddAlias ("x", cmd_obj_sp);
233 
234     cmd_obj_sp = GetCommandSPExact ("_regexp-up", false);
235     if (cmd_obj_sp)
236         AddAlias ("up", cmd_obj_sp);
237 
238     cmd_obj_sp = GetCommandSPExact ("_regexp-down", false);
239     if (cmd_obj_sp)
240         AddAlias ("down", cmd_obj_sp);
241 
242     cmd_obj_sp = GetCommandSPExact ("_regexp-display", false);
243     if (cmd_obj_sp)
244         AddAlias ("display", cmd_obj_sp);
245 
246     cmd_obj_sp = GetCommandSPExact ("disassemble", false);
247     if (cmd_obj_sp)
248         AddAlias ("dis", cmd_obj_sp);
249 
250     cmd_obj_sp = GetCommandSPExact ("disassemble", false);
251     if (cmd_obj_sp)
252         AddAlias ("di", cmd_obj_sp);
253 
254 
255 
256     cmd_obj_sp = GetCommandSPExact ("_regexp-undisplay", false);
257     if (cmd_obj_sp)
258         AddAlias ("undisplay", cmd_obj_sp);
259 
260     cmd_obj_sp = GetCommandSPExact ("_regexp-bt", false);
261     if (cmd_obj_sp)
262         AddAlias ("bt", cmd_obj_sp);
263 
264     cmd_obj_sp = GetCommandSPExact ("target create", false);
265     if (cmd_obj_sp)
266         AddAlias ("file", cmd_obj_sp);
267 
268     cmd_obj_sp = GetCommandSPExact ("target modules", false);
269     if (cmd_obj_sp)
270         AddAlias ("image", cmd_obj_sp);
271 
272 
273     OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector);
274 
275     cmd_obj_sp = GetCommandSPExact ("expression", false);
276     if (cmd_obj_sp)
277     {
278         AddAlias ("expr", cmd_obj_sp);
279 
280         ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
281         AddAlias ("p", cmd_obj_sp);
282         AddAlias ("print", cmd_obj_sp);
283         AddAlias ("call", cmd_obj_sp);
284         AddOrReplaceAliasOptions ("p", alias_arguments_vector_sp);
285         AddOrReplaceAliasOptions ("print", alias_arguments_vector_sp);
286         AddOrReplaceAliasOptions ("call", alias_arguments_vector_sp);
287 
288         alias_arguments_vector_sp.reset (new OptionArgVector);
289         ProcessAliasOptionsArgs (cmd_obj_sp, "-O --", alias_arguments_vector_sp);
290         AddAlias ("po", cmd_obj_sp);
291         AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp);
292     }
293 
294     cmd_obj_sp = GetCommandSPExact ("process kill", false);
295     if (cmd_obj_sp)
296     {
297         AddAlias ("kill", cmd_obj_sp);
298     }
299 
300     cmd_obj_sp = GetCommandSPExact ("process launch", false);
301     if (cmd_obj_sp)
302     {
303         alias_arguments_vector_sp.reset (new OptionArgVector);
304 #if defined (__arm__)
305         ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
306 #else
307         ProcessAliasOptionsArgs (cmd_obj_sp, "--shell=/bin/bash --", alias_arguments_vector_sp);
308 #endif
309         AddAlias ("r", cmd_obj_sp);
310         AddAlias ("run", cmd_obj_sp);
311         AddOrReplaceAliasOptions ("r", alias_arguments_vector_sp);
312         AddOrReplaceAliasOptions ("run", alias_arguments_vector_sp);
313     }
314 
315     cmd_obj_sp = GetCommandSPExact ("target symbols add", false);
316     if (cmd_obj_sp)
317     {
318         AddAlias ("add-dsym", cmd_obj_sp);
319     }
320 
321     cmd_obj_sp = GetCommandSPExact ("breakpoint set", false);
322     if (cmd_obj_sp)
323     {
324         alias_arguments_vector_sp.reset (new OptionArgVector);
325         ProcessAliasOptionsArgs (cmd_obj_sp, "--func-regex %1", alias_arguments_vector_sp);
326         AddAlias ("rbreak", cmd_obj_sp);
327         AddOrReplaceAliasOptions("rbreak", alias_arguments_vector_sp);
328     }
329 }
330 
331 const char *
332 CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg)
333 {
334     // This function has not yet been implemented.
335 
336     // Look for any embedded script command
337     // If found,
338     //    get interpreter object from the command dictionary,
339     //    call execute_one_command on it,
340     //    get the results as a string,
341     //    substitute that string for current stuff.
342 
343     return arg;
344 }
345 
346 
347 void
348 CommandInterpreter::LoadCommandDictionary ()
349 {
350     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
351 
352     // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
353     //
354     // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref)
355     // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use
356     // the cross-referencing stuff) are created!!!
357     //
358     // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
359 
360 
361     // Command objects that inherit from CommandObjectCrossref must be created before other command objects
362     // are created.  This is so that when another command is created that needs to go into a crossref object,
363     // the crossref object exists and is ready to take the cross reference. Put the cross referencing command
364     // objects into the CommandDictionary now, so they are ready for use when the other commands get created.
365 
366     // Non-CommandObjectCrossref commands can now be created.
367 
368     lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage();
369 
370     m_command_dict["apropos"]   = CommandObjectSP (new CommandObjectApropos (*this));
371     m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
372     //m_command_dict["call"]      = CommandObjectSP (new CommandObjectCall (*this));
373     m_command_dict["command"]   = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
374     m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
375     m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
376 //    m_command_dict["file"]      = CommandObjectSP (new CommandObjectFile (*this));
377     m_command_dict["frame"]     = CommandObjectSP (new CommandObjectMultiwordFrame (*this));
378     m_command_dict["help"]      = CommandObjectSP (new CommandObjectHelp (*this));
379     ///    m_command_dict["image"]     = CommandObjectSP (new CommandObjectImage (*this));
380     m_command_dict["log"]       = CommandObjectSP (new CommandObjectLog (*this));
381     m_command_dict["memory"]    = CommandObjectSP (new CommandObjectMemory (*this));
382     m_command_dict["platform"]  = CommandObjectSP (new CommandObjectPlatform (*this));
383     m_command_dict["plugin"]    = CommandObjectSP (new CommandObjectPlugin (*this));
384     m_command_dict["process"]   = CommandObjectSP (new CommandObjectMultiwordProcess (*this));
385     m_command_dict["quit"]      = CommandObjectSP (new CommandObjectQuit (*this));
386     m_command_dict["register"]  = CommandObjectSP (new CommandObjectRegister (*this));
387     m_command_dict["script"]    = CommandObjectSP (new CommandObjectScript (*this, script_language));
388     m_command_dict["settings"]  = CommandObjectSP (new CommandObjectMultiwordSettings (*this));
389     m_command_dict["source"]    = CommandObjectSP (new CommandObjectMultiwordSource (*this));
390     m_command_dict["target"]    = CommandObjectSP (new CommandObjectMultiwordTarget (*this));
391     m_command_dict["thread"]    = CommandObjectSP (new CommandObjectMultiwordThread (*this));
392     m_command_dict["type"]      = CommandObjectSP (new CommandObjectType (*this));
393     m_command_dict["version"]   = CommandObjectSP (new CommandObjectVersion (*this));
394     m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this));
395 
396     const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"},
397                                       {"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"},
398                                       {"^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
399                                       {"^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
400                                       {"^(-.*)$", "breakpoint set %1"},
401                                       {"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"},
402                                       {"^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"}};
403 
404     size_t num_regexes = sizeof break_regexes/sizeof(char *[2]);
405 
406     std::auto_ptr<CommandObjectRegexCommand>
407     break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
408                                                       "_regexp-break",
409                                                       "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
410                                                       "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
411 
412     if (break_regex_cmd_ap.get())
413     {
414         bool success = true;
415         for (size_t i = 0; i < num_regexes; i++)
416         {
417             success = break_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], break_regexes[i][1]);
418             if (!success)
419                 break;
420         }
421         success = break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full");
422 
423         if (success)
424         {
425             CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release());
426             m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp;
427         }
428     }
429 
430     std::auto_ptr<CommandObjectRegexCommand>
431     tbreak_regex_cmd_ap(new CommandObjectRegexCommand (*this,
432                                                       "_regexp-tbreak",
433                                                       "Set a one shot breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
434                                                       "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
435 
436     if (tbreak_regex_cmd_ap.get())
437     {
438         bool success = true;
439         for (size_t i = 0; i < num_regexes; i++)
440         {
441             // If you add a resultant command string longer than 1024 characters be sure to increase the size of this buffer.
442             char buffer[1024];
443             int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o");
444             assert (num_printed < 1024);
445             success = tbreak_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], buffer);
446             if (!success)
447                 break;
448         }
449         success = tbreak_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full");
450 
451         if (success)
452         {
453             CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_ap.release());
454             m_command_dict[tbreak_regex_cmd_sp->GetCommandName ()] = tbreak_regex_cmd_sp;
455         }
456     }
457 
458     std::auto_ptr<CommandObjectRegexCommand>
459     attach_regex_cmd_ap(new CommandObjectRegexCommand (*this,
460                                                        "_regexp-attach",
461                                                        "Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.",
462                                                        "_regexp-attach [<pid>]\n_regexp-attach [<process-name>]", 2));
463     if (attach_regex_cmd_ap.get())
464     {
465         if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") &&
466             attach_regex_cmd_ap->AddRegexCommand("^(-.*|.* -.*)$", "process attach %1") && // Any options that are specified get passed to 'process attach'
467             attach_regex_cmd_ap->AddRegexCommand("^(.+)$", "process attach --name '%1'") &&
468             attach_regex_cmd_ap->AddRegexCommand("^$", "process attach"))
469         {
470             CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_ap.release());
471             m_command_dict[attach_regex_cmd_sp->GetCommandName ()] = attach_regex_cmd_sp;
472         }
473     }
474 
475     std::auto_ptr<CommandObjectRegexCommand>
476     down_regex_cmd_ap(new CommandObjectRegexCommand (*this,
477                                                      "_regexp-down",
478                                                      "Go down \"n\" frames in the stack (1 frame by default).",
479                                                      "_regexp-down [n]", 2));
480     if (down_regex_cmd_ap.get())
481     {
482         if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") &&
483             down_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r -%1"))
484         {
485             CommandObjectSP down_regex_cmd_sp(down_regex_cmd_ap.release());
486             m_command_dict[down_regex_cmd_sp->GetCommandName ()] = down_regex_cmd_sp;
487         }
488     }
489 
490     std::auto_ptr<CommandObjectRegexCommand>
491     up_regex_cmd_ap(new CommandObjectRegexCommand (*this,
492                                                    "_regexp-up",
493                                                    "Go up \"n\" frames in the stack (1 frame by default).",
494                                                    "_regexp-up [n]", 2));
495     if (up_regex_cmd_ap.get())
496     {
497         if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") &&
498             up_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r %1"))
499         {
500             CommandObjectSP up_regex_cmd_sp(up_regex_cmd_ap.release());
501             m_command_dict[up_regex_cmd_sp->GetCommandName ()] = up_regex_cmd_sp;
502         }
503     }
504 
505     std::auto_ptr<CommandObjectRegexCommand>
506     display_regex_cmd_ap(new CommandObjectRegexCommand (*this,
507                                                    "_regexp-display",
508                                                    "Add an expression evaluation stop-hook.",
509                                                    "_regexp-display expression", 2));
510     if (display_regex_cmd_ap.get())
511     {
512         if (display_regex_cmd_ap->AddRegexCommand("^(.+)$", "target stop-hook add -o \"expr -- %1\""))
513         {
514             CommandObjectSP display_regex_cmd_sp(display_regex_cmd_ap.release());
515             m_command_dict[display_regex_cmd_sp->GetCommandName ()] = display_regex_cmd_sp;
516         }
517     }
518 
519     std::auto_ptr<CommandObjectRegexCommand>
520     undisplay_regex_cmd_ap(new CommandObjectRegexCommand (*this,
521                                                    "_regexp-undisplay",
522                                                    "Remove an expression evaluation stop-hook.",
523                                                    "_regexp-undisplay stop-hook-number", 2));
524     if (undisplay_regex_cmd_ap.get())
525     {
526         if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1"))
527         {
528             CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_ap.release());
529             m_command_dict[undisplay_regex_cmd_sp->GetCommandName ()] = undisplay_regex_cmd_sp;
530         }
531     }
532 
533     std::auto_ptr<CommandObjectRegexCommand>
534     connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand (*this,
535                                                       "gdb-remote",
536                                                       "Connect to a remote GDB server.  If no hostname is provided, localhost is assumed.",
537                                                       "gdb-remote [<hostname>:]<portnum>", 2));
538     if (connect_gdb_remote_cmd_ap.get())
539     {
540         if (connect_gdb_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin gdb-remote connect://%1") &&
541             connect_gdb_remote_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "process connect --plugin gdb-remote connect://localhost:%1"))
542         {
543             CommandObjectSP command_sp(connect_gdb_remote_cmd_ap.release());
544             m_command_dict[command_sp->GetCommandName ()] = command_sp;
545         }
546     }
547 
548     std::auto_ptr<CommandObjectRegexCommand>
549     connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand (*this,
550                                                              "kdp-remote",
551                                                              "Connect to a remote KDP server.  udp port 41139 is the default port number.",
552                                                              "kdp-remote <hostname>[:<portnum>]", 2));
553     if (connect_kdp_remote_cmd_ap.get())
554     {
555         if (connect_kdp_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin kdp-remote udp://%1") &&
556             connect_kdp_remote_cmd_ap->AddRegexCommand("^(.+)$", "process connect --plugin kdp-remote udp://%1:41139"))
557         {
558             CommandObjectSP command_sp(connect_kdp_remote_cmd_ap.release());
559             m_command_dict[command_sp->GetCommandName ()] = command_sp;
560         }
561     }
562 
563     std::auto_ptr<CommandObjectRegexCommand>
564     bt_regex_cmd_ap(new CommandObjectRegexCommand (*this,
565                                                      "_regexp-bt",
566                                                      "Show a backtrace.  An optional argument is accepted; if that argument is a number, it specifies the number of frames to display.  If that argument is 'all', full backtraces of all threads are displayed.",
567                                                      "bt [<digit>|all]", 2));
568     if (bt_regex_cmd_ap.get())
569     {
570         // accept but don't document "bt -c <number>" -- before bt was a regex command if you wanted to backtrace
571         // three frames you would do "bt -c 3" but the intention is to have this emulate the gdb "bt" command and
572         // so now "bt 3" is the preferred form, in line with gdb.
573         if (bt_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "thread backtrace -c %1") &&
574             bt_regex_cmd_ap->AddRegexCommand("^-c ([[:digit:]]+)$", "thread backtrace -c %1") &&
575             bt_regex_cmd_ap->AddRegexCommand("^all$", "thread backtrace all") &&
576             bt_regex_cmd_ap->AddRegexCommand("^$", "thread backtrace"))
577         {
578             CommandObjectSP command_sp(bt_regex_cmd_ap.release());
579             m_command_dict[command_sp->GetCommandName ()] = command_sp;
580         }
581     }
582 
583 }
584 
585 int
586 CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases,
587                                                           StringList &matches)
588 {
589     CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches);
590 
591     if (include_aliases)
592     {
593         CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches);
594     }
595 
596     return matches.GetSize();
597 }
598 
599 CommandObjectSP
600 CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches)
601 {
602     CommandObject::CommandMap::iterator pos;
603     CommandObjectSP command_sp;
604 
605     std::string cmd(cmd_cstr);
606 
607     if (HasCommands())
608     {
609         pos = m_command_dict.find(cmd);
610         if (pos != m_command_dict.end())
611             command_sp = pos->second;
612     }
613 
614     if (include_aliases && HasAliases())
615     {
616         pos = m_alias_dict.find(cmd);
617         if (pos != m_alias_dict.end())
618             command_sp = pos->second;
619     }
620 
621     if (HasUserCommands())
622     {
623         pos = m_user_dict.find(cmd);
624         if (pos != m_user_dict.end())
625             command_sp = pos->second;
626     }
627 
628     if (!exact && !command_sp)
629     {
630         // We will only get into here if we didn't find any exact matches.
631 
632         CommandObjectSP user_match_sp, alias_match_sp, real_match_sp;
633 
634         StringList local_matches;
635         if (matches == NULL)
636             matches = &local_matches;
637 
638         unsigned int num_cmd_matches = 0;
639         unsigned int num_alias_matches = 0;
640         unsigned int num_user_matches = 0;
641 
642         // Look through the command dictionaries one by one, and if we get only one match from any of
643         // them in toto, then return that, otherwise return an empty CommandObjectSP and the list of matches.
644 
645         if (HasCommands())
646         {
647             num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches);
648         }
649 
650         if (num_cmd_matches == 1)
651         {
652             cmd.assign(matches->GetStringAtIndex(0));
653             pos = m_command_dict.find(cmd);
654             if (pos != m_command_dict.end())
655                 real_match_sp = pos->second;
656         }
657 
658         if (include_aliases && HasAliases())
659         {
660             num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches);
661 
662         }
663 
664         if (num_alias_matches == 1)
665         {
666             cmd.assign(matches->GetStringAtIndex (num_cmd_matches));
667             pos = m_alias_dict.find(cmd);
668             if (pos != m_alias_dict.end())
669                 alias_match_sp = pos->second;
670         }
671 
672         if (HasUserCommands())
673         {
674             num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches);
675         }
676 
677         if (num_user_matches == 1)
678         {
679             cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches));
680 
681             pos = m_user_dict.find (cmd);
682             if (pos != m_user_dict.end())
683                 user_match_sp = pos->second;
684         }
685 
686         // If we got exactly one match, return that, otherwise return the match list.
687 
688         if (num_user_matches + num_cmd_matches + num_alias_matches == 1)
689         {
690             if (num_cmd_matches)
691                 return real_match_sp;
692             else if (num_alias_matches)
693                 return alias_match_sp;
694             else
695                 return user_match_sp;
696         }
697     }
698     else if (matches && command_sp)
699     {
700         matches->AppendString (cmd_cstr);
701     }
702 
703 
704     return command_sp;
705 }
706 
707 bool
708 CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
709 {
710     if (name && name[0])
711     {
712         std::string name_sstr(name);
713         bool found = (m_command_dict.find (name_sstr) != m_command_dict.end());
714         if (found && !can_replace)
715             return false;
716         if (found && m_command_dict[name_sstr]->IsRemovable() == false)
717             return false;
718         m_command_dict[name_sstr] = cmd_sp;
719         return true;
720     }
721     return false;
722 }
723 
724 bool
725 CommandInterpreter::AddUserCommand (std::string name,
726                                     const lldb::CommandObjectSP &cmd_sp,
727                                     bool can_replace)
728 {
729     if (!name.empty())
730     {
731 
732         const char* name_cstr = name.c_str();
733 
734         // do not allow replacement of internal commands
735         if (CommandExists(name_cstr))
736         {
737             if (can_replace == false)
738                 return false;
739             if (m_command_dict[name]->IsRemovable() == false)
740                 return false;
741         }
742 
743         if (UserCommandExists(name_cstr))
744         {
745             if (can_replace == false)
746                 return false;
747             if (m_user_dict[name]->IsRemovable() == false)
748                 return false;
749         }
750 
751         m_user_dict[name] = cmd_sp;
752         return true;
753     }
754     return false;
755 }
756 
757 CommandObjectSP
758 CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases)
759 {
760     Args cmd_words (cmd_cstr); // Break up the command string into words, in case it's a multi-word command.
761     CommandObjectSP ret_val;   // Possibly empty return value.
762 
763     if (cmd_cstr == NULL)
764         return ret_val;
765 
766     if (cmd_words.GetArgumentCount() == 1)
767         return GetCommandSP(cmd_cstr, include_aliases, true, NULL);
768     else
769     {
770         // We have a multi-word command (seemingly), so we need to do more work.
771         // First, get the cmd_obj_sp for the first word in the command.
772         CommandObjectSP cmd_obj_sp = GetCommandSP (cmd_words.GetArgumentAtIndex (0), include_aliases, true, NULL);
773         if (cmd_obj_sp.get() != NULL)
774         {
775             // Loop through the rest of the words in the command (everything passed in was supposed to be part of a
776             // command name), and find the appropriate sub-command SP for each command word....
777             size_t end = cmd_words.GetArgumentCount();
778             for (size_t j= 1; j < end; ++j)
779             {
780                 if (cmd_obj_sp->IsMultiwordObject())
781                 {
782                     cmd_obj_sp = cmd_obj_sp->GetSubcommandSP (cmd_words.GetArgumentAtIndex (j));
783                     if (cmd_obj_sp.get() == NULL)
784                         // The sub-command name was invalid.  Fail and return the empty 'ret_val'.
785                         return ret_val;
786                 }
787                 else
788                     // We have more words in the command name, but we don't have a multiword object. Fail and return
789                     // empty 'ret_val'.
790                     return ret_val;
791             }
792             // We successfully looped through all the command words and got valid command objects for them.  Assign the
793             // last object retrieved to 'ret_val'.
794             ret_val = cmd_obj_sp;
795         }
796     }
797     return ret_val;
798 }
799 
800 CommandObject *
801 CommandInterpreter::GetCommandObjectExact (const char *cmd_cstr, bool include_aliases)
802 {
803     return GetCommandSPExact (cmd_cstr, include_aliases).get();
804 }
805 
806 CommandObject *
807 CommandInterpreter::GetCommandObject (const char *cmd_cstr, StringList *matches)
808 {
809     CommandObject *command_obj = GetCommandSP (cmd_cstr, false, true, matches).get();
810 
811     // If we didn't find an exact match to the command string in the commands, look in
812     // the aliases.
813 
814     if (command_obj == NULL)
815     {
816         command_obj = GetCommandSP (cmd_cstr, true, true, matches).get();
817     }
818 
819     // Finally, if there wasn't an exact match among the aliases, look for an inexact match
820     // in both the commands and the aliases.
821 
822     if (command_obj == NULL)
823         command_obj = GetCommandSP(cmd_cstr, true, false, matches).get();
824 
825     return command_obj;
826 }
827 
828 bool
829 CommandInterpreter::CommandExists (const char *cmd)
830 {
831     return m_command_dict.find(cmd) != m_command_dict.end();
832 }
833 
834 bool
835 CommandInterpreter::ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
836                                             const char *options_args,
837                                             OptionArgVectorSP &option_arg_vector_sp)
838 {
839     bool success = true;
840     OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
841 
842     if (!options_args || (strlen (options_args) < 1))
843         return true;
844 
845     std::string options_string (options_args);
846     Args args (options_args);
847     CommandReturnObject result;
848     // Check to see if the command being aliased can take any command options.
849     Options *options = cmd_obj_sp->GetOptions ();
850     if (options)
851     {
852         // See if any options were specified as part of the alias;  if so, handle them appropriately.
853         options->NotifyOptionParsingStarting ();
854         args.Unshift ("dummy_arg");
855         args.ParseAliasOptions (*options, result, option_arg_vector, options_string);
856         args.Shift ();
857         if (result.Succeeded())
858             options->VerifyPartialOptions (result);
859         if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
860         {
861             result.AppendError ("Unable to create requested alias.\n");
862             return false;
863         }
864     }
865 
866     if (!options_string.empty())
867     {
868         if (cmd_obj_sp->WantsRawCommandString ())
869             option_arg_vector->push_back (OptionArgPair ("<argument>",
870                                                           OptionArgValue (-1,
871                                                                           options_string)));
872         else
873         {
874             const size_t argc = args.GetArgumentCount();
875             for (size_t i = 0; i < argc; ++i)
876                 if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
877                     option_arg_vector->push_back
878                                 (OptionArgPair ("<argument>",
879                                                 OptionArgValue (-1,
880                                                                 std::string (args.GetArgumentAtIndex (i)))));
881         }
882     }
883 
884     return success;
885 }
886 
887 bool
888 CommandInterpreter::AliasExists (const char *cmd)
889 {
890     return m_alias_dict.find(cmd) != m_alias_dict.end();
891 }
892 
893 bool
894 CommandInterpreter::UserCommandExists (const char *cmd)
895 {
896     return m_user_dict.find(cmd) != m_user_dict.end();
897 }
898 
899 void
900 CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp)
901 {
902     command_obj_sp->SetIsAlias (true);
903     m_alias_dict[alias_name] = command_obj_sp;
904 }
905 
906 bool
907 CommandInterpreter::RemoveAlias (const char *alias_name)
908 {
909     CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name);
910     if (pos != m_alias_dict.end())
911     {
912         m_alias_dict.erase(pos);
913         return true;
914     }
915     return false;
916 }
917 bool
918 CommandInterpreter::RemoveUser (const char *alias_name)
919 {
920     CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name);
921     if (pos != m_user_dict.end())
922     {
923         m_user_dict.erase(pos);
924         return true;
925     }
926     return false;
927 }
928 
929 void
930 CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string)
931 {
932     help_string.Printf ("'%s", command_name);
933     OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
934 
935     if (option_arg_vector_sp)
936     {
937         OptionArgVector *options = option_arg_vector_sp.get();
938         for (int i = 0; i < options->size(); ++i)
939         {
940             OptionArgPair cur_option = (*options)[i];
941             std::string opt = cur_option.first;
942             OptionArgValue value_pair = cur_option.second;
943             std::string value = value_pair.second;
944             if (opt.compare("<argument>") == 0)
945             {
946                 help_string.Printf (" %s", value.c_str());
947             }
948             else
949             {
950                 help_string.Printf (" %s", opt.c_str());
951                 if ((value.compare ("<no-argument>") != 0)
952                     && (value.compare ("<need-argument") != 0))
953                 {
954                     help_string.Printf (" %s", value.c_str());
955                 }
956             }
957         }
958     }
959 
960     help_string.Printf ("'");
961 }
962 
963 size_t
964 CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict)
965 {
966     CommandObject::CommandMap::const_iterator pos;
967     CommandObject::CommandMap::const_iterator end = dict.end();
968     size_t max_len = 0;
969 
970     for (pos = dict.begin(); pos != end; ++pos)
971     {
972         size_t len = pos->first.size();
973         if (max_len < len)
974             max_len = len;
975     }
976     return max_len;
977 }
978 
979 void
980 CommandInterpreter::GetHelp (CommandReturnObject &result,
981                              uint32_t cmd_types)
982 {
983     CommandObject::CommandMap::const_iterator pos;
984     size_t max_len = FindLongestCommandWord (m_command_dict);
985 
986     if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
987     {
988 
989         result.AppendMessage("The following is a list of built-in, permanent debugger commands:");
990         result.AppendMessage("");
991 
992         for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
993         {
994             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
995                                      max_len);
996         }
997         result.AppendMessage("");
998 
999     }
1000 
1001     if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases ))
1002     {
1003         result.AppendMessage("The following is a list of your current command abbreviations "
1004                              "(see 'help command alias' for more info):");
1005         result.AppendMessage("");
1006         max_len = FindLongestCommandWord (m_alias_dict);
1007 
1008         for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos)
1009         {
1010             StreamString sstr;
1011             StreamString translation_and_help;
1012             std::string entry_name = pos->first;
1013             std::string second_entry = pos->second.get()->GetCommandName();
1014             GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr);
1015 
1016             translation_and_help.Printf ("(%s)  %s", sstr.GetData(), pos->second->GetHelp());
1017             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--",
1018                                      translation_and_help.GetData(), max_len);
1019         }
1020         result.AppendMessage("");
1021     }
1022 
1023     if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef ))
1024     {
1025         result.AppendMessage ("The following is a list of your current user-defined commands:");
1026         result.AppendMessage("");
1027         max_len = FindLongestCommandWord (m_user_dict);
1028         for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
1029         {
1030             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
1031                                      max_len);
1032         }
1033         result.AppendMessage("");
1034     }
1035 
1036     result.AppendMessage("For more information on any particular command, try 'help <command-name>'.");
1037 }
1038 
1039 CommandObject *
1040 CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
1041 {
1042     // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will
1043     // eventually be invoked by the given command line.
1044 
1045     CommandObject *cmd_obj = NULL;
1046     std::string white_space (" \t\v");
1047     size_t start = command_string.find_first_not_of (white_space);
1048     size_t end = 0;
1049     bool done = false;
1050     while (!done)
1051     {
1052         if (start != std::string::npos)
1053         {
1054             // Get the next word from command_string.
1055             end = command_string.find_first_of (white_space, start);
1056             if (end == std::string::npos)
1057                 end = command_string.size();
1058             std::string cmd_word = command_string.substr (start, end - start);
1059 
1060             if (cmd_obj == NULL)
1061                 // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid
1062                 // command or alias.
1063                 cmd_obj = GetCommandObject (cmd_word.c_str());
1064             else if (cmd_obj->IsMultiwordObject ())
1065             {
1066                 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object.
1067                 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str());
1068                 if (sub_cmd_obj)
1069                     cmd_obj = sub_cmd_obj;
1070                 else // cmd_word was not a valid sub-command word, so we are donee
1071                     done = true;
1072             }
1073             else
1074                 // We have a cmd_obj and it is not a multi-word object, so we are done.
1075                 done = true;
1076 
1077             // If we didn't find a valid command object, or our command object is not a multi-word object, or
1078             // we are at the end of the command_string, then we are done.  Otherwise, find the start of the
1079             // next word.
1080 
1081             if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size())
1082                 done = true;
1083             else
1084                 start = command_string.find_first_not_of (white_space, end);
1085         }
1086         else
1087             // Unable to find any more words.
1088             done = true;
1089     }
1090 
1091     if (end == command_string.size())
1092         command_string.clear();
1093     else
1094         command_string = command_string.substr(end);
1095 
1096     return cmd_obj;
1097 }
1098 
1099 static const char *k_white_space = " \t\v";
1100 static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1101 static void
1102 StripLeadingSpaces (std::string &s)
1103 {
1104     if (!s.empty())
1105     {
1106         size_t pos = s.find_first_not_of (k_white_space);
1107         if (pos == std::string::npos)
1108             s.clear();
1109         else if (pos == 0)
1110             return;
1111         s.erase (0, pos);
1112     }
1113 }
1114 
1115 static size_t
1116 FindArgumentTerminator (const std::string &s)
1117 {
1118     const size_t s_len = s.size();
1119     size_t offset = 0;
1120     while (offset < s_len)
1121     {
1122         size_t pos = s.find ("--", offset);
1123         if (pos == std::string::npos)
1124             break;
1125         if (pos > 0)
1126         {
1127             if (isspace(s[pos-1]))
1128             {
1129                 // Check if the string ends "\s--" (where \s is a space character)
1130                 // or if we have "\s--\s".
1131                 if ((pos + 2 >= s_len) || isspace(s[pos+2]))
1132                 {
1133                     return pos;
1134                 }
1135             }
1136         }
1137         offset = pos + 2;
1138     }
1139     return std::string::npos;
1140 }
1141 
1142 static bool
1143 ExtractCommand (std::string &command_string, std::string &command, std::string &suffix, char &quote_char)
1144 {
1145     command.clear();
1146     suffix.clear();
1147     StripLeadingSpaces (command_string);
1148 
1149     bool result = false;
1150     quote_char = '\0';
1151 
1152     if (!command_string.empty())
1153     {
1154         const char first_char = command_string[0];
1155         if (first_char == '\'' || first_char == '"')
1156         {
1157             quote_char = first_char;
1158             const size_t end_quote_pos = command_string.find (quote_char, 1);
1159             if (end_quote_pos == std::string::npos)
1160             {
1161                 command.swap (command_string);
1162                 command_string.erase ();
1163             }
1164             else
1165             {
1166                 command.assign (command_string, 1, end_quote_pos - 1);
1167                 if (end_quote_pos + 1 < command_string.size())
1168                     command_string.erase (0, command_string.find_first_not_of (k_white_space, end_quote_pos + 1));
1169                 else
1170                     command_string.erase ();
1171             }
1172         }
1173         else
1174         {
1175             const size_t first_space_pos = command_string.find_first_of (k_white_space);
1176             if (first_space_pos == std::string::npos)
1177             {
1178                 command.swap (command_string);
1179                 command_string.erase();
1180             }
1181             else
1182             {
1183                 command.assign (command_string, 0, first_space_pos);
1184                 command_string.erase(0, command_string.find_first_not_of (k_white_space, first_space_pos));
1185             }
1186         }
1187         result = true;
1188     }
1189 
1190 
1191     if (!command.empty())
1192     {
1193         // actual commands can't start with '-' or '_'
1194         if (command[0] != '-' && command[0] != '_')
1195         {
1196             size_t pos = command.find_first_not_of(k_valid_command_chars);
1197             if (pos > 0 && pos != std::string::npos)
1198             {
1199                 suffix.assign (command.begin() + pos, command.end());
1200                 command.erase (pos);
1201             }
1202         }
1203     }
1204 
1205     return result;
1206 }
1207 
1208 CommandObject *
1209 CommandInterpreter::BuildAliasResult (const char *alias_name,
1210                                       std::string &raw_input_string,
1211                                       std::string &alias_result,
1212                                       CommandReturnObject &result)
1213 {
1214     CommandObject *alias_cmd_obj = NULL;
1215     Args cmd_args (raw_input_string.c_str());
1216     alias_cmd_obj = GetCommandObject (alias_name);
1217     StreamString result_str;
1218 
1219     if (alias_cmd_obj)
1220     {
1221         std::string alias_name_str = alias_name;
1222         if ((cmd_args.GetArgumentCount() == 0)
1223             || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0))
1224             cmd_args.Unshift (alias_name);
1225 
1226         result_str.Printf ("%s", alias_cmd_obj->GetCommandName ());
1227         OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
1228 
1229         if (option_arg_vector_sp.get())
1230         {
1231             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
1232 
1233             for (int i = 0; i < option_arg_vector->size(); ++i)
1234             {
1235                 OptionArgPair option_pair = (*option_arg_vector)[i];
1236                 OptionArgValue value_pair = option_pair.second;
1237                 int value_type = value_pair.first;
1238                 std::string option = option_pair.first;
1239                 std::string value = value_pair.second;
1240                 if (option.compare ("<argument>") == 0)
1241                     result_str.Printf (" %s", value.c_str());
1242                 else
1243                 {
1244                     result_str.Printf (" %s", option.c_str());
1245                     if (value_type != optional_argument)
1246                         result_str.Printf (" ");
1247                     if (value.compare ("<no_argument>") != 0)
1248                     {
1249                         int index = GetOptionArgumentPosition (value.c_str());
1250                         if (index == 0)
1251                             result_str.Printf ("%s", value.c_str());
1252                         else if (index >= cmd_args.GetArgumentCount())
1253                         {
1254 
1255                             result.AppendErrorWithFormat
1256                             ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
1257                              index);
1258                             result.SetStatus (eReturnStatusFailed);
1259                             return alias_cmd_obj;
1260                         }
1261                         else
1262                         {
1263                             size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
1264                             if (strpos != std::string::npos)
1265                                 raw_input_string = raw_input_string.erase (strpos,
1266                                                                           strlen (cmd_args.GetArgumentAtIndex (index)));
1267                             result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index));
1268                         }
1269                     }
1270                 }
1271             }
1272         }
1273 
1274         alias_result = result_str.GetData();
1275     }
1276     return alias_cmd_obj;
1277 }
1278 
1279 Error
1280 CommandInterpreter::PreprocessCommand (std::string &command)
1281 {
1282     // The command preprocessor needs to do things to the command
1283     // line before any parsing of arguments or anything else is done.
1284     // The only current stuff that gets proprocessed is anyting enclosed
1285     // in backtick ('`') characters is evaluated as an expression and
1286     // the result of the expression must be a scalar that can be substituted
1287     // into the command. An example would be:
1288     // (lldb) memory read `$rsp + 20`
1289     Error error; // Error for any expressions that might not evaluate
1290     size_t start_backtick;
1291     size_t pos = 0;
1292     while ((start_backtick = command.find ('`', pos)) != std::string::npos)
1293     {
1294         if (start_backtick > 0 && command[start_backtick-1] == '\\')
1295         {
1296             // The backtick was preceeded by a '\' character, remove the slash
1297             // and don't treat the backtick as the start of an expression
1298             command.erase(start_backtick-1, 1);
1299             // No need to add one to start_backtick since we just deleted a char
1300             pos = start_backtick;
1301         }
1302         else
1303         {
1304             const size_t expr_content_start = start_backtick + 1;
1305             const size_t end_backtick = command.find ('`', expr_content_start);
1306             if (end_backtick == std::string::npos)
1307                 return error;
1308             else if (end_backtick == expr_content_start)
1309             {
1310                 // Empty expression (two backticks in a row)
1311                 command.erase (start_backtick, 2);
1312             }
1313             else
1314             {
1315                 std::string expr_str (command, expr_content_start, end_backtick - expr_content_start);
1316 
1317                 ExecutionContext exe_ctx(GetExecutionContext());
1318                 Target *target = exe_ctx.GetTargetPtr();
1319                 // Get a dummy target to allow for calculator mode while processing backticks.
1320                 // This also helps break the infinite loop caused when target is null.
1321                 if (!target)
1322                     target = Host::GetDummyTarget(GetDebugger()).get();
1323                 if (target)
1324                 {
1325                     ValueObjectSP expr_result_valobj_sp;
1326 
1327                     EvaluateExpressionOptions options;
1328                     options.SetCoerceToId(false)
1329                     .SetUnwindOnError(true)
1330                     .SetIgnoreBreakpoints(true)
1331                     .SetKeepInMemory(false)
1332                     .SetRunOthers(true)
1333                     .SetTimeoutUsec(0);
1334 
1335                     ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
1336                                                                                exe_ctx.GetFramePtr(),
1337                                                                                expr_result_valobj_sp,
1338                                                                                options);
1339 
1340                     if (expr_result == eExecutionCompleted)
1341                     {
1342                         Scalar scalar;
1343                         if (expr_result_valobj_sp->ResolveValue (scalar))
1344                         {
1345                             command.erase (start_backtick, end_backtick - start_backtick + 1);
1346                             StreamString value_strm;
1347                             const bool show_type = false;
1348                             scalar.GetValue (&value_strm, show_type);
1349                             size_t value_string_size = value_strm.GetSize();
1350                             if (value_string_size)
1351                             {
1352                                 command.insert (start_backtick, value_strm.GetData(), value_string_size);
1353                                 pos = start_backtick + value_string_size;
1354                                 continue;
1355                             }
1356                             else
1357                             {
1358                                 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
1359                             }
1360                         }
1361                         else
1362                         {
1363                             error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
1364                         }
1365                     }
1366                     else
1367                     {
1368                         if (expr_result_valobj_sp)
1369                             error = expr_result_valobj_sp->GetError();
1370                         if (error.Success())
1371                         {
1372 
1373                             switch (expr_result)
1374                             {
1375                                 case eExecutionSetupError:
1376                                     error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str());
1377                                     break;
1378                                 case eExecutionCompleted:
1379                                     break;
1380                                 case eExecutionDiscarded:
1381                                     error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str());
1382                                     break;
1383                                 case eExecutionInterrupted:
1384                                     error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str());
1385                                     break;
1386                                 case eExecutionHitBreakpoint:
1387                                     error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str());
1388                                     break;
1389                                 case eExecutionTimedOut:
1390                                     error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str());
1391                                     break;
1392                             }
1393                         }
1394                     }
1395                 }
1396             }
1397             if (error.Fail())
1398                 break;
1399         }
1400     }
1401     return error;
1402 }
1403 
1404 
1405 bool
1406 CommandInterpreter::HandleCommand (const char *command_line,
1407                                    LazyBool lazy_add_to_history,
1408                                    CommandReturnObject &result,
1409                                    ExecutionContext *override_context,
1410                                    bool repeat_on_empty_command,
1411                                    bool no_context_switching)
1412 
1413 {
1414 
1415     bool done = false;
1416     CommandObject *cmd_obj = NULL;
1417     bool wants_raw_input = false;
1418     std::string command_string (command_line);
1419     std::string original_command_string (command_line);
1420 
1421     LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
1422     Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line);
1423 
1424     // Make a scoped cleanup object that will clear the crash description string
1425     // on exit of this function.
1426     lldb_utility::CleanUp <const char *> crash_description_cleanup(NULL, Host::SetCrashDescription);
1427 
1428     if (log)
1429         log->Printf ("Processing command: %s", command_line);
1430 
1431     Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line);
1432 
1433     if (!no_context_switching)
1434         UpdateExecutionContext (override_context);
1435 
1436     // <rdar://problem/11328896>
1437     bool add_to_history;
1438     if (lazy_add_to_history == eLazyBoolCalculate)
1439         add_to_history = (m_command_source_depth == 0);
1440     else
1441         add_to_history = (lazy_add_to_history == eLazyBoolYes);
1442 
1443     bool empty_command = false;
1444     bool comment_command = false;
1445     if (command_string.empty())
1446         empty_command = true;
1447     else
1448     {
1449         const char *k_space_characters = "\t\n\v\f\r ";
1450 
1451         size_t non_space = command_string.find_first_not_of (k_space_characters);
1452         // Check for empty line or comment line (lines whose first
1453         // non-space character is the comment character for this interpreter)
1454         if (non_space == std::string::npos)
1455             empty_command = true;
1456         else if (command_string[non_space] == m_comment_char)
1457              comment_command = true;
1458         else if (command_string[non_space] == m_repeat_char)
1459         {
1460             const char *history_string = FindHistoryString (command_string.c_str() + non_space);
1461             if (history_string == NULL)
1462             {
1463                 result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str());
1464                 result.SetStatus(eReturnStatusFailed);
1465                 return false;
1466             }
1467             add_to_history = false;
1468             command_string = history_string;
1469             original_command_string = history_string;
1470         }
1471     }
1472 
1473     if (empty_command)
1474     {
1475         if (repeat_on_empty_command)
1476         {
1477             if (m_command_history.empty())
1478             {
1479                 result.AppendError ("empty command");
1480                 result.SetStatus(eReturnStatusFailed);
1481                 return false;
1482             }
1483             else
1484             {
1485                 command_line = m_repeat_command.c_str();
1486                 command_string = command_line;
1487                 original_command_string = command_line;
1488                 if (m_repeat_command.empty())
1489                 {
1490                     result.AppendErrorWithFormat("No auto repeat.\n");
1491                     result.SetStatus (eReturnStatusFailed);
1492                     return false;
1493                 }
1494             }
1495             add_to_history = false;
1496         }
1497         else
1498         {
1499             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1500             return true;
1501         }
1502     }
1503     else if (comment_command)
1504     {
1505         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1506         return true;
1507     }
1508 
1509 
1510     Error error (PreprocessCommand (command_string));
1511 
1512     if (error.Fail())
1513     {
1514         result.AppendError (error.AsCString());
1515         result.SetStatus(eReturnStatusFailed);
1516         return false;
1517     }
1518     // Phase 1.
1519 
1520     // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object
1521     // is for the specified command, and whether or not it wants raw input.  This gets complicated by the fact that
1522     // the user could have specified an alias, and in translating the alias there may also be command options and/or
1523     // even data (including raw text strings) that need to be found and inserted into the command line as part of
1524     // the translation.  So this first step is plain look-up & replacement, resulting in three things:  1). the command
1525     // object whose Execute method will actually be called; 2). a revised command string, with all substitutions &
1526     // replacements taken care of; 3). whether or not the Execute function wants raw input or not.
1527 
1528     StreamString revised_command_line;
1529     size_t actual_cmd_name_len = 0;
1530     std::string next_word;
1531     StringList matches;
1532     while (!done)
1533     {
1534         char quote_char = '\0';
1535         std::string suffix;
1536         ExtractCommand (command_string, next_word, suffix, quote_char);
1537         if (cmd_obj == NULL)
1538         {
1539             if (AliasExists (next_word.c_str()))
1540             {
1541                 std::string alias_result;
1542                 cmd_obj = BuildAliasResult (next_word.c_str(), command_string, alias_result, result);
1543                 revised_command_line.Printf ("%s", alias_result.c_str());
1544                 if (cmd_obj)
1545                 {
1546                     wants_raw_input = cmd_obj->WantsRawCommandString ();
1547                     actual_cmd_name_len = strlen (cmd_obj->GetCommandName());
1548                 }
1549             }
1550             else
1551             {
1552                 cmd_obj = GetCommandObject (next_word.c_str(), &matches);
1553                 if (cmd_obj)
1554                 {
1555                     actual_cmd_name_len += next_word.length();
1556                     revised_command_line.Printf ("%s", next_word.c_str());
1557                     wants_raw_input = cmd_obj->WantsRawCommandString ();
1558                 }
1559                 else
1560                 {
1561                     revised_command_line.Printf ("%s", next_word.c_str());
1562                 }
1563             }
1564         }
1565         else
1566         {
1567             if (cmd_obj->IsMultiwordObject ())
1568             {
1569                 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str());
1570                 if (sub_cmd_obj)
1571                 {
1572                     actual_cmd_name_len += next_word.length() + 1;
1573                     revised_command_line.Printf (" %s", next_word.c_str());
1574                     cmd_obj = sub_cmd_obj;
1575                     wants_raw_input = cmd_obj->WantsRawCommandString ();
1576                 }
1577                 else
1578                 {
1579                     if (quote_char)
1580                         revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
1581                     else
1582                         revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str());
1583                     done = true;
1584                 }
1585             }
1586             else
1587             {
1588                 if (quote_char)
1589                     revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
1590                 else
1591                     revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str());
1592                 done = true;
1593             }
1594         }
1595 
1596         if (cmd_obj == NULL)
1597         {
1598             const size_t num_matches = matches.GetSize();
1599             if (matches.GetSize() > 1) {
1600                 StreamString error_msg;
1601                 error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
1602 
1603                 for (uint32_t i = 0; i < num_matches; ++i) {
1604                     error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i));
1605                 }
1606                 result.AppendRawError (error_msg.GetString().c_str());
1607             } else {
1608                 // We didn't have only one match, otherwise we wouldn't get here.
1609                 assert(num_matches == 0);
1610                 result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str());
1611             }
1612             result.SetStatus (eReturnStatusFailed);
1613             return false;
1614         }
1615 
1616         if (cmd_obj->IsMultiwordObject ())
1617         {
1618             if (!suffix.empty())
1619             {
1620 
1621                 result.AppendErrorWithFormat ("multi-word commands ('%s') can't have shorthand suffixes: '%s'\n",
1622                                               next_word.c_str(),
1623                                               suffix.c_str());
1624                 result.SetStatus (eReturnStatusFailed);
1625                 return false;
1626             }
1627         }
1628         else
1629         {
1630             // If we found a normal command, we are done
1631             done = true;
1632             if (!suffix.empty())
1633             {
1634                 switch (suffix[0])
1635                 {
1636                 case '/':
1637                     // GDB format suffixes
1638                     {
1639                         Options *command_options = cmd_obj->GetOptions();
1640                         if (command_options && command_options->SupportsLongOption("gdb-format"))
1641                         {
1642                             std::string gdb_format_option ("--gdb-format=");
1643                             gdb_format_option += (suffix.c_str() + 1);
1644 
1645                             bool inserted = false;
1646                             std::string &cmd = revised_command_line.GetString();
1647                             size_t arg_terminator_idx = FindArgumentTerminator (cmd);
1648                             if (arg_terminator_idx != std::string::npos)
1649                             {
1650                                 // Insert the gdb format option before the "--" that terminates options
1651                                 gdb_format_option.append(1,' ');
1652                                 cmd.insert(arg_terminator_idx, gdb_format_option);
1653                                 inserted = true;
1654                             }
1655 
1656                             if (!inserted)
1657                                 revised_command_line.Printf (" %s", gdb_format_option.c_str());
1658 
1659                             if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos)
1660                                 revised_command_line.PutCString (" --");
1661                         }
1662                         else
1663                         {
1664                             result.AppendErrorWithFormat ("the '%s' command doesn't support the --gdb-format option\n",
1665                                                           cmd_obj->GetCommandName());
1666                             result.SetStatus (eReturnStatusFailed);
1667                             return false;
1668                         }
1669                     }
1670                     break;
1671 
1672                 default:
1673                     result.AppendErrorWithFormat ("unknown command shorthand suffix: '%s'\n",
1674                                                   suffix.c_str());
1675                     result.SetStatus (eReturnStatusFailed);
1676                     return false;
1677 
1678                 }
1679             }
1680         }
1681         if (command_string.length() == 0)
1682             done = true;
1683 
1684     }
1685 
1686     if (!command_string.empty())
1687         revised_command_line.Printf (" %s", command_string.c_str());
1688 
1689     // End of Phase 1.
1690     // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command
1691     // specified was valid; revised_command_line contains the complete command line (including command name(s)),
1692     // fully translated with all substitutions & translations taken care of (still in raw text format); and
1693     // wants_raw_input specifies whether the Execute method expects raw input or not.
1694 
1695 
1696     if (log)
1697     {
1698         log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>");
1699         log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData());
1700         log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False");
1701     }
1702 
1703     // Phase 2.
1704     // Take care of things like setting up the history command & calling the appropriate Execute method on the
1705     // CommandObject, with the appropriate arguments.
1706 
1707     if (cmd_obj != NULL)
1708     {
1709         if (add_to_history)
1710         {
1711             Args command_args (revised_command_line.GetData());
1712             const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0);
1713             if (repeat_command != NULL)
1714                 m_repeat_command.assign(repeat_command);
1715             else
1716                 m_repeat_command.assign(original_command_string.c_str());
1717 
1718             // Don't keep pushing the same command onto the history...
1719             if (m_command_history.empty() || m_command_history.back() != original_command_string)
1720                 m_command_history.push_back (original_command_string);
1721         }
1722 
1723         command_string = revised_command_line.GetData();
1724         std::string command_name (cmd_obj->GetCommandName());
1725         std::string remainder;
1726         if (actual_cmd_name_len < command_string.length())
1727             remainder = command_string.substr (actual_cmd_name_len);  // Note: 'actual_cmd_name_len' may be considerably shorter
1728                                                            // than cmd_obj->GetCommandName(), because name completion
1729                                                            // allows users to enter short versions of the names,
1730                                                            // e.g. 'br s' for 'breakpoint set'.
1731 
1732         // Remove any initial spaces
1733         std::string white_space (" \t\v");
1734         size_t pos = remainder.find_first_not_of (white_space);
1735         if (pos != 0 && pos != std::string::npos)
1736             remainder.erase(0, pos);
1737 
1738         if (log)
1739             log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str());
1740 
1741         cmd_obj->Execute (remainder.c_str(), result);
1742     }
1743     else
1744     {
1745         // We didn't find the first command object, so complete the first argument.
1746         Args command_args (revised_command_line.GetData());
1747         StringList matches;
1748         int num_matches;
1749         int cursor_index = 0;
1750         int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0));
1751         bool word_complete;
1752         num_matches = HandleCompletionMatches (command_args,
1753                                                cursor_index,
1754                                                cursor_char_position,
1755                                                0,
1756                                                -1,
1757                                                word_complete,
1758                                                matches);
1759 
1760         if (num_matches > 0)
1761         {
1762             std::string error_msg;
1763             error_msg.assign ("ambiguous command '");
1764             error_msg.append(command_args.GetArgumentAtIndex(0));
1765             error_msg.append ("'.");
1766 
1767             error_msg.append (" Possible completions:");
1768             for (int i = 0; i < num_matches; i++)
1769             {
1770                 error_msg.append ("\n\t");
1771                 error_msg.append (matches.GetStringAtIndex (i));
1772             }
1773             error_msg.append ("\n");
1774             result.AppendRawError (error_msg.c_str());
1775         }
1776         else
1777             result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0));
1778 
1779         result.SetStatus (eReturnStatusFailed);
1780     }
1781 
1782     if (log)
1783       log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed"));
1784 
1785     return result.Succeeded();
1786 }
1787 
1788 int
1789 CommandInterpreter::HandleCompletionMatches (Args &parsed_line,
1790                                              int &cursor_index,
1791                                              int &cursor_char_position,
1792                                              int match_start_point,
1793                                              int max_return_elements,
1794                                              bool &word_complete,
1795                                              StringList &matches)
1796 {
1797     int num_command_matches = 0;
1798     bool look_for_subcommand = false;
1799 
1800     // For any of the command completions a unique match will be a complete word.
1801     word_complete = true;
1802 
1803     if (cursor_index == -1)
1804     {
1805         // We got nothing on the command line, so return the list of commands
1806         bool include_aliases = true;
1807         num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches);
1808     }
1809     else if (cursor_index == 0)
1810     {
1811         // The cursor is in the first argument, so just do a lookup in the dictionary.
1812         CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches);
1813         num_command_matches = matches.GetSize();
1814 
1815         if (num_command_matches == 1
1816             && cmd_obj && cmd_obj->IsMultiwordObject()
1817             && matches.GetStringAtIndex(0) != NULL
1818             && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0)
1819         {
1820             look_for_subcommand = true;
1821             num_command_matches = 0;
1822             matches.DeleteStringAtIndex(0);
1823             parsed_line.AppendArgument ("");
1824             cursor_index++;
1825             cursor_char_position = 0;
1826         }
1827     }
1828 
1829     if (cursor_index > 0 || look_for_subcommand)
1830     {
1831         // We are completing further on into a commands arguments, so find the command and tell it
1832         // to complete the command.
1833         // First see if there is a matching initial command:
1834         CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0));
1835         if (command_object == NULL)
1836         {
1837             return 0;
1838         }
1839         else
1840         {
1841             parsed_line.Shift();
1842             cursor_index--;
1843             num_command_matches = command_object->HandleCompletion (parsed_line,
1844                                                                     cursor_index,
1845                                                                     cursor_char_position,
1846                                                                     match_start_point,
1847                                                                     max_return_elements,
1848                                                                     word_complete,
1849                                                                     matches);
1850         }
1851     }
1852 
1853     return num_command_matches;
1854 
1855 }
1856 
1857 int
1858 CommandInterpreter::HandleCompletion (const char *current_line,
1859                                       const char *cursor,
1860                                       const char *last_char,
1861                                       int match_start_point,
1862                                       int max_return_elements,
1863                                       StringList &matches)
1864 {
1865     // We parse the argument up to the cursor, so the last argument in parsed_line is
1866     // the one containing the cursor, and the cursor is after the last character.
1867 
1868     Args parsed_line(current_line, last_char - current_line);
1869     Args partial_parsed_line(current_line, cursor - current_line);
1870 
1871     // Don't complete comments, and if the line we are completing is just the history repeat character,
1872     // substitute the appropriate history line.
1873     const char *first_arg = parsed_line.GetArgumentAtIndex(0);
1874     if (first_arg)
1875     {
1876         if (first_arg[0] == m_comment_char)
1877             return 0;
1878         else if (first_arg[0] == m_repeat_char)
1879         {
1880             const char *history_string = FindHistoryString (first_arg);
1881             if (history_string != NULL)
1882             {
1883                 matches.Clear();
1884                 matches.InsertStringAtIndex(0, history_string);
1885                 return -2;
1886             }
1887             else
1888                 return 0;
1889 
1890         }
1891     }
1892 
1893 
1894     int num_args = partial_parsed_line.GetArgumentCount();
1895     int cursor_index = partial_parsed_line.GetArgumentCount() - 1;
1896     int cursor_char_position;
1897 
1898     if (cursor_index == -1)
1899         cursor_char_position = 0;
1900     else
1901         cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index));
1902 
1903     if (cursor > current_line && cursor[-1] == ' ')
1904     {
1905         // We are just after a space.  If we are in an argument, then we will continue
1906         // parsing, but if we are between arguments, then we have to complete whatever the next
1907         // element would be.
1908         // We can distinguish the two cases because if we are in an argument (e.g. because the space is
1909         // protected by a quote) then the space will also be in the parsed argument...
1910 
1911         const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index);
1912         if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ')
1913         {
1914             parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '"');
1915             cursor_index++;
1916             cursor_char_position = 0;
1917         }
1918     }
1919 
1920     int num_command_matches;
1921 
1922     matches.Clear();
1923 
1924     // Only max_return_elements == -1 is supported at present:
1925     assert (max_return_elements == -1);
1926     bool word_complete;
1927     num_command_matches = HandleCompletionMatches (parsed_line,
1928                                                    cursor_index,
1929                                                    cursor_char_position,
1930                                                    match_start_point,
1931                                                    max_return_elements,
1932                                                    word_complete,
1933                                                    matches);
1934 
1935     if (num_command_matches <= 0)
1936             return num_command_matches;
1937 
1938     if (num_args == 0)
1939     {
1940         // If we got an empty string, insert nothing.
1941         matches.InsertStringAtIndex(0, "");
1942     }
1943     else
1944     {
1945         // Now figure out if there is a common substring, and if so put that in element 0, otherwise
1946         // put an empty string in element 0.
1947         std::string command_partial_str;
1948         if (cursor_index >= 0)
1949             command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index),
1950                                        parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position);
1951 
1952         std::string common_prefix;
1953         matches.LongestCommonPrefix (common_prefix);
1954         const size_t partial_name_len = command_partial_str.size();
1955 
1956         // If we matched a unique single command, add a space...
1957         // Only do this if the completer told us this was a complete word, however...
1958         if (num_command_matches == 1 && word_complete)
1959         {
1960             char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index);
1961             if (quote_char != '\0')
1962                 common_prefix.push_back(quote_char);
1963 
1964             common_prefix.push_back(' ');
1965         }
1966         common_prefix.erase (0, partial_name_len);
1967         matches.InsertStringAtIndex(0, common_prefix.c_str());
1968     }
1969     return num_command_matches;
1970 }
1971 
1972 
1973 CommandInterpreter::~CommandInterpreter ()
1974 {
1975 }
1976 
1977 const char *
1978 CommandInterpreter::GetPrompt ()
1979 {
1980     return m_debugger.GetPrompt();
1981 }
1982 
1983 void
1984 CommandInterpreter::SetPrompt (const char *new_prompt)
1985 {
1986     m_debugger.SetPrompt (new_prompt);
1987 }
1988 
1989 size_t
1990 CommandInterpreter::GetConfirmationInputReaderCallback
1991 (
1992     void *baton,
1993     InputReader &reader,
1994     lldb::InputReaderAction action,
1995     const char *bytes,
1996     size_t bytes_len
1997 )
1998 {
1999     File &out_file = reader.GetDebugger().GetOutputFile();
2000     bool *response_ptr = (bool *) baton;
2001 
2002     switch (action)
2003     {
2004     case eInputReaderActivate:
2005         if (out_file.IsValid())
2006         {
2007             if (reader.GetPrompt())
2008             {
2009                 out_file.Printf ("%s", reader.GetPrompt());
2010                 out_file.Flush ();
2011             }
2012         }
2013         break;
2014 
2015     case eInputReaderDeactivate:
2016         break;
2017 
2018     case eInputReaderReactivate:
2019         if (out_file.IsValid() && reader.GetPrompt())
2020         {
2021             out_file.Printf ("%s", reader.GetPrompt());
2022             out_file.Flush ();
2023         }
2024         break;
2025 
2026     case eInputReaderAsynchronousOutputWritten:
2027         break;
2028 
2029     case eInputReaderGotToken:
2030         if (bytes_len == 0)
2031         {
2032             reader.SetIsDone(true);
2033         }
2034         else if (bytes[0] == 'y' || bytes[0] == 'Y')
2035         {
2036             *response_ptr = true;
2037             reader.SetIsDone(true);
2038         }
2039         else if (bytes[0] == 'n' || bytes[0] == 'N')
2040         {
2041             *response_ptr = false;
2042             reader.SetIsDone(true);
2043         }
2044         else
2045         {
2046             if (out_file.IsValid() && !reader.IsDone() && reader.GetPrompt())
2047             {
2048                 out_file.Printf ("Please answer \"y\" or \"n\".\n%s", reader.GetPrompt());
2049                 out_file.Flush ();
2050             }
2051         }
2052         break;
2053 
2054     case eInputReaderInterrupt:
2055     case eInputReaderEndOfFile:
2056         *response_ptr = false;  // Assume ^C or ^D means cancel the proposed action
2057         reader.SetIsDone (true);
2058         break;
2059 
2060     case eInputReaderDone:
2061         break;
2062     }
2063 
2064     return bytes_len;
2065 
2066 }
2067 
2068 bool
2069 CommandInterpreter::Confirm (const char *message, bool default_answer)
2070 {
2071     // Check AutoConfirm first:
2072     if (m_debugger.GetAutoConfirm())
2073         return default_answer;
2074 
2075     InputReaderSP reader_sp (new InputReader(GetDebugger()));
2076     bool response = default_answer;
2077     if (reader_sp)
2078     {
2079         std::string prompt(message);
2080         prompt.append(": [");
2081         if (default_answer)
2082             prompt.append ("Y/n] ");
2083         else
2084             prompt.append ("y/N] ");
2085 
2086         Error err (reader_sp->Initialize (CommandInterpreter::GetConfirmationInputReaderCallback,
2087                                           &response,                    // baton
2088                                           eInputReaderGranularityLine,  // token size, to pass to callback function
2089                                           NULL,                         // end token
2090                                           prompt.c_str(),               // prompt
2091                                           true));                       // echo input
2092         if (err.Success())
2093         {
2094             GetDebugger().PushInputReader (reader_sp);
2095         }
2096         reader_sp->WaitOnReaderIsDone();
2097     }
2098     return response;
2099 }
2100 
2101 
2102 void
2103 CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type)
2104 {
2105     CommandObjectSP cmd_obj_sp = GetCommandSPExact (dest_cmd, true);
2106 
2107     if (cmd_obj_sp)
2108     {
2109         CommandObject *cmd_obj = cmd_obj_sp.get();
2110         if (cmd_obj->IsCrossRefObject ())
2111             cmd_obj->AddObject (object_type);
2112     }
2113 }
2114 
2115 OptionArgVectorSP
2116 CommandInterpreter::GetAliasOptions (const char *alias_name)
2117 {
2118     OptionArgMap::iterator pos;
2119     OptionArgVectorSP ret_val;
2120 
2121     std::string alias (alias_name);
2122 
2123     if (HasAliasOptions())
2124     {
2125         pos = m_alias_options.find (alias);
2126         if (pos != m_alias_options.end())
2127           ret_val = pos->second;
2128     }
2129 
2130     return ret_val;
2131 }
2132 
2133 void
2134 CommandInterpreter::RemoveAliasOptions (const char *alias_name)
2135 {
2136     OptionArgMap::iterator pos = m_alias_options.find(alias_name);
2137     if (pos != m_alias_options.end())
2138     {
2139         m_alias_options.erase (pos);
2140     }
2141 }
2142 
2143 void
2144 CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp)
2145 {
2146     m_alias_options[alias_name] = option_arg_vector_sp;
2147 }
2148 
2149 bool
2150 CommandInterpreter::HasCommands ()
2151 {
2152     return (!m_command_dict.empty());
2153 }
2154 
2155 bool
2156 CommandInterpreter::HasAliases ()
2157 {
2158     return (!m_alias_dict.empty());
2159 }
2160 
2161 bool
2162 CommandInterpreter::HasUserCommands ()
2163 {
2164     return (!m_user_dict.empty());
2165 }
2166 
2167 bool
2168 CommandInterpreter::HasAliasOptions ()
2169 {
2170     return (!m_alias_options.empty());
2171 }
2172 
2173 void
2174 CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
2175                                            const char *alias_name,
2176                                            Args &cmd_args,
2177                                            std::string &raw_input_string,
2178                                            CommandReturnObject &result)
2179 {
2180     OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
2181 
2182     bool wants_raw_input = alias_cmd_obj->WantsRawCommandString();
2183 
2184     // Make sure that the alias name is the 0th element in cmd_args
2185     std::string alias_name_str = alias_name;
2186     if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)
2187         cmd_args.Unshift (alias_name);
2188 
2189     Args new_args (alias_cmd_obj->GetCommandName());
2190     if (new_args.GetArgumentCount() == 2)
2191         new_args.Shift();
2192 
2193     if (option_arg_vector_sp.get())
2194     {
2195         if (wants_raw_input)
2196         {
2197             // We have a command that both has command options and takes raw input.  Make *sure* it has a
2198             // " -- " in the right place in the raw_input_string.
2199             size_t pos = raw_input_string.find(" -- ");
2200             if (pos == std::string::npos)
2201             {
2202                 // None found; assume it goes at the beginning of the raw input string
2203                 raw_input_string.insert (0, " -- ");
2204             }
2205         }
2206 
2207         OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
2208         const size_t old_size = cmd_args.GetArgumentCount();
2209         std::vector<bool> used (old_size + 1, false);
2210 
2211         used[0] = true;
2212 
2213         for (int i = 0; i < option_arg_vector->size(); ++i)
2214         {
2215             OptionArgPair option_pair = (*option_arg_vector)[i];
2216             OptionArgValue value_pair = option_pair.second;
2217             int value_type = value_pair.first;
2218             std::string option = option_pair.first;
2219             std::string value = value_pair.second;
2220             if (option.compare ("<argument>") == 0)
2221             {
2222                 if (!wants_raw_input
2223                     || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice
2224                     new_args.AppendArgument (value.c_str());
2225             }
2226             else
2227             {
2228                 if (value_type != optional_argument)
2229                     new_args.AppendArgument (option.c_str());
2230                 if (value.compare ("<no-argument>") != 0)
2231                 {
2232                     int index = GetOptionArgumentPosition (value.c_str());
2233                     if (index == 0)
2234                     {
2235                         // value was NOT a positional argument; must be a real value
2236                         if (value_type != optional_argument)
2237                             new_args.AppendArgument (value.c_str());
2238                         else
2239                         {
2240                             char buffer[255];
2241                             ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str());
2242                             new_args.AppendArgument (buffer);
2243                         }
2244 
2245                     }
2246                     else if (index >= cmd_args.GetArgumentCount())
2247                     {
2248                         result.AppendErrorWithFormat
2249                                     ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
2250                                      index);
2251                         result.SetStatus (eReturnStatusFailed);
2252                         return;
2253                     }
2254                     else
2255                     {
2256                         // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string
2257                         size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
2258                         if (strpos != std::string::npos)
2259                         {
2260                             raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index)));
2261                         }
2262 
2263                         if (value_type != optional_argument)
2264                             new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index));
2265                         else
2266                         {
2267                             char buffer[255];
2268                             ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(),
2269                                         cmd_args.GetArgumentAtIndex (index));
2270                             new_args.AppendArgument (buffer);
2271                         }
2272                         used[index] = true;
2273                     }
2274                 }
2275             }
2276         }
2277 
2278         for (int j = 0; j < cmd_args.GetArgumentCount(); ++j)
2279         {
2280             if (!used[j] && !wants_raw_input)
2281                 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j));
2282         }
2283 
2284         cmd_args.Clear();
2285         cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
2286     }
2287     else
2288     {
2289         result.SetStatus (eReturnStatusSuccessFinishNoResult);
2290         // This alias was not created with any options; nothing further needs to be done, unless it is a command that
2291         // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw
2292         // input string.
2293         if (wants_raw_input)
2294         {
2295             cmd_args.Clear();
2296             cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
2297         }
2298         return;
2299     }
2300 
2301     result.SetStatus (eReturnStatusSuccessFinishNoResult);
2302     return;
2303 }
2304 
2305 
2306 int
2307 CommandInterpreter::GetOptionArgumentPosition (const char *in_string)
2308 {
2309     int position = 0;   // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position
2310                         // of zero.
2311 
2312     char *cptr = (char *) in_string;
2313 
2314     // Does it start with '%'
2315     if (cptr[0] == '%')
2316     {
2317         ++cptr;
2318 
2319         // Is the rest of it entirely digits?
2320         if (isdigit (cptr[0]))
2321         {
2322             const char *start = cptr;
2323             while (isdigit (cptr[0]))
2324                 ++cptr;
2325 
2326             // We've gotten to the end of the digits; are we at the end of the string?
2327             if (cptr[0] == '\0')
2328                 position = atoi (start);
2329         }
2330     }
2331 
2332     return position;
2333 }
2334 
2335 void
2336 CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
2337 {
2338     FileSpec init_file;
2339     if (in_cwd)
2340     {
2341         // In the current working directory we don't load any program specific
2342         // .lldbinit files, we only look for a "./.lldbinit" file.
2343         if (m_skip_lldbinit_files)
2344             return;
2345 
2346         init_file.SetFile ("./.lldbinit", true);
2347     }
2348     else
2349     {
2350         // If we aren't looking in the current working directory we are looking
2351         // in the home directory. We will first see if there is an application
2352         // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a
2353         // "-" and the name of the program. If this file doesn't exist, we fall
2354         // back to just the "~/.lldbinit" file. We also obey any requests to not
2355         // load the init files.
2356         const char *init_file_path = "~/.lldbinit";
2357 
2358         if (m_skip_app_init_files == false)
2359         {
2360             FileSpec program_file_spec (Host::GetProgramFileSpec());
2361             const char *program_name = program_file_spec.GetFilename().AsCString();
2362 
2363             if (program_name)
2364             {
2365                 char program_init_file_name[PATH_MAX];
2366                 ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path, program_name);
2367                 init_file.SetFile (program_init_file_name, true);
2368                 if (!init_file.Exists())
2369                     init_file.Clear();
2370             }
2371         }
2372 
2373         if (!init_file && !m_skip_lldbinit_files)
2374 			init_file.SetFile (init_file_path, true);
2375     }
2376 
2377     // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting
2378     // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details).
2379 
2380     if (init_file.Exists())
2381     {
2382         ExecutionContext *exe_ctx = NULL;  // We don't have any context yet.
2383         bool stop_on_continue = true;
2384         bool stop_on_error    = false;
2385         bool echo_commands    = false;
2386         bool print_results    = false;
2387 
2388         HandleCommandsFromFile (init_file, exe_ctx, stop_on_continue, stop_on_error, echo_commands, print_results, eLazyBoolNo, result);
2389     }
2390     else
2391     {
2392         // nothing to be done if the file doesn't exist
2393         result.SetStatus(eReturnStatusSuccessFinishNoResult);
2394     }
2395 }
2396 
2397 PlatformSP
2398 CommandInterpreter::GetPlatform (bool prefer_target_platform)
2399 {
2400     PlatformSP platform_sp;
2401     if (prefer_target_platform)
2402     {
2403         ExecutionContext exe_ctx(GetExecutionContext());
2404         Target *target = exe_ctx.GetTargetPtr();
2405         if (target)
2406             platform_sp = target->GetPlatform();
2407     }
2408 
2409     if (!platform_sp)
2410         platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform();
2411     return platform_sp;
2412 }
2413 
2414 void
2415 CommandInterpreter::HandleCommands (const StringList &commands,
2416                                     ExecutionContext *override_context,
2417                                     bool stop_on_continue,
2418                                     bool stop_on_error,
2419                                     bool echo_commands,
2420                                     bool print_results,
2421                                     LazyBool add_to_history,
2422                                     CommandReturnObject &result)
2423 {
2424     size_t num_lines = commands.GetSize();
2425 
2426     // If we are going to continue past a "continue" then we need to run the commands synchronously.
2427     // Make sure you reset this value anywhere you return from the function.
2428 
2429     bool old_async_execution = m_debugger.GetAsyncExecution();
2430 
2431     // If we've been given an execution context, set it at the start, but don't keep resetting it or we will
2432     // cause series of commands that change the context, then do an operation that relies on that context to fail.
2433 
2434     if (override_context != NULL)
2435         UpdateExecutionContext (override_context);
2436 
2437     if (!stop_on_continue)
2438     {
2439         m_debugger.SetAsyncExecution (false);
2440     }
2441 
2442     for (int idx = 0; idx < num_lines; idx++)
2443     {
2444         const char *cmd = commands.GetStringAtIndex(idx);
2445         if (cmd[0] == '\0')
2446             continue;
2447 
2448         if (echo_commands)
2449         {
2450             result.AppendMessageWithFormat ("%s %s\n",
2451                                              GetPrompt(),
2452                                              cmd);
2453         }
2454 
2455         CommandReturnObject tmp_result;
2456         // If override_context is not NULL, pass no_context_switching = true for
2457         // HandleCommand() since we updated our context already.
2458         bool success = HandleCommand(cmd, add_to_history, tmp_result,
2459                                      NULL, /* override_context */
2460                                      true, /* repeat_on_empty_command */
2461                                      override_context != NULL /* no_context_switching */);
2462 
2463         if (print_results)
2464         {
2465             if (tmp_result.Succeeded())
2466               result.AppendMessageWithFormat("%s", tmp_result.GetOutputData());
2467         }
2468 
2469         if (!success || !tmp_result.Succeeded())
2470         {
2471             const char *error_msg = tmp_result.GetErrorData();
2472             if (error_msg == NULL || error_msg[0] == '\0')
2473                 error_msg = "<unknown error>.\n";
2474             if (stop_on_error)
2475             {
2476                 result.AppendErrorWithFormat("Aborting reading of commands after command #%d: '%s' failed with %s",
2477                                          idx, cmd, error_msg);
2478                 result.SetStatus (eReturnStatusFailed);
2479                 m_debugger.SetAsyncExecution (old_async_execution);
2480                 return;
2481             }
2482             else if (print_results)
2483             {
2484                 result.AppendMessageWithFormat ("Command #%d '%s' failed with %s",
2485                                                 idx + 1,
2486                                                 cmd,
2487                                                 error_msg);
2488             }
2489         }
2490 
2491         if (result.GetImmediateOutputStream())
2492             result.GetImmediateOutputStream()->Flush();
2493 
2494         if (result.GetImmediateErrorStream())
2495             result.GetImmediateErrorStream()->Flush();
2496 
2497         // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution
2498         // could be running (for instance in Breakpoint Commands.
2499         // So we check the return value to see if it is has running in it.
2500         if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
2501                 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult))
2502         {
2503             if (stop_on_continue)
2504             {
2505                 // If we caused the target to proceed, and we're going to stop in that case, set the
2506                 // status in our real result before returning.  This is an error if the continue was not the
2507                 // last command in the set of commands to be run.
2508                 if (idx != num_lines - 1)
2509                     result.AppendErrorWithFormat("Aborting reading of commands after command #%d: '%s' continued the target.\n",
2510                                                  idx + 1, cmd);
2511                 else
2512                     result.AppendMessageWithFormat ("Command #%d '%s' continued the target.\n", idx + 1, cmd);
2513 
2514                 result.SetStatus(tmp_result.GetStatus());
2515                 m_debugger.SetAsyncExecution (old_async_execution);
2516 
2517                 return;
2518             }
2519         }
2520 
2521     }
2522 
2523     result.SetStatus (eReturnStatusSuccessFinishResult);
2524     m_debugger.SetAsyncExecution (old_async_execution);
2525 
2526     return;
2527 }
2528 
2529 void
2530 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
2531                                             ExecutionContext *context,
2532                                             bool stop_on_continue,
2533                                             bool stop_on_error,
2534                                             bool echo_command,
2535                                             bool print_result,
2536                                             LazyBool add_to_history,
2537                                             CommandReturnObject &result)
2538 {
2539     if (cmd_file.Exists())
2540     {
2541         bool success;
2542         StringList commands;
2543         success = commands.ReadFileLines(cmd_file);
2544         if (!success)
2545         {
2546             result.AppendErrorWithFormat ("Error reading commands from file: %s.\n", cmd_file.GetFilename().AsCString());
2547             result.SetStatus (eReturnStatusFailed);
2548             return;
2549         }
2550         m_command_source_depth++;
2551         HandleCommands (commands, context, stop_on_continue, stop_on_error, echo_command, print_result, add_to_history, result);
2552         m_command_source_depth--;
2553     }
2554     else
2555     {
2556         result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n",
2557                                       cmd_file.GetFilename().AsCString());
2558         result.SetStatus (eReturnStatusFailed);
2559         return;
2560     }
2561 }
2562 
2563 ScriptInterpreter *
2564 CommandInterpreter::GetScriptInterpreter (bool can_create)
2565 {
2566     if (m_script_interpreter_ap.get() != NULL)
2567         return m_script_interpreter_ap.get();
2568 
2569     if (!can_create)
2570         return NULL;
2571 
2572     // <rdar://problem/11751427>
2573     // we need to protect the initialization of the script interpreter
2574     // otherwise we could end up with two threads both trying to create
2575     // their instance of it, and for some languages (e.g. Python)
2576     // this is a bulletproof recipe for disaster!
2577     // this needs to be a function-level static because multiple Debugger instances living in the same process
2578     // still need to be isolated and not try to initialize Python concurrently
2579     static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive);
2580     Mutex::Locker interpreter_lock(g_interpreter_mutex);
2581 
2582     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
2583     if (log)
2584         log->Printf("Initializing the ScriptInterpreter now\n");
2585 
2586     lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage();
2587     switch (script_lang)
2588     {
2589         case eScriptLanguagePython:
2590 #ifndef LLDB_DISABLE_PYTHON
2591             m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this));
2592             break;
2593 #else
2594             // Fall through to the None case when python is disabled
2595 #endif
2596         case eScriptLanguageNone:
2597             m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this));
2598             break;
2599     };
2600 
2601     return m_script_interpreter_ap.get();
2602 }
2603 
2604 
2605 
2606 bool
2607 CommandInterpreter::GetSynchronous ()
2608 {
2609     return m_synchronous_execution;
2610 }
2611 
2612 void
2613 CommandInterpreter::SetSynchronous (bool value)
2614 {
2615     m_synchronous_execution  = value;
2616 }
2617 
2618 void
2619 CommandInterpreter::OutputFormattedHelpText (Stream &strm,
2620                                              const char *word_text,
2621                                              const char *separator,
2622                                              const char *help_text,
2623                                              size_t max_word_len)
2624 {
2625     const uint32_t max_columns = m_debugger.GetTerminalWidth();
2626 
2627     int indent_size = max_word_len + strlen (separator) + 2;
2628 
2629     strm.IndentMore (indent_size);
2630 
2631     StreamString text_strm;
2632     text_strm.Printf ("%-*s %s %s",  (int)max_word_len, word_text, separator, help_text);
2633 
2634     size_t len = text_strm.GetSize();
2635     const char *text = text_strm.GetData();
2636     if (text[len - 1] == '\n')
2637     {
2638         text_strm.EOL();
2639         len = text_strm.GetSize();
2640     }
2641 
2642     if (len  < max_columns)
2643     {
2644         // Output it as a single line.
2645         strm.Printf ("%s", text);
2646     }
2647     else
2648     {
2649         // We need to break it up into multiple lines.
2650         bool first_line = true;
2651         int text_width;
2652         size_t start = 0;
2653         size_t end = start;
2654         const size_t final_end = strlen (text);
2655 
2656         while (end < final_end)
2657         {
2658             if (first_line)
2659                 text_width = max_columns - 1;
2660             else
2661                 text_width = max_columns - indent_size - 1;
2662 
2663             // Don't start the 'text' on a space, since we're already outputting the indentation.
2664             if (!first_line)
2665             {
2666                 while ((start < final_end) && (text[start] == ' '))
2667                   start++;
2668             }
2669 
2670             end = start + text_width;
2671             if (end > final_end)
2672                 end = final_end;
2673             else
2674             {
2675                 // If we're not at the end of the text, make sure we break the line on white space.
2676                 while (end > start
2677                        && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
2678                     end--;
2679                 assert (end > 0);
2680             }
2681 
2682             const size_t sub_len = end - start;
2683             if (start != 0)
2684               strm.EOL();
2685             if (!first_line)
2686                 strm.Indent();
2687             else
2688                 first_line = false;
2689             assert (start <= final_end);
2690             assert (start + sub_len <= final_end);
2691             if (sub_len > 0)
2692                 strm.Write (text + start, sub_len);
2693             start = end + 1;
2694         }
2695     }
2696     strm.EOL();
2697     strm.IndentLess(indent_size);
2698 }
2699 
2700 void
2701 CommandInterpreter::OutputHelpText (Stream &strm,
2702                                     const char *word_text,
2703                                     const char *separator,
2704                                     const char *help_text,
2705                                     uint32_t max_word_len)
2706 {
2707     int indent_size = max_word_len + strlen (separator) + 2;
2708 
2709     strm.IndentMore (indent_size);
2710 
2711     StreamString text_strm;
2712     text_strm.Printf ("%-*s %s %s",  max_word_len, word_text, separator, help_text);
2713 
2714     const uint32_t max_columns = m_debugger.GetTerminalWidth();
2715 
2716     size_t len = text_strm.GetSize();
2717     const char *text = text_strm.GetData();
2718 
2719     uint32_t chars_left = max_columns;
2720 
2721     for (uint32_t i = 0; i < len; i++)
2722     {
2723         if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n')
2724         {
2725             chars_left = max_columns - indent_size;
2726             strm.EOL();
2727             strm.Indent();
2728         }
2729         else
2730         {
2731             strm.PutChar(text[i]);
2732             chars_left--;
2733         }
2734 
2735     }
2736 
2737     strm.EOL();
2738     strm.IndentLess(indent_size);
2739 }
2740 
2741 void
2742 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
2743                                             StringList &commands_help)
2744 {
2745     CommandObject::CommandMap::const_iterator pos;
2746 
2747     for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
2748     {
2749         const char *command_name = pos->first.c_str();
2750         CommandObject *cmd_obj = pos->second.get();
2751 
2752         if (cmd_obj->HelpTextContainsWord (search_word))
2753         {
2754             commands_found.AppendString (command_name);
2755             commands_help.AppendString (cmd_obj->GetHelp());
2756         }
2757 
2758         if (cmd_obj->IsMultiwordObject())
2759             cmd_obj->AproposAllSubCommands (command_name,
2760                                             search_word,
2761                                             commands_found,
2762                                             commands_help);
2763 
2764     }
2765 }
2766 
2767 
2768 void
2769 CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
2770 {
2771     if (override_context != NULL)
2772     {
2773         m_exe_ctx_ref = *override_context;
2774     }
2775     else
2776     {
2777         const bool adopt_selected = true;
2778         m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected);
2779     }
2780 }
2781 
2782 void
2783 CommandInterpreter::DumpHistory (Stream &stream, uint32_t count) const
2784 {
2785     DumpHistory (stream, 0, count - 1);
2786 }
2787 
2788 void
2789 CommandInterpreter::DumpHistory (Stream &stream, uint32_t start, uint32_t end) const
2790 {
2791     const size_t last_idx = std::min<size_t>(m_command_history.size(), end + 1);
2792     for (size_t i = start; i < last_idx; i++)
2793     {
2794         if (!m_command_history[i].empty())
2795         {
2796             stream.Indent();
2797             stream.Printf ("%4zu: %s\n", i, m_command_history[i].c_str());
2798         }
2799     }
2800 }
2801 
2802 const char *
2803 CommandInterpreter::FindHistoryString (const char *input_str) const
2804 {
2805     if (input_str[0] != m_repeat_char)
2806         return NULL;
2807     if (input_str[1] == '-')
2808     {
2809         bool success;
2810         size_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
2811         if (!success)
2812             return NULL;
2813         if (idx > m_command_history.size())
2814             return NULL;
2815         idx = m_command_history.size() - idx;
2816         return m_command_history[idx].c_str();
2817 
2818     }
2819     else if (input_str[1] == m_repeat_char)
2820     {
2821         if (m_command_history.empty())
2822             return NULL;
2823         else
2824             return m_command_history.back().c_str();
2825     }
2826     else
2827     {
2828         bool success;
2829         uint32_t idx = Args::StringToUInt32 (input_str+1, 0, 0, &success);
2830         if (!success)
2831             return NULL;
2832         if (idx >= m_command_history.size())
2833             return NULL;
2834         return m_command_history[idx].c_str();
2835     }
2836 }
2837