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