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