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