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