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