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, 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     // Set up some initial aliases.
189     CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false);
190     if (cmd_obj_sp)
191     {
192         AddAlias ("q", cmd_obj_sp);
193         AddAlias ("exit", cmd_obj_sp);
194     }
195 
196     cmd_obj_sp = GetCommandSPExact ("_regexp-attach",false);
197     if (cmd_obj_sp)
198     {
199         AddAlias ("attach", cmd_obj_sp);
200     }
201 
202     cmd_obj_sp = GetCommandSPExact ("process detach",false);
203     if (cmd_obj_sp)
204     {
205         AddAlias ("detach", cmd_obj_sp);
206     }
207 
208     cmd_obj_sp = GetCommandSPExact ("process continue", false);
209     if (cmd_obj_sp)
210     {
211         AddAlias ("c", cmd_obj_sp);
212         AddAlias ("continue", cmd_obj_sp);
213     }
214 
215     cmd_obj_sp = GetCommandSPExact ("_regexp-break",false);
216     if (cmd_obj_sp)
217         AddAlias ("b", cmd_obj_sp);
218 
219     cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false);
220     if (cmd_obj_sp)
221         AddAlias ("tbreak", cmd_obj_sp);
222 
223     cmd_obj_sp = GetCommandSPExact ("thread step-inst", false);
224     if (cmd_obj_sp)
225     {
226         AddAlias ("stepi", cmd_obj_sp);
227         AddAlias ("si", cmd_obj_sp);
228     }
229 
230     cmd_obj_sp = GetCommandSPExact ("thread step-inst-over", false);
231     if (cmd_obj_sp)
232     {
233         AddAlias ("nexti", cmd_obj_sp);
234         AddAlias ("ni", cmd_obj_sp);
235     }
236 
237     cmd_obj_sp = GetCommandSPExact ("thread step-in", false);
238     if (cmd_obj_sp)
239     {
240         AddAlias ("s", cmd_obj_sp);
241         AddAlias ("step", cmd_obj_sp);
242     }
243 
244     cmd_obj_sp = GetCommandSPExact ("thread step-over", false);
245     if (cmd_obj_sp)
246     {
247         AddAlias ("n", cmd_obj_sp);
248         AddAlias ("next", cmd_obj_sp);
249     }
250 
251     cmd_obj_sp = GetCommandSPExact ("thread step-out", false);
252     if (cmd_obj_sp)
253     {
254         AddAlias ("finish", cmd_obj_sp);
255     }
256 
257     cmd_obj_sp = GetCommandSPExact ("frame select", false);
258     if (cmd_obj_sp)
259     {
260         AddAlias ("f", cmd_obj_sp);
261     }
262 
263     cmd_obj_sp = GetCommandSPExact ("thread select", false);
264     if (cmd_obj_sp)
265     {
266         AddAlias ("t", cmd_obj_sp);
267     }
268 
269     cmd_obj_sp = GetCommandSPExact ("_regexp-jump",false);
270     if (cmd_obj_sp)
271     {
272         AddAlias ("j", cmd_obj_sp);
273         AddAlias ("jump", cmd_obj_sp);
274     }
275 
276     cmd_obj_sp = GetCommandSPExact ("_regexp-list", false);
277     if (cmd_obj_sp)
278     {
279         AddAlias ("l", cmd_obj_sp);
280         AddAlias ("list", cmd_obj_sp);
281     }
282 
283     cmd_obj_sp = GetCommandSPExact ("_regexp-env", false);
284     if (cmd_obj_sp)
285     {
286         AddAlias ("env", cmd_obj_sp);
287     }
288 
289     cmd_obj_sp = GetCommandSPExact ("memory read", false);
290     if (cmd_obj_sp)
291         AddAlias ("x", cmd_obj_sp);
292 
293     cmd_obj_sp = GetCommandSPExact ("_regexp-up", false);
294     if (cmd_obj_sp)
295         AddAlias ("up", cmd_obj_sp);
296 
297     cmd_obj_sp = GetCommandSPExact ("_regexp-down", false);
298     if (cmd_obj_sp)
299         AddAlias ("down", cmd_obj_sp);
300 
301     cmd_obj_sp = GetCommandSPExact ("_regexp-display", false);
302     if (cmd_obj_sp)
303         AddAlias ("display", cmd_obj_sp);
304 
305     cmd_obj_sp = GetCommandSPExact ("disassemble", false);
306     if (cmd_obj_sp)
307         AddAlias ("dis", cmd_obj_sp);
308 
309     cmd_obj_sp = GetCommandSPExact ("disassemble", false);
310     if (cmd_obj_sp)
311         AddAlias ("di", cmd_obj_sp);
312 
313 
314 
315     cmd_obj_sp = GetCommandSPExact ("_regexp-undisplay", false);
316     if (cmd_obj_sp)
317         AddAlias ("undisplay", cmd_obj_sp);
318 
319     cmd_obj_sp = GetCommandSPExact ("_regexp-bt", false);
320     if (cmd_obj_sp)
321         AddAlias ("bt", cmd_obj_sp);
322 
323     cmd_obj_sp = GetCommandSPExact ("target create", false);
324     if (cmd_obj_sp)
325         AddAlias ("file", cmd_obj_sp);
326 
327     cmd_obj_sp = GetCommandSPExact ("target modules", false);
328     if (cmd_obj_sp)
329         AddAlias ("image", cmd_obj_sp);
330 
331 
332     OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector);
333 
334     cmd_obj_sp = GetCommandSPExact ("expression", false);
335     if (cmd_obj_sp)
336     {
337         ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
338         AddAlias ("p", cmd_obj_sp);
339         AddAlias ("print", cmd_obj_sp);
340         AddAlias ("call", cmd_obj_sp);
341         AddOrReplaceAliasOptions ("p", alias_arguments_vector_sp);
342         AddOrReplaceAliasOptions ("print", alias_arguments_vector_sp);
343         AddOrReplaceAliasOptions ("call", alias_arguments_vector_sp);
344 
345         alias_arguments_vector_sp.reset (new OptionArgVector);
346         ProcessAliasOptionsArgs (cmd_obj_sp, "-O -- ", alias_arguments_vector_sp);
347         AddAlias ("po", cmd_obj_sp);
348         AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp);
349     }
350 
351     cmd_obj_sp = GetCommandSPExact ("process kill", false);
352     if (cmd_obj_sp)
353     {
354         AddAlias ("kill", cmd_obj_sp);
355     }
356 
357     cmd_obj_sp = GetCommandSPExact ("process launch", false);
358     if (cmd_obj_sp)
359     {
360         alias_arguments_vector_sp.reset (new OptionArgVector);
361 #if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
362         ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
363 #else
364     #if defined(__APPLE__)
365         std::string shell_option;
366         shell_option.append("--shell-expand-args");
367         shell_option.append(" true");
368         shell_option.append(" --");
369         ProcessAliasOptionsArgs (cmd_obj_sp, shell_option.c_str(), alias_arguments_vector_sp);
370     #else
371         std::string shell_option;
372         shell_option.append("--shell=");
373         shell_option.append(HostInfo::GetDefaultShell().GetPath());
374         shell_option.append(" --");
375         ProcessAliasOptionsArgs (cmd_obj_sp, shell_option.c_str(), alias_arguments_vector_sp);
376     #endif
377 #endif
378         AddAlias ("r", cmd_obj_sp);
379         AddAlias ("run", cmd_obj_sp);
380         AddOrReplaceAliasOptions ("r", alias_arguments_vector_sp);
381         AddOrReplaceAliasOptions ("run", alias_arguments_vector_sp);
382     }
383 
384     cmd_obj_sp = GetCommandSPExact ("target symbols add", false);
385     if (cmd_obj_sp)
386     {
387         AddAlias ("add-dsym", cmd_obj_sp);
388     }
389 
390     cmd_obj_sp = GetCommandSPExact ("breakpoint set", false);
391     if (cmd_obj_sp)
392     {
393         alias_arguments_vector_sp.reset (new OptionArgVector);
394         ProcessAliasOptionsArgs (cmd_obj_sp, "--func-regex %1", alias_arguments_vector_sp);
395         AddAlias ("rbreak", cmd_obj_sp);
396         AddOrReplaceAliasOptions("rbreak", alias_arguments_vector_sp);
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     CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches);
757 
758     if (include_aliases)
759     {
760         CommandObject::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         pos = m_alias_dict.find(cmd);
784         if (pos != m_alias_dict.end())
785             command_sp = 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 = CommandObject::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 = CommandObject::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             pos = m_alias_dict.find(cmd);
835             if (pos != m_alias_dict.end())
836                 alias_match_sp = pos->second;
837         }
838 
839         if (HasUserCommands())
840         {
841             num_user_matches = CommandObject::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::ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
1018                                             const char *options_args,
1019                                             OptionArgVectorSP &option_arg_vector_sp)
1020 {
1021     bool success = true;
1022     OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
1023 
1024     if (!options_args || (strlen (options_args) < 1))
1025         return true;
1026 
1027     std::string options_string (options_args);
1028     Args args (options_args);
1029     CommandReturnObject result;
1030     // Check to see if the command being aliased can take any command options.
1031     Options *options = cmd_obj_sp->GetOptions ();
1032     if (options)
1033     {
1034         // See if any options were specified as part of the alias;  if so, handle them appropriately.
1035         options->NotifyOptionParsingStarting ();
1036         args.Unshift ("dummy_arg");
1037         args.ParseAliasOptions (*options, result, option_arg_vector, options_string);
1038         args.Shift ();
1039         if (result.Succeeded())
1040             options->VerifyPartialOptions (result);
1041         if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
1042         {
1043             result.AppendError ("Unable to create requested alias.\n");
1044             return false;
1045         }
1046     }
1047 
1048     if (!options_string.empty())
1049     {
1050         if (cmd_obj_sp->WantsRawCommandString ())
1051             option_arg_vector->push_back (OptionArgPair ("<argument>",
1052                                                           OptionArgValue (-1,
1053                                                                           options_string)));
1054         else
1055         {
1056             const size_t argc = args.GetArgumentCount();
1057             for (size_t i = 0; i < argc; ++i)
1058                 if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
1059                     option_arg_vector->push_back
1060                                 (OptionArgPair ("<argument>",
1061                                                 OptionArgValue (-1,
1062                                                                 std::string (args.GetArgumentAtIndex (i)))));
1063         }
1064     }
1065 
1066     return success;
1067 }
1068 
1069 bool
1070 CommandInterpreter::GetAliasFullName (const char *cmd, std::string &full_name)
1071 {
1072     bool exact_match  = (m_alias_dict.find(cmd) != m_alias_dict.end());
1073     if (exact_match)
1074     {
1075         full_name.assign(cmd);
1076         return exact_match;
1077     }
1078     else
1079     {
1080         StringList matches;
1081         size_t num_alias_matches;
1082         num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd, matches);
1083         if (num_alias_matches == 1)
1084         {
1085             // Make sure this isn't shadowing a command in the regular command space:
1086             StringList regular_matches;
1087             const bool include_aliases = false;
1088             const bool exact = false;
1089             CommandObjectSP cmd_obj_sp(GetCommandSP (cmd, include_aliases, exact, &regular_matches));
1090             if (cmd_obj_sp || regular_matches.GetSize() > 0)
1091                 return false;
1092             else
1093             {
1094                 full_name.assign (matches.GetStringAtIndex(0));
1095                 return true;
1096             }
1097         }
1098         else
1099             return false;
1100     }
1101 }
1102 
1103 bool
1104 CommandInterpreter::AliasExists (const char *cmd)
1105 {
1106     return m_alias_dict.find(cmd) != m_alias_dict.end();
1107 }
1108 
1109 bool
1110 CommandInterpreter::UserCommandExists (const char *cmd)
1111 {
1112     return m_user_dict.find(cmd) != m_user_dict.end();
1113 }
1114 
1115 void
1116 CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp)
1117 {
1118     if (command_obj_sp.get())
1119         assert((this == &command_obj_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter");
1120 
1121     command_obj_sp->SetIsAlias (true);
1122     m_alias_dict[alias_name] = command_obj_sp;
1123 }
1124 
1125 bool
1126 CommandInterpreter::RemoveAlias (const char *alias_name)
1127 {
1128     CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name);
1129     if (pos != m_alias_dict.end())
1130     {
1131         m_alias_dict.erase(pos);
1132         return true;
1133     }
1134     return false;
1135 }
1136 
1137 bool
1138 CommandInterpreter::RemoveCommand (const char *cmd)
1139 {
1140     auto pos = m_command_dict.find(cmd);
1141     if (pos != m_command_dict.end())
1142     {
1143         if (pos->second->IsRemovable())
1144         {
1145             // Only regular expression objects or python commands are removable
1146             m_command_dict.erase(pos);
1147             return true;
1148         }
1149     }
1150     return false;
1151 }
1152 bool
1153 CommandInterpreter::RemoveUser (const char *alias_name)
1154 {
1155     CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name);
1156     if (pos != m_user_dict.end())
1157     {
1158         m_user_dict.erase(pos);
1159         return true;
1160     }
1161     return false;
1162 }
1163 
1164 void
1165 CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string)
1166 {
1167     help_string.Printf ("'%s", command_name);
1168     OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
1169 
1170     if (option_arg_vector_sp)
1171     {
1172         OptionArgVector *options = option_arg_vector_sp.get();
1173         for (size_t i = 0; i < options->size(); ++i)
1174         {
1175             OptionArgPair cur_option = (*options)[i];
1176             std::string opt = cur_option.first;
1177             OptionArgValue value_pair = cur_option.second;
1178             std::string value = value_pair.second;
1179             if (opt.compare("<argument>") == 0)
1180             {
1181                 help_string.Printf (" %s", value.c_str());
1182             }
1183             else
1184             {
1185                 help_string.Printf (" %s", opt.c_str());
1186                 if ((value.compare ("<no-argument>") != 0)
1187                     && (value.compare ("<need-argument") != 0))
1188                 {
1189                     help_string.Printf (" %s", value.c_str());
1190                 }
1191             }
1192         }
1193     }
1194 
1195     help_string.Printf ("'");
1196 }
1197 
1198 size_t
1199 CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict)
1200 {
1201     CommandObject::CommandMap::const_iterator pos;
1202     CommandObject::CommandMap::const_iterator end = dict.end();
1203     size_t max_len = 0;
1204 
1205     for (pos = dict.begin(); pos != end; ++pos)
1206     {
1207         size_t len = pos->first.size();
1208         if (max_len < len)
1209             max_len = len;
1210     }
1211     return max_len;
1212 }
1213 
1214 void
1215 CommandInterpreter::GetHelp (CommandReturnObject &result,
1216                              uint32_t cmd_types)
1217 {
1218     const char * help_prologue = GetDebugger().GetIOHandlerHelpPrologue();
1219     if (help_prologue != NULL)
1220     {
1221         OutputFormattedHelpText(result.GetOutputStream(), NULL, help_prologue);
1222     }
1223 
1224     CommandObject::CommandMap::const_iterator pos;
1225     size_t max_len = FindLongestCommandWord (m_command_dict);
1226 
1227     if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
1228     {
1229         result.AppendMessage("Debugger commands:");
1230         result.AppendMessage("");
1231 
1232         for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
1233         {
1234             if (!(cmd_types & eCommandTypesHidden) && (pos->first.compare(0, 1, "_") == 0))
1235                 continue;
1236 
1237             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
1238                                      max_len);
1239         }
1240         result.AppendMessage("");
1241 
1242     }
1243 
1244     if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases ))
1245     {
1246         result.AppendMessageWithFormat("Current command abbreviations "
1247                                        "(type '%shelp command alias' for more info):\n",
1248                                        GetCommandPrefix());
1249         result.AppendMessage("");
1250         max_len = FindLongestCommandWord (m_alias_dict);
1251 
1252         for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos)
1253         {
1254             StreamString sstr;
1255             StreamString translation_and_help;
1256             std::string entry_name = pos->first;
1257             std::string second_entry = pos->second.get()->GetCommandName();
1258             GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr);
1259 
1260             translation_and_help.Printf ("(%s)  %s", sstr.GetData(), pos->second->GetHelp());
1261             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--",
1262                                      translation_and_help.GetData(), max_len);
1263         }
1264         result.AppendMessage("");
1265     }
1266 
1267     if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef ))
1268     {
1269         result.AppendMessage ("Current user-defined commands:");
1270         result.AppendMessage("");
1271         max_len = FindLongestCommandWord (m_user_dict);
1272         for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
1273         {
1274             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
1275                                      max_len);
1276         }
1277         result.AppendMessage("");
1278     }
1279 
1280     result.AppendMessageWithFormat("For more information on any command, type '%shelp <command-name>'.\n",
1281                                    GetCommandPrefix());
1282 }
1283 
1284 CommandObject *
1285 CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
1286 {
1287     // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will
1288     // eventually be invoked by the given command line.
1289 
1290     CommandObject *cmd_obj = nullptr;
1291     size_t start = command_string.find_first_not_of (k_white_space);
1292     size_t end = 0;
1293     bool done = false;
1294     while (!done)
1295     {
1296         if (start != std::string::npos)
1297         {
1298             // Get the next word from command_string.
1299             end = command_string.find_first_of (k_white_space, start);
1300             if (end == std::string::npos)
1301                 end = command_string.size();
1302             std::string cmd_word = command_string.substr (start, end - start);
1303 
1304             if (cmd_obj == nullptr)
1305                 // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid
1306                 // command or alias.
1307                 cmd_obj = GetCommandObject (cmd_word.c_str());
1308             else if (cmd_obj->IsMultiwordObject ())
1309             {
1310                 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object.
1311                 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str());
1312                 if (sub_cmd_obj)
1313                     cmd_obj = sub_cmd_obj;
1314                 else // cmd_word was not a valid sub-command word, so we are done
1315                     done = true;
1316             }
1317             else
1318                 // We have a cmd_obj and it is not a multi-word object, so we are done.
1319                 done = true;
1320 
1321             // If we didn't find a valid command object, or our command object is not a multi-word object, or
1322             // we are at the end of the command_string, then we are done.  Otherwise, find the start of the
1323             // next word.
1324 
1325             if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size())
1326                 done = true;
1327             else
1328                 start = command_string.find_first_not_of (k_white_space, end);
1329         }
1330         else
1331             // Unable to find any more words.
1332             done = true;
1333     }
1334 
1335     if (end == command_string.size())
1336         command_string.clear();
1337     else
1338         command_string = command_string.substr(end);
1339 
1340     return cmd_obj;
1341 }
1342 
1343 static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1344 static void
1345 StripLeadingSpaces (std::string &s)
1346 {
1347     if (!s.empty())
1348     {
1349         size_t pos = s.find_first_not_of (k_white_space);
1350         if (pos == std::string::npos)
1351             s.clear();
1352         else if (pos == 0)
1353             return;
1354         s.erase (0, pos);
1355     }
1356 }
1357 
1358 static size_t
1359 FindArgumentTerminator (const std::string &s)
1360 {
1361     const size_t s_len = s.size();
1362     size_t offset = 0;
1363     while (offset < s_len)
1364     {
1365         size_t pos = s.find ("--", offset);
1366         if (pos == std::string::npos)
1367             break;
1368         if (pos > 0)
1369         {
1370             if (isspace(s[pos-1]))
1371             {
1372                 // Check if the string ends "\s--" (where \s is a space character)
1373                 // or if we have "\s--\s".
1374                 if ((pos + 2 >= s_len) || isspace(s[pos+2]))
1375                 {
1376                     return pos;
1377                 }
1378             }
1379         }
1380         offset = pos + 2;
1381     }
1382     return std::string::npos;
1383 }
1384 
1385 static bool
1386 ExtractCommand (std::string &command_string, std::string &command, std::string &suffix, char &quote_char)
1387 {
1388     command.clear();
1389     suffix.clear();
1390     StripLeadingSpaces (command_string);
1391 
1392     bool result = false;
1393     quote_char = '\0';
1394 
1395     if (!command_string.empty())
1396     {
1397         const char first_char = command_string[0];
1398         if (first_char == '\'' || first_char == '"')
1399         {
1400             quote_char = first_char;
1401             const size_t end_quote_pos = command_string.find (quote_char, 1);
1402             if (end_quote_pos == std::string::npos)
1403             {
1404                 command.swap (command_string);
1405                 command_string.erase ();
1406             }
1407             else
1408             {
1409                 command.assign (command_string, 1, end_quote_pos - 1);
1410                 if (end_quote_pos + 1 < command_string.size())
1411                     command_string.erase (0, command_string.find_first_not_of (k_white_space, end_quote_pos + 1));
1412                 else
1413                     command_string.erase ();
1414             }
1415         }
1416         else
1417         {
1418             const size_t first_space_pos = command_string.find_first_of (k_white_space);
1419             if (first_space_pos == std::string::npos)
1420             {
1421                 command.swap (command_string);
1422                 command_string.erase();
1423             }
1424             else
1425             {
1426                 command.assign (command_string, 0, first_space_pos);
1427                 command_string.erase(0, command_string.find_first_not_of (k_white_space, first_space_pos));
1428             }
1429         }
1430         result = true;
1431     }
1432 
1433 
1434     if (!command.empty())
1435     {
1436         // actual commands can't start with '-' or '_'
1437         if (command[0] != '-' && command[0] != '_')
1438         {
1439             size_t pos = command.find_first_not_of(k_valid_command_chars);
1440             if (pos > 0 && pos != std::string::npos)
1441             {
1442                 suffix.assign (command.begin() + pos, command.end());
1443                 command.erase (pos);
1444             }
1445         }
1446     }
1447 
1448     return result;
1449 }
1450 
1451 CommandObject *
1452 CommandInterpreter::BuildAliasResult (const char *alias_name,
1453                                       std::string &raw_input_string,
1454                                       std::string &alias_result,
1455                                       CommandReturnObject &result)
1456 {
1457     CommandObject *alias_cmd_obj = nullptr;
1458     Args cmd_args (raw_input_string);
1459     alias_cmd_obj = GetCommandObject (alias_name);
1460     StreamString result_str;
1461 
1462     if (alias_cmd_obj)
1463     {
1464         std::string alias_name_str = alias_name;
1465         if ((cmd_args.GetArgumentCount() == 0)
1466             || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0))
1467             cmd_args.Unshift (alias_name);
1468 
1469         result_str.Printf ("%s", alias_cmd_obj->GetCommandName ());
1470         OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
1471 
1472         if (option_arg_vector_sp.get())
1473         {
1474             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
1475 
1476             for (size_t i = 0; i < option_arg_vector->size(); ++i)
1477             {
1478                 OptionArgPair option_pair = (*option_arg_vector)[i];
1479                 OptionArgValue value_pair = option_pair.second;
1480                 int value_type = value_pair.first;
1481                 std::string option = option_pair.first;
1482                 std::string value = value_pair.second;
1483                 if (option.compare ("<argument>") == 0)
1484                     result_str.Printf (" %s", value.c_str());
1485                 else
1486                 {
1487                     result_str.Printf (" %s", option.c_str());
1488                     if (value_type != OptionParser::eNoArgument)
1489                     {
1490                         if (value_type != OptionParser::eOptionalArgument)
1491                             result_str.Printf (" ");
1492                         int index = GetOptionArgumentPosition (value.c_str());
1493                         if (index == 0)
1494                             result_str.Printf ("%s", value.c_str());
1495                         else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount())
1496                         {
1497 
1498                             result.AppendErrorWithFormat
1499                             ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
1500                              index);
1501                             result.SetStatus (eReturnStatusFailed);
1502                             return nullptr;
1503                         }
1504                         else
1505                         {
1506                             size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
1507                             if (strpos != std::string::npos)
1508                                 raw_input_string = raw_input_string.erase (strpos,
1509                                                                           strlen (cmd_args.GetArgumentAtIndex (index)));
1510                             result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index));
1511                         }
1512                     }
1513                 }
1514             }
1515         }
1516 
1517         alias_result = result_str.GetData();
1518     }
1519     return alias_cmd_obj;
1520 }
1521 
1522 Error
1523 CommandInterpreter::PreprocessCommand (std::string &command)
1524 {
1525     // The command preprocessor needs to do things to the command
1526     // line before any parsing of arguments or anything else is done.
1527     // The only current stuff that gets preprocessed is anything enclosed
1528     // in backtick ('`') characters is evaluated as an expression and
1529     // the result of the expression must be a scalar that can be substituted
1530     // into the command. An example would be:
1531     // (lldb) memory read `$rsp + 20`
1532     Error error; // Error for any expressions that might not evaluate
1533     size_t start_backtick;
1534     size_t pos = 0;
1535     while ((start_backtick = command.find ('`', pos)) != std::string::npos)
1536     {
1537         if (start_backtick > 0 && command[start_backtick-1] == '\\')
1538         {
1539             // The backtick was preceded by a '\' character, remove the slash
1540             // and don't treat the backtick as the start of an expression
1541             command.erase(start_backtick-1, 1);
1542             // No need to add one to start_backtick since we just deleted a char
1543             pos = start_backtick;
1544         }
1545         else
1546         {
1547             const size_t expr_content_start = start_backtick + 1;
1548             const size_t end_backtick = command.find ('`', expr_content_start);
1549             if (end_backtick == std::string::npos)
1550                 return error;
1551             else if (end_backtick == expr_content_start)
1552             {
1553                 // Empty expression (two backticks in a row)
1554                 command.erase (start_backtick, 2);
1555             }
1556             else
1557             {
1558                 std::string expr_str (command, expr_content_start, end_backtick - expr_content_start);
1559 
1560                 ExecutionContext exe_ctx(GetExecutionContext());
1561                 Target *target = exe_ctx.GetTargetPtr();
1562                 // Get a dummy target to allow for calculator mode while processing backticks.
1563                 // This also helps break the infinite loop caused when target is null.
1564                 if (!target)
1565                     target = m_debugger.GetDummyTarget();
1566                 if (target)
1567                 {
1568                     ValueObjectSP expr_result_valobj_sp;
1569 
1570                     EvaluateExpressionOptions options;
1571                     options.SetCoerceToId(false);
1572                     options.SetUnwindOnError(true);
1573                     options.SetIgnoreBreakpoints(true);
1574                     options.SetKeepInMemory(false);
1575                     options.SetTryAllThreads(true);
1576                     options.SetTimeoutUsec(0);
1577 
1578                     ExpressionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
1579                                                                                 exe_ctx.GetFramePtr(),
1580                                                                                 expr_result_valobj_sp,
1581                                                                                 options);
1582 
1583                     if (expr_result == eExpressionCompleted)
1584                     {
1585                         Scalar scalar;
1586                         if (expr_result_valobj_sp)
1587                             expr_result_valobj_sp = expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(expr_result_valobj_sp->GetDynamicValueType(), true);
1588                         if (expr_result_valobj_sp->ResolveValue (scalar))
1589                         {
1590                             command.erase (start_backtick, end_backtick - start_backtick + 1);
1591                             StreamString value_strm;
1592                             const bool show_type = false;
1593                             scalar.GetValue (&value_strm, show_type);
1594                             size_t value_string_size = value_strm.GetSize();
1595                             if (value_string_size)
1596                             {
1597                                 command.insert (start_backtick, value_strm.GetData(), value_string_size);
1598                                 pos = start_backtick + value_string_size;
1599                                 continue;
1600                             }
1601                             else
1602                             {
1603                                 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
1604                             }
1605                         }
1606                         else
1607                         {
1608                             error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
1609                         }
1610                     }
1611                     else
1612                     {
1613                         if (expr_result_valobj_sp)
1614                             error = expr_result_valobj_sp->GetError();
1615                         if (error.Success())
1616                         {
1617 
1618                             switch (expr_result)
1619                             {
1620                                 case eExpressionSetupError:
1621                                     error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str());
1622                                     break;
1623                                 case eExpressionParseError:
1624                                     error.SetErrorStringWithFormat ("expression parse error for the expression '%s'", expr_str.c_str());
1625                                     break;
1626                                 case eExpressionResultUnavailable:
1627                                     error.SetErrorStringWithFormat ("expression error fetching result for the expression '%s'", expr_str.c_str());
1628                                 case eExpressionCompleted:
1629                                     break;
1630                                 case eExpressionDiscarded:
1631                                     error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str());
1632                                     break;
1633                                 case eExpressionInterrupted:
1634                                     error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str());
1635                                     break;
1636                                 case eExpressionHitBreakpoint:
1637                                     error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str());
1638                                     break;
1639                                 case eExpressionTimedOut:
1640                                     error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str());
1641                                     break;
1642                                 case eExpressionStoppedForDebug:
1643                                     error.SetErrorStringWithFormat("expression stop at entry point for debugging for the expression '%s'", expr_str.c_str());
1644                                     break;
1645                             }
1646                         }
1647                     }
1648                 }
1649             }
1650             if (error.Fail())
1651                 break;
1652         }
1653     }
1654     return error;
1655 }
1656 
1657 
1658 bool
1659 CommandInterpreter::HandleCommand (const char *command_line,
1660                                    LazyBool lazy_add_to_history,
1661                                    CommandReturnObject &result,
1662                                    ExecutionContext *override_context,
1663                                    bool repeat_on_empty_command,
1664                                    bool no_context_switching)
1665 
1666 {
1667 
1668     std::string command_string (command_line);
1669     std::string original_command_string (command_line);
1670 
1671     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
1672     Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line);
1673 
1674     // Make a scoped cleanup object that will clear the crash description string
1675     // on exit of this function.
1676     lldb_utility::CleanUp <const char *> crash_description_cleanup(nullptr, Host::SetCrashDescription);
1677 
1678     if (log)
1679         log->Printf ("Processing command: %s", command_line);
1680 
1681     Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line);
1682 
1683     if (!no_context_switching)
1684         UpdateExecutionContext (override_context);
1685 
1686     bool add_to_history;
1687     if (lazy_add_to_history == eLazyBoolCalculate)
1688         add_to_history = (m_command_source_depth == 0);
1689     else
1690         add_to_history = (lazy_add_to_history == eLazyBoolYes);
1691 
1692     bool empty_command = false;
1693     bool comment_command = false;
1694     if (command_string.empty())
1695         empty_command = true;
1696     else
1697     {
1698         const char *k_space_characters = "\t\n\v\f\r ";
1699 
1700         size_t non_space = command_string.find_first_not_of (k_space_characters);
1701         // Check for empty line or comment line (lines whose first
1702         // non-space character is the comment character for this interpreter)
1703         if (non_space == std::string::npos)
1704             empty_command = true;
1705         else if (command_string[non_space] == m_comment_char)
1706              comment_command = true;
1707         else if (command_string[non_space] == CommandHistory::g_repeat_char)
1708         {
1709             const char *history_string = m_command_history.FindString(command_string.c_str() + non_space);
1710             if (history_string == nullptr)
1711             {
1712                 result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str());
1713                 result.SetStatus(eReturnStatusFailed);
1714                 return false;
1715             }
1716             add_to_history = false;
1717             command_string = history_string;
1718             original_command_string = history_string;
1719         }
1720     }
1721 
1722     if (empty_command)
1723     {
1724         if (repeat_on_empty_command)
1725         {
1726             if (m_command_history.IsEmpty())
1727             {
1728                 result.AppendError ("empty command");
1729                 result.SetStatus(eReturnStatusFailed);
1730                 return false;
1731             }
1732             else
1733             {
1734                 command_line = m_repeat_command.c_str();
1735                 command_string = command_line;
1736                 original_command_string = command_line;
1737                 if (m_repeat_command.empty())
1738                 {
1739                     result.AppendErrorWithFormat("No auto repeat.\n");
1740                     result.SetStatus (eReturnStatusFailed);
1741                     return false;
1742                 }
1743             }
1744             add_to_history = false;
1745         }
1746         else
1747         {
1748             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1749             return true;
1750         }
1751     }
1752     else if (comment_command)
1753     {
1754         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1755         return true;
1756     }
1757 
1758 
1759     Error error (PreprocessCommand (command_string));
1760 
1761     if (error.Fail())
1762     {
1763         result.AppendError (error.AsCString());
1764         result.SetStatus(eReturnStatusFailed);
1765         return false;
1766     }
1767 
1768     // Phase 1.
1769 
1770     // Before we do ANY kind of argument processing, we need to figure out what
1771     // the real/final command object is for the specified command.  This gets
1772     // complicated by the fact that the user could have specified an alias, and,
1773     // in translating the alias, there may also be command options and/or even
1774     // data (including raw text strings) that need to be found and inserted into
1775     // the command line as part of the translation.  So this first step is plain
1776     // look-up and replacement, resulting in:
1777     //    1. the command object whose Execute method will actually be called
1778     //    2. a revised command string, with all substitutions and replacements
1779     //       taken care of
1780     // From 1 above, we can determine whether the Execute function wants raw
1781     // input or not.
1782 
1783     CommandObject *cmd_obj = ResolveCommandImpl(command_string, result);
1784 
1785     // Although the user may have abbreviated the command, the command_string now
1786     // has the command expanded to the full name.  For example, if the input
1787     // was "br s -n main", command_string is now "breakpoint set -n main".
1788 
1789     if (log)
1790     {
1791         log->Printf("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>");
1792         log->Printf("HandleCommand, (revised) command_string: '%s'", command_string.c_str());
1793         const bool wants_raw_input = (cmd_obj != NULL) ? cmd_obj->WantsRawCommandString() : false;
1794         log->Printf("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False");
1795     }
1796 
1797     // Phase 2.
1798     // Take care of things like setting up the history command & calling the appropriate Execute method on the
1799     // CommandObject, with the appropriate arguments.
1800 
1801     if (cmd_obj != nullptr)
1802     {
1803         if (add_to_history)
1804         {
1805             Args command_args (command_string);
1806             const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0);
1807             if (repeat_command != nullptr)
1808                 m_repeat_command.assign(repeat_command);
1809             else
1810                 m_repeat_command.assign(original_command_string.c_str());
1811 
1812             m_command_history.AppendString (original_command_string);
1813         }
1814 
1815         std::string remainder;
1816         const std::size_t actual_cmd_name_len = strlen (cmd_obj->GetCommandName());
1817         if (actual_cmd_name_len < command_string.length())
1818             remainder = command_string.substr (actual_cmd_name_len);
1819 
1820         // Remove any initial spaces
1821         size_t pos = remainder.find_first_not_of (k_white_space);
1822         if (pos != 0 && pos != std::string::npos)
1823             remainder.erase(0, pos);
1824 
1825         if (log)
1826             log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str());
1827 
1828         cmd_obj->Execute (remainder.c_str(), result);
1829     }
1830     else
1831     {
1832         // We didn't find the first command object, so complete the first argument.
1833         Args command_args (command_string);
1834         StringList matches;
1835         int num_matches;
1836         int cursor_index = 0;
1837         int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0));
1838         bool word_complete;
1839         num_matches = HandleCompletionMatches (command_args,
1840                                                cursor_index,
1841                                                cursor_char_position,
1842                                                0,
1843                                                -1,
1844                                                word_complete,
1845                                                matches);
1846 
1847         if (num_matches > 0)
1848         {
1849             std::string error_msg;
1850             error_msg.assign ("ambiguous command '");
1851             error_msg.append(command_args.GetArgumentAtIndex(0));
1852             error_msg.append ("'.");
1853 
1854             error_msg.append (" Possible completions:");
1855             for (int i = 0; i < num_matches; i++)
1856             {
1857                 error_msg.append ("\n\t");
1858                 error_msg.append (matches.GetStringAtIndex (i));
1859             }
1860             error_msg.append ("\n");
1861             result.AppendRawError (error_msg.c_str());
1862         }
1863         else
1864             result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0));
1865 
1866         result.SetStatus (eReturnStatusFailed);
1867     }
1868 
1869     if (log)
1870       log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed"));
1871 
1872     return result.Succeeded();
1873 }
1874 
1875 int
1876 CommandInterpreter::HandleCompletionMatches (Args &parsed_line,
1877                                              int &cursor_index,
1878                                              int &cursor_char_position,
1879                                              int match_start_point,
1880                                              int max_return_elements,
1881                                              bool &word_complete,
1882                                              StringList &matches)
1883 {
1884     int num_command_matches = 0;
1885     bool look_for_subcommand = false;
1886 
1887     // For any of the command completions a unique match will be a complete word.
1888     word_complete = true;
1889 
1890     if (cursor_index == -1)
1891     {
1892         // We got nothing on the command line, so return the list of commands
1893         bool include_aliases = true;
1894         num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches);
1895     }
1896     else if (cursor_index == 0)
1897     {
1898         // The cursor is in the first argument, so just do a lookup in the dictionary.
1899         CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches);
1900         num_command_matches = matches.GetSize();
1901 
1902         if (num_command_matches == 1
1903             && cmd_obj && cmd_obj->IsMultiwordObject()
1904             && matches.GetStringAtIndex(0) != nullptr
1905             && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0)
1906         {
1907             if (parsed_line.GetArgumentCount() == 1)
1908             {
1909                 word_complete = true;
1910             }
1911             else
1912             {
1913                 look_for_subcommand = true;
1914                 num_command_matches = 0;
1915                 matches.DeleteStringAtIndex(0);
1916                 parsed_line.AppendArgument ("");
1917                 cursor_index++;
1918                 cursor_char_position = 0;
1919             }
1920         }
1921     }
1922 
1923     if (cursor_index > 0 || look_for_subcommand)
1924     {
1925         // We are completing further on into a commands arguments, so find the command and tell it
1926         // to complete the command.
1927         // First see if there is a matching initial command:
1928         CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0));
1929         if (command_object == nullptr)
1930         {
1931             return 0;
1932         }
1933         else
1934         {
1935             parsed_line.Shift();
1936             cursor_index--;
1937             num_command_matches = command_object->HandleCompletion (parsed_line,
1938                                                                     cursor_index,
1939                                                                     cursor_char_position,
1940                                                                     match_start_point,
1941                                                                     max_return_elements,
1942                                                                     word_complete,
1943                                                                     matches);
1944         }
1945     }
1946 
1947     return num_command_matches;
1948 
1949 }
1950 
1951 int
1952 CommandInterpreter::HandleCompletion (const char *current_line,
1953                                       const char *cursor,
1954                                       const char *last_char,
1955                                       int match_start_point,
1956                                       int max_return_elements,
1957                                       StringList &matches)
1958 {
1959     // We parse the argument up to the cursor, so the last argument in parsed_line is
1960     // the one containing the cursor, and the cursor is after the last character.
1961 
1962     Args parsed_line(llvm::StringRef(current_line, last_char - current_line));
1963     Args partial_parsed_line(llvm::StringRef(current_line, cursor - current_line));
1964 
1965     // Don't complete comments, and if the line we are completing is just the history repeat character,
1966     // substitute the appropriate history line.
1967     const char *first_arg = parsed_line.GetArgumentAtIndex(0);
1968     if (first_arg)
1969     {
1970         if (first_arg[0] == m_comment_char)
1971             return 0;
1972         else if (first_arg[0] == CommandHistory::g_repeat_char)
1973         {
1974             const char *history_string = m_command_history.FindString (first_arg);
1975             if (history_string != nullptr)
1976             {
1977                 matches.Clear();
1978                 matches.InsertStringAtIndex(0, history_string);
1979                 return -2;
1980             }
1981             else
1982                 return 0;
1983 
1984         }
1985     }
1986 
1987 
1988     int num_args = partial_parsed_line.GetArgumentCount();
1989     int cursor_index = partial_parsed_line.GetArgumentCount() - 1;
1990     int cursor_char_position;
1991 
1992     if (cursor_index == -1)
1993         cursor_char_position = 0;
1994     else
1995         cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index));
1996 
1997     if (cursor > current_line && cursor[-1] == ' ')
1998     {
1999         // We are just after a space.  If we are in an argument, then we will continue
2000         // parsing, but if we are between arguments, then we have to complete whatever the next
2001         // element would be.
2002         // We can distinguish the two cases because if we are in an argument (e.g. because the space is
2003         // protected by a quote) then the space will also be in the parsed argument...
2004 
2005         const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index);
2006         if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ')
2007         {
2008             parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '\0');
2009             cursor_index++;
2010             cursor_char_position = 0;
2011         }
2012     }
2013 
2014     int num_command_matches;
2015 
2016     matches.Clear();
2017 
2018     // Only max_return_elements == -1 is supported at present:
2019     assert (max_return_elements == -1);
2020     bool word_complete;
2021     num_command_matches = HandleCompletionMatches (parsed_line,
2022                                                    cursor_index,
2023                                                    cursor_char_position,
2024                                                    match_start_point,
2025                                                    max_return_elements,
2026                                                    word_complete,
2027                                                    matches);
2028 
2029     if (num_command_matches <= 0)
2030         return num_command_matches;
2031 
2032     if (num_args == 0)
2033     {
2034         // If we got an empty string, insert nothing.
2035         matches.InsertStringAtIndex(0, "");
2036     }
2037     else
2038     {
2039         // Now figure out if there is a common substring, and if so put that in element 0, otherwise
2040         // put an empty string in element 0.
2041         std::string command_partial_str;
2042         if (cursor_index >= 0)
2043             command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index),
2044                                        parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position);
2045 
2046         std::string common_prefix;
2047         matches.LongestCommonPrefix (common_prefix);
2048         const size_t partial_name_len = command_partial_str.size();
2049         common_prefix.erase (0, partial_name_len);
2050 
2051         // If we matched a unique single command, add a space...
2052         // Only do this if the completer told us this was a complete word, however...
2053         if (num_command_matches == 1 && word_complete)
2054         {
2055             char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index);
2056             common_prefix = Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
2057             if (quote_char != '\0')
2058                 common_prefix.push_back(quote_char);
2059             common_prefix.push_back(' ');
2060         }
2061         matches.InsertStringAtIndex(0, common_prefix.c_str());
2062     }
2063     return num_command_matches;
2064 }
2065 
2066 
2067 CommandInterpreter::~CommandInterpreter ()
2068 {
2069 }
2070 
2071 void
2072 CommandInterpreter::UpdatePrompt (const char *new_prompt)
2073 {
2074     EventSP prompt_change_event_sp (new Event(eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
2075     BroadcastEvent (prompt_change_event_sp);
2076     if (m_command_io_handler_sp)
2077         m_command_io_handler_sp->SetPrompt(new_prompt);
2078 }
2079 
2080 
2081 bool
2082 CommandInterpreter::Confirm (const char *message, bool default_answer)
2083 {
2084     // Check AutoConfirm first:
2085     if (m_debugger.GetAutoConfirm())
2086         return default_answer;
2087 
2088     IOHandlerConfirm *confirm = new IOHandlerConfirm(m_debugger,
2089                                                      message,
2090                                                      default_answer);
2091     IOHandlerSP io_handler_sp (confirm);
2092     m_debugger.RunIOHandler (io_handler_sp);
2093     return confirm->GetResponse();
2094 }
2095 
2096 OptionArgVectorSP
2097 CommandInterpreter::GetAliasOptions (const char *alias_name)
2098 {
2099     OptionArgMap::iterator pos;
2100     OptionArgVectorSP ret_val;
2101 
2102     std::string alias (alias_name);
2103 
2104     if (HasAliasOptions())
2105     {
2106         pos = m_alias_options.find (alias);
2107         if (pos != m_alias_options.end())
2108           ret_val = pos->second;
2109     }
2110 
2111     return ret_val;
2112 }
2113 
2114 void
2115 CommandInterpreter::RemoveAliasOptions (const char *alias_name)
2116 {
2117     OptionArgMap::iterator pos = m_alias_options.find(alias_name);
2118     if (pos != m_alias_options.end())
2119     {
2120         m_alias_options.erase (pos);
2121     }
2122 }
2123 
2124 void
2125 CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp)
2126 {
2127     m_alias_options[alias_name] = option_arg_vector_sp;
2128 }
2129 
2130 bool
2131 CommandInterpreter::HasCommands ()
2132 {
2133     return (!m_command_dict.empty());
2134 }
2135 
2136 bool
2137 CommandInterpreter::HasAliases ()
2138 {
2139     return (!m_alias_dict.empty());
2140 }
2141 
2142 bool
2143 CommandInterpreter::HasUserCommands ()
2144 {
2145     return (!m_user_dict.empty());
2146 }
2147 
2148 bool
2149 CommandInterpreter::HasAliasOptions ()
2150 {
2151     return (!m_alias_options.empty());
2152 }
2153 
2154 void
2155 CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
2156                                            const char *alias_name,
2157                                            Args &cmd_args,
2158                                            std::string &raw_input_string,
2159                                            CommandReturnObject &result)
2160 {
2161     OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
2162 
2163     bool wants_raw_input = alias_cmd_obj->WantsRawCommandString();
2164 
2165     // Make sure that the alias name is the 0th element in cmd_args
2166     std::string alias_name_str = alias_name;
2167     if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)
2168         cmd_args.Unshift (alias_name);
2169 
2170     Args new_args (alias_cmd_obj->GetCommandName());
2171     if (new_args.GetArgumentCount() == 2)
2172         new_args.Shift();
2173 
2174     if (option_arg_vector_sp.get())
2175     {
2176         if (wants_raw_input)
2177         {
2178             // We have a command that both has command options and takes raw input.  Make *sure* it has a
2179             // " -- " in the right place in the raw_input_string.
2180             size_t pos = raw_input_string.find(" -- ");
2181             if (pos == std::string::npos)
2182             {
2183                 // None found; assume it goes at the beginning of the raw input string
2184                 raw_input_string.insert (0, " -- ");
2185             }
2186         }
2187 
2188         OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
2189         const size_t old_size = cmd_args.GetArgumentCount();
2190         std::vector<bool> used (old_size + 1, false);
2191 
2192         used[0] = true;
2193 
2194         for (size_t i = 0; i < option_arg_vector->size(); ++i)
2195         {
2196             OptionArgPair option_pair = (*option_arg_vector)[i];
2197             OptionArgValue value_pair = option_pair.second;
2198             int value_type = value_pair.first;
2199             std::string option = option_pair.first;
2200             std::string value = value_pair.second;
2201             if (option.compare ("<argument>") == 0)
2202             {
2203                 if (!wants_raw_input
2204                     || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice
2205                     new_args.AppendArgument (value.c_str());
2206             }
2207             else
2208             {
2209                 if (value_type != OptionParser::eOptionalArgument)
2210                     new_args.AppendArgument (option.c_str());
2211                 if (value.compare ("<no-argument>") != 0)
2212                 {
2213                     int index = GetOptionArgumentPosition (value.c_str());
2214                     if (index == 0)
2215                     {
2216                         // value was NOT a positional argument; must be a real value
2217                         if (value_type != OptionParser::eOptionalArgument)
2218                             new_args.AppendArgument (value.c_str());
2219                         else
2220                         {
2221                             char buffer[255];
2222                             ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str());
2223                             new_args.AppendArgument (buffer);
2224                         }
2225 
2226                     }
2227                     else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount())
2228                     {
2229                         result.AppendErrorWithFormat
2230                                     ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
2231                                      index);
2232                         result.SetStatus (eReturnStatusFailed);
2233                         return;
2234                     }
2235                     else
2236                     {
2237                         // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string
2238                         size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
2239                         if (strpos != std::string::npos)
2240                         {
2241                             raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index)));
2242                         }
2243 
2244                         if (value_type != OptionParser::eOptionalArgument)
2245                             new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index));
2246                         else
2247                         {
2248                             char buffer[255];
2249                             ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(),
2250                                         cmd_args.GetArgumentAtIndex (index));
2251                             new_args.AppendArgument (buffer);
2252                         }
2253                         used[index] = true;
2254                     }
2255                 }
2256             }
2257         }
2258 
2259         for (size_t j = 0; j < cmd_args.GetArgumentCount(); ++j)
2260         {
2261             if (!used[j] && !wants_raw_input)
2262                 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j));
2263         }
2264 
2265         cmd_args.Clear();
2266         cmd_args.SetArguments (new_args.GetArgumentCount(), new_args.GetConstArgumentVector());
2267     }
2268     else
2269     {
2270         result.SetStatus (eReturnStatusSuccessFinishNoResult);
2271         // This alias was not created with any options; nothing further needs to be done, unless it is a command that
2272         // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw
2273         // input string.
2274         if (wants_raw_input)
2275         {
2276             cmd_args.Clear();
2277             cmd_args.SetArguments (new_args.GetArgumentCount(), new_args.GetConstArgumentVector());
2278         }
2279         return;
2280     }
2281 
2282     result.SetStatus (eReturnStatusSuccessFinishNoResult);
2283     return;
2284 }
2285 
2286 
2287 int
2288 CommandInterpreter::GetOptionArgumentPosition (const char *in_string)
2289 {
2290     int position = 0;   // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position
2291                         // of zero.
2292 
2293     const char *cptr = in_string;
2294 
2295     // Does it start with '%'
2296     if (cptr[0] == '%')
2297     {
2298         ++cptr;
2299 
2300         // Is the rest of it entirely digits?
2301         if (isdigit (cptr[0]))
2302         {
2303             const char *start = cptr;
2304             while (isdigit (cptr[0]))
2305                 ++cptr;
2306 
2307             // We've gotten to the end of the digits; are we at the end of the string?
2308             if (cptr[0] == '\0')
2309                 position = atoi (start);
2310         }
2311     }
2312 
2313     return position;
2314 }
2315 
2316 void
2317 CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
2318 {
2319     FileSpec init_file;
2320     if (in_cwd)
2321     {
2322         ExecutionContext exe_ctx(GetExecutionContext());
2323         Target *target = exe_ctx.GetTargetPtr();
2324         if (target)
2325         {
2326             // In the current working directory we don't load any program specific
2327             // .lldbinit files, we only look for a ".lldbinit" file.
2328             if (m_skip_lldbinit_files)
2329                 return;
2330 
2331             LoadCWDlldbinitFile should_load = target->TargetProperties::GetLoadCWDlldbinitFile ();
2332             if (should_load == eLoadCWDlldbinitWarn)
2333             {
2334                 FileSpec dot_lldb (".lldbinit", true);
2335                 llvm::SmallString<64> home_dir_path;
2336                 llvm::sys::path::home_directory (home_dir_path);
2337                 FileSpec homedir_dot_lldb (home_dir_path.c_str(), false);
2338                 homedir_dot_lldb.AppendPathComponent (".lldbinit");
2339                 homedir_dot_lldb.ResolvePath ();
2340                 if (dot_lldb.Exists ()
2341                     && dot_lldb.GetDirectory() != homedir_dot_lldb.GetDirectory())
2342                 {
2343                     result.AppendErrorWithFormat (
2344                             "There is a .lldbinit file in the current directory which is not being read.\n"
2345                             "To silence this warning without sourcing in the local .lldbinit,\n"
2346                             "add the following to the lldbinit file in your home directory:\n"
2347                             "    settings set target.load-cwd-lldbinit false\n"
2348                             "To allow lldb to source .lldbinit files in the current working directory,\n"
2349                             "set the value of this variable to true.  Only do so if you understand and\n"
2350                             "accept the security risk.");
2351                     result.SetStatus (eReturnStatusFailed);
2352                     return;
2353                 }
2354             }
2355             else if (should_load == eLoadCWDlldbinitTrue)
2356             {
2357                 init_file.SetFile ("./.lldbinit", true);
2358             }
2359         }
2360     }
2361     else
2362     {
2363         // If we aren't looking in the current working directory we are looking
2364         // in the home directory. We will first see if there is an application
2365         // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a
2366         // "-" and the name of the program. If this file doesn't exist, we fall
2367         // back to just the "~/.lldbinit" file. We also obey any requests to not
2368         // load the init files.
2369         llvm::SmallString<64> home_dir_path;
2370         llvm::sys::path::home_directory(home_dir_path);
2371         FileSpec profilePath(home_dir_path.c_str(), false);
2372         profilePath.AppendPathComponent(".lldbinit");
2373         std::string init_file_path = profilePath.GetPath();
2374 
2375         if (m_skip_app_init_files == false)
2376         {
2377             FileSpec program_file_spec(HostInfo::GetProgramFileSpec());
2378             const char *program_name = program_file_spec.GetFilename().AsCString();
2379 
2380             if (program_name)
2381             {
2382                 char program_init_file_name[PATH_MAX];
2383                 ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path.c_str(), program_name);
2384                 init_file.SetFile (program_init_file_name, true);
2385                 if (!init_file.Exists())
2386                     init_file.Clear();
2387             }
2388         }
2389 
2390         if (!init_file && !m_skip_lldbinit_files)
2391 			init_file.SetFile (init_file_path.c_str(), false);
2392     }
2393 
2394     // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting
2395     // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details).
2396 
2397     if (init_file.Exists())
2398     {
2399         const bool saved_batch = SetBatchCommandMode (true);
2400         CommandInterpreterRunOptions options;
2401         options.SetSilent (true);
2402         options.SetStopOnError (false);
2403         options.SetStopOnContinue (true);
2404 
2405         HandleCommandsFromFile (init_file,
2406                                 nullptr,           // Execution context
2407                                 options,
2408                                 result);
2409         SetBatchCommandMode (saved_batch);
2410     }
2411     else
2412     {
2413         // nothing to be done if the file doesn't exist
2414         result.SetStatus(eReturnStatusSuccessFinishNoResult);
2415     }
2416 }
2417 
2418 const char *
2419 CommandInterpreter::GetCommandPrefix()
2420 {
2421     const char * prefix = GetDebugger().GetIOHandlerCommandPrefix();
2422     return prefix == NULL ? "" : prefix;
2423 }
2424 
2425 PlatformSP
2426 CommandInterpreter::GetPlatform (bool prefer_target_platform)
2427 {
2428     PlatformSP platform_sp;
2429     if (prefer_target_platform)
2430     {
2431         ExecutionContext exe_ctx(GetExecutionContext());
2432         Target *target = exe_ctx.GetTargetPtr();
2433         if (target)
2434             platform_sp = target->GetPlatform();
2435     }
2436 
2437     if (!platform_sp)
2438         platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform();
2439     return platform_sp;
2440 }
2441 
2442 void
2443 CommandInterpreter::HandleCommands (const StringList &commands,
2444                                     ExecutionContext *override_context,
2445                                     CommandInterpreterRunOptions &options,
2446                                     CommandReturnObject &result)
2447 {
2448     size_t num_lines = commands.GetSize();
2449 
2450     // If we are going to continue past a "continue" then we need to run the commands synchronously.
2451     // Make sure you reset this value anywhere you return from the function.
2452 
2453     bool old_async_execution = m_debugger.GetAsyncExecution();
2454 
2455     // If we've been given an execution context, set it at the start, but don't keep resetting it or we will
2456     // cause series of commands that change the context, then do an operation that relies on that context to fail.
2457 
2458     if (override_context != nullptr)
2459         UpdateExecutionContext (override_context);
2460 
2461     if (!options.GetStopOnContinue())
2462     {
2463         m_debugger.SetAsyncExecution (false);
2464     }
2465 
2466     for (size_t idx = 0; idx < num_lines; idx++)
2467     {
2468         const char *cmd = commands.GetStringAtIndex(idx);
2469         if (cmd[0] == '\0')
2470             continue;
2471 
2472         if (options.GetEchoCommands())
2473         {
2474             result.AppendMessageWithFormat ("%s %s\n",
2475                                             m_debugger.GetPrompt(),
2476                                             cmd);
2477         }
2478 
2479         CommandReturnObject tmp_result;
2480         // If override_context is not NULL, pass no_context_switching = true for
2481         // HandleCommand() since we updated our context already.
2482 
2483         // We might call into a regex or alias command, in which case the add_to_history will get lost.  This
2484         // m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here.
2485         if (!options.GetAddToHistory())
2486             m_command_source_depth++;
2487         bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result,
2488                                      nullptr, /* override_context */
2489                                      true, /* repeat_on_empty_command */
2490                                      override_context != nullptr /* no_context_switching */);
2491         if (!options.GetAddToHistory())
2492             m_command_source_depth--;
2493 
2494         if (options.GetPrintResults())
2495         {
2496             if (tmp_result.Succeeded())
2497               result.AppendMessageWithFormat("%s", tmp_result.GetOutputData());
2498         }
2499 
2500         if (!success || !tmp_result.Succeeded())
2501         {
2502             const char *error_msg = tmp_result.GetErrorData();
2503             if (error_msg == nullptr || error_msg[0] == '\0')
2504                 error_msg = "<unknown error>.\n";
2505             if (options.GetStopOnError())
2506             {
2507                 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s",
2508                                                 (uint64_t)idx, cmd, error_msg);
2509                 result.SetStatus (eReturnStatusFailed);
2510                 m_debugger.SetAsyncExecution (old_async_execution);
2511                 return;
2512             }
2513             else if (options.GetPrintResults())
2514             {
2515                 result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s",
2516                                                 (uint64_t)idx + 1,
2517                                                 cmd,
2518                                                 error_msg);
2519             }
2520         }
2521 
2522         if (result.GetImmediateOutputStream())
2523             result.GetImmediateOutputStream()->Flush();
2524 
2525         if (result.GetImmediateErrorStream())
2526             result.GetImmediateErrorStream()->Flush();
2527 
2528         // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution
2529         // could be running (for instance in Breakpoint Commands.
2530         // So we check the return value to see if it is has running in it.
2531         if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
2532                 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult))
2533         {
2534             if (options.GetStopOnContinue())
2535             {
2536                 // If we caused the target to proceed, and we're going to stop in that case, set the
2537                 // status in our real result before returning.  This is an error if the continue was not the
2538                 // last command in the set of commands to be run.
2539                 if (idx != num_lines - 1)
2540                     result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' continued the target.\n",
2541                                                  (uint64_t)idx + 1, cmd);
2542                 else
2543                     result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' continued the target.\n", (uint64_t)idx + 1, cmd);
2544 
2545                 result.SetStatus(tmp_result.GetStatus());
2546                 m_debugger.SetAsyncExecution (old_async_execution);
2547 
2548                 return;
2549             }
2550         }
2551 
2552         // Also check for "stop on crash here:
2553         bool should_stop = false;
2554         if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash())
2555         {
2556             TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
2557             if (target_sp)
2558             {
2559                 ProcessSP process_sp (target_sp->GetProcessSP());
2560                 if (process_sp)
2561                 {
2562                     for (ThreadSP thread_sp : process_sp->GetThreadList().Threads())
2563                     {
2564                         StopReason reason = thread_sp->GetStopReason();
2565                         if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation)
2566                         {
2567                             should_stop = true;
2568                             break;
2569                         }
2570                     }
2571                 }
2572             }
2573             if (should_stop)
2574             {
2575                 if (idx != num_lines - 1)
2576                     result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' stopped with a signal or exception.\n",
2577                                                  (uint64_t)idx + 1, cmd);
2578                 else
2579                     result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' stopped with a signal or exception.\n", (uint64_t)idx + 1, cmd);
2580 
2581                 result.SetStatus(tmp_result.GetStatus());
2582                 m_debugger.SetAsyncExecution (old_async_execution);
2583 
2584                 return;
2585             }
2586         }
2587 
2588     }
2589 
2590     result.SetStatus (eReturnStatusSuccessFinishResult);
2591     m_debugger.SetAsyncExecution (old_async_execution);
2592 
2593     return;
2594 }
2595 
2596 // Make flags that we can pass into the IOHandler so our delegates can do the right thing
2597 enum {
2598     eHandleCommandFlagStopOnContinue = (1u << 0),
2599     eHandleCommandFlagStopOnError    = (1u << 1),
2600     eHandleCommandFlagEchoCommand    = (1u << 2),
2601     eHandleCommandFlagPrintResult    = (1u << 3),
2602     eHandleCommandFlagStopOnCrash    = (1u << 4)
2603 };
2604 
2605 void
2606 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
2607                                             ExecutionContext *context,
2608                                             CommandInterpreterRunOptions &options,
2609                                             CommandReturnObject &result)
2610 {
2611     if (cmd_file.Exists())
2612     {
2613         StreamFileSP input_file_sp (new StreamFile());
2614 
2615         std::string cmd_file_path = cmd_file.GetPath();
2616         Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), File::eOpenOptionRead);
2617 
2618         if (error.Success())
2619         {
2620             Debugger &debugger = GetDebugger();
2621 
2622             uint32_t flags = 0;
2623 
2624             if (options.m_stop_on_continue == eLazyBoolCalculate)
2625             {
2626                 if (m_command_source_flags.empty())
2627                 {
2628                     // Stop on continue by default
2629                     flags |= eHandleCommandFlagStopOnContinue;
2630                 }
2631                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnContinue)
2632                 {
2633                     flags |= eHandleCommandFlagStopOnContinue;
2634                 }
2635             }
2636             else if (options.m_stop_on_continue == eLazyBoolYes)
2637             {
2638                 flags |= eHandleCommandFlagStopOnContinue;
2639             }
2640 
2641             if (options.m_stop_on_error == eLazyBoolCalculate)
2642             {
2643                 if (m_command_source_flags.empty())
2644                 {
2645                     if (GetStopCmdSourceOnError())
2646                         flags |= eHandleCommandFlagStopOnError;
2647                 }
2648                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnError)
2649                 {
2650                     flags |= eHandleCommandFlagStopOnError;
2651                 }
2652             }
2653             else if (options.m_stop_on_error == eLazyBoolYes)
2654             {
2655                 flags |= eHandleCommandFlagStopOnError;
2656             }
2657 
2658             if (options.GetStopOnCrash())
2659             {
2660                 if (m_command_source_flags.empty())
2661                 {
2662                     // Echo command by default
2663                     flags |= eHandleCommandFlagStopOnCrash;
2664                 }
2665                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnCrash)
2666                 {
2667                     flags |= eHandleCommandFlagStopOnCrash;
2668                 }
2669             }
2670 
2671             if (options.m_echo_commands == eLazyBoolCalculate)
2672             {
2673                 if (m_command_source_flags.empty())
2674                 {
2675                     // Echo command by default
2676                     flags |= eHandleCommandFlagEchoCommand;
2677                 }
2678                 else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand)
2679                 {
2680                     flags |= eHandleCommandFlagEchoCommand;
2681                 }
2682             }
2683             else if (options.m_echo_commands == eLazyBoolYes)
2684             {
2685                 flags |= eHandleCommandFlagEchoCommand;
2686             }
2687 
2688             if (options.m_print_results == eLazyBoolCalculate)
2689             {
2690                 if (m_command_source_flags.empty())
2691                 {
2692                     // Print output by default
2693                     flags |= eHandleCommandFlagPrintResult;
2694                 }
2695                 else if (m_command_source_flags.back() & eHandleCommandFlagPrintResult)
2696                 {
2697                     flags |= eHandleCommandFlagPrintResult;
2698                 }
2699             }
2700             else if (options.m_print_results == eLazyBoolYes)
2701             {
2702                 flags |= eHandleCommandFlagPrintResult;
2703             }
2704 
2705             if (flags & eHandleCommandFlagPrintResult)
2706             {
2707                 debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", cmd_file_path.c_str());
2708             }
2709 
2710             // Used for inheriting the right settings when "command source" might have
2711             // nested "command source" commands
2712             lldb::StreamFileSP empty_stream_sp;
2713             m_command_source_flags.push_back(flags);
2714             IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
2715                                                               IOHandler::Type::CommandInterpreter,
2716                                                               input_file_sp,
2717                                                               empty_stream_sp, // Pass in an empty stream so we inherit the top input reader output stream
2718                                                               empty_stream_sp, // Pass in an empty stream so we inherit the top input reader error stream
2719                                                               flags,
2720                                                               nullptr, // Pass in NULL for "editline_name" so no history is saved, or written
2721                                                               debugger.GetPrompt(),
2722                                                               NULL,
2723                                                               false, // Not multi-line
2724                                                               debugger.GetUseColor(),
2725                                                               0,
2726                                                               *this));
2727             const bool old_async_execution = debugger.GetAsyncExecution();
2728 
2729             // Set synchronous execution if we are not stopping on continue
2730             if ((flags & eHandleCommandFlagStopOnContinue) == 0)
2731                 debugger.SetAsyncExecution (false);
2732 
2733             m_command_source_depth++;
2734 
2735             debugger.RunIOHandler(io_handler_sp);
2736             if (!m_command_source_flags.empty())
2737                 m_command_source_flags.pop_back();
2738             m_command_source_depth--;
2739             result.SetStatus (eReturnStatusSuccessFinishNoResult);
2740             debugger.SetAsyncExecution (old_async_execution);
2741         }
2742         else
2743         {
2744             result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString());
2745             result.SetStatus (eReturnStatusFailed);
2746         }
2747 
2748 
2749     }
2750     else
2751     {
2752         result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n",
2753                                       cmd_file.GetFilename().AsCString("<Unknown>"));
2754         result.SetStatus (eReturnStatusFailed);
2755         return;
2756     }
2757 }
2758 
2759 ScriptInterpreter *
2760 CommandInterpreter::GetScriptInterpreter(bool can_create)
2761 {
2762     if (m_script_interpreter_sp)
2763         return m_script_interpreter_sp.get();
2764 
2765     if (!can_create)
2766         return nullptr;
2767 
2768     lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage();
2769     m_script_interpreter_sp = PluginManager::GetScriptInterpreterForLanguage(script_lang, *this);
2770     return m_script_interpreter_sp.get();
2771 }
2772 
2773 bool
2774 CommandInterpreter::GetSynchronous ()
2775 {
2776     return m_synchronous_execution;
2777 }
2778 
2779 void
2780 CommandInterpreter::SetSynchronous (bool value)
2781 {
2782     m_synchronous_execution  = value;
2783 }
2784 
2785 void
2786 CommandInterpreter::OutputFormattedHelpText (Stream &strm,
2787                                              const char *prefix,
2788                                              const char *help_text)
2789 {
2790     const uint32_t max_columns = m_debugger.GetTerminalWidth();
2791     if (prefix == NULL)
2792         prefix = "";
2793 
2794     size_t prefix_width = strlen(prefix);
2795     size_t line_width_max = max_columns - prefix_width;
2796     const char *help_text_end = help_text + strlen(help_text);
2797     const char *line_start = help_text;
2798     if (line_width_max < 16)
2799         line_width_max = help_text_end - help_text + prefix_width;
2800 
2801     strm.IndentMore (prefix_width);
2802     while (line_start < help_text_end)
2803     {
2804         // Break each line at the first newline or last space/tab before
2805         // the maximum number of characters that fit on a line.  Lines with no
2806         // natural break are left unbroken to wrap.
2807         const char *line_end = help_text_end;
2808         const char *line_scan = line_start;
2809         const char *line_scan_end = help_text_end;
2810         while (line_scan < line_scan_end)
2811         {
2812             char next = *line_scan;
2813             if (next == '\t' || next == ' ')
2814             {
2815                 line_end = line_scan;
2816                 line_scan_end = line_start + line_width_max;
2817             }
2818             else if (next == '\n' || next == '\0')
2819             {
2820                 line_end = line_scan;
2821                 break;
2822             }
2823             ++line_scan;
2824         }
2825 
2826         // Prefix the first line, indent subsequent lines to line up
2827         if (line_start == help_text)
2828             strm.Write (prefix, prefix_width);
2829         else
2830             strm.Indent();
2831         strm.Write (line_start, line_end - line_start);
2832         strm.EOL();
2833 
2834         // When a line breaks at whitespace consume it before continuing
2835         line_start = line_end;
2836         char next = *line_start;
2837         if (next == '\n')
2838             ++line_start;
2839         else while (next == ' ' || next == '\t')
2840             next = *(++line_start);
2841     }
2842     strm.IndentLess (prefix_width);
2843 }
2844 
2845 void
2846 CommandInterpreter::OutputFormattedHelpText (Stream &strm,
2847                                              const char *word_text,
2848                                              const char *separator,
2849                                              const char *help_text,
2850                                              size_t max_word_len)
2851 {
2852     StreamString prefix_stream;
2853     prefix_stream.Printf ("  %-*s %s ",  (int)max_word_len, word_text, separator);
2854     OutputFormattedHelpText (strm, prefix_stream.GetData(), help_text);
2855 }
2856 
2857 void
2858 CommandInterpreter::OutputHelpText (Stream &strm,
2859                                     const char *word_text,
2860                                     const char *separator,
2861                                     const char *help_text,
2862                                     uint32_t max_word_len)
2863 {
2864     int indent_size = max_word_len + strlen (separator) + 2;
2865 
2866     strm.IndentMore (indent_size);
2867 
2868     StreamString text_strm;
2869     text_strm.Printf ("%-*s %s %s",  max_word_len, word_text, separator, help_text);
2870 
2871     const uint32_t max_columns = m_debugger.GetTerminalWidth();
2872 
2873     size_t len = text_strm.GetSize();
2874     const char *text = text_strm.GetData();
2875 
2876     uint32_t chars_left = max_columns;
2877 
2878     for (uint32_t i = 0; i < len; i++)
2879     {
2880         if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n')
2881         {
2882             chars_left = max_columns - indent_size;
2883             strm.EOL();
2884             strm.Indent();
2885         }
2886         else
2887         {
2888             strm.PutChar(text[i]);
2889             chars_left--;
2890         }
2891 
2892     }
2893 
2894     strm.EOL();
2895     strm.IndentLess(indent_size);
2896 }
2897 
2898 void
2899 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
2900                                             StringList &commands_help, bool search_builtin_commands, bool search_user_commands)
2901 {
2902     CommandObject::CommandMap::const_iterator pos;
2903 
2904     if (search_builtin_commands)
2905     {
2906         for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
2907         {
2908             const char *command_name = pos->first.c_str();
2909             CommandObject *cmd_obj = pos->second.get();
2910 
2911             if (cmd_obj->HelpTextContainsWord (search_word))
2912             {
2913                 commands_found.AppendString (command_name);
2914                 commands_help.AppendString (cmd_obj->GetHelp());
2915             }
2916 
2917             if (cmd_obj->IsMultiwordObject())
2918                 cmd_obj->AproposAllSubCommands (command_name,
2919                                                 search_word,
2920                                                 commands_found,
2921                                                 commands_help);
2922 
2923         }
2924     }
2925 
2926     if (search_user_commands)
2927     {
2928         for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
2929         {
2930             const char *command_name = pos->first.c_str();
2931             CommandObject *cmd_obj = pos->second.get();
2932 
2933             if (cmd_obj->HelpTextContainsWord (search_word))
2934             {
2935                 commands_found.AppendString (command_name);
2936                 commands_help.AppendString (cmd_obj->GetHelp());
2937             }
2938 
2939             if (cmd_obj->IsMultiwordObject())
2940                 cmd_obj->AproposAllSubCommands (command_name,
2941                                                 search_word,
2942                                                 commands_found,
2943                                                 commands_help);
2944 
2945         }
2946     }
2947 }
2948 
2949 void
2950 CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
2951 {
2952     if (override_context != nullptr)
2953     {
2954         m_exe_ctx_ref = *override_context;
2955     }
2956     else
2957     {
2958         const bool adopt_selected = true;
2959         m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected);
2960     }
2961 }
2962 
2963 
2964 size_t
2965 CommandInterpreter::GetProcessOutput ()
2966 {
2967     //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
2968     char stdio_buffer[1024];
2969     size_t len;
2970     size_t total_bytes = 0;
2971     Error error;
2972     TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
2973     if (target_sp)
2974     {
2975         ProcessSP process_sp (target_sp->GetProcessSP());
2976         if (process_sp)
2977         {
2978             while ((len = process_sp->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
2979             {
2980                 size_t bytes_written = len;
2981                 m_debugger.GetOutputFile()->Write (stdio_buffer, bytes_written);
2982                 total_bytes += len;
2983             }
2984             while ((len = process_sp->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
2985             {
2986                 size_t bytes_written = len;
2987                 m_debugger.GetErrorFile()->Write (stdio_buffer, bytes_written);
2988                 total_bytes += len;
2989             }
2990         }
2991     }
2992     return total_bytes;
2993 }
2994 
2995 void
2996 CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
2997 {
2998     const bool is_interactive = io_handler.GetIsInteractive();
2999     if (is_interactive == false)
3000     {
3001         // When we are not interactive, don't execute blank lines. This will happen
3002         // sourcing a commands file. We don't want blank lines to repeat the previous
3003         // command and cause any errors to occur (like redefining an alias, get an error
3004         // and stop parsing the commands file).
3005         if (line.empty())
3006             return;
3007 
3008         // When using a non-interactive file handle (like when sourcing commands from a file)
3009         // we need to echo the command out so we don't just see the command output and no
3010         // command...
3011         if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand))
3012             io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str());
3013     }
3014 
3015     lldb_private::CommandReturnObject result;
3016     HandleCommand(line.c_str(), eLazyBoolCalculate, result);
3017 
3018     // Now emit the command output text from the command we just executed
3019     if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult))
3020     {
3021         // Display any STDOUT/STDERR _prior_ to emitting the command result text
3022         GetProcessOutput ();
3023 
3024         if (!result.GetImmediateOutputStream())
3025         {
3026             const char *output = result.GetOutputData();
3027             if (output && output[0])
3028                 io_handler.GetOutputStreamFile()->PutCString(output);
3029         }
3030 
3031         // Now emit the command error text from the command we just executed
3032         if (!result.GetImmediateErrorStream())
3033         {
3034             const char *error = result.GetErrorData();
3035             if (error && error[0])
3036                 io_handler.GetErrorStreamFile()->PutCString(error);
3037         }
3038     }
3039 
3040     switch (result.GetStatus())
3041     {
3042         case eReturnStatusInvalid:
3043         case eReturnStatusSuccessFinishNoResult:
3044         case eReturnStatusSuccessFinishResult:
3045         case eReturnStatusStarted:
3046             break;
3047 
3048         case eReturnStatusSuccessContinuingNoResult:
3049         case eReturnStatusSuccessContinuingResult:
3050             if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue))
3051                 io_handler.SetIsDone(true);
3052             break;
3053 
3054         case eReturnStatusFailed:
3055             m_num_errors++;
3056             if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError))
3057                 io_handler.SetIsDone(true);
3058             break;
3059 
3060         case eReturnStatusQuit:
3061             m_quit_requested = true;
3062             io_handler.SetIsDone(true);
3063             break;
3064     }
3065 
3066     // Finally, if we're going to stop on crash, check that here:
3067     if (!m_quit_requested
3068         && result.GetDidChangeProcessState()
3069         && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash))
3070     {
3071         bool should_stop = false;
3072         TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
3073         if (target_sp)
3074         {
3075             ProcessSP process_sp (target_sp->GetProcessSP());
3076             if (process_sp)
3077             {
3078                 for (ThreadSP thread_sp : process_sp->GetThreadList().Threads())
3079                 {
3080                     StopReason reason = thread_sp->GetStopReason();
3081                     if ((reason == eStopReasonSignal
3082                         || reason == eStopReasonException
3083                         || reason == eStopReasonInstrumentation)
3084                         && !result.GetAbnormalStopWasExpected())
3085                     {
3086                         should_stop = true;
3087                         break;
3088                     }
3089                 }
3090             }
3091         }
3092         if (should_stop)
3093         {
3094             io_handler.SetIsDone(true);
3095             m_stopped_for_crash = true;
3096         }
3097     }
3098 }
3099 
3100 bool
3101 CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler)
3102 {
3103     ExecutionContext exe_ctx (GetExecutionContext());
3104     Process *process = exe_ctx.GetProcessPtr();
3105 
3106     if (process)
3107     {
3108         StateType state = process->GetState();
3109         if (StateIsRunningState(state))
3110         {
3111             process->Halt();
3112             return true; // Don't do any updating when we are running
3113         }
3114     }
3115 
3116     ScriptInterpreter *script_interpreter = GetScriptInterpreter (false);
3117     if (script_interpreter)
3118     {
3119         if (script_interpreter->Interrupt())
3120             return true;
3121     }
3122     return false;
3123 }
3124 
3125 void
3126 CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt,
3127                                                   IOHandlerDelegate &delegate,
3128                                                   bool asynchronously,
3129                                                   void *baton)
3130 {
3131     Debugger &debugger = GetDebugger();
3132     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
3133                                                       IOHandler::Type::CommandList,
3134                                                       "lldb",       // Name of input reader for history
3135                                                       prompt,       // Prompt
3136                                                       NULL,         // Continuation prompt
3137                                                       true,         // Get multiple lines
3138                                                       debugger.GetUseColor(),
3139                                                       0,            // Don't show line numbers
3140                                                       delegate));   // IOHandlerDelegate
3141 
3142     if (io_handler_sp)
3143     {
3144         io_handler_sp->SetUserData (baton);
3145         if (asynchronously)
3146             debugger.PushIOHandler(io_handler_sp);
3147         else
3148             debugger.RunIOHandler(io_handler_sp);
3149     }
3150 
3151 }
3152 
3153 
3154 void
3155 CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt,
3156                                                     IOHandlerDelegate &delegate,
3157                                                     bool asynchronously,
3158                                                     void *baton)
3159 {
3160     Debugger &debugger = GetDebugger();
3161     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
3162                                                       IOHandler::Type::PythonCode,
3163                                                       "lldb-python",    // Name of input reader for history
3164                                                       prompt,           // Prompt
3165                                                       NULL,             // Continuation prompt
3166                                                       true,             // Get multiple lines
3167                                                       debugger.GetUseColor(),
3168                                                       0,                // Don't show line numbers
3169                                                       delegate));       // IOHandlerDelegate
3170 
3171     if (io_handler_sp)
3172     {
3173         io_handler_sp->SetUserData (baton);
3174         if (asynchronously)
3175             debugger.PushIOHandler(io_handler_sp);
3176         else
3177             debugger.RunIOHandler(io_handler_sp);
3178     }
3179 
3180 }
3181 
3182 bool
3183 CommandInterpreter::IsActive ()
3184 {
3185     return m_debugger.IsTopIOHandler (m_command_io_handler_sp);
3186 }
3187 
3188 lldb::IOHandlerSP
3189 CommandInterpreter::GetIOHandler(bool force_create, CommandInterpreterRunOptions *options)
3190 {
3191     // Always re-create the IOHandlerEditline in case the input
3192     // changed. The old instance might have had a non-interactive
3193     // input and now it does or vice versa.
3194     if (force_create || !m_command_io_handler_sp)
3195     {
3196         // Always re-create the IOHandlerEditline in case the input
3197         // changed. The old instance might have had a non-interactive
3198         // input and now it does or vice versa.
3199         uint32_t flags = 0;
3200 
3201         if (options)
3202         {
3203             if (options->m_stop_on_continue == eLazyBoolYes)
3204                 flags |= eHandleCommandFlagStopOnContinue;
3205             if (options->m_stop_on_error == eLazyBoolYes)
3206                 flags |= eHandleCommandFlagStopOnError;
3207             if (options->m_stop_on_crash == eLazyBoolYes)
3208                 flags |= eHandleCommandFlagStopOnCrash;
3209             if (options->m_echo_commands != eLazyBoolNo)
3210                 flags |= eHandleCommandFlagEchoCommand;
3211             if (options->m_print_results != eLazyBoolNo)
3212                 flags |= eHandleCommandFlagPrintResult;
3213         }
3214         else
3215         {
3216             flags = eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult;
3217         }
3218 
3219         m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger,
3220                                                              IOHandler::Type::CommandInterpreter,
3221                                                              m_debugger.GetInputFile(),
3222                                                              m_debugger.GetOutputFile(),
3223                                                              m_debugger.GetErrorFile(),
3224                                                              flags,
3225                                                              "lldb",
3226                                                              m_debugger.GetPrompt(),
3227                                                              NULL,                      // Continuation prompt
3228                                                              false,                     // Don't enable multiple line input, just single line commands
3229                                                              m_debugger.GetUseColor(),
3230                                                              0,            // Don't show line numbers
3231                                                              *this));
3232     }
3233     return m_command_io_handler_sp;
3234 }
3235 
3236 void
3237 CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
3238                                           bool spawn_thread,
3239                                           CommandInterpreterRunOptions &options)
3240 {
3241     // Always re-create the command interpreter when we run it in case
3242     // any file handles have changed.
3243     bool force_create = true;
3244     m_debugger.PushIOHandler(GetIOHandler(force_create, &options));
3245     m_stopped_for_crash = false;
3246 
3247     if (auto_handle_events)
3248         m_debugger.StartEventHandlerThread();
3249 
3250     if (spawn_thread)
3251     {
3252         m_debugger.StartIOHandlerThread();
3253     }
3254     else
3255     {
3256         m_debugger.ExecuteIOHandlers();
3257 
3258         if (auto_handle_events)
3259             m_debugger.StopEventHandlerThread();
3260     }
3261 
3262 }
3263 
3264 CommandObject *
3265 CommandInterpreter::ResolveCommandImpl(std::string &command_line, CommandReturnObject &result)
3266 {
3267     std::string scratch_command(command_line);  // working copy so we don't modify command_line unless we succeed
3268     CommandObject *cmd_obj = nullptr;
3269     StreamString revised_command_line;
3270     bool wants_raw_input = false;
3271     size_t actual_cmd_name_len = 0;
3272     std::string next_word;
3273     StringList matches;
3274     bool done = false;
3275     while (!done)
3276     {
3277         char quote_char = '\0';
3278         std::string suffix;
3279         ExtractCommand(scratch_command, next_word, suffix, quote_char);
3280         if (cmd_obj == nullptr)
3281         {
3282             std::string full_name;
3283             if (GetAliasFullName(next_word.c_str(), full_name))
3284             {
3285                 std::string alias_result;
3286                 cmd_obj = BuildAliasResult(full_name.c_str(), scratch_command, alias_result, result);
3287                 revised_command_line.Printf("%s", alias_result.c_str());
3288                 if (cmd_obj)
3289                 {
3290                     wants_raw_input = cmd_obj->WantsRawCommandString();
3291                     actual_cmd_name_len = strlen(cmd_obj->GetCommandName());
3292                 }
3293             }
3294             else
3295             {
3296                 cmd_obj = GetCommandObject(next_word.c_str(), &matches);
3297                 if (cmd_obj)
3298                 {
3299                     actual_cmd_name_len += strlen(cmd_obj->GetCommandName());
3300                     revised_command_line.Printf("%s", cmd_obj->GetCommandName());
3301                     wants_raw_input = cmd_obj->WantsRawCommandString();
3302                 }
3303                 else
3304                 {
3305                     revised_command_line.Printf ("%s", next_word.c_str());
3306                 }
3307             }
3308         }
3309         else
3310         {
3311             if (cmd_obj->IsMultiwordObject ())
3312             {
3313                 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject(next_word.c_str());
3314                 if (sub_cmd_obj)
3315                 {
3316                     // The subcommand's name includes the parent command's name,
3317                     // so restart rather than append to the revised_command_line.
3318                     actual_cmd_name_len = strlen(sub_cmd_obj->GetCommandName()) + 1;
3319                     revised_command_line.Clear();
3320                     revised_command_line.Printf("%s", sub_cmd_obj->GetCommandName());
3321                     cmd_obj = sub_cmd_obj;
3322                     wants_raw_input = cmd_obj->WantsRawCommandString();
3323                 }
3324                 else
3325                 {
3326                     if (quote_char)
3327                         revised_command_line.Printf(" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
3328                     else
3329                         revised_command_line.Printf(" %s%s", next_word.c_str(), suffix.c_str());
3330                     done = true;
3331                 }
3332             }
3333             else
3334             {
3335                 if (quote_char)
3336                     revised_command_line.Printf(" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
3337                 else
3338                     revised_command_line.Printf(" %s%s", next_word.c_str(), suffix.c_str());
3339                 done = true;
3340             }
3341         }
3342 
3343         if (cmd_obj == nullptr)
3344         {
3345             const size_t num_matches = matches.GetSize();
3346             if (matches.GetSize() > 1) {
3347                 StreamString error_msg;
3348                 error_msg.Printf("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
3349 
3350                 for (uint32_t i = 0; i < num_matches; ++i) {
3351                     error_msg.Printf("\t%s\n", matches.GetStringAtIndex(i));
3352                 }
3353                 result.AppendRawError(error_msg.GetString().c_str());
3354             } else {
3355                 // We didn't have only one match, otherwise we wouldn't get here.
3356                 assert(num_matches == 0);
3357                 result.AppendErrorWithFormat("'%s' is not a valid command.\n", next_word.c_str());
3358             }
3359             result.SetStatus(eReturnStatusFailed);
3360             return nullptr;
3361         }
3362 
3363         if (cmd_obj->IsMultiwordObject())
3364         {
3365             if (!suffix.empty())
3366             {
3367                 result.AppendErrorWithFormat("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n",
3368                                              cmd_obj->GetCommandName(),
3369                                              next_word.empty() ? "" : next_word.c_str(),
3370                                              next_word.empty() ? " -- " : " ",
3371                                              suffix.c_str());
3372                 result.SetStatus(eReturnStatusFailed);
3373                 return nullptr;
3374             }
3375         }
3376         else
3377         {
3378             // If we found a normal command, we are done
3379             done = true;
3380             if (!suffix.empty())
3381             {
3382                 switch (suffix[0])
3383                 {
3384                 case '/':
3385                     // GDB format suffixes
3386                     {
3387                         Options *command_options = cmd_obj->GetOptions();
3388                         if (command_options && command_options->SupportsLongOption("gdb-format"))
3389                         {
3390                             std::string gdb_format_option("--gdb-format=");
3391                             gdb_format_option += (suffix.c_str() + 1);
3392 
3393                             bool inserted = false;
3394                             std::string &cmd = revised_command_line.GetString();
3395                             size_t arg_terminator_idx = FindArgumentTerminator(cmd);
3396                             if (arg_terminator_idx != std::string::npos)
3397                             {
3398                                 // Insert the gdb format option before the "--" that terminates options
3399                                 gdb_format_option.append(1,' ');
3400                                 cmd.insert(arg_terminator_idx, gdb_format_option);
3401                                 inserted = true;
3402                             }
3403 
3404                             if (!inserted)
3405                                 revised_command_line.Printf(" %s", gdb_format_option.c_str());
3406 
3407                             if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos)
3408                                 revised_command_line.PutCString(" --");
3409                         }
3410                         else
3411                         {
3412                             result.AppendErrorWithFormat("the '%s' command doesn't support the --gdb-format option\n",
3413                                                          cmd_obj->GetCommandName());
3414                             result.SetStatus(eReturnStatusFailed);
3415                             return nullptr;
3416                         }
3417                     }
3418                     break;
3419 
3420                 default:
3421                     result.AppendErrorWithFormat("unknown command shorthand suffix: '%s'\n",
3422                                                  suffix.c_str());
3423                     result.SetStatus(eReturnStatusFailed);
3424                     return nullptr;
3425                 }
3426             }
3427         }
3428         if (scratch_command.empty())
3429             done = true;
3430     }
3431 
3432     if (!scratch_command.empty())
3433         revised_command_line.Printf(" %s", scratch_command.c_str());
3434 
3435     if (cmd_obj != NULL)
3436         command_line = revised_command_line.GetData();
3437 
3438     return cmd_obj;
3439 }
3440