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