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     CommandObject::CommandMap::const_iterator pos;
1174     size_t max_len = FindLongestCommandWord (m_command_dict);
1175 
1176     if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
1177     {
1178 
1179         result.AppendMessage("The following is a list of built-in, permanent debugger commands:");
1180         result.AppendMessage("");
1181 
1182         for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
1183         {
1184             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
1185                                      max_len);
1186         }
1187         result.AppendMessage("");
1188 
1189     }
1190 
1191     if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases ))
1192     {
1193         result.AppendMessage("The following is a list of your current command abbreviations "
1194                              "(see 'help command alias' for more info):");
1195         result.AppendMessage("");
1196         max_len = FindLongestCommandWord (m_alias_dict);
1197 
1198         for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos)
1199         {
1200             StreamString sstr;
1201             StreamString translation_and_help;
1202             std::string entry_name = pos->first;
1203             std::string second_entry = pos->second.get()->GetCommandName();
1204             GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr);
1205 
1206             translation_and_help.Printf ("(%s)  %s", sstr.GetData(), pos->second->GetHelp());
1207             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--",
1208                                      translation_and_help.GetData(), max_len);
1209         }
1210         result.AppendMessage("");
1211     }
1212 
1213     if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef ))
1214     {
1215         result.AppendMessage ("The following is a list of your current user-defined commands:");
1216         result.AppendMessage("");
1217         max_len = FindLongestCommandWord (m_user_dict);
1218         for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
1219         {
1220             OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
1221                                      max_len);
1222         }
1223         result.AppendMessage("");
1224     }
1225 
1226     result.AppendMessage("For more information on any particular command, try 'help <command-name>'.");
1227 }
1228 
1229 CommandObject *
1230 CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
1231 {
1232     // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will
1233     // eventually be invoked by the given command line.
1234 
1235     CommandObject *cmd_obj = nullptr;
1236     std::string white_space (" \t\v");
1237     size_t start = command_string.find_first_not_of (white_space);
1238     size_t end = 0;
1239     bool done = false;
1240     while (!done)
1241     {
1242         if (start != std::string::npos)
1243         {
1244             // Get the next word from command_string.
1245             end = command_string.find_first_of (white_space, start);
1246             if (end == std::string::npos)
1247                 end = command_string.size();
1248             std::string cmd_word = command_string.substr (start, end - start);
1249 
1250             if (cmd_obj == nullptr)
1251                 // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid
1252                 // command or alias.
1253                 cmd_obj = GetCommandObject (cmd_word.c_str());
1254             else if (cmd_obj->IsMultiwordObject ())
1255             {
1256                 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object.
1257                 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str());
1258                 if (sub_cmd_obj)
1259                     cmd_obj = sub_cmd_obj;
1260                 else // cmd_word was not a valid sub-command word, so we are donee
1261                     done = true;
1262             }
1263             else
1264                 // We have a cmd_obj and it is not a multi-word object, so we are done.
1265                 done = true;
1266 
1267             // If we didn't find a valid command object, or our command object is not a multi-word object, or
1268             // we are at the end of the command_string, then we are done.  Otherwise, find the start of the
1269             // next word.
1270 
1271             if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size())
1272                 done = true;
1273             else
1274                 start = command_string.find_first_not_of (white_space, end);
1275         }
1276         else
1277             // Unable to find any more words.
1278             done = true;
1279     }
1280 
1281     if (end == command_string.size())
1282         command_string.clear();
1283     else
1284         command_string = command_string.substr(end);
1285 
1286     return cmd_obj;
1287 }
1288 
1289 static const char *k_white_space = " \t\v";
1290 static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1291 static void
1292 StripLeadingSpaces (std::string &s)
1293 {
1294     if (!s.empty())
1295     {
1296         size_t pos = s.find_first_not_of (k_white_space);
1297         if (pos == std::string::npos)
1298             s.clear();
1299         else if (pos == 0)
1300             return;
1301         s.erase (0, pos);
1302     }
1303 }
1304 
1305 static size_t
1306 FindArgumentTerminator (const std::string &s)
1307 {
1308     const size_t s_len = s.size();
1309     size_t offset = 0;
1310     while (offset < s_len)
1311     {
1312         size_t pos = s.find ("--", offset);
1313         if (pos == std::string::npos)
1314             break;
1315         if (pos > 0)
1316         {
1317             if (isspace(s[pos-1]))
1318             {
1319                 // Check if the string ends "\s--" (where \s is a space character)
1320                 // or if we have "\s--\s".
1321                 if ((pos + 2 >= s_len) || isspace(s[pos+2]))
1322                 {
1323                     return pos;
1324                 }
1325             }
1326         }
1327         offset = pos + 2;
1328     }
1329     return std::string::npos;
1330 }
1331 
1332 static bool
1333 ExtractCommand (std::string &command_string, std::string &command, std::string &suffix, char &quote_char)
1334 {
1335     command.clear();
1336     suffix.clear();
1337     StripLeadingSpaces (command_string);
1338 
1339     bool result = false;
1340     quote_char = '\0';
1341 
1342     if (!command_string.empty())
1343     {
1344         const char first_char = command_string[0];
1345         if (first_char == '\'' || first_char == '"')
1346         {
1347             quote_char = first_char;
1348             const size_t end_quote_pos = command_string.find (quote_char, 1);
1349             if (end_quote_pos == std::string::npos)
1350             {
1351                 command.swap (command_string);
1352                 command_string.erase ();
1353             }
1354             else
1355             {
1356                 command.assign (command_string, 1, end_quote_pos - 1);
1357                 if (end_quote_pos + 1 < command_string.size())
1358                     command_string.erase (0, command_string.find_first_not_of (k_white_space, end_quote_pos + 1));
1359                 else
1360                     command_string.erase ();
1361             }
1362         }
1363         else
1364         {
1365             const size_t first_space_pos = command_string.find_first_of (k_white_space);
1366             if (first_space_pos == std::string::npos)
1367             {
1368                 command.swap (command_string);
1369                 command_string.erase();
1370             }
1371             else
1372             {
1373                 command.assign (command_string, 0, first_space_pos);
1374                 command_string.erase(0, command_string.find_first_not_of (k_white_space, first_space_pos));
1375             }
1376         }
1377         result = true;
1378     }
1379 
1380 
1381     if (!command.empty())
1382     {
1383         // actual commands can't start with '-' or '_'
1384         if (command[0] != '-' && command[0] != '_')
1385         {
1386             size_t pos = command.find_first_not_of(k_valid_command_chars);
1387             if (pos > 0 && pos != std::string::npos)
1388             {
1389                 suffix.assign (command.begin() + pos, command.end());
1390                 command.erase (pos);
1391             }
1392         }
1393     }
1394 
1395     return result;
1396 }
1397 
1398 CommandObject *
1399 CommandInterpreter::BuildAliasResult (const char *alias_name,
1400                                       std::string &raw_input_string,
1401                                       std::string &alias_result,
1402                                       CommandReturnObject &result)
1403 {
1404     CommandObject *alias_cmd_obj = nullptr;
1405     Args cmd_args (raw_input_string.c_str());
1406     alias_cmd_obj = GetCommandObject (alias_name);
1407     StreamString result_str;
1408 
1409     if (alias_cmd_obj)
1410     {
1411         std::string alias_name_str = alias_name;
1412         if ((cmd_args.GetArgumentCount() == 0)
1413             || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0))
1414             cmd_args.Unshift (alias_name);
1415 
1416         result_str.Printf ("%s", alias_cmd_obj->GetCommandName ());
1417         OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
1418 
1419         if (option_arg_vector_sp.get())
1420         {
1421             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
1422 
1423             for (size_t i = 0; i < option_arg_vector->size(); ++i)
1424             {
1425                 OptionArgPair option_pair = (*option_arg_vector)[i];
1426                 OptionArgValue value_pair = option_pair.second;
1427                 int value_type = value_pair.first;
1428                 std::string option = option_pair.first;
1429                 std::string value = value_pair.second;
1430                 if (option.compare ("<argument>") == 0)
1431                     result_str.Printf (" %s", value.c_str());
1432                 else
1433                 {
1434                     result_str.Printf (" %s", option.c_str());
1435                     if (value_type != OptionParser::eOptionalArgument)
1436                         result_str.Printf (" ");
1437                     if (value.compare ("<OptionParser::eNoArgument>") != 0)
1438                     {
1439                         int index = GetOptionArgumentPosition (value.c_str());
1440                         if (index == 0)
1441                             result_str.Printf ("%s", value.c_str());
1442                         else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount())
1443                         {
1444 
1445                             result.AppendErrorWithFormat
1446                             ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
1447                              index);
1448                             result.SetStatus (eReturnStatusFailed);
1449                             return alias_cmd_obj;
1450                         }
1451                         else
1452                         {
1453                             size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
1454                             if (strpos != std::string::npos)
1455                                 raw_input_string = raw_input_string.erase (strpos,
1456                                                                           strlen (cmd_args.GetArgumentAtIndex (index)));
1457                             result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index));
1458                         }
1459                     }
1460                 }
1461             }
1462         }
1463 
1464         alias_result = result_str.GetData();
1465     }
1466     return alias_cmd_obj;
1467 }
1468 
1469 Error
1470 CommandInterpreter::PreprocessCommand (std::string &command)
1471 {
1472     // The command preprocessor needs to do things to the command
1473     // line before any parsing of arguments or anything else is done.
1474     // The only current stuff that gets proprocessed is anyting enclosed
1475     // in backtick ('`') characters is evaluated as an expression and
1476     // the result of the expression must be a scalar that can be substituted
1477     // into the command. An example would be:
1478     // (lldb) memory read `$rsp + 20`
1479     Error error; // Error for any expressions that might not evaluate
1480     size_t start_backtick;
1481     size_t pos = 0;
1482     while ((start_backtick = command.find ('`', pos)) != std::string::npos)
1483     {
1484         if (start_backtick > 0 && command[start_backtick-1] == '\\')
1485         {
1486             // The backtick was preceeded by a '\' character, remove the slash
1487             // and don't treat the backtick as the start of an expression
1488             command.erase(start_backtick-1, 1);
1489             // No need to add one to start_backtick since we just deleted a char
1490             pos = start_backtick;
1491         }
1492         else
1493         {
1494             const size_t expr_content_start = start_backtick + 1;
1495             const size_t end_backtick = command.find ('`', expr_content_start);
1496             if (end_backtick == std::string::npos)
1497                 return error;
1498             else if (end_backtick == expr_content_start)
1499             {
1500                 // Empty expression (two backticks in a row)
1501                 command.erase (start_backtick, 2);
1502             }
1503             else
1504             {
1505                 std::string expr_str (command, expr_content_start, end_backtick - expr_content_start);
1506 
1507                 ExecutionContext exe_ctx(GetExecutionContext());
1508                 Target *target = exe_ctx.GetTargetPtr();
1509                 // Get a dummy target to allow for calculator mode while processing backticks.
1510                 // This also helps break the infinite loop caused when target is null.
1511                 if (!target)
1512                     target = m_debugger.GetDummyTarget();
1513                 if (target)
1514                 {
1515                     ValueObjectSP expr_result_valobj_sp;
1516 
1517                     EvaluateExpressionOptions options;
1518                     options.SetCoerceToId(false);
1519                     options.SetUnwindOnError(true);
1520                     options.SetIgnoreBreakpoints(true);
1521                     options.SetKeepInMemory(false);
1522                     options.SetTryAllThreads(true);
1523                     options.SetTimeoutUsec(0);
1524 
1525                     ExpressionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
1526                                                                                 exe_ctx.GetFramePtr(),
1527                                                                                 expr_result_valobj_sp,
1528                                                                                 options);
1529 
1530                     if (expr_result == eExpressionCompleted)
1531                     {
1532                         Scalar scalar;
1533                         if (expr_result_valobj_sp)
1534                             expr_result_valobj_sp = expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(expr_result_valobj_sp->GetDynamicValueType(), true);
1535                         if (expr_result_valobj_sp->ResolveValue (scalar))
1536                         {
1537                             command.erase (start_backtick, end_backtick - start_backtick + 1);
1538                             StreamString value_strm;
1539                             const bool show_type = false;
1540                             scalar.GetValue (&value_strm, show_type);
1541                             size_t value_string_size = value_strm.GetSize();
1542                             if (value_string_size)
1543                             {
1544                                 command.insert (start_backtick, value_strm.GetData(), value_string_size);
1545                                 pos = start_backtick + value_string_size;
1546                                 continue;
1547                             }
1548                             else
1549                             {
1550                                 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
1551                             }
1552                         }
1553                         else
1554                         {
1555                             error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
1556                         }
1557                     }
1558                     else
1559                     {
1560                         if (expr_result_valobj_sp)
1561                             error = expr_result_valobj_sp->GetError();
1562                         if (error.Success())
1563                         {
1564 
1565                             switch (expr_result)
1566                             {
1567                                 case eExpressionSetupError:
1568                                     error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str());
1569                                     break;
1570                                 case eExpressionParseError:
1571                                     error.SetErrorStringWithFormat ("expression parse error for the expression '%s'", expr_str.c_str());
1572                                     break;
1573                                 case eExpressionResultUnavailable:
1574                                     error.SetErrorStringWithFormat ("expression error fetching result for the expression '%s'", expr_str.c_str());
1575                                 case eExpressionCompleted:
1576                                     break;
1577                                 case eExpressionDiscarded:
1578                                     error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str());
1579                                     break;
1580                                 case eExpressionInterrupted:
1581                                     error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str());
1582                                     break;
1583                                 case eExpressionHitBreakpoint:
1584                                     error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str());
1585                                     break;
1586                                 case eExpressionTimedOut:
1587                                     error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str());
1588                                     break;
1589                                 case eExpressionStoppedForDebug:
1590                                     error.SetErrorStringWithFormat("expression stop at entry point for debugging for the expression '%s'", expr_str.c_str());
1591                                     break;
1592                             }
1593                         }
1594                     }
1595                 }
1596             }
1597             if (error.Fail())
1598                 break;
1599         }
1600     }
1601     return error;
1602 }
1603 
1604 
1605 bool
1606 CommandInterpreter::HandleCommand (const char *command_line,
1607                                    LazyBool lazy_add_to_history,
1608                                    CommandReturnObject &result,
1609                                    ExecutionContext *override_context,
1610                                    bool repeat_on_empty_command,
1611                                    bool no_context_switching)
1612 
1613 {
1614 
1615     bool done = false;
1616     CommandObject *cmd_obj = nullptr;
1617     bool wants_raw_input = false;
1618     std::string command_string (command_line);
1619     std::string original_command_string (command_line);
1620 
1621     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
1622     Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line);
1623 
1624     // Make a scoped cleanup object that will clear the crash description string
1625     // on exit of this function.
1626     lldb_utility::CleanUp <const char *> crash_description_cleanup(nullptr, Host::SetCrashDescription);
1627 
1628     if (log)
1629         log->Printf ("Processing command: %s", command_line);
1630 
1631     Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line);
1632 
1633     if (!no_context_switching)
1634         UpdateExecutionContext (override_context);
1635 
1636     bool add_to_history;
1637     if (lazy_add_to_history == eLazyBoolCalculate)
1638         add_to_history = (m_command_source_depth == 0);
1639     else
1640         add_to_history = (lazy_add_to_history == eLazyBoolYes);
1641 
1642     bool empty_command = false;
1643     bool comment_command = false;
1644     if (command_string.empty())
1645         empty_command = true;
1646     else
1647     {
1648         const char *k_space_characters = "\t\n\v\f\r ";
1649 
1650         size_t non_space = command_string.find_first_not_of (k_space_characters);
1651         // Check for empty line or comment line (lines whose first
1652         // non-space character is the comment character for this interpreter)
1653         if (non_space == std::string::npos)
1654             empty_command = true;
1655         else if (command_string[non_space] == m_comment_char)
1656              comment_command = true;
1657         else if (command_string[non_space] == CommandHistory::g_repeat_char)
1658         {
1659             const char *history_string = m_command_history.FindString(command_string.c_str() + non_space);
1660             if (history_string == nullptr)
1661             {
1662                 result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str());
1663                 result.SetStatus(eReturnStatusFailed);
1664                 return false;
1665             }
1666             add_to_history = false;
1667             command_string = history_string;
1668             original_command_string = history_string;
1669         }
1670     }
1671 
1672     if (empty_command)
1673     {
1674         if (repeat_on_empty_command)
1675         {
1676             if (m_command_history.IsEmpty())
1677             {
1678                 result.AppendError ("empty command");
1679                 result.SetStatus(eReturnStatusFailed);
1680                 return false;
1681             }
1682             else
1683             {
1684                 command_line = m_repeat_command.c_str();
1685                 command_string = command_line;
1686                 original_command_string = command_line;
1687                 if (m_repeat_command.empty())
1688                 {
1689                     result.AppendErrorWithFormat("No auto repeat.\n");
1690                     result.SetStatus (eReturnStatusFailed);
1691                     return false;
1692                 }
1693             }
1694             add_to_history = false;
1695         }
1696         else
1697         {
1698             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1699             return true;
1700         }
1701     }
1702     else if (comment_command)
1703     {
1704         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1705         return true;
1706     }
1707 
1708 
1709     Error error (PreprocessCommand (command_string));
1710 
1711     if (error.Fail())
1712     {
1713         result.AppendError (error.AsCString());
1714         result.SetStatus(eReturnStatusFailed);
1715         return false;
1716     }
1717     // Phase 1.
1718 
1719     // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object
1720     // is for the specified command, and whether or not it wants raw input.  This gets complicated by the fact that
1721     // the user could have specified an alias, and in translating the alias there may also be command options and/or
1722     // even data (including raw text strings) that need to be found and inserted into the command line as part of
1723     // the translation.  So this first step is plain look-up & replacement, resulting in three things:  1). the command
1724     // object whose Execute method will actually be called; 2). a revised command string, with all substitutions &
1725     // replacements taken care of; 3). whether or not the Execute function wants raw input or not.
1726 
1727     StreamString revised_command_line;
1728     size_t actual_cmd_name_len = 0;
1729     std::string next_word;
1730     StringList matches;
1731     while (!done)
1732     {
1733         char quote_char = '\0';
1734         std::string suffix;
1735         ExtractCommand (command_string, next_word, suffix, quote_char);
1736         if (cmd_obj == nullptr)
1737         {
1738             std::string full_name;
1739             if (GetAliasFullName(next_word.c_str(), full_name))
1740             {
1741                 std::string alias_result;
1742                 cmd_obj = BuildAliasResult (full_name.c_str(), command_string, alias_result, result);
1743                 revised_command_line.Printf ("%s", alias_result.c_str());
1744                 if (cmd_obj)
1745                 {
1746                     wants_raw_input = cmd_obj->WantsRawCommandString ();
1747                     actual_cmd_name_len = strlen (cmd_obj->GetCommandName());
1748                 }
1749             }
1750             else
1751             {
1752                 cmd_obj = GetCommandObject (next_word.c_str(), &matches);
1753                 if (cmd_obj)
1754                 {
1755                     actual_cmd_name_len += next_word.length();
1756                     revised_command_line.Printf ("%s", next_word.c_str());
1757                     wants_raw_input = cmd_obj->WantsRawCommandString ();
1758                 }
1759                 else
1760                 {
1761                     revised_command_line.Printf ("%s", next_word.c_str());
1762                 }
1763             }
1764         }
1765         else
1766         {
1767             if (cmd_obj->IsMultiwordObject ())
1768             {
1769                 CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str());
1770                 if (sub_cmd_obj)
1771                 {
1772                     actual_cmd_name_len += next_word.length() + 1;
1773                     revised_command_line.Printf (" %s", next_word.c_str());
1774                     cmd_obj = sub_cmd_obj;
1775                     wants_raw_input = cmd_obj->WantsRawCommandString ();
1776                 }
1777                 else
1778                 {
1779                     if (quote_char)
1780                         revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
1781                     else
1782                         revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str());
1783                     done = true;
1784                 }
1785             }
1786             else
1787             {
1788                 if (quote_char)
1789                     revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
1790                 else
1791                     revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str());
1792                 done = true;
1793             }
1794         }
1795 
1796         if (cmd_obj == nullptr)
1797         {
1798             const size_t num_matches = matches.GetSize();
1799             if (matches.GetSize() > 1) {
1800                 StreamString error_msg;
1801                 error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
1802 
1803                 for (uint32_t i = 0; i < num_matches; ++i) {
1804                     error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i));
1805                 }
1806                 result.AppendRawError (error_msg.GetString().c_str());
1807             } else {
1808                 // We didn't have only one match, otherwise we wouldn't get here.
1809                 assert(num_matches == 0);
1810                 result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str());
1811             }
1812             result.SetStatus (eReturnStatusFailed);
1813             return false;
1814         }
1815 
1816         if (cmd_obj->IsMultiwordObject ())
1817         {
1818             if (!suffix.empty())
1819             {
1820 
1821                 result.AppendErrorWithFormat ("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n",
1822                                               cmd_obj->GetCommandName(),
1823                                               next_word.empty() ? "" : next_word.c_str(),
1824                                               next_word.empty() ? " -- " : " ",
1825                                               suffix.c_str());
1826                 result.SetStatus (eReturnStatusFailed);
1827                 return false;
1828             }
1829         }
1830         else
1831         {
1832             // If we found a normal command, we are done
1833             done = true;
1834             if (!suffix.empty())
1835             {
1836                 switch (suffix[0])
1837                 {
1838                 case '/':
1839                     // GDB format suffixes
1840                     {
1841                         Options *command_options = cmd_obj->GetOptions();
1842                         if (command_options && command_options->SupportsLongOption("gdb-format"))
1843                         {
1844                             std::string gdb_format_option ("--gdb-format=");
1845                             gdb_format_option += (suffix.c_str() + 1);
1846 
1847                             bool inserted = false;
1848                             std::string &cmd = revised_command_line.GetString();
1849                             size_t arg_terminator_idx = FindArgumentTerminator (cmd);
1850                             if (arg_terminator_idx != std::string::npos)
1851                             {
1852                                 // Insert the gdb format option before the "--" that terminates options
1853                                 gdb_format_option.append(1,' ');
1854                                 cmd.insert(arg_terminator_idx, gdb_format_option);
1855                                 inserted = true;
1856                             }
1857 
1858                             if (!inserted)
1859                                 revised_command_line.Printf (" %s", gdb_format_option.c_str());
1860 
1861                             if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos)
1862                                 revised_command_line.PutCString (" --");
1863                         }
1864                         else
1865                         {
1866                             result.AppendErrorWithFormat ("the '%s' command doesn't support the --gdb-format option\n",
1867                                                           cmd_obj->GetCommandName());
1868                             result.SetStatus (eReturnStatusFailed);
1869                             return false;
1870                         }
1871                     }
1872                     break;
1873 
1874                 default:
1875                     result.AppendErrorWithFormat ("unknown command shorthand suffix: '%s'\n",
1876                                                   suffix.c_str());
1877                     result.SetStatus (eReturnStatusFailed);
1878                     return false;
1879 
1880                 }
1881             }
1882         }
1883         if (command_string.length() == 0)
1884             done = true;
1885 
1886     }
1887 
1888     if (!command_string.empty())
1889         revised_command_line.Printf (" %s", command_string.c_str());
1890 
1891     // End of Phase 1.
1892     // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command
1893     // specified was valid; revised_command_line contains the complete command line (including command name(s)),
1894     // fully translated with all substitutions & translations taken care of (still in raw text format); and
1895     // wants_raw_input specifies whether the Execute method expects raw input or not.
1896 
1897 
1898     if (log)
1899     {
1900         log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>");
1901         log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData());
1902         log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False");
1903     }
1904 
1905     // Phase 2.
1906     // Take care of things like setting up the history command & calling the appropriate Execute method on the
1907     // CommandObject, with the appropriate arguments.
1908 
1909     if (cmd_obj != nullptr)
1910     {
1911         if (add_to_history)
1912         {
1913             Args command_args (revised_command_line.GetData());
1914             const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0);
1915             if (repeat_command != nullptr)
1916                 m_repeat_command.assign(repeat_command);
1917             else
1918                 m_repeat_command.assign(original_command_string.c_str());
1919 
1920             m_command_history.AppendString (original_command_string);
1921         }
1922 
1923         command_string = revised_command_line.GetData();
1924         std::string command_name (cmd_obj->GetCommandName());
1925         std::string remainder;
1926         if (actual_cmd_name_len < command_string.length())
1927             remainder = command_string.substr (actual_cmd_name_len);  // Note: 'actual_cmd_name_len' may be considerably shorter
1928                                                            // than cmd_obj->GetCommandName(), because name completion
1929                                                            // allows users to enter short versions of the names,
1930                                                            // e.g. 'br s' for 'breakpoint set'.
1931 
1932         // Remove any initial spaces
1933         std::string white_space (" \t\v");
1934         size_t pos = remainder.find_first_not_of (white_space);
1935         if (pos != 0 && pos != std::string::npos)
1936             remainder.erase(0, pos);
1937 
1938         if (log)
1939             log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str());
1940 
1941         cmd_obj->Execute (remainder.c_str(), result);
1942     }
1943     else
1944     {
1945         // We didn't find the first command object, so complete the first argument.
1946         Args command_args (revised_command_line.GetData());
1947         StringList matches;
1948         int num_matches;
1949         int cursor_index = 0;
1950         int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0));
1951         bool word_complete;
1952         num_matches = HandleCompletionMatches (command_args,
1953                                                cursor_index,
1954                                                cursor_char_position,
1955                                                0,
1956                                                -1,
1957                                                word_complete,
1958                                                matches);
1959 
1960         if (num_matches > 0)
1961         {
1962             std::string error_msg;
1963             error_msg.assign ("ambiguous command '");
1964             error_msg.append(command_args.GetArgumentAtIndex(0));
1965             error_msg.append ("'.");
1966 
1967             error_msg.append (" Possible completions:");
1968             for (int i = 0; i < num_matches; i++)
1969             {
1970                 error_msg.append ("\n\t");
1971                 error_msg.append (matches.GetStringAtIndex (i));
1972             }
1973             error_msg.append ("\n");
1974             result.AppendRawError (error_msg.c_str());
1975         }
1976         else
1977             result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0));
1978 
1979         result.SetStatus (eReturnStatusFailed);
1980     }
1981 
1982     if (log)
1983       log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed"));
1984 
1985     return result.Succeeded();
1986 }
1987 
1988 int
1989 CommandInterpreter::HandleCompletionMatches (Args &parsed_line,
1990                                              int &cursor_index,
1991                                              int &cursor_char_position,
1992                                              int match_start_point,
1993                                              int max_return_elements,
1994                                              bool &word_complete,
1995                                              StringList &matches)
1996 {
1997     int num_command_matches = 0;
1998     bool look_for_subcommand = false;
1999 
2000     // For any of the command completions a unique match will be a complete word.
2001     word_complete = true;
2002 
2003     if (cursor_index == -1)
2004     {
2005         // We got nothing on the command line, so return the list of commands
2006         bool include_aliases = true;
2007         num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches);
2008     }
2009     else if (cursor_index == 0)
2010     {
2011         // The cursor is in the first argument, so just do a lookup in the dictionary.
2012         CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches);
2013         num_command_matches = matches.GetSize();
2014 
2015         if (num_command_matches == 1
2016             && cmd_obj && cmd_obj->IsMultiwordObject()
2017             && matches.GetStringAtIndex(0) != nullptr
2018             && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0)
2019         {
2020             if (parsed_line.GetArgumentCount() == 1)
2021             {
2022                 word_complete = true;
2023             }
2024             else
2025             {
2026                 look_for_subcommand = true;
2027                 num_command_matches = 0;
2028                 matches.DeleteStringAtIndex(0);
2029                 parsed_line.AppendArgument ("");
2030                 cursor_index++;
2031                 cursor_char_position = 0;
2032             }
2033         }
2034     }
2035 
2036     if (cursor_index > 0 || look_for_subcommand)
2037     {
2038         // We are completing further on into a commands arguments, so find the command and tell it
2039         // to complete the command.
2040         // First see if there is a matching initial command:
2041         CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0));
2042         if (command_object == nullptr)
2043         {
2044             return 0;
2045         }
2046         else
2047         {
2048             parsed_line.Shift();
2049             cursor_index--;
2050             num_command_matches = command_object->HandleCompletion (parsed_line,
2051                                                                     cursor_index,
2052                                                                     cursor_char_position,
2053                                                                     match_start_point,
2054                                                                     max_return_elements,
2055                                                                     word_complete,
2056                                                                     matches);
2057         }
2058     }
2059 
2060     return num_command_matches;
2061 
2062 }
2063 
2064 int
2065 CommandInterpreter::HandleCompletion (const char *current_line,
2066                                       const char *cursor,
2067                                       const char *last_char,
2068                                       int match_start_point,
2069                                       int max_return_elements,
2070                                       StringList &matches)
2071 {
2072     // We parse the argument up to the cursor, so the last argument in parsed_line is
2073     // the one containing the cursor, and the cursor is after the last character.
2074 
2075     Args parsed_line(current_line, last_char - current_line);
2076     Args partial_parsed_line(current_line, cursor - current_line);
2077 
2078     // Don't complete comments, and if the line we are completing is just the history repeat character,
2079     // substitute the appropriate history line.
2080     const char *first_arg = parsed_line.GetArgumentAtIndex(0);
2081     if (first_arg)
2082     {
2083         if (first_arg[0] == m_comment_char)
2084             return 0;
2085         else if (first_arg[0] == CommandHistory::g_repeat_char)
2086         {
2087             const char *history_string = m_command_history.FindString (first_arg);
2088             if (history_string != nullptr)
2089             {
2090                 matches.Clear();
2091                 matches.InsertStringAtIndex(0, history_string);
2092                 return -2;
2093             }
2094             else
2095                 return 0;
2096 
2097         }
2098     }
2099 
2100 
2101     int num_args = partial_parsed_line.GetArgumentCount();
2102     int cursor_index = partial_parsed_line.GetArgumentCount() - 1;
2103     int cursor_char_position;
2104 
2105     if (cursor_index == -1)
2106         cursor_char_position = 0;
2107     else
2108         cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index));
2109 
2110     if (cursor > current_line && cursor[-1] == ' ')
2111     {
2112         // We are just after a space.  If we are in an argument, then we will continue
2113         // parsing, but if we are between arguments, then we have to complete whatever the next
2114         // element would be.
2115         // We can distinguish the two cases because if we are in an argument (e.g. because the space is
2116         // protected by a quote) then the space will also be in the parsed argument...
2117 
2118         const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index);
2119         if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ')
2120         {
2121             parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '\0');
2122             cursor_index++;
2123             cursor_char_position = 0;
2124         }
2125     }
2126 
2127     int num_command_matches;
2128 
2129     matches.Clear();
2130 
2131     // Only max_return_elements == -1 is supported at present:
2132     assert (max_return_elements == -1);
2133     bool word_complete;
2134     num_command_matches = HandleCompletionMatches (parsed_line,
2135                                                    cursor_index,
2136                                                    cursor_char_position,
2137                                                    match_start_point,
2138                                                    max_return_elements,
2139                                                    word_complete,
2140                                                    matches);
2141 
2142     if (num_command_matches <= 0)
2143             return num_command_matches;
2144 
2145     if (num_args == 0)
2146     {
2147         // If we got an empty string, insert nothing.
2148         matches.InsertStringAtIndex(0, "");
2149     }
2150     else
2151     {
2152         // Now figure out if there is a common substring, and if so put that in element 0, otherwise
2153         // put an empty string in element 0.
2154         std::string command_partial_str;
2155         if (cursor_index >= 0)
2156             command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index),
2157                                        parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position);
2158 
2159         std::string common_prefix;
2160         matches.LongestCommonPrefix (common_prefix);
2161         const size_t partial_name_len = command_partial_str.size();
2162 
2163         // If we matched a unique single command, add a space...
2164         // Only do this if the completer told us this was a complete word, however...
2165         if (num_command_matches == 1 && word_complete)
2166         {
2167             char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index);
2168             if (quote_char != '\0')
2169                 common_prefix.push_back(quote_char);
2170 
2171             common_prefix.push_back(' ');
2172         }
2173         common_prefix.erase (0, partial_name_len);
2174         matches.InsertStringAtIndex(0, common_prefix.c_str());
2175     }
2176     return num_command_matches;
2177 }
2178 
2179 
2180 CommandInterpreter::~CommandInterpreter ()
2181 {
2182 }
2183 
2184 void
2185 CommandInterpreter::UpdatePrompt (const char *new_prompt)
2186 {
2187     EventSP prompt_change_event_sp (new Event(eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
2188     BroadcastEvent (prompt_change_event_sp);
2189     if (m_command_io_handler_sp)
2190         m_command_io_handler_sp->SetPrompt(new_prompt);
2191 }
2192 
2193 
2194 bool
2195 CommandInterpreter::Confirm (const char *message, bool default_answer)
2196 {
2197     // Check AutoConfirm first:
2198     if (m_debugger.GetAutoConfirm())
2199         return default_answer;
2200 
2201     IOHandlerConfirm *confirm = new IOHandlerConfirm(m_debugger,
2202                                                      message,
2203                                                      default_answer);
2204     IOHandlerSP io_handler_sp (confirm);
2205     m_debugger.RunIOHandler (io_handler_sp);
2206     return confirm->GetResponse();
2207 }
2208 
2209 OptionArgVectorSP
2210 CommandInterpreter::GetAliasOptions (const char *alias_name)
2211 {
2212     OptionArgMap::iterator pos;
2213     OptionArgVectorSP ret_val;
2214 
2215     std::string alias (alias_name);
2216 
2217     if (HasAliasOptions())
2218     {
2219         pos = m_alias_options.find (alias);
2220         if (pos != m_alias_options.end())
2221           ret_val = pos->second;
2222     }
2223 
2224     return ret_val;
2225 }
2226 
2227 void
2228 CommandInterpreter::RemoveAliasOptions (const char *alias_name)
2229 {
2230     OptionArgMap::iterator pos = m_alias_options.find(alias_name);
2231     if (pos != m_alias_options.end())
2232     {
2233         m_alias_options.erase (pos);
2234     }
2235 }
2236 
2237 void
2238 CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp)
2239 {
2240     m_alias_options[alias_name] = option_arg_vector_sp;
2241 }
2242 
2243 bool
2244 CommandInterpreter::HasCommands ()
2245 {
2246     return (!m_command_dict.empty());
2247 }
2248 
2249 bool
2250 CommandInterpreter::HasAliases ()
2251 {
2252     return (!m_alias_dict.empty());
2253 }
2254 
2255 bool
2256 CommandInterpreter::HasUserCommands ()
2257 {
2258     return (!m_user_dict.empty());
2259 }
2260 
2261 bool
2262 CommandInterpreter::HasAliasOptions ()
2263 {
2264     return (!m_alias_options.empty());
2265 }
2266 
2267 void
2268 CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
2269                                            const char *alias_name,
2270                                            Args &cmd_args,
2271                                            std::string &raw_input_string,
2272                                            CommandReturnObject &result)
2273 {
2274     OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
2275 
2276     bool wants_raw_input = alias_cmd_obj->WantsRawCommandString();
2277 
2278     // Make sure that the alias name is the 0th element in cmd_args
2279     std::string alias_name_str = alias_name;
2280     if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)
2281         cmd_args.Unshift (alias_name);
2282 
2283     Args new_args (alias_cmd_obj->GetCommandName());
2284     if (new_args.GetArgumentCount() == 2)
2285         new_args.Shift();
2286 
2287     if (option_arg_vector_sp.get())
2288     {
2289         if (wants_raw_input)
2290         {
2291             // We have a command that both has command options and takes raw input.  Make *sure* it has a
2292             // " -- " in the right place in the raw_input_string.
2293             size_t pos = raw_input_string.find(" -- ");
2294             if (pos == std::string::npos)
2295             {
2296                 // None found; assume it goes at the beginning of the raw input string
2297                 raw_input_string.insert (0, " -- ");
2298             }
2299         }
2300 
2301         OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
2302         const size_t old_size = cmd_args.GetArgumentCount();
2303         std::vector<bool> used (old_size + 1, false);
2304 
2305         used[0] = true;
2306 
2307         for (size_t i = 0; i < option_arg_vector->size(); ++i)
2308         {
2309             OptionArgPair option_pair = (*option_arg_vector)[i];
2310             OptionArgValue value_pair = option_pair.second;
2311             int value_type = value_pair.first;
2312             std::string option = option_pair.first;
2313             std::string value = value_pair.second;
2314             if (option.compare ("<argument>") == 0)
2315             {
2316                 if (!wants_raw_input
2317                     || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice
2318                     new_args.AppendArgument (value.c_str());
2319             }
2320             else
2321             {
2322                 if (value_type != OptionParser::eOptionalArgument)
2323                     new_args.AppendArgument (option.c_str());
2324                 if (value.compare ("<no-argument>") != 0)
2325                 {
2326                     int index = GetOptionArgumentPosition (value.c_str());
2327                     if (index == 0)
2328                     {
2329                         // value was NOT a positional argument; must be a real value
2330                         if (value_type != OptionParser::eOptionalArgument)
2331                             new_args.AppendArgument (value.c_str());
2332                         else
2333                         {
2334                             char buffer[255];
2335                             ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str());
2336                             new_args.AppendArgument (buffer);
2337                         }
2338 
2339                     }
2340                     else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount())
2341                     {
2342                         result.AppendErrorWithFormat
2343                                     ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
2344                                      index);
2345                         result.SetStatus (eReturnStatusFailed);
2346                         return;
2347                     }
2348                     else
2349                     {
2350                         // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string
2351                         size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
2352                         if (strpos != std::string::npos)
2353                         {
2354                             raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index)));
2355                         }
2356 
2357                         if (value_type != OptionParser::eOptionalArgument)
2358                             new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index));
2359                         else
2360                         {
2361                             char buffer[255];
2362                             ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(),
2363                                         cmd_args.GetArgumentAtIndex (index));
2364                             new_args.AppendArgument (buffer);
2365                         }
2366                         used[index] = true;
2367                     }
2368                 }
2369             }
2370         }
2371 
2372         for (size_t j = 0; j < cmd_args.GetArgumentCount(); ++j)
2373         {
2374             if (!used[j] && !wants_raw_input)
2375                 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j));
2376         }
2377 
2378         cmd_args.Clear();
2379         cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
2380     }
2381     else
2382     {
2383         result.SetStatus (eReturnStatusSuccessFinishNoResult);
2384         // This alias was not created with any options; nothing further needs to be done, unless it is a command that
2385         // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw
2386         // input string.
2387         if (wants_raw_input)
2388         {
2389             cmd_args.Clear();
2390             cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
2391         }
2392         return;
2393     }
2394 
2395     result.SetStatus (eReturnStatusSuccessFinishNoResult);
2396     return;
2397 }
2398 
2399 
2400 int
2401 CommandInterpreter::GetOptionArgumentPosition (const char *in_string)
2402 {
2403     int position = 0;   // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position
2404                         // of zero.
2405 
2406     char *cptr = (char *) in_string;
2407 
2408     // Does it start with '%'
2409     if (cptr[0] == '%')
2410     {
2411         ++cptr;
2412 
2413         // Is the rest of it entirely digits?
2414         if (isdigit (cptr[0]))
2415         {
2416             const char *start = cptr;
2417             while (isdigit (cptr[0]))
2418                 ++cptr;
2419 
2420             // We've gotten to the end of the digits; are we at the end of the string?
2421             if (cptr[0] == '\0')
2422                 position = atoi (start);
2423         }
2424     }
2425 
2426     return position;
2427 }
2428 
2429 void
2430 CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
2431 {
2432     FileSpec init_file;
2433     if (in_cwd)
2434     {
2435         // In the current working directory we don't load any program specific
2436         // .lldbinit files, we only look for a "./.lldbinit" file.
2437         if (m_skip_lldbinit_files)
2438             return;
2439 
2440         init_file.SetFile ("./.lldbinit", true);
2441     }
2442     else
2443     {
2444         // If we aren't looking in the current working directory we are looking
2445         // in the home directory. We will first see if there is an application
2446         // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a
2447         // "-" and the name of the program. If this file doesn't exist, we fall
2448         // back to just the "~/.lldbinit" file. We also obey any requests to not
2449         // load the init files.
2450         llvm::SmallString<64> home_dir_path;
2451         llvm::sys::path::home_directory(home_dir_path);
2452         FileSpec profilePath(home_dir_path.c_str(), false);
2453         profilePath.AppendPathComponent(".lldbinit");
2454         std::string init_file_path = profilePath.GetPath();
2455 
2456         if (m_skip_app_init_files == false)
2457         {
2458             FileSpec program_file_spec(HostInfo::GetProgramFileSpec());
2459             const char *program_name = program_file_spec.GetFilename().AsCString();
2460 
2461             if (program_name)
2462             {
2463                 char program_init_file_name[PATH_MAX];
2464                 ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path.c_str(), program_name);
2465                 init_file.SetFile (program_init_file_name, true);
2466                 if (!init_file.Exists())
2467                     init_file.Clear();
2468             }
2469         }
2470 
2471         if (!init_file && !m_skip_lldbinit_files)
2472 			init_file.SetFile (init_file_path.c_str(), false);
2473     }
2474 
2475     // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting
2476     // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details).
2477 
2478     if (init_file.Exists())
2479     {
2480         const bool saved_batch = SetBatchCommandMode (true);
2481         CommandInterpreterRunOptions options;
2482         options.SetSilent (true);
2483         options.SetStopOnError (false);
2484         options.SetStopOnContinue (true);
2485 
2486         HandleCommandsFromFile (init_file,
2487                                 nullptr,           // Execution context
2488                                 options,
2489                                 result);
2490         SetBatchCommandMode (saved_batch);
2491     }
2492     else
2493     {
2494         // nothing to be done if the file doesn't exist
2495         result.SetStatus(eReturnStatusSuccessFinishNoResult);
2496     }
2497 }
2498 
2499 PlatformSP
2500 CommandInterpreter::GetPlatform (bool prefer_target_platform)
2501 {
2502     PlatformSP platform_sp;
2503     if (prefer_target_platform)
2504     {
2505         ExecutionContext exe_ctx(GetExecutionContext());
2506         Target *target = exe_ctx.GetTargetPtr();
2507         if (target)
2508             platform_sp = target->GetPlatform();
2509     }
2510 
2511     if (!platform_sp)
2512         platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform();
2513     return platform_sp;
2514 }
2515 
2516 void
2517 CommandInterpreter::HandleCommands (const StringList &commands,
2518                                     ExecutionContext *override_context,
2519                                     CommandInterpreterRunOptions &options,
2520                                     CommandReturnObject &result)
2521 {
2522     size_t num_lines = commands.GetSize();
2523 
2524     // If we are going to continue past a "continue" then we need to run the commands synchronously.
2525     // Make sure you reset this value anywhere you return from the function.
2526 
2527     bool old_async_execution = m_debugger.GetAsyncExecution();
2528 
2529     // If we've been given an execution context, set it at the start, but don't keep resetting it or we will
2530     // cause series of commands that change the context, then do an operation that relies on that context to fail.
2531 
2532     if (override_context != nullptr)
2533         UpdateExecutionContext (override_context);
2534 
2535     if (!options.GetStopOnContinue())
2536     {
2537         m_debugger.SetAsyncExecution (false);
2538     }
2539 
2540     for (size_t idx = 0; idx < num_lines; idx++)
2541     {
2542         const char *cmd = commands.GetStringAtIndex(idx);
2543         if (cmd[0] == '\0')
2544             continue;
2545 
2546         if (options.GetEchoCommands())
2547         {
2548             result.AppendMessageWithFormat ("%s %s\n",
2549                                             m_debugger.GetPrompt(),
2550                                             cmd);
2551         }
2552 
2553         CommandReturnObject tmp_result;
2554         // If override_context is not NULL, pass no_context_switching = true for
2555         // HandleCommand() since we updated our context already.
2556 
2557         // We might call into a regex or alias command, in which case the add_to_history will get lost.  This
2558         // m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here.
2559         if (!options.GetAddToHistory())
2560             m_command_source_depth++;
2561         bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result,
2562                                      nullptr, /* override_context */
2563                                      true, /* repeat_on_empty_command */
2564                                      override_context != nullptr /* no_context_switching */);
2565         if (!options.GetAddToHistory())
2566             m_command_source_depth--;
2567 
2568         if (options.GetPrintResults())
2569         {
2570             if (tmp_result.Succeeded())
2571               result.AppendMessageWithFormat("%s", tmp_result.GetOutputData());
2572         }
2573 
2574         if (!success || !tmp_result.Succeeded())
2575         {
2576             const char *error_msg = tmp_result.GetErrorData();
2577             if (error_msg == nullptr || error_msg[0] == '\0')
2578                 error_msg = "<unknown error>.\n";
2579             if (options.GetStopOnError())
2580             {
2581                 result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s",
2582                                                 (uint64_t)idx, cmd, error_msg);
2583                 result.SetStatus (eReturnStatusFailed);
2584                 m_debugger.SetAsyncExecution (old_async_execution);
2585                 return;
2586             }
2587             else if (options.GetPrintResults())
2588             {
2589                 result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s",
2590                                                 (uint64_t)idx + 1,
2591                                                 cmd,
2592                                                 error_msg);
2593             }
2594         }
2595 
2596         if (result.GetImmediateOutputStream())
2597             result.GetImmediateOutputStream()->Flush();
2598 
2599         if (result.GetImmediateErrorStream())
2600             result.GetImmediateErrorStream()->Flush();
2601 
2602         // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution
2603         // could be running (for instance in Breakpoint Commands.
2604         // So we check the return value to see if it is has running in it.
2605         if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
2606                 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult))
2607         {
2608             if (options.GetStopOnContinue())
2609             {
2610                 // If we caused the target to proceed, and we're going to stop in that case, set the
2611                 // status in our real result before returning.  This is an error if the continue was not the
2612                 // last command in the set of commands to be run.
2613                 if (idx != num_lines - 1)
2614                     result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' continued the target.\n",
2615                                                  (uint64_t)idx + 1, cmd);
2616                 else
2617                     result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' continued the target.\n", (uint64_t)idx + 1, cmd);
2618 
2619                 result.SetStatus(tmp_result.GetStatus());
2620                 m_debugger.SetAsyncExecution (old_async_execution);
2621 
2622                 return;
2623             }
2624         }
2625 
2626         // Also check for "stop on crash here:
2627         bool should_stop = false;
2628         if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash())
2629         {
2630             TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
2631             if (target_sp)
2632             {
2633                 ProcessSP process_sp (target_sp->GetProcessSP());
2634                 if (process_sp)
2635                 {
2636                     for (ThreadSP thread_sp : process_sp->GetThreadList().Threads())
2637                     {
2638                         StopReason reason = thread_sp->GetStopReason();
2639                         if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation)
2640                         {
2641                             should_stop = true;
2642                             break;
2643                         }
2644                     }
2645                 }
2646             }
2647             if (should_stop)
2648             {
2649                 if (idx != num_lines - 1)
2650                     result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' stopped with a signal or exception.\n",
2651                                                  (uint64_t)idx + 1, cmd);
2652                 else
2653                     result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' stopped with a signal or exception.\n", (uint64_t)idx + 1, cmd);
2654 
2655                 result.SetStatus(tmp_result.GetStatus());
2656                 m_debugger.SetAsyncExecution (old_async_execution);
2657 
2658                 return;
2659             }
2660         }
2661 
2662     }
2663 
2664     result.SetStatus (eReturnStatusSuccessFinishResult);
2665     m_debugger.SetAsyncExecution (old_async_execution);
2666 
2667     return;
2668 }
2669 
2670 // Make flags that we can pass into the IOHandler so our delegates can do the right thing
2671 enum {
2672     eHandleCommandFlagStopOnContinue = (1u << 0),
2673     eHandleCommandFlagStopOnError    = (1u << 1),
2674     eHandleCommandFlagEchoCommand    = (1u << 2),
2675     eHandleCommandFlagPrintResult    = (1u << 3),
2676     eHandleCommandFlagStopOnCrash    = (1u << 4)
2677 };
2678 
2679 void
2680 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
2681                                             ExecutionContext *context,
2682                                             CommandInterpreterRunOptions &options,
2683                                             CommandReturnObject &result)
2684 {
2685     if (cmd_file.Exists())
2686     {
2687         StreamFileSP input_file_sp (new StreamFile());
2688 
2689         std::string cmd_file_path = cmd_file.GetPath();
2690         Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), File::eOpenOptionRead);
2691 
2692         if (error.Success())
2693         {
2694             Debugger &debugger = GetDebugger();
2695 
2696             uint32_t flags = 0;
2697 
2698             if (options.m_stop_on_continue == eLazyBoolCalculate)
2699             {
2700                 if (m_command_source_flags.empty())
2701                 {
2702                     // Stop on continue by default
2703                     flags |= eHandleCommandFlagStopOnContinue;
2704                 }
2705                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnContinue)
2706                 {
2707                     flags |= eHandleCommandFlagStopOnContinue;
2708                 }
2709             }
2710             else if (options.m_stop_on_continue == eLazyBoolYes)
2711             {
2712                 flags |= eHandleCommandFlagStopOnContinue;
2713             }
2714 
2715             if (options.m_stop_on_error == eLazyBoolCalculate)
2716             {
2717                 if (m_command_source_flags.empty())
2718                 {
2719                     if (GetStopCmdSourceOnError())
2720                         flags |= eHandleCommandFlagStopOnError;
2721                 }
2722                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnError)
2723                 {
2724                     flags |= eHandleCommandFlagStopOnError;
2725                 }
2726             }
2727             else if (options.m_stop_on_error == eLazyBoolYes)
2728             {
2729                 flags |= eHandleCommandFlagStopOnError;
2730             }
2731 
2732             if (options.GetStopOnCrash())
2733             {
2734                 if (m_command_source_flags.empty())
2735                 {
2736                     // Echo command by default
2737                     flags |= eHandleCommandFlagStopOnCrash;
2738                 }
2739                 else if (m_command_source_flags.back() & eHandleCommandFlagStopOnCrash)
2740                 {
2741                     flags |= eHandleCommandFlagStopOnCrash;
2742                 }
2743             }
2744 
2745             if (options.m_echo_commands == eLazyBoolCalculate)
2746             {
2747                 if (m_command_source_flags.empty())
2748                 {
2749                     // Echo command by default
2750                     flags |= eHandleCommandFlagEchoCommand;
2751                 }
2752                 else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand)
2753                 {
2754                     flags |= eHandleCommandFlagEchoCommand;
2755                 }
2756             }
2757             else if (options.m_echo_commands == eLazyBoolYes)
2758             {
2759                 flags |= eHandleCommandFlagEchoCommand;
2760             }
2761 
2762             if (options.m_print_results == eLazyBoolCalculate)
2763             {
2764                 if (m_command_source_flags.empty())
2765                 {
2766                     // Print output by default
2767                     flags |= eHandleCommandFlagPrintResult;
2768                 }
2769                 else if (m_command_source_flags.back() & eHandleCommandFlagPrintResult)
2770                 {
2771                     flags |= eHandleCommandFlagPrintResult;
2772                 }
2773             }
2774             else if (options.m_print_results == eLazyBoolYes)
2775             {
2776                 flags |= eHandleCommandFlagPrintResult;
2777             }
2778 
2779             if (flags & eHandleCommandFlagPrintResult)
2780             {
2781                 debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", cmd_file_path.c_str());
2782             }
2783 
2784             // Used for inheriting the right settings when "command source" might have
2785             // nested "command source" commands
2786             lldb::StreamFileSP empty_stream_sp;
2787             m_command_source_flags.push_back(flags);
2788             IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
2789                                                               IOHandler::Type::CommandInterpreter,
2790                                                               input_file_sp,
2791                                                               empty_stream_sp, // Pass in an empty stream so we inherit the top input reader output stream
2792                                                               empty_stream_sp, // Pass in an empty stream so we inherit the top input reader error stream
2793                                                               flags,
2794                                                               nullptr, // Pass in NULL for "editline_name" so no history is saved, or written
2795                                                               debugger.GetPrompt(),
2796                                                               NULL,
2797                                                               false, // Not multi-line
2798                                                               debugger.GetUseColor(),
2799                                                               0,
2800                                                               *this));
2801             const bool old_async_execution = debugger.GetAsyncExecution();
2802 
2803             // Set synchronous execution if we are not stopping on continue
2804             if ((flags & eHandleCommandFlagStopOnContinue) == 0)
2805                 debugger.SetAsyncExecution (false);
2806 
2807             m_command_source_depth++;
2808 
2809             debugger.RunIOHandler(io_handler_sp);
2810             if (!m_command_source_flags.empty())
2811                 m_command_source_flags.pop_back();
2812             m_command_source_depth--;
2813             result.SetStatus (eReturnStatusSuccessFinishNoResult);
2814             debugger.SetAsyncExecution (old_async_execution);
2815         }
2816         else
2817         {
2818             result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString());
2819             result.SetStatus (eReturnStatusFailed);
2820         }
2821 
2822 
2823     }
2824     else
2825     {
2826         result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n",
2827                                       cmd_file.GetFilename().AsCString("<Unknown>"));
2828         result.SetStatus (eReturnStatusFailed);
2829         return;
2830     }
2831 }
2832 
2833 ScriptInterpreter *
2834 CommandInterpreter::GetScriptInterpreter (bool can_create)
2835 {
2836     if (m_script_interpreter_ap.get() != nullptr)
2837         return m_script_interpreter_ap.get();
2838 
2839     if (!can_create)
2840         return nullptr;
2841 
2842     // <rdar://problem/11751427>
2843     // we need to protect the initialization of the script interpreter
2844     // otherwise we could end up with two threads both trying to create
2845     // their instance of it, and for some languages (e.g. Python)
2846     // this is a bulletproof recipe for disaster!
2847     // this needs to be a function-level static because multiple Debugger instances living in the same process
2848     // still need to be isolated and not try to initialize Python concurrently
2849     static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive);
2850     Mutex::Locker interpreter_lock(g_interpreter_mutex);
2851 
2852     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
2853     if (log)
2854         log->Printf("Initializing the ScriptInterpreter now\n");
2855 
2856     lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage();
2857     switch (script_lang)
2858     {
2859         case eScriptLanguagePython:
2860 #ifndef LLDB_DISABLE_PYTHON
2861             m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this));
2862             break;
2863 #else
2864             // Fall through to the None case when python is disabled
2865 #endif
2866         case eScriptLanguageNone:
2867             m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this));
2868             break;
2869     };
2870 
2871     return m_script_interpreter_ap.get();
2872 }
2873 
2874 
2875 
2876 bool
2877 CommandInterpreter::GetSynchronous ()
2878 {
2879     return m_synchronous_execution;
2880 }
2881 
2882 void
2883 CommandInterpreter::SetSynchronous (bool value)
2884 {
2885     m_synchronous_execution  = value;
2886 }
2887 
2888 void
2889 CommandInterpreter::OutputFormattedHelpText (Stream &strm,
2890                                              const char *word_text,
2891                                              const char *separator,
2892                                              const char *help_text,
2893                                              size_t max_word_len)
2894 {
2895     const uint32_t max_columns = m_debugger.GetTerminalWidth();
2896 
2897     int indent_size = max_word_len + strlen (separator) + 2;
2898 
2899     strm.IndentMore (indent_size);
2900 
2901     StreamString text_strm;
2902     text_strm.Printf ("%-*s %s %s",  (int)max_word_len, word_text, separator, help_text);
2903 
2904     size_t len = text_strm.GetSize();
2905     const char *text = text_strm.GetData();
2906     if (text[len - 1] == '\n')
2907     {
2908         text_strm.EOL();
2909         len = text_strm.GetSize();
2910     }
2911 
2912     if (len  < max_columns)
2913     {
2914         // Output it as a single line.
2915         strm.Printf ("%s", text);
2916     }
2917     else
2918     {
2919         // We need to break it up into multiple lines.
2920         bool first_line = true;
2921         int text_width;
2922         size_t start = 0;
2923         size_t end = start;
2924         const size_t final_end = strlen (text);
2925 
2926         while (end < final_end)
2927         {
2928             if (first_line)
2929                 text_width = max_columns - 1;
2930             else
2931                 text_width = max_columns - indent_size - 1;
2932 
2933             // Don't start the 'text' on a space, since we're already outputting the indentation.
2934             if (!first_line)
2935             {
2936                 while ((start < final_end) && (text[start] == ' '))
2937                   start++;
2938             }
2939 
2940             end = start + text_width;
2941             if (end > final_end)
2942                 end = final_end;
2943             else
2944             {
2945                 // If we're not at the end of the text, make sure we break the line on white space.
2946                 while (end > start
2947                        && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
2948                     end--;
2949                 assert (end > 0);
2950             }
2951 
2952             const size_t sub_len = end - start;
2953             if (start != 0)
2954               strm.EOL();
2955             if (!first_line)
2956                 strm.Indent();
2957             else
2958                 first_line = false;
2959             assert (start <= final_end);
2960             assert (start + sub_len <= final_end);
2961             if (sub_len > 0)
2962                 strm.Write (text + start, sub_len);
2963             start = end + 1;
2964         }
2965     }
2966     strm.EOL();
2967     strm.IndentLess(indent_size);
2968 }
2969 
2970 void
2971 CommandInterpreter::OutputHelpText (Stream &strm,
2972                                     const char *word_text,
2973                                     const char *separator,
2974                                     const char *help_text,
2975                                     uint32_t max_word_len)
2976 {
2977     int indent_size = max_word_len + strlen (separator) + 2;
2978 
2979     strm.IndentMore (indent_size);
2980 
2981     StreamString text_strm;
2982     text_strm.Printf ("%-*s %s %s",  max_word_len, word_text, separator, help_text);
2983 
2984     const uint32_t max_columns = m_debugger.GetTerminalWidth();
2985 
2986     size_t len = text_strm.GetSize();
2987     const char *text = text_strm.GetData();
2988 
2989     uint32_t chars_left = max_columns;
2990 
2991     for (uint32_t i = 0; i < len; i++)
2992     {
2993         if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n')
2994         {
2995             chars_left = max_columns - indent_size;
2996             strm.EOL();
2997             strm.Indent();
2998         }
2999         else
3000         {
3001             strm.PutChar(text[i]);
3002             chars_left--;
3003         }
3004 
3005     }
3006 
3007     strm.EOL();
3008     strm.IndentLess(indent_size);
3009 }
3010 
3011 void
3012 CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
3013                                             StringList &commands_help, bool search_builtin_commands, bool search_user_commands)
3014 {
3015     CommandObject::CommandMap::const_iterator pos;
3016 
3017     if (search_builtin_commands)
3018     {
3019         for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
3020         {
3021             const char *command_name = pos->first.c_str();
3022             CommandObject *cmd_obj = pos->second.get();
3023 
3024             if (cmd_obj->HelpTextContainsWord (search_word))
3025             {
3026                 commands_found.AppendString (command_name);
3027                 commands_help.AppendString (cmd_obj->GetHelp());
3028             }
3029 
3030             if (cmd_obj->IsMultiwordObject())
3031                 cmd_obj->AproposAllSubCommands (command_name,
3032                                                 search_word,
3033                                                 commands_found,
3034                                                 commands_help);
3035 
3036         }
3037     }
3038 
3039     if (search_user_commands)
3040     {
3041         for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
3042         {
3043             const char *command_name = pos->first.c_str();
3044             CommandObject *cmd_obj = pos->second.get();
3045 
3046             if (cmd_obj->HelpTextContainsWord (search_word))
3047             {
3048                 commands_found.AppendString (command_name);
3049                 commands_help.AppendString (cmd_obj->GetHelp());
3050             }
3051 
3052             if (cmd_obj->IsMultiwordObject())
3053                 cmd_obj->AproposAllSubCommands (command_name,
3054                                                 search_word,
3055                                                 commands_found,
3056                                                 commands_help);
3057 
3058         }
3059     }
3060 }
3061 
3062 void
3063 CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
3064 {
3065     if (override_context != nullptr)
3066     {
3067         m_exe_ctx_ref = *override_context;
3068     }
3069     else
3070     {
3071         const bool adopt_selected = true;
3072         m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected);
3073     }
3074 }
3075 
3076 
3077 size_t
3078 CommandInterpreter::GetProcessOutput ()
3079 {
3080     //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
3081     char stdio_buffer[1024];
3082     size_t len;
3083     size_t total_bytes = 0;
3084     Error error;
3085     TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
3086     if (target_sp)
3087     {
3088         ProcessSP process_sp (target_sp->GetProcessSP());
3089         if (process_sp)
3090         {
3091             while ((len = process_sp->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
3092             {
3093                 size_t bytes_written = len;
3094                 m_debugger.GetOutputFile()->Write (stdio_buffer, bytes_written);
3095                 total_bytes += len;
3096             }
3097             while ((len = process_sp->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
3098             {
3099                 size_t bytes_written = len;
3100                 m_debugger.GetErrorFile()->Write (stdio_buffer, bytes_written);
3101                 total_bytes += len;
3102             }
3103         }
3104     }
3105     return total_bytes;
3106 }
3107 
3108 void
3109 CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
3110 {
3111     const bool is_interactive = io_handler.GetIsInteractive();
3112     if (is_interactive == false)
3113     {
3114         // When we are not interactive, don't execute blank lines. This will happen
3115         // sourcing a commands file. We don't want blank lines to repeat the previous
3116         // command and cause any errors to occur (like redefining an alias, get an error
3117         // and stop parsing the commands file).
3118         if (line.empty())
3119             return;
3120 
3121         // When using a non-interactive file handle (like when sourcing commands from a file)
3122         // we need to echo the command out so we don't just see the command output and no
3123         // command...
3124         if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand))
3125             io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str());
3126     }
3127 
3128     lldb_private::CommandReturnObject result;
3129     HandleCommand(line.c_str(), eLazyBoolCalculate, result);
3130 
3131     // Now emit the command output text from the command we just executed
3132     if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult))
3133     {
3134         // Display any STDOUT/STDERR _prior_ to emitting the command result text
3135         GetProcessOutput ();
3136 
3137         if (!result.GetImmediateOutputStream())
3138         {
3139             const char *output = result.GetOutputData();
3140             if (output && output[0])
3141                 io_handler.GetOutputStreamFile()->PutCString(output);
3142         }
3143 
3144         // Now emit the command error text from the command we just executed
3145         if (!result.GetImmediateErrorStream())
3146         {
3147             const char *error = result.GetErrorData();
3148             if (error && error[0])
3149                 io_handler.GetErrorStreamFile()->PutCString(error);
3150         }
3151     }
3152 
3153     switch (result.GetStatus())
3154     {
3155         case eReturnStatusInvalid:
3156         case eReturnStatusSuccessFinishNoResult:
3157         case eReturnStatusSuccessFinishResult:
3158         case eReturnStatusStarted:
3159             break;
3160 
3161         case eReturnStatusSuccessContinuingNoResult:
3162         case eReturnStatusSuccessContinuingResult:
3163             if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue))
3164                 io_handler.SetIsDone(true);
3165             break;
3166 
3167         case eReturnStatusFailed:
3168             m_num_errors++;
3169             if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError))
3170                 io_handler.SetIsDone(true);
3171             break;
3172 
3173         case eReturnStatusQuit:
3174             m_quit_requested = true;
3175             io_handler.SetIsDone(true);
3176             break;
3177     }
3178 
3179     // Finally, if we're going to stop on crash, check that here:
3180     if (!m_quit_requested
3181         && result.GetDidChangeProcessState()
3182         && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash))
3183     {
3184         bool should_stop = false;
3185         TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
3186         if (target_sp)
3187         {
3188             ProcessSP process_sp (target_sp->GetProcessSP());
3189             if (process_sp)
3190             {
3191                 for (ThreadSP thread_sp : process_sp->GetThreadList().Threads())
3192                 {
3193                     StopReason reason = thread_sp->GetStopReason();
3194                     if (reason == eStopReasonSignal || reason == eStopReasonException || reason == eStopReasonInstrumentation)
3195                     {
3196                         should_stop = true;
3197                         break;
3198                     }
3199                 }
3200             }
3201         }
3202         if (should_stop)
3203         {
3204             io_handler.SetIsDone(true);
3205             m_stopped_for_crash = true;
3206         }
3207     }
3208 }
3209 
3210 bool
3211 CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler)
3212 {
3213     ExecutionContext exe_ctx (GetExecutionContext());
3214     Process *process = exe_ctx.GetProcessPtr();
3215 
3216     if (process)
3217     {
3218         StateType state = process->GetState();
3219         if (StateIsRunningState(state))
3220         {
3221             process->Halt();
3222             return true; // Don't do any updating when we are running
3223         }
3224     }
3225     return false;
3226 }
3227 
3228 void
3229 CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt,
3230                                                   IOHandlerDelegate &delegate,
3231                                                   bool asynchronously,
3232                                                   void *baton)
3233 {
3234     Debugger &debugger = GetDebugger();
3235     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
3236                                                       IOHandler::Type::CommandList,
3237                                                       "lldb",       // Name of input reader for history
3238                                                       prompt,       // Prompt
3239                                                       NULL,         // Continuation prompt
3240                                                       true,         // Get multiple lines
3241                                                       debugger.GetUseColor(),
3242                                                       0,            // Don't show line numbers
3243                                                       delegate));   // IOHandlerDelegate
3244 
3245     if (io_handler_sp)
3246     {
3247         io_handler_sp->SetUserData (baton);
3248         if (asynchronously)
3249             debugger.PushIOHandler(io_handler_sp);
3250         else
3251             debugger.RunIOHandler(io_handler_sp);
3252     }
3253 
3254 }
3255 
3256 
3257 void
3258 CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt,
3259                                                     IOHandlerDelegate &delegate,
3260                                                     bool asynchronously,
3261                                                     void *baton)
3262 {
3263     Debugger &debugger = GetDebugger();
3264     IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
3265                                                       IOHandler::Type::PythonCode,
3266                                                       "lldb-python",    // Name of input reader for history
3267                                                       prompt,           // Prompt
3268                                                       NULL,             // Continuation prompt
3269                                                       true,             // Get multiple lines
3270                                                       debugger.GetUseColor(),
3271                                                       0,                // Don't show line numbers
3272                                                       delegate));       // IOHandlerDelegate
3273 
3274     if (io_handler_sp)
3275     {
3276         io_handler_sp->SetUserData (baton);
3277         if (asynchronously)
3278             debugger.PushIOHandler(io_handler_sp);
3279         else
3280             debugger.RunIOHandler(io_handler_sp);
3281     }
3282 
3283 }
3284 
3285 bool
3286 CommandInterpreter::IsActive ()
3287 {
3288     return m_debugger.IsTopIOHandler (m_command_io_handler_sp);
3289 }
3290 
3291 lldb::IOHandlerSP
3292 CommandInterpreter::GetIOHandler(bool force_create, CommandInterpreterRunOptions *options)
3293 {
3294     // Always re-create the IOHandlerEditline in case the input
3295     // changed. The old instance might have had a non-interactive
3296     // input and now it does or vice versa.
3297     if (force_create || !m_command_io_handler_sp)
3298     {
3299         // Always re-create the IOHandlerEditline in case the input
3300         // changed. The old instance might have had a non-interactive
3301         // input and now it does or vice versa.
3302         uint32_t flags = 0;
3303 
3304         if (options)
3305         {
3306             if (options->m_stop_on_continue == eLazyBoolYes)
3307                 flags |= eHandleCommandFlagStopOnContinue;
3308             if (options->m_stop_on_error == eLazyBoolYes)
3309                 flags |= eHandleCommandFlagStopOnError;
3310             if (options->m_stop_on_crash == eLazyBoolYes)
3311                 flags |= eHandleCommandFlagStopOnCrash;
3312             if (options->m_echo_commands != eLazyBoolNo)
3313                 flags |= eHandleCommandFlagEchoCommand;
3314             if (options->m_print_results != eLazyBoolNo)
3315                 flags |= eHandleCommandFlagPrintResult;
3316         }
3317         else
3318         {
3319             flags = eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult;
3320         }
3321 
3322         m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger,
3323                                                              IOHandler::Type::CommandInterpreter,
3324                                                              m_debugger.GetInputFile(),
3325                                                              m_debugger.GetOutputFile(),
3326                                                              m_debugger.GetErrorFile(),
3327                                                              flags,
3328                                                              "lldb",
3329                                                              m_debugger.GetPrompt(),
3330                                                              NULL,                      // Continuation prompt
3331                                                              false,                     // Don't enable multiple line input, just single line commands
3332                                                              m_debugger.GetUseColor(),
3333                                                              0,            // Don't show line numbers
3334                                                              *this));
3335     }
3336     return m_command_io_handler_sp;
3337 }
3338 
3339 void
3340 CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
3341                                           bool spawn_thread,
3342                                           CommandInterpreterRunOptions &options)
3343 {
3344     // Always re-create the command intepreter when we run it in case
3345     // any file handles have changed.
3346     bool force_create = true;
3347     m_debugger.PushIOHandler(GetIOHandler(force_create, &options));
3348     m_stopped_for_crash = false;
3349 
3350     if (auto_handle_events)
3351         m_debugger.StartEventHandlerThread();
3352 
3353     if (spawn_thread)
3354     {
3355         m_debugger.StartIOHandlerThread();
3356     }
3357     else
3358     {
3359         m_debugger.ExecuteIOHanders();
3360 
3361         if (auto_handle_events)
3362             m_debugger.StopEventHandlerThread();
3363     }
3364 
3365 }
3366 
3367