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         // In the current working directory we don't load any program specific
2323         // .lldbinit files, we only look for a "./.lldbinit" file.
2324         if (m_skip_lldbinit_files)
2325             return;
2326 
2327         init_file.SetFile ("./.lldbinit", true);
2328     }
2329     else
2330     {
2331         // If we aren't looking in the current working directory we are looking
2332         // in the home directory. We will first see if there is an application
2333         // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a
2334         // "-" and the name of the program. If this file doesn't exist, we fall
2335         // back to just the "~/.lldbinit" file. We also obey any requests to not
2336         // load the init files.
2337         llvm::SmallString<64> home_dir_path;
2338         llvm::sys::path::home_directory(home_dir_path);
2339         FileSpec profilePath(home_dir_path.c_str(), false);
2340         profilePath.AppendPathComponent(".lldbinit");
2341         std::string init_file_path = profilePath.GetPath();
2342 
2343         if (m_skip_app_init_files == false)
2344         {
2345             FileSpec program_file_spec(HostInfo::GetProgramFileSpec());
2346             const char *program_name = program_file_spec.GetFilename().AsCString();
2347 
2348             if (program_name)
2349             {
2350                 char program_init_file_name[PATH_MAX];
2351                 ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path.c_str(), program_name);
2352                 init_file.SetFile (program_init_file_name, true);
2353                 if (!init_file.Exists())
2354                     init_file.Clear();
2355             }
2356         }
2357 
2358         if (!init_file && !m_skip_lldbinit_files)
2359 			init_file.SetFile (init_file_path.c_str(), false);
2360     }
2361 
2362     // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting
2363     // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details).
2364 
2365     if (init_file.Exists())
2366     {
2367         const bool saved_batch = SetBatchCommandMode (true);
2368         CommandInterpreterRunOptions options;
2369         options.SetSilent (true);
2370         options.SetStopOnError (false);
2371         options.SetStopOnContinue (true);
2372 
2373         HandleCommandsFromFile (init_file,
2374                                 nullptr,           // Execution context
2375                                 options,
2376                                 result);
2377         SetBatchCommandMode (saved_batch);
2378     }
2379     else
2380     {
2381         // nothing to be done if the file doesn't exist
2382         result.SetStatus(eReturnStatusSuccessFinishNoResult);
2383     }
2384 }
2385 
2386 const char *
2387 CommandInterpreter::GetCommandPrefix()
2388 {
2389     const char * prefix = GetDebugger().GetIOHandlerCommandPrefix();
2390     return prefix == NULL ? "" : prefix;
2391 }
2392 
2393 PlatformSP
2394 CommandInterpreter::GetPlatform (bool prefer_target_platform)
2395 {
2396     PlatformSP platform_sp;
2397     if (prefer_target_platform)
2398     {
2399         ExecutionContext exe_ctx(GetExecutionContext());
2400         Target *target = exe_ctx.GetTargetPtr();
2401         if (target)
2402             platform_sp = target->GetPlatform();
2403     }
2404 
2405     if (!platform_sp)
2406         platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform();
2407     return platform_sp;
2408 }
2409 
2410 void
2411 CommandInterpreter::HandleCommands (const StringList &commands,
2412                                     ExecutionContext *override_context,
2413                                     CommandInterpreterRunOptions &options,
2414                                     CommandReturnObject &result)
2415 {
2416     size_t num_lines = commands.GetSize();
2417 
2418     // If we are going to continue past a "continue" then we need to run the commands synchronously.
2419     // Make sure you reset this value anywhere you return from the function.
2420 
2421     bool old_async_execution = m_debugger.GetAsyncExecution();
2422 
2423     // If we've been given an execution context, set it at the start, but don't keep resetting it or we will
2424     // cause series of commands that change the context, then do an operation that relies on that context to fail.
2425 
2426     if (override_context != nullptr)
2427         UpdateExecutionContext (override_context);
2428 
2429     if (!options.GetStopOnContinue())
2430     {
2431         m_debugger.SetAsyncExecution (false);
2432     }
2433 
2434     for (size_t idx = 0; idx < num_lines; idx++)
2435     {
2436         const char *cmd = commands.GetStringAtIndex(idx);
2437         if (cmd[0] == '\0')
2438             continue;
2439 
2440         if (options.GetEchoCommands())
2441         {
2442             result.AppendMessageWithFormat ("%s %s\n",
2443                                             m_debugger.GetPrompt(),
2444                                             cmd);
2445         }
2446 
2447         CommandReturnObject tmp_result;
2448         // If override_context is not NULL, pass no_context_switching = true for
2449         // HandleCommand() since we updated our context already.
2450 
2451         // We might call into a regex or alias command, in which case the add_to_history will get lost.  This
2452         // m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here.
2453         if (!options.GetAddToHistory())
2454             m_command_source_depth++;
2455         bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result,
2456                                      nullptr, /* override_context */
2457                                      true, /* repeat_on_empty_command */
2458                                      override_context != nullptr /* no_context_switching */);
2459         if (!options.GetAddToHistory())
2460             m_command_source_depth--;
2461 
2462         if (options.GetPrintResults())
2463         {
2464             if (tmp_result.Succeeded())
2465               result.AppendMessageWithFormat("%s", tmp_result.GetOutputData());
2466         }
2467 
2468         if (!success || !tmp_result.Succeeded())
2469         {
2470             const char *error_msg = tmp_result.GetErrorData();
2471             if (error_msg == nullptr || error_msg[0] == '\0')
2472                 error_msg = "<unknown error>.\n";
2473             if (options.GetStopOnError())
2474             {
2475                 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s",
2476                                                 (uint64_t)idx, cmd, error_msg);
2477                 result.SetStatus (eReturnStatusFailed);
2478                 m_debugger.SetAsyncExecution (old_async_execution);
2479                 return;
2480             }
2481             else if (options.GetPrintResults())
2482             {
2483                 result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s",
2484                                                 (uint64_t)idx + 1,
2485                                                 cmd,
2486                                                 error_msg);
2487             }
2488         }
2489 
2490         if (result.GetImmediateOutputStream())
2491             result.GetImmediateOutputStream()->Flush();
2492 
2493         if (result.GetImmediateErrorStream())
2494             result.GetImmediateErrorStream()->Flush();
2495 
2496         // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution
2497         // could be running (for instance in Breakpoint Commands.
2498         // So we check the return value to see if it is has running in it.
2499         if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
2500                 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult))
2501         {
2502             if (options.GetStopOnContinue())
2503             {
2504                 // If we caused the target to proceed, and we're going to stop in that case, set the
2505                 // status in our real result before returning.  This is an error if the continue was not the
2506                 // last command in the set of commands to be run.
2507                 if (idx != num_lines - 1)
2508                     result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' continued the target.\n",
2509                                                  (uint64_t)idx + 1, cmd);
2510                 else
2511                     result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' continued the target.\n", (uint64_t)idx + 1, cmd);
2512 
2513                 result.SetStatus(tmp_result.GetStatus());
2514                 m_debugger.SetAsyncExecution (old_async_execution);
2515 
2516                 return;
2517             }
2518         }
2519 
2520         // Also check for "stop on crash here:
2521         bool should_stop = false;
2522         if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash())
2523         {
2524             TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
2525             if (target_sp)
2526             {
2527                 ProcessSP process_sp (target_sp->GetProcessSP());
2528                 if (process_sp)
2529                 {
2530                     for (ThreadSP thread_sp : process_sp->GetThreadList().Threads())
2531                     {
2532                         StopReason reason = thread_sp->GetStopReason();
2533                         if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation)
2534                         {
2535                             should_stop = true;
2536                             break;
2537                         }
2538                     }
2539                 }
2540             }
2541             if (should_stop)
2542             {
2543                 if (idx != num_lines - 1)
2544                     result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' stopped with a signal or exception.\n",
2545                                                  (uint64_t)idx + 1, cmd);
2546                 else
2547                     result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' stopped with a signal or exception.\n", (uint64_t)idx + 1, cmd);
2548 
2549                 result.SetStatus(tmp_result.GetStatus());
2550                 m_debugger.SetAsyncExecution (old_async_execution);
2551 
2552                 return;
2553             }
2554         }
2555 
2556     }
2557 
2558     result.SetStatus (eReturnStatusSuccessFinishResult);
2559     m_debugger.SetAsyncExecution (old_async_execution);
2560 
2561     return;
2562 }
2563 
2564 // Make flags that we can pass into the IOHandler so our delegates can do the right thing
2565 enum {
2566     eHandleCommandFlagStopOnContinue = (1u << 0),
2567     eHandleCommandFlagStopOnError    = (1u << 1),
2568     eHandleCommandFlagEchoCommand    = (1u << 2),
2569     eHandleCommandFlagPrintResult    = (1u << 3),
2570     eHandleCommandFlagStopOnCrash    = (1u << 4)
2571 };
2572 
2573 void
2574 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
2575                                             ExecutionContext *context,
2576                                             CommandInterpreterRunOptions &options,
2577                                             CommandReturnObject &result)
2578 {
2579     if (cmd_file.Exists())
2580     {
2581         StreamFileSP input_file_sp (new StreamFile());
2582 
2583         std::string cmd_file_path = cmd_file.GetPath();
2584         Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), File::eOpenOptionRead);
2585 
2586         if (error.Success())
2587         {
2588             Debugger &debugger = GetDebugger();
2589 
2590             uint32_t flags = 0;
2591 
2592             if (options.m_stop_on_continue == eLazyBoolCalculate)
2593             {
2594                 if (m_command_source_flags.empty())
2595                 {
2596                     // Stop on continue by default
2597                     flags |= eHandleCommandFlagStopOnContinue;
2598                 }
2599                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnContinue)
2600                 {
2601                     flags |= eHandleCommandFlagStopOnContinue;
2602                 }
2603             }
2604             else if (options.m_stop_on_continue == eLazyBoolYes)
2605             {
2606                 flags |= eHandleCommandFlagStopOnContinue;
2607             }
2608 
2609             if (options.m_stop_on_error == eLazyBoolCalculate)
2610             {
2611                 if (m_command_source_flags.empty())
2612                 {
2613                     if (GetStopCmdSourceOnError())
2614                         flags |= eHandleCommandFlagStopOnError;
2615                 }
2616                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnError)
2617                 {
2618                     flags |= eHandleCommandFlagStopOnError;
2619                 }
2620             }
2621             else if (options.m_stop_on_error == eLazyBoolYes)
2622             {
2623                 flags |= eHandleCommandFlagStopOnError;
2624             }
2625 
2626             if (options.GetStopOnCrash())
2627             {
2628                 if (m_command_source_flags.empty())
2629                 {
2630                     // Echo command by default
2631                     flags |= eHandleCommandFlagStopOnCrash;
2632                 }
2633                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnCrash)
2634                 {
2635                     flags |= eHandleCommandFlagStopOnCrash;
2636                 }
2637             }
2638 
2639             if (options.m_echo_commands == eLazyBoolCalculate)
2640             {
2641                 if (m_command_source_flags.empty())
2642                 {
2643                     // Echo command by default
2644                     flags |= eHandleCommandFlagEchoCommand;
2645                 }
2646                 else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand)
2647                 {
2648                     flags |= eHandleCommandFlagEchoCommand;
2649                 }
2650             }
2651             else if (options.m_echo_commands == eLazyBoolYes)
2652             {
2653                 flags |= eHandleCommandFlagEchoCommand;
2654             }
2655 
2656             if (options.m_print_results == eLazyBoolCalculate)
2657             {
2658                 if (m_command_source_flags.empty())
2659                 {
2660                     // Print output by default
2661                     flags |= eHandleCommandFlagPrintResult;
2662                 }
2663                 else if (m_command_source_flags.back() & eHandleCommandFlagPrintResult)
2664                 {
2665                     flags |= eHandleCommandFlagPrintResult;
2666                 }
2667             }
2668             else if (options.m_print_results == eLazyBoolYes)
2669             {
2670                 flags |= eHandleCommandFlagPrintResult;
2671             }
2672 
2673             if (flags & eHandleCommandFlagPrintResult)
2674             {
2675                 debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", cmd_file_path.c_str());
2676             }
2677 
2678             // Used for inheriting the right settings when "command source" might have
2679             // nested "command source" commands
2680             lldb::StreamFileSP empty_stream_sp;
2681             m_command_source_flags.push_back(flags);
2682             IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
2683                                                               IOHandler::Type::CommandInterpreter,
2684                                                               input_file_sp,
2685                                                               empty_stream_sp, // Pass in an empty stream so we inherit the top input reader output stream
2686                                                               empty_stream_sp, // Pass in an empty stream so we inherit the top input reader error stream
2687                                                               flags,
2688                                                               nullptr, // Pass in NULL for "editline_name" so no history is saved, or written
2689                                                               debugger.GetPrompt(),
2690                                                               NULL,
2691                                                               false, // Not multi-line
2692                                                               debugger.GetUseColor(),
2693                                                               0,
2694                                                               *this));
2695             const bool old_async_execution = debugger.GetAsyncExecution();
2696 
2697             // Set synchronous execution if we are not stopping on continue
2698             if ((flags & eHandleCommandFlagStopOnContinue) == 0)
2699                 debugger.SetAsyncExecution (false);
2700 
2701             m_command_source_depth++;
2702 
2703             debugger.RunIOHandler(io_handler_sp);
2704             if (!m_command_source_flags.empty())
2705                 m_command_source_flags.pop_back();
2706             m_command_source_depth--;
2707             result.SetStatus (eReturnStatusSuccessFinishNoResult);
2708             debugger.SetAsyncExecution (old_async_execution);
2709         }
2710         else
2711         {
2712             result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString());
2713             result.SetStatus (eReturnStatusFailed);
2714         }
2715 
2716 
2717     }
2718     else
2719     {
2720         result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n",
2721                                       cmd_file.GetFilename().AsCString("<Unknown>"));
2722         result.SetStatus (eReturnStatusFailed);
2723         return;
2724     }
2725 }
2726 
2727 ScriptInterpreter *
2728 CommandInterpreter::GetScriptInterpreter(bool can_create)
2729 {
2730     if (m_script_interpreter_sp)
2731         return m_script_interpreter_sp.get();
2732 
2733     if (!can_create)
2734         return nullptr;
2735 
2736     lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage();
2737     m_script_interpreter_sp = PluginManager::GetScriptInterpreterForLanguage(script_lang, *this);
2738     return m_script_interpreter_sp.get();
2739 }
2740 
2741 bool
2742 CommandInterpreter::GetSynchronous ()
2743 {
2744     return m_synchronous_execution;
2745 }
2746 
2747 void
2748 CommandInterpreter::SetSynchronous (bool value)
2749 {
2750     m_synchronous_execution  = value;
2751 }
2752 
2753 void
2754 CommandInterpreter::OutputFormattedHelpText (Stream &strm,
2755                                              const char *prefix,
2756                                              const char *help_text)
2757 {
2758     const uint32_t max_columns = m_debugger.GetTerminalWidth();
2759     if (prefix == NULL)
2760         prefix = "";
2761 
2762     size_t prefix_width = strlen(prefix);
2763     size_t line_width_max = max_columns - prefix_width;
2764     const char *help_text_end = help_text + strlen(help_text);
2765     const char *line_start = help_text;
2766     if (line_width_max < 16)
2767         line_width_max = help_text_end - help_text + prefix_width;
2768 
2769     strm.IndentMore (prefix_width);
2770     while (line_start < help_text_end)
2771     {
2772         // Break each line at the first newline or last space/tab before
2773         // the maximum number of characters that fit on a line.  Lines with no
2774         // natural break are left unbroken to wrap.
2775         const char *line_end = help_text_end;
2776         const char *line_scan = line_start;
2777         const char *line_scan_end = help_text_end;
2778         while (line_scan < line_scan_end)
2779         {
2780             char next = *line_scan;
2781             if (next == '\t' || next == ' ')
2782             {
2783                 line_end = line_scan;
2784                 line_scan_end = line_start + line_width_max;
2785             }
2786             else if (next == '\n' || next == '\0')
2787             {
2788                 line_end = line_scan;
2789                 break;
2790             }
2791             ++line_scan;
2792         }
2793 
2794         // Prefix the first line, indent subsequent lines to line up
2795         if (line_start == help_text)
2796             strm.Write (prefix, prefix_width);
2797         else
2798             strm.Indent();
2799         strm.Write (line_start, line_end - line_start);
2800         strm.EOL();
2801 
2802         // When a line breaks at whitespace consume it before continuing
2803         line_start = line_end;
2804         char next = *line_start;
2805         if (next == '\n')
2806             ++line_start;
2807         else while (next == ' ' || next == '\t')
2808             next = *(++line_start);
2809     }
2810     strm.IndentLess (prefix_width);
2811 }
2812 
2813 void
2814 CommandInterpreter::OutputFormattedHelpText (Stream &strm,
2815                                              const char *word_text,
2816                                              const char *separator,
2817                                              const char *help_text,
2818                                              size_t max_word_len)
2819 {
2820     StreamString prefix_stream;
2821     prefix_stream.Printf ("  %-*s %s ",  (int)max_word_len, word_text, separator);
2822     OutputFormattedHelpText (strm, prefix_stream.GetData(), help_text);
2823 }
2824 
2825 void
2826 CommandInterpreter::OutputHelpText (Stream &strm,
2827                                     const char *word_text,
2828                                     const char *separator,
2829                                     const char *help_text,
2830                                     uint32_t max_word_len)
2831 {
2832     int indent_size = max_word_len + strlen (separator) + 2;
2833 
2834     strm.IndentMore (indent_size);
2835 
2836     StreamString text_strm;
2837     text_strm.Printf ("%-*s %s %s",  max_word_len, word_text, separator, help_text);
2838 
2839     const uint32_t max_columns = m_debugger.GetTerminalWidth();
2840 
2841     size_t len = text_strm.GetSize();
2842     const char *text = text_strm.GetData();
2843 
2844     uint32_t chars_left = max_columns;
2845 
2846     for (uint32_t i = 0; i < len; i++)
2847     {
2848         if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n')
2849         {
2850             chars_left = max_columns - indent_size;
2851             strm.EOL();
2852             strm.Indent();
2853         }
2854         else
2855         {
2856             strm.PutChar(text[i]);
2857             chars_left--;
2858         }
2859 
2860     }
2861 
2862     strm.EOL();
2863     strm.IndentLess(indent_size);
2864 }
2865 
2866 void
2867 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
2868                                             StringList &commands_help, bool search_builtin_commands, bool search_user_commands)
2869 {
2870     CommandObject::CommandMap::const_iterator pos;
2871 
2872     if (search_builtin_commands)
2873     {
2874         for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
2875         {
2876             const char *command_name = pos->first.c_str();
2877             CommandObject *cmd_obj = pos->second.get();
2878 
2879             if (cmd_obj->HelpTextContainsWord (search_word))
2880             {
2881                 commands_found.AppendString (command_name);
2882                 commands_help.AppendString (cmd_obj->GetHelp());
2883             }
2884 
2885             if (cmd_obj->IsMultiwordObject())
2886                 cmd_obj->AproposAllSubCommands (command_name,
2887                                                 search_word,
2888                                                 commands_found,
2889                                                 commands_help);
2890 
2891         }
2892     }
2893 
2894     if (search_user_commands)
2895     {
2896         for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
2897         {
2898             const char *command_name = pos->first.c_str();
2899             CommandObject *cmd_obj = pos->second.get();
2900 
2901             if (cmd_obj->HelpTextContainsWord (search_word))
2902             {
2903                 commands_found.AppendString (command_name);
2904                 commands_help.AppendString (cmd_obj->GetHelp());
2905             }
2906 
2907             if (cmd_obj->IsMultiwordObject())
2908                 cmd_obj->AproposAllSubCommands (command_name,
2909                                                 search_word,
2910                                                 commands_found,
2911                                                 commands_help);
2912 
2913         }
2914     }
2915 }
2916 
2917 void
2918 CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
2919 {
2920     if (override_context != nullptr)
2921     {
2922         m_exe_ctx_ref = *override_context;
2923     }
2924     else
2925     {
2926         const bool adopt_selected = true;
2927         m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected);
2928     }
2929 }
2930 
2931 
2932 size_t
2933 CommandInterpreter::GetProcessOutput ()
2934 {
2935     //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
2936     char stdio_buffer[1024];
2937     size_t len;
2938     size_t total_bytes = 0;
2939     Error error;
2940     TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
2941     if (target_sp)
2942     {
2943         ProcessSP process_sp (target_sp->GetProcessSP());
2944         if (process_sp)
2945         {
2946             while ((len = process_sp->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
2947             {
2948                 size_t bytes_written = len;
2949                 m_debugger.GetOutputFile()->Write (stdio_buffer, bytes_written);
2950                 total_bytes += len;
2951             }
2952             while ((len = process_sp->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
2953             {
2954                 size_t bytes_written = len;
2955                 m_debugger.GetErrorFile()->Write (stdio_buffer, bytes_written);
2956                 total_bytes += len;
2957             }
2958         }
2959     }
2960     return total_bytes;
2961 }
2962 
2963 void
2964 CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
2965 {
2966     const bool is_interactive = io_handler.GetIsInteractive();
2967     if (is_interactive == false)
2968     {
2969         // When we are not interactive, don't execute blank lines. This will happen
2970         // sourcing a commands file. We don't want blank lines to repeat the previous
2971         // command and cause any errors to occur (like redefining an alias, get an error
2972         // and stop parsing the commands file).
2973         if (line.empty())
2974             return;
2975 
2976         // When using a non-interactive file handle (like when sourcing commands from a file)
2977         // we need to echo the command out so we don't just see the command output and no
2978         // command...
2979         if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand))
2980             io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str());
2981     }
2982 
2983     lldb_private::CommandReturnObject result;
2984     HandleCommand(line.c_str(), eLazyBoolCalculate, result);
2985 
2986     // Now emit the command output text from the command we just executed
2987     if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult))
2988     {
2989         // Display any STDOUT/STDERR _prior_ to emitting the command result text
2990         GetProcessOutput ();
2991 
2992         if (!result.GetImmediateOutputStream())
2993         {
2994             const char *output = result.GetOutputData();
2995             if (output && output[0])
2996                 io_handler.GetOutputStreamFile()->PutCString(output);
2997         }
2998 
2999         // Now emit the command error text from the command we just executed
3000         if (!result.GetImmediateErrorStream())
3001         {
3002             const char *error = result.GetErrorData();
3003             if (error && error[0])
3004                 io_handler.GetErrorStreamFile()->PutCString(error);
3005         }
3006     }
3007 
3008     switch (result.GetStatus())
3009     {
3010         case eReturnStatusInvalid:
3011         case eReturnStatusSuccessFinishNoResult:
3012         case eReturnStatusSuccessFinishResult:
3013         case eReturnStatusStarted:
3014             break;
3015 
3016         case eReturnStatusSuccessContinuingNoResult:
3017         case eReturnStatusSuccessContinuingResult:
3018             if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue))
3019                 io_handler.SetIsDone(true);
3020             break;
3021 
3022         case eReturnStatusFailed:
3023             m_num_errors++;
3024             if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError))
3025                 io_handler.SetIsDone(true);
3026             break;
3027 
3028         case eReturnStatusQuit:
3029             m_quit_requested = true;
3030             io_handler.SetIsDone(true);
3031             break;
3032     }
3033 
3034     // Finally, if we're going to stop on crash, check that here:
3035     if (!m_quit_requested
3036         && result.GetDidChangeProcessState()
3037         && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash))
3038     {
3039         bool should_stop = false;
3040         TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
3041         if (target_sp)
3042         {
3043             ProcessSP process_sp (target_sp->GetProcessSP());
3044             if (process_sp)
3045             {
3046                 for (ThreadSP thread_sp : process_sp->GetThreadList().Threads())
3047                 {
3048                     StopReason reason = thread_sp->GetStopReason();
3049                     if ((reason == eStopReasonSignal
3050                         || reason == eStopReasonException
3051                         || reason == eStopReasonInstrumentation)
3052                         && !result.GetAbnormalStopWasExpected())
3053                     {
3054                         should_stop = true;
3055                         break;
3056                     }
3057                 }
3058             }
3059         }
3060         if (should_stop)
3061         {
3062             io_handler.SetIsDone(true);
3063             m_stopped_for_crash = true;
3064         }
3065     }
3066 }
3067 
3068 bool
3069 CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler)
3070 {
3071     ExecutionContext exe_ctx (GetExecutionContext());
3072     Process *process = exe_ctx.GetProcessPtr();
3073 
3074     if (process)
3075     {
3076         StateType state = process->GetState();
3077         if (StateIsRunningState(state))
3078         {
3079             process->Halt();
3080             return true; // Don't do any updating when we are running
3081         }
3082     }
3083 
3084     ScriptInterpreter *script_interpreter = GetScriptInterpreter (false);
3085     if (script_interpreter)
3086     {
3087         if (script_interpreter->Interrupt())
3088             return true;
3089     }
3090     return false;
3091 }
3092 
3093 void
3094 CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt,
3095                                                   IOHandlerDelegate &delegate,
3096                                                   bool asynchronously,
3097                                                   void *baton)
3098 {
3099     Debugger &debugger = GetDebugger();
3100     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
3101                                                       IOHandler::Type::CommandList,
3102                                                       "lldb",       // Name of input reader for history
3103                                                       prompt,       // Prompt
3104                                                       NULL,         // Continuation prompt
3105                                                       true,         // Get multiple lines
3106                                                       debugger.GetUseColor(),
3107                                                       0,            // Don't show line numbers
3108                                                       delegate));   // IOHandlerDelegate
3109 
3110     if (io_handler_sp)
3111     {
3112         io_handler_sp->SetUserData (baton);
3113         if (asynchronously)
3114             debugger.PushIOHandler(io_handler_sp);
3115         else
3116             debugger.RunIOHandler(io_handler_sp);
3117     }
3118 
3119 }
3120 
3121 
3122 void
3123 CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt,
3124                                                     IOHandlerDelegate &delegate,
3125                                                     bool asynchronously,
3126                                                     void *baton)
3127 {
3128     Debugger &debugger = GetDebugger();
3129     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
3130                                                       IOHandler::Type::PythonCode,
3131                                                       "lldb-python",    // Name of input reader for history
3132                                                       prompt,           // Prompt
3133                                                       NULL,             // Continuation prompt
3134                                                       true,             // Get multiple lines
3135                                                       debugger.GetUseColor(),
3136                                                       0,                // Don't show line numbers
3137                                                       delegate));       // IOHandlerDelegate
3138 
3139     if (io_handler_sp)
3140     {
3141         io_handler_sp->SetUserData (baton);
3142         if (asynchronously)
3143             debugger.PushIOHandler(io_handler_sp);
3144         else
3145             debugger.RunIOHandler(io_handler_sp);
3146     }
3147 
3148 }
3149 
3150 bool
3151 CommandInterpreter::IsActive ()
3152 {
3153     return m_debugger.IsTopIOHandler (m_command_io_handler_sp);
3154 }
3155 
3156 lldb::IOHandlerSP
3157 CommandInterpreter::GetIOHandler(bool force_create, CommandInterpreterRunOptions *options)
3158 {
3159     // Always re-create the IOHandlerEditline in case the input
3160     // changed. The old instance might have had a non-interactive
3161     // input and now it does or vice versa.
3162     if (force_create || !m_command_io_handler_sp)
3163     {
3164         // Always re-create the IOHandlerEditline in case the input
3165         // changed. The old instance might have had a non-interactive
3166         // input and now it does or vice versa.
3167         uint32_t flags = 0;
3168 
3169         if (options)
3170         {
3171             if (options->m_stop_on_continue == eLazyBoolYes)
3172                 flags |= eHandleCommandFlagStopOnContinue;
3173             if (options->m_stop_on_error == eLazyBoolYes)
3174                 flags |= eHandleCommandFlagStopOnError;
3175             if (options->m_stop_on_crash == eLazyBoolYes)
3176                 flags |= eHandleCommandFlagStopOnCrash;
3177             if (options->m_echo_commands != eLazyBoolNo)
3178                 flags |= eHandleCommandFlagEchoCommand;
3179             if (options->m_print_results != eLazyBoolNo)
3180                 flags |= eHandleCommandFlagPrintResult;
3181         }
3182         else
3183         {
3184             flags = eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult;
3185         }
3186 
3187         m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger,
3188                                                              IOHandler::Type::CommandInterpreter,
3189                                                              m_debugger.GetInputFile(),
3190                                                              m_debugger.GetOutputFile(),
3191                                                              m_debugger.GetErrorFile(),
3192                                                              flags,
3193                                                              "lldb",
3194                                                              m_debugger.GetPrompt(),
3195                                                              NULL,                      // Continuation prompt
3196                                                              false,                     // Don't enable multiple line input, just single line commands
3197                                                              m_debugger.GetUseColor(),
3198                                                              0,            // Don't show line numbers
3199                                                              *this));
3200     }
3201     return m_command_io_handler_sp;
3202 }
3203 
3204 void
3205 CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
3206                                           bool spawn_thread,
3207                                           CommandInterpreterRunOptions &options)
3208 {
3209     // Always re-create the command interpreter when we run it in case
3210     // any file handles have changed.
3211     bool force_create = true;
3212     m_debugger.PushIOHandler(GetIOHandler(force_create, &options));
3213     m_stopped_for_crash = false;
3214 
3215     if (auto_handle_events)
3216         m_debugger.StartEventHandlerThread();
3217 
3218     if (spawn_thread)
3219     {
3220         m_debugger.StartIOHandlerThread();
3221     }
3222     else
3223     {
3224         m_debugger.ExecuteIOHandlers();
3225 
3226         if (auto_handle_events)
3227             m_debugger.StopEventHandlerThread();
3228     }
3229 
3230 }
3231 
3232 CommandObject *
3233 CommandInterpreter::ResolveCommandImpl(std::string &command_line, CommandReturnObject &result)
3234 {
3235     std::string scratch_command(command_line);  // working copy so we don't modify command_line unless we succeed
3236     CommandObject *cmd_obj = nullptr;
3237     StreamString revised_command_line;
3238     bool wants_raw_input = false;
3239     size_t actual_cmd_name_len = 0;
3240     std::string next_word;
3241     StringList matches;
3242     bool done = false;
3243     while (!done)
3244     {
3245         char quote_char = '\0';
3246         std::string suffix;
3247         ExtractCommand(scratch_command, next_word, suffix, quote_char);
3248         if (cmd_obj == nullptr)
3249         {
3250             std::string full_name;
3251             if (GetAliasFullName(next_word.c_str(), full_name))
3252             {
3253                 std::string alias_result;
3254                 cmd_obj = BuildAliasResult(full_name.c_str(), scratch_command, alias_result, result);
3255                 revised_command_line.Printf("%s", alias_result.c_str());
3256                 if (cmd_obj)
3257                 {
3258                     wants_raw_input = cmd_obj->WantsRawCommandString();
3259                     actual_cmd_name_len = strlen(cmd_obj->GetCommandName());
3260                 }
3261             }
3262             else
3263             {
3264                 cmd_obj = GetCommandObject(next_word.c_str(), &matches);
3265                 if (cmd_obj)
3266                 {
3267                     actual_cmd_name_len += strlen(cmd_obj->GetCommandName());
3268                     revised_command_line.Printf("%s", cmd_obj->GetCommandName());
3269                     wants_raw_input = cmd_obj->WantsRawCommandString();
3270                 }
3271                 else
3272                 {
3273                     revised_command_line.Printf ("%s", next_word.c_str());
3274                 }
3275             }
3276         }
3277         else
3278         {
3279             if (cmd_obj->IsMultiwordObject ())
3280             {
3281                 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject(next_word.c_str());
3282                 if (sub_cmd_obj)
3283                 {
3284                     // The subcommand's name includes the parent command's name,
3285                     // so restart rather than append to the revised_command_line.
3286                     actual_cmd_name_len = strlen(sub_cmd_obj->GetCommandName()) + 1;
3287                     revised_command_line.Clear();
3288                     revised_command_line.Printf("%s", sub_cmd_obj->GetCommandName());
3289                     cmd_obj = sub_cmd_obj;
3290                     wants_raw_input = cmd_obj->WantsRawCommandString();
3291                 }
3292                 else
3293                 {
3294                     if (quote_char)
3295                         revised_command_line.Printf(" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
3296                     else
3297                         revised_command_line.Printf(" %s%s", next_word.c_str(), suffix.c_str());
3298                     done = true;
3299                 }
3300             }
3301             else
3302             {
3303                 if (quote_char)
3304                     revised_command_line.Printf(" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
3305                 else
3306                     revised_command_line.Printf(" %s%s", next_word.c_str(), suffix.c_str());
3307                 done = true;
3308             }
3309         }
3310 
3311         if (cmd_obj == nullptr)
3312         {
3313             const size_t num_matches = matches.GetSize();
3314             if (matches.GetSize() > 1) {
3315                 StreamString error_msg;
3316                 error_msg.Printf("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
3317 
3318                 for (uint32_t i = 0; i < num_matches; ++i) {
3319                     error_msg.Printf("\t%s\n", matches.GetStringAtIndex(i));
3320                 }
3321                 result.AppendRawError(error_msg.GetString().c_str());
3322             } else {
3323                 // We didn't have only one match, otherwise we wouldn't get here.
3324                 assert(num_matches == 0);
3325                 result.AppendErrorWithFormat("'%s' is not a valid command.\n", next_word.c_str());
3326             }
3327             result.SetStatus(eReturnStatusFailed);
3328             return nullptr;
3329         }
3330 
3331         if (cmd_obj->IsMultiwordObject())
3332         {
3333             if (!suffix.empty())
3334             {
3335                 result.AppendErrorWithFormat("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n",
3336                                              cmd_obj->GetCommandName(),
3337                                              next_word.empty() ? "" : next_word.c_str(),
3338                                              next_word.empty() ? " -- " : " ",
3339                                              suffix.c_str());
3340                 result.SetStatus(eReturnStatusFailed);
3341                 return nullptr;
3342             }
3343         }
3344         else
3345         {
3346             // If we found a normal command, we are done
3347             done = true;
3348             if (!suffix.empty())
3349             {
3350                 switch (suffix[0])
3351                 {
3352                 case '/':
3353                     // GDB format suffixes
3354                     {
3355                         Options *command_options = cmd_obj->GetOptions();
3356                         if (command_options && command_options->SupportsLongOption("gdb-format"))
3357                         {
3358                             std::string gdb_format_option("--gdb-format=");
3359                             gdb_format_option += (suffix.c_str() + 1);
3360 
3361                             bool inserted = false;
3362                             std::string &cmd = revised_command_line.GetString();
3363                             size_t arg_terminator_idx = FindArgumentTerminator(cmd);
3364                             if (arg_terminator_idx != std::string::npos)
3365                             {
3366                                 // Insert the gdb format option before the "--" that terminates options
3367                                 gdb_format_option.append(1,' ');
3368                                 cmd.insert(arg_terminator_idx, gdb_format_option);
3369                                 inserted = true;
3370                             }
3371 
3372                             if (!inserted)
3373                                 revised_command_line.Printf(" %s", gdb_format_option.c_str());
3374 
3375                             if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos)
3376                                 revised_command_line.PutCString(" --");
3377                         }
3378                         else
3379                         {
3380                             result.AppendErrorWithFormat("the '%s' command doesn't support the --gdb-format option\n",
3381                                                          cmd_obj->GetCommandName());
3382                             result.SetStatus(eReturnStatusFailed);
3383                             return nullptr;
3384                         }
3385                     }
3386                     break;
3387 
3388                 default:
3389                     result.AppendErrorWithFormat("unknown command shorthand suffix: '%s'\n",
3390                                                  suffix.c_str());
3391                     result.SetStatus(eReturnStatusFailed);
3392                     return nullptr;
3393                 }
3394             }
3395         }
3396         if (scratch_command.empty())
3397             done = true;
3398     }
3399 
3400     if (!scratch_command.empty())
3401         revised_command_line.Printf(" %s", scratch_command.c_str());
3402 
3403     if (cmd_obj != NULL)
3404         command_line = revised_command_line.GetData();
3405 
3406     return cmd_obj;
3407 }
3408