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