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