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