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