blob: edd2bfac21fc21ddd8d874fb262d0554d58819fb [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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>
Caroline Ticebd5c63e2010-10-12 21:57:09 +000011#include <vector>
Chris Lattner24943d22010-06-08 16:52:24 +000012
13#include <getopt.h>
14#include <stdlib.h>
15
Greg Clayton5c28dd12011-06-23 17:59:56 +000016#include "CommandObjectScript.h"
Peter Collingbourne921fac02011-06-23 20:37:26 +000017#include "lldb/Interpreter/CommandObjectRegexCommand.h"
Greg Clayton5c28dd12011-06-23 17:59:56 +000018
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000019#include "../Commands/CommandObjectApropos.h"
20#include "../Commands/CommandObjectArgs.h"
21#include "../Commands/CommandObjectBreakpoint.h"
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000022#include "../Commands/CommandObjectDisassemble.h"
23#include "../Commands/CommandObjectExpression.h"
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000024#include "../Commands/CommandObjectFrame.h"
25#include "../Commands/CommandObjectHelp.h"
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000026#include "../Commands/CommandObjectLog.h"
27#include "../Commands/CommandObjectMemory.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000028#include "../Commands/CommandObjectPlatform.h"
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000029#include "../Commands/CommandObjectProcess.h"
30#include "../Commands/CommandObjectQuit.h"
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000031#include "../Commands/CommandObjectRegister.h"
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000032#include "../Commands/CommandObjectSettings.h"
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000033#include "../Commands/CommandObjectSource.h"
Jim Ingham767af882010-07-07 03:36:20 +000034#include "../Commands/CommandObjectCommands.h"
Eli Friedmanccdb9ec2010-06-13 02:17:17 +000035#include "../Commands/CommandObjectSyntax.h"
36#include "../Commands/CommandObjectTarget.h"
37#include "../Commands/CommandObjectThread.h"
Greg Clayton5c28dd12011-06-23 17:59:56 +000038#include "../Commands/CommandObjectType.h"
Johnny Chen902e0182010-12-23 20:21:44 +000039#include "../Commands/CommandObjectVersion.h"
Johnny Chen01acfa72011-09-22 18:04:58 +000040#include "../Commands/CommandObjectWatchpoint.h"
Chris Lattner24943d22010-06-08 16:52:24 +000041
Jim Ingham84cdc152010-06-15 19:49:27 +000042#include "lldb/Interpreter/Args.h"
Caroline Tice5ddbe212011-05-06 21:37:15 +000043#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000044#include "lldb/Core/Debugger.h"
Jim Ingham5e16ef52010-10-04 19:49:29 +000045#include "lldb/Core/InputReader.h"
Chris Lattner24943d22010-06-08 16:52:24 +000046#include "lldb/Core/Stream.h"
47#include "lldb/Core/Timer.h"
Greg Claytoncd548032011-02-01 01:31:41 +000048#include "lldb/Host/Host.h"
Chris Lattner24943d22010-06-08 16:52:24 +000049#include "lldb/Target/Process.h"
50#include "lldb/Target/Thread.h"
51#include "lldb/Target/TargetList.h"
Greg Claytone98ac252010-11-10 04:57:04 +000052#include "lldb/Utility/CleanUp.h"
Chris Lattner24943d22010-06-08 16:52:24 +000053
54#include "lldb/Interpreter/CommandReturnObject.h"
55#include "lldb/Interpreter/CommandInterpreter.h"
Caroline Tice0aa2e552011-01-14 00:29:16 +000056#include "lldb/Interpreter/ScriptInterpreterNone.h"
57#include "lldb/Interpreter/ScriptInterpreterPython.h"
Chris Lattner24943d22010-06-08 16:52:24 +000058
59using namespace lldb;
60using namespace lldb_private;
61
62CommandInterpreter::CommandInterpreter
63(
Greg Clayton63094e02010-06-23 01:19:29 +000064 Debugger &debugger,
Chris Lattner24943d22010-06-08 16:52:24 +000065 ScriptLanguage script_language,
Greg Clayton63094e02010-06-23 01:19:29 +000066 bool synchronous_execution
Chris Lattner24943d22010-06-08 16:52:24 +000067) :
Greg Clayton49ce6822010-10-31 03:01:06 +000068 Broadcaster ("lldb.command-interpreter"),
Greg Clayton63094e02010-06-23 01:19:29 +000069 m_debugger (debugger),
Greg Clayton887aa282010-10-11 01:05:37 +000070 m_synchronous_execution (synchronous_execution),
Caroline Tice0aa2e552011-01-14 00:29:16 +000071 m_skip_lldbinit_files (false),
Jim Ingham574c3d62011-08-12 23:34:31 +000072 m_skip_app_init_files (false),
Jim Ingham949d5ac2011-02-18 00:54:25 +000073 m_script_interpreter_ap (),
Caroline Tice892fadd2011-06-16 16:27:19 +000074 m_comment_char ('#'),
Jim Ingham6247dbe2011-07-12 03:12:18 +000075 m_repeat_char ('!'),
Enrico Granata293a7b32011-08-15 19:24:02 +000076 m_batch_command_mode (false),
77 m_truncation_warning(eNoTruncation)
Chris Lattner24943d22010-06-08 16:52:24 +000078{
Caroline Tice6e4c5ce2010-09-04 00:03:46 +000079 const char *dbg_name = debugger.GetInstanceName().AsCString();
80 std::string lang_name = ScriptInterpreter::LanguageToString (script_language);
81 StreamString var_name;
82 var_name.Printf ("[%s].script-lang", dbg_name);
Caroline Tice1d2aefd2010-09-09 06:25:08 +000083 debugger.GetSettingsController()->SetVariable (var_name.GetData(), lang_name.c_str(),
Greg Claytonb3448432011-03-24 21:19:54 +000084 eVarSetOperationAssign, false,
Greg Clayton49ce6822010-10-31 03:01:06 +000085 m_debugger.GetInstanceName().AsCString());
86 SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit");
87 SetEventName (eBroadcastBitResetPrompt, "reset-prompt");
88 SetEventName (eBroadcastBitQuitCommandReceived, "quit");
Chris Lattner24943d22010-06-08 16:52:24 +000089}
90
91void
92CommandInterpreter::Initialize ()
93{
94 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
95
96 CommandReturnObject result;
97
98 LoadCommandDictionary ();
99
Chris Lattner24943d22010-06-08 16:52:24 +0000100 // Set up some initial aliases.
Caroline Tice5ddbe212011-05-06 21:37:15 +0000101 CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false);
102 if (cmd_obj_sp)
103 {
104 AddAlias ("q", cmd_obj_sp);
105 AddAlias ("exit", cmd_obj_sp);
106 }
107
108 cmd_obj_sp = GetCommandSPExact ("process continue", false);
109 if (cmd_obj_sp)
110 {
111 AddAlias ("c", cmd_obj_sp);
112 AddAlias ("continue", cmd_obj_sp);
113 }
114
115 cmd_obj_sp = GetCommandSPExact ("_regexp-break",false);
116 if (cmd_obj_sp)
117 AddAlias ("b", cmd_obj_sp);
118
119 cmd_obj_sp = GetCommandSPExact ("thread backtrace", false);
120 if (cmd_obj_sp)
121 AddAlias ("bt", cmd_obj_sp);
122
123 cmd_obj_sp = GetCommandSPExact ("thread step-inst", false);
124 if (cmd_obj_sp)
Jason Molenda47eb00e2011-10-22 00:47:41 +0000125 {
126 AddAlias ("stepi", cmd_obj_sp);
Caroline Tice5ddbe212011-05-06 21:37:15 +0000127 AddAlias ("si", cmd_obj_sp);
Jason Molenda47eb00e2011-10-22 00:47:41 +0000128 }
129
130 cmd_obj_sp = GetCommandSPExact ("thread step-inst-over", false);
131 if (cmd_obj_sp)
132 {
133 AddAlias ("nexti", cmd_obj_sp);
134 AddAlias ("ni", cmd_obj_sp);
135 }
Caroline Tice5ddbe212011-05-06 21:37:15 +0000136
137 cmd_obj_sp = GetCommandSPExact ("thread step-in", false);
138 if (cmd_obj_sp)
139 {
140 AddAlias ("s", cmd_obj_sp);
141 AddAlias ("step", cmd_obj_sp);
142 }
143
144 cmd_obj_sp = GetCommandSPExact ("thread step-over", false);
145 if (cmd_obj_sp)
146 {
147 AddAlias ("n", cmd_obj_sp);
148 AddAlias ("next", cmd_obj_sp);
149 }
150
151 cmd_obj_sp = GetCommandSPExact ("thread step-out", false);
152 if (cmd_obj_sp)
153 {
154 AddAlias ("f", cmd_obj_sp);
155 AddAlias ("finish", cmd_obj_sp);
156 }
157
158 cmd_obj_sp = GetCommandSPExact ("source list", false);
159 if (cmd_obj_sp)
160 {
161 AddAlias ("l", cmd_obj_sp);
162 AddAlias ("list", cmd_obj_sp);
163 }
164
165 cmd_obj_sp = GetCommandSPExact ("memory read", false);
166 if (cmd_obj_sp)
167 AddAlias ("x", cmd_obj_sp);
168
169 cmd_obj_sp = GetCommandSPExact ("_regexp-up", false);
170 if (cmd_obj_sp)
171 AddAlias ("up", cmd_obj_sp);
172
173 cmd_obj_sp = GetCommandSPExact ("_regexp-down", false);
174 if (cmd_obj_sp)
175 AddAlias ("down", cmd_obj_sp);
176
177 cmd_obj_sp = GetCommandSPExact ("target create", false);
178 if (cmd_obj_sp)
179 AddAlias ("file", cmd_obj_sp);
180
181 cmd_obj_sp = GetCommandSPExact ("target modules", false);
182 if (cmd_obj_sp)
183 AddAlias ("image", cmd_obj_sp);
184
185
186 OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector);
Jim Inghame56493f2011-03-22 02:29:32 +0000187
Caroline Tice5ddbe212011-05-06 21:37:15 +0000188 cmd_obj_sp = GetCommandSPExact ("expression", false);
189 if (cmd_obj_sp)
190 {
191 AddAlias ("expr", cmd_obj_sp);
192
193 ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
194 AddAlias ("p", cmd_obj_sp);
195 AddAlias ("print", cmd_obj_sp);
196 AddOrReplaceAliasOptions ("p", alias_arguments_vector_sp);
197 AddOrReplaceAliasOptions ("print", alias_arguments_vector_sp);
198
199 alias_arguments_vector_sp.reset (new OptionArgVector);
200 ProcessAliasOptionsArgs (cmd_obj_sp, "-o --", alias_arguments_vector_sp);
201 AddAlias ("po", cmd_obj_sp);
202 AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp);
203 }
204
205 cmd_obj_sp = GetCommandSPExact ("process launch", false);
206 if (cmd_obj_sp)
207 {
208 alias_arguments_vector_sp.reset (new OptionArgVector);
209 ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
210 AddAlias ("r", cmd_obj_sp);
211 AddAlias ("run", cmd_obj_sp);
212 AddOrReplaceAliasOptions ("r", alias_arguments_vector_sp);
213 AddOrReplaceAliasOptions ("run", alias_arguments_vector_sp);
214 }
215
Chris Lattner24943d22010-06-08 16:52:24 +0000216}
217
Chris Lattner24943d22010-06-08 16:52:24 +0000218const char *
219CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg)
220{
221 // This function has not yet been implemented.
222
223 // Look for any embedded script command
224 // If found,
225 // get interpreter object from the command dictionary,
226 // call execute_one_command on it,
227 // get the results as a string,
228 // substitute that string for current stuff.
229
230 return arg;
231}
232
233
234void
235CommandInterpreter::LoadCommandDictionary ()
236{
237 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
238
239 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
240 //
241 // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref)
242 // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use
243 // the cross-referencing stuff) are created!!!
244 //
245 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
246
247
248 // Command objects that inherit from CommandObjectCrossref must be created before other command objects
249 // are created. This is so that when another command is created that needs to go into a crossref object,
250 // the crossref object exists and is ready to take the cross reference. Put the cross referencing command
251 // objects into the CommandDictionary now, so they are ready for use when the other commands get created.
252
Chris Lattner24943d22010-06-08 16:52:24 +0000253 // Non-CommandObjectCrossref commands can now be created.
254
Caroline Tice5bc8c972010-09-20 20:44:43 +0000255 lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage();
Caroline Tice6e4c5ce2010-09-04 00:03:46 +0000256
Greg Clayton238c0a12010-09-18 01:14:36 +0000257 m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this));
Greg Clayton63094e02010-06-23 01:19:29 +0000258 m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
Greg Clayton238c0a12010-09-18 01:14:36 +0000259 //m_command_dict["call"] = CommandObjectSP (new CommandObjectCall (*this));
Johnny Chen9e4c3d72011-04-21 00:39:18 +0000260 m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
Greg Clayton238c0a12010-09-18 01:14:36 +0000261 m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
262 m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
Greg Claytonabe0fed2011-04-18 08:33:37 +0000263// m_command_dict["file"] = CommandObjectSP (new CommandObjectFile (*this));
Greg Clayton63094e02010-06-23 01:19:29 +0000264 m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this));
Greg Clayton238c0a12010-09-18 01:14:36 +0000265 m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this));
Greg Claytone1f50b92011-05-03 22:09:39 +0000266 /// m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (*this));
Greg Clayton63094e02010-06-23 01:19:29 +0000267 m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this));
268 m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this));
Greg Claytonb1888f22011-03-19 01:12:21 +0000269 m_command_dict["platform"] = CommandObjectSP (new CommandObjectPlatform (*this));
Greg Clayton63094e02010-06-23 01:19:29 +0000270 m_command_dict["process"] = CommandObjectSP (new CommandObjectMultiwordProcess (*this));
Greg Clayton238c0a12010-09-18 01:14:36 +0000271 m_command_dict["quit"] = CommandObjectSP (new CommandObjectQuit (*this));
Greg Clayton63094e02010-06-23 01:19:29 +0000272 m_command_dict["register"] = CommandObjectSP (new CommandObjectRegister (*this));
Greg Clayton238c0a12010-09-18 01:14:36 +0000273 m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (*this, script_language));
Caroline Tice6e4c5ce2010-09-04 00:03:46 +0000274 m_command_dict["settings"] = CommandObjectSP (new CommandObjectMultiwordSettings (*this));
Jim Ingham767af882010-07-07 03:36:20 +0000275 m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this));
Greg Clayton63094e02010-06-23 01:19:29 +0000276 m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this));
277 m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this));
Enrico Granata6b1596d2011-08-16 23:24:13 +0000278 m_command_dict["type"] = CommandObjectSP (new CommandObjectType (*this));
Johnny Chen902e0182010-12-23 20:21:44 +0000279 m_command_dict["version"] = CommandObjectSP (new CommandObjectVersion (*this));
Johnny Chen01acfa72011-09-22 18:04:58 +0000280 m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this));
Chris Lattner24943d22010-06-08 16:52:24 +0000281
282 std::auto_ptr<CommandObjectRegexCommand>
Greg Clayton238c0a12010-09-18 01:14:36 +0000283 break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
Greg Claytonb72d0f02011-04-12 05:54:46 +0000284 "_regexp-break",
Caroline Ticec1ad82e2010-09-07 22:38:08 +0000285 "Set a breakpoint using a regular expression to specify the location.",
Greg Claytonb72d0f02011-04-12 05:54:46 +0000286 "_regexp-break [<filename>:<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
Chris Lattner24943d22010-06-08 16:52:24 +0000287 if (break_regex_cmd_ap.get())
288 {
289 if (break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2") &&
290 break_regex_cmd_ap->AddRegexCommand("^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1") &&
291 break_regex_cmd_ap->AddRegexCommand("^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'") &&
Greg Claytonb72d0f02011-04-12 05:54:46 +0000292 break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full") &&
Chris Lattner24943d22010-06-08 16:52:24 +0000293 break_regex_cmd_ap->AddRegexCommand("^(-.*)$", "breakpoint set %1") &&
Greg Claytonb01000f2011-01-17 03:46:26 +0000294 break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'") &&
Chris Lattner24943d22010-06-08 16:52:24 +0000295 break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"))
296 {
297 CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release());
298 m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp;
299 }
300 }
Jim Inghame56493f2011-03-22 02:29:32 +0000301
302 std::auto_ptr<CommandObjectRegexCommand>
303 down_regex_cmd_ap(new CommandObjectRegexCommand (*this,
Greg Claytonb72d0f02011-04-12 05:54:46 +0000304 "_regexp-down",
305 "Go down \"n\" frames in the stack (1 frame by default).",
306 "_regexp-down [n]", 2));
Jim Inghame56493f2011-03-22 02:29:32 +0000307 if (down_regex_cmd_ap.get())
308 {
309 if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") &&
310 down_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r -%1"))
311 {
312 CommandObjectSP down_regex_cmd_sp(down_regex_cmd_ap.release());
313 m_command_dict[down_regex_cmd_sp->GetCommandName ()] = down_regex_cmd_sp;
314 }
315 }
316
317 std::auto_ptr<CommandObjectRegexCommand>
318 up_regex_cmd_ap(new CommandObjectRegexCommand (*this,
Greg Claytonb72d0f02011-04-12 05:54:46 +0000319 "_regexp-up",
320 "Go up \"n\" frames in the stack (1 frame by default).",
321 "_regexp-up [n]", 2));
Jim Inghame56493f2011-03-22 02:29:32 +0000322 if (up_regex_cmd_ap.get())
323 {
324 if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") &&
325 up_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r %1"))
326 {
327 CommandObjectSP up_regex_cmd_sp(up_regex_cmd_ap.release());
328 m_command_dict[up_regex_cmd_sp->GetCommandName ()] = up_regex_cmd_sp;
329 }
330 }
Chris Lattner24943d22010-06-08 16:52:24 +0000331}
332
333int
334CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases,
335 StringList &matches)
336{
337 CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches);
338
339 if (include_aliases)
340 {
341 CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches);
342 }
343
344 return matches.GetSize();
345}
346
347CommandObjectSP
348CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches)
349{
350 CommandObject::CommandMap::iterator pos;
351 CommandObjectSP ret_val;
352
353 std::string cmd(cmd_cstr);
354
355 if (HasCommands())
356 {
357 pos = m_command_dict.find(cmd);
358 if (pos != m_command_dict.end())
359 ret_val = pos->second;
360 }
361
362 if (include_aliases && HasAliases())
363 {
364 pos = m_alias_dict.find(cmd);
365 if (pos != m_alias_dict.end())
366 ret_val = pos->second;
367 }
368
369 if (HasUserCommands())
370 {
371 pos = m_user_dict.find(cmd);
372 if (pos != m_user_dict.end())
373 ret_val = pos->second;
374 }
375
376 if (!exact && ret_val == NULL)
377 {
Jim Inghamd40f8a62010-07-06 22:46:59 +0000378 // We will only get into here if we didn't find any exact matches.
379
380 CommandObjectSP user_match_sp, alias_match_sp, real_match_sp;
381
Chris Lattner24943d22010-06-08 16:52:24 +0000382 StringList local_matches;
383 if (matches == NULL)
384 matches = &local_matches;
385
Jim Inghamd40f8a62010-07-06 22:46:59 +0000386 unsigned int num_cmd_matches = 0;
387 unsigned int num_alias_matches = 0;
388 unsigned int num_user_matches = 0;
389
390 // Look through the command dictionaries one by one, and if we get only one match from any of
391 // them in toto, then return that, otherwise return an empty CommandObjectSP and the list of matches.
392
Chris Lattner24943d22010-06-08 16:52:24 +0000393 if (HasCommands())
394 {
395 num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches);
396 }
397
398 if (num_cmd_matches == 1)
399 {
400 cmd.assign(matches->GetStringAtIndex(0));
401 pos = m_command_dict.find(cmd);
402 if (pos != m_command_dict.end())
Jim Inghamd40f8a62010-07-06 22:46:59 +0000403 real_match_sp = pos->second;
Chris Lattner24943d22010-06-08 16:52:24 +0000404 }
405
Jim Ingham9a574172010-06-24 20:28:42 +0000406 if (include_aliases && HasAliases())
Chris Lattner24943d22010-06-08 16:52:24 +0000407 {
408 num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches);
409
410 }
411
Jim Inghamd40f8a62010-07-06 22:46:59 +0000412 if (num_alias_matches == 1)
Chris Lattner24943d22010-06-08 16:52:24 +0000413 {
414 cmd.assign(matches->GetStringAtIndex (num_cmd_matches));
415 pos = m_alias_dict.find(cmd);
416 if (pos != m_alias_dict.end())
Jim Inghamd40f8a62010-07-06 22:46:59 +0000417 alias_match_sp = pos->second;
Chris Lattner24943d22010-06-08 16:52:24 +0000418 }
419
Jim Ingham9a574172010-06-24 20:28:42 +0000420 if (HasUserCommands())
Chris Lattner24943d22010-06-08 16:52:24 +0000421 {
422 num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches);
423 }
424
Jim Inghamd40f8a62010-07-06 22:46:59 +0000425 if (num_user_matches == 1)
Chris Lattner24943d22010-06-08 16:52:24 +0000426 {
427 cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches));
428
429 pos = m_user_dict.find (cmd);
430 if (pos != m_user_dict.end())
Jim Inghamd40f8a62010-07-06 22:46:59 +0000431 user_match_sp = pos->second;
432 }
433
434 // If we got exactly one match, return that, otherwise return the match list.
435
436 if (num_user_matches + num_cmd_matches + num_alias_matches == 1)
437 {
438 if (num_cmd_matches)
439 return real_match_sp;
440 else if (num_alias_matches)
441 return alias_match_sp;
442 else
443 return user_match_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000444 }
445 }
Jim Inghamd40f8a62010-07-06 22:46:59 +0000446 else if (matches && ret_val != NULL)
447 {
448 matches->AppendString (cmd_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +0000449 }
450
451
452 return ret_val;
453}
454
Greg Claytond12aeab2011-04-20 16:37:46 +0000455bool
456CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
457{
458 if (name && name[0])
459 {
460 std::string name_sstr(name);
461 if (!can_replace)
462 {
463 if (m_command_dict.find (name_sstr) != m_command_dict.end())
464 return false;
465 }
466 m_command_dict[name_sstr] = cmd_sp;
467 return true;
468 }
469 return false;
470}
471
Enrico Granata6b1596d2011-08-16 23:24:13 +0000472bool
473CommandInterpreter::AddUserCommand (const char *name,
474 const lldb::CommandObjectSP &cmd_sp,
475 bool can_replace)
476{
477 if (name && name[0])
478 {
479 std::string name_sstr(name);
480 if (!can_replace)
481 {
482 if (m_user_dict.find (name_sstr) != m_user_dict.end())
483 return false;
484 }
485 m_user_dict[name_sstr] = cmd_sp;
486 return true;
487 }
488 return false;
489}
Greg Claytond12aeab2011-04-20 16:37:46 +0000490
Jim Inghamd40f8a62010-07-06 22:46:59 +0000491CommandObjectSP
492CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases)
Chris Lattner24943d22010-06-08 16:52:24 +0000493{
Caroline Tice56d2fc42010-12-14 18:51:39 +0000494 Args cmd_words (cmd_cstr); // Break up the command string into words, in case it's a multi-word command.
495 CommandObjectSP ret_val; // Possibly empty return value.
496
497 if (cmd_cstr == NULL)
498 return ret_val;
499
500 if (cmd_words.GetArgumentCount() == 1)
501 return GetCommandSP(cmd_cstr, include_aliases, true, NULL);
502 else
503 {
504 // We have a multi-word command (seemingly), so we need to do more work.
505 // First, get the cmd_obj_sp for the first word in the command.
506 CommandObjectSP cmd_obj_sp = GetCommandSP (cmd_words.GetArgumentAtIndex (0), include_aliases, true, NULL);
507 if (cmd_obj_sp.get() != NULL)
508 {
509 // Loop through the rest of the words in the command (everything passed in was supposed to be part of a
510 // command name), and find the appropriate sub-command SP for each command word....
511 size_t end = cmd_words.GetArgumentCount();
512 for (size_t j= 1; j < end; ++j)
513 {
514 if (cmd_obj_sp->IsMultiwordObject())
515 {
516 cmd_obj_sp = ((CommandObjectMultiword *) cmd_obj_sp.get())->GetSubcommandSP
517 (cmd_words.GetArgumentAtIndex (j));
518 if (cmd_obj_sp.get() == NULL)
519 // The sub-command name was invalid. Fail and return the empty 'ret_val'.
520 return ret_val;
521 }
522 else
523 // We have more words in the command name, but we don't have a multiword object. Fail and return
524 // empty 'ret_val'.
525 return ret_val;
526 }
527 // We successfully looped through all the command words and got valid command objects for them. Assign the
528 // last object retrieved to 'ret_val'.
529 ret_val = cmd_obj_sp;
530 }
531 }
532 return ret_val;
Jim Inghamd40f8a62010-07-06 22:46:59 +0000533}
534
535CommandObject *
536CommandInterpreter::GetCommandObjectExact (const char *cmd_cstr, bool include_aliases)
537{
538 return GetCommandSPExact (cmd_cstr, include_aliases).get();
539}
540
541CommandObject *
542CommandInterpreter::GetCommandObject (const char *cmd_cstr, StringList *matches)
543{
544 CommandObject *command_obj = GetCommandSP (cmd_cstr, false, true, matches).get();
545
546 // If we didn't find an exact match to the command string in the commands, look in
547 // the aliases.
548
549 if (command_obj == NULL)
550 {
551 command_obj = GetCommandSP (cmd_cstr, true, true, matches).get();
552 }
553
554 // Finally, if there wasn't an exact match among the aliases, look for an inexact match
555 // in both the commands and the aliases.
556
557 if (command_obj == NULL)
558 command_obj = GetCommandSP(cmd_cstr, true, false, matches).get();
559
560 return command_obj;
Chris Lattner24943d22010-06-08 16:52:24 +0000561}
562
563bool
564CommandInterpreter::CommandExists (const char *cmd)
565{
566 return m_command_dict.find(cmd) != m_command_dict.end();
567}
568
569bool
Caroline Tice5ddbe212011-05-06 21:37:15 +0000570CommandInterpreter::ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
571 const char *options_args,
572 OptionArgVectorSP &option_arg_vector_sp)
573{
574 bool success = true;
575 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
576
577 if (!options_args || (strlen (options_args) < 1))
578 return true;
579
580 std::string options_string (options_args);
581 Args args (options_args);
582 CommandReturnObject result;
583 // Check to see if the command being aliased can take any command options.
584 Options *options = cmd_obj_sp->GetOptions ();
585 if (options)
586 {
587 // See if any options were specified as part of the alias; if so, handle them appropriately.
588 options->NotifyOptionParsingStarting ();
589 args.Unshift ("dummy_arg");
590 args.ParseAliasOptions (*options, result, option_arg_vector, options_string);
591 args.Shift ();
592 if (result.Succeeded())
593 options->VerifyPartialOptions (result);
594 if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
595 {
596 result.AppendError ("Unable to create requested alias.\n");
597 return false;
598 }
599 }
600
601 if (options_string.size() > 0)
602 {
603 if (cmd_obj_sp->WantsRawCommandString ())
604 option_arg_vector->push_back (OptionArgPair ("<argument>",
605 OptionArgValue (-1,
606 options_string)));
607 else
608 {
609 int argc = args.GetArgumentCount();
610 for (size_t i = 0; i < argc; ++i)
611 if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
612 option_arg_vector->push_back
613 (OptionArgPair ("<argument>",
614 OptionArgValue (-1,
615 std::string (args.GetArgumentAtIndex (i)))));
616 }
617 }
618
619 return success;
620}
621
622bool
Chris Lattner24943d22010-06-08 16:52:24 +0000623CommandInterpreter::AliasExists (const char *cmd)
624{
625 return m_alias_dict.find(cmd) != m_alias_dict.end();
626}
627
628bool
629CommandInterpreter::UserCommandExists (const char *cmd)
630{
631 return m_user_dict.find(cmd) != m_user_dict.end();
632}
633
634void
635CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp)
636{
Jim Inghamd40f8a62010-07-06 22:46:59 +0000637 command_obj_sp->SetIsAlias (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000638 m_alias_dict[alias_name] = command_obj_sp;
639}
640
641bool
642CommandInterpreter::RemoveAlias (const char *alias_name)
643{
644 CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name);
645 if (pos != m_alias_dict.end())
646 {
647 m_alias_dict.erase(pos);
648 return true;
649 }
650 return false;
651}
652bool
653CommandInterpreter::RemoveUser (const char *alias_name)
654{
655 CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name);
656 if (pos != m_user_dict.end())
657 {
658 m_user_dict.erase(pos);
659 return true;
660 }
661 return false;
662}
663
Chris Lattner24943d22010-06-08 16:52:24 +0000664void
665CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string)
666{
667 help_string.Printf ("'%s", command_name);
668 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
669
670 if (option_arg_vector_sp != NULL)
671 {
672 OptionArgVector *options = option_arg_vector_sp.get();
673 for (int i = 0; i < options->size(); ++i)
674 {
675 OptionArgPair cur_option = (*options)[i];
676 std::string opt = cur_option.first;
Caroline Tice44c841d2010-12-07 19:58:26 +0000677 OptionArgValue value_pair = cur_option.second;
678 std::string value = value_pair.second;
Chris Lattner24943d22010-06-08 16:52:24 +0000679 if (opt.compare("<argument>") == 0)
680 {
681 help_string.Printf (" %s", value.c_str());
682 }
683 else
684 {
685 help_string.Printf (" %s", opt.c_str());
686 if ((value.compare ("<no-argument>") != 0)
687 && (value.compare ("<need-argument") != 0))
688 {
689 help_string.Printf (" %s", value.c_str());
690 }
691 }
692 }
693 }
694
695 help_string.Printf ("'");
696}
697
Greg Clayton65124ea2010-08-26 22:05:43 +0000698size_t
Chris Lattner24943d22010-06-08 16:52:24 +0000699CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict)
700{
701 CommandObject::CommandMap::const_iterator pos;
Greg Clayton65124ea2010-08-26 22:05:43 +0000702 CommandObject::CommandMap::const_iterator end = dict.end();
703 size_t max_len = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000704
Greg Clayton65124ea2010-08-26 22:05:43 +0000705 for (pos = dict.begin(); pos != end; ++pos)
706 {
707 size_t len = pos->first.size();
708 if (max_len < len)
709 max_len = len;
Chris Lattner24943d22010-06-08 16:52:24 +0000710 }
Greg Clayton65124ea2010-08-26 22:05:43 +0000711 return max_len;
Chris Lattner24943d22010-06-08 16:52:24 +0000712}
713
714void
Enrico Granata6b1596d2011-08-16 23:24:13 +0000715CommandInterpreter::GetHelp (CommandReturnObject &result,
Enrico Granata1ac6d1f2011-09-09 17:49:36 +0000716 uint32_t cmd_types)
Chris Lattner24943d22010-06-08 16:52:24 +0000717{
718 CommandObject::CommandMap::const_iterator pos;
Greg Clayton65124ea2010-08-26 22:05:43 +0000719 uint32_t max_len = FindLongestCommandWord (m_command_dict);
Enrico Granata6b1596d2011-08-16 23:24:13 +0000720
721 if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
Chris Lattner24943d22010-06-08 16:52:24 +0000722 {
Enrico Granata6b1596d2011-08-16 23:24:13 +0000723
724 result.AppendMessage("The following is a list of built-in, permanent debugger commands:");
725 result.AppendMessage("");
Chris Lattner24943d22010-06-08 16:52:24 +0000726
Enrico Granata6b1596d2011-08-16 23:24:13 +0000727 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
728 {
729 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
730 max_len);
731 }
732 result.AppendMessage("");
733
734 }
735
736 if (m_alias_dict.size() > 0 && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases ))
Chris Lattner24943d22010-06-08 16:52:24 +0000737 {
Jim Inghame3663e82010-10-22 18:47:16 +0000738 result.AppendMessage("The following is a list of your current command abbreviations "
Johnny Chen9e4c3d72011-04-21 00:39:18 +0000739 "(see 'help command alias' for more info):");
Chris Lattner24943d22010-06-08 16:52:24 +0000740 result.AppendMessage("");
Greg Clayton65124ea2010-08-26 22:05:43 +0000741 max_len = FindLongestCommandWord (m_alias_dict);
742
Chris Lattner24943d22010-06-08 16:52:24 +0000743 for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos)
744 {
745 StreamString sstr;
746 StreamString translation_and_help;
747 std::string entry_name = pos->first;
748 std::string second_entry = pos->second.get()->GetCommandName();
749 GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr);
750
751 translation_and_help.Printf ("(%s) %s", sstr.GetData(), pos->second->GetHelp());
752 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--",
753 translation_and_help.GetData(), max_len);
754 }
755 result.AppendMessage("");
756 }
757
Enrico Granata6b1596d2011-08-16 23:24:13 +0000758 if (m_user_dict.size() > 0 && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef ))
Chris Lattner24943d22010-06-08 16:52:24 +0000759 {
760 result.AppendMessage ("The following is a list of your current user-defined commands:");
761 result.AppendMessage("");
Enrico Granata6b1596d2011-08-16 23:24:13 +0000762 max_len = FindLongestCommandWord (m_user_dict);
Chris Lattner24943d22010-06-08 16:52:24 +0000763 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
764 {
Enrico Granata6b1596d2011-08-16 23:24:13 +0000765 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
766 max_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000767 }
768 result.AppendMessage("");
769 }
770
771 result.AppendMessage("For more information on any particular command, try 'help <command-name>'.");
772}
773
Caroline Ticee0da7a52010-12-09 22:52:49 +0000774CommandObject *
775CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
Chris Lattner24943d22010-06-08 16:52:24 +0000776{
Caroline Ticee0da7a52010-12-09 22:52:49 +0000777 // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will
778 // eventually be invoked by the given command line.
779
780 CommandObject *cmd_obj = NULL;
781 std::string white_space (" \t\v");
782 size_t start = command_string.find_first_not_of (white_space);
783 size_t end = 0;
784 bool done = false;
785 while (!done)
786 {
787 if (start != std::string::npos)
788 {
789 // Get the next word from command_string.
790 end = command_string.find_first_of (white_space, start);
791 if (end == std::string::npos)
792 end = command_string.size();
793 std::string cmd_word = command_string.substr (start, end - start);
794
795 if (cmd_obj == NULL)
796 // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid
797 // command or alias.
798 cmd_obj = GetCommandObject (cmd_word.c_str());
799 else if (cmd_obj->IsMultiwordObject ())
800 {
801 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object.
802 CommandObject *sub_cmd_obj =
803 ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (cmd_word.c_str());
804 if (sub_cmd_obj)
805 cmd_obj = sub_cmd_obj;
806 else // cmd_word was not a valid sub-command word, so we are donee
807 done = true;
808 }
809 else
810 // We have a cmd_obj and it is not a multi-word object, so we are done.
811 done = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000812
Caroline Ticee0da7a52010-12-09 22:52:49 +0000813 // If we didn't find a valid command object, or our command object is not a multi-word object, or
814 // we are at the end of the command_string, then we are done. Otherwise, find the start of the
815 // next word.
816
817 if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size())
818 done = true;
819 else
820 start = command_string.find_first_not_of (white_space, end);
821 }
822 else
823 // Unable to find any more words.
824 done = true;
825 }
826
827 if (end == command_string.size())
828 command_string.clear();
829 else
830 command_string = command_string.substr(end);
831
832 return cmd_obj;
833}
834
835bool
Caroline Tice649116c2011-05-11 16:07:06 +0000836CommandInterpreter::StripFirstWord (std::string &command_string, std::string &word, bool &was_quoted, char &quote_char)
Caroline Ticee0da7a52010-12-09 22:52:49 +0000837{
838 std::string white_space (" \t\v");
839 size_t start;
840 size_t end;
841
842 start = command_string.find_first_not_of (white_space);
843 if (start != std::string::npos)
844 {
Caroline Tice649116c2011-05-11 16:07:06 +0000845 size_t len = command_string.size() - start;
846 if (len >= 2
847 && ((command_string[start] == '\'') || (command_string[start] == '"')))
Caroline Ticee0da7a52010-12-09 22:52:49 +0000848 {
Caroline Tice649116c2011-05-11 16:07:06 +0000849 was_quoted = true;
850 quote_char = command_string[start];
851 std::string quote_string = command_string.substr (start, 1);
852 start = start + 1;
853 end = command_string.find (quote_string, start);
854 if (end != std::string::npos)
855 {
856 word = command_string.substr (start, end - start);
857 if (end + 1 < len)
858 command_string = command_string.substr (end+1);
859 else
860 command_string.erase ();
861 size_t pos = command_string.find_first_not_of (white_space);
862 if ((pos != 0) && (pos != std::string::npos))
863 command_string = command_string.substr (pos);
864 }
865 else
866 {
867 word = command_string.substr (start - 1);
868 command_string.erase ();
869 }
Caroline Ticee0da7a52010-12-09 22:52:49 +0000870 }
871 else
872 {
Caroline Tice649116c2011-05-11 16:07:06 +0000873 end = command_string.find_first_of (white_space, start);
874 if (end != std::string::npos)
875 {
876 word = command_string.substr (start, end - start);
877 command_string = command_string.substr (end);
878 size_t pos = command_string.find_first_not_of (white_space);
879 if ((pos != 0) && (pos != std::string::npos))
880 command_string = command_string.substr (pos);
881 }
882 else
883 {
884 word = command_string.substr (start);
885 command_string.erase();
886 }
Caroline Ticee0da7a52010-12-09 22:52:49 +0000887 }
888
889 }
890 return true;
891}
892
893void
894CommandInterpreter::BuildAliasResult (const char *alias_name, std::string &raw_input_string, std::string &alias_result,
895 CommandObject *&alias_cmd_obj, CommandReturnObject &result)
896{
897 Args cmd_args (raw_input_string.c_str());
898 alias_cmd_obj = GetCommandObject (alias_name);
899 StreamString result_str;
900
901 if (alias_cmd_obj)
902 {
903 std::string alias_name_str = alias_name;
904 if ((cmd_args.GetArgumentCount() == 0)
905 || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0))
906 cmd_args.Unshift (alias_name);
907
908 result_str.Printf ("%s", alias_cmd_obj->GetCommandName ());
909 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
910
911 if (option_arg_vector_sp.get())
912 {
913 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
914
915 for (int i = 0; i < option_arg_vector->size(); ++i)
916 {
917 OptionArgPair option_pair = (*option_arg_vector)[i];
918 OptionArgValue value_pair = option_pair.second;
919 int value_type = value_pair.first;
920 std::string option = option_pair.first;
921 std::string value = value_pair.second;
922 if (option.compare ("<argument>") == 0)
923 result_str.Printf (" %s", value.c_str());
924 else
925 {
926 result_str.Printf (" %s", option.c_str());
927 if (value_type != optional_argument)
928 result_str.Printf (" ");
929 if (value.compare ("<no_argument>") != 0)
930 {
931 int index = GetOptionArgumentPosition (value.c_str());
932 if (index == 0)
933 result_str.Printf ("%s", value.c_str());
934 else if (index >= cmd_args.GetArgumentCount())
935 {
936
937 result.AppendErrorWithFormat
938 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
939 index);
940 result.SetStatus (eReturnStatusFailed);
941 return;
942 }
943 else
944 {
945 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
946 if (strpos != std::string::npos)
947 raw_input_string = raw_input_string.erase (strpos,
948 strlen (cmd_args.GetArgumentAtIndex (index)));
949 result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index));
950 }
951 }
952 }
953 }
954 }
955
956 alias_result = result_str.GetData();
957 }
958}
959
Greg Claytonf5c0c722011-10-14 07:41:33 +0000960Error
961CommandInterpreter::PreprocessCommand (std::string &command)
962{
963 // The command preprocessor needs to do things to the command
964 // line before any parsing of arguments or anything else is done.
965 // The only current stuff that gets proprocessed is anyting enclosed
966 // in backtick ('`') characters is evaluated as an expression and
967 // the result of the expression must be a scalar that can be substituted
968 // into the command. An example would be:
969 // (lldb) memory read `$rsp + 20`
970 Error error; // Error for any expressions that might not evaluate
971 size_t start_backtick;
972 size_t pos = 0;
973 while ((start_backtick = command.find ('`', pos)) != std::string::npos)
974 {
975 if (start_backtick > 0 && command[start_backtick-1] == '\\')
976 {
977 // The backtick was preceeded by a '\' character, remove the slash
978 // and don't treat the backtick as the start of an expression
979 command.erase(start_backtick-1, 1);
980 // No need to add one to start_backtick since we just deleted a char
981 pos = start_backtick;
982 }
983 else
984 {
985 const size_t expr_content_start = start_backtick + 1;
986 const size_t end_backtick = command.find ('`', expr_content_start);
987 if (end_backtick == std::string::npos)
988 return error;
989 else if (end_backtick == expr_content_start)
990 {
991 // Empty expression (two backticks in a row)
992 command.erase (start_backtick, 2);
993 }
994 else
995 {
996 std::string expr_str (command, expr_content_start, end_backtick - expr_content_start);
997
998 Target *target = m_exe_ctx.GetTargetPtr();
999 if (target)
1000 {
1001 const bool unwind_on_error = true;
1002 const bool keep_in_memory = false;
1003 ValueObjectSP expr_result_valobj_sp;
1004 ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
1005 m_exe_ctx.GetFramePtr(),
1006 eExecutionPolicyOnlyWhenNeeded,
1007 unwind_on_error, keep_in_memory,
1008 eNoDynamicValues,
1009 expr_result_valobj_sp);
1010 if (expr_result == eExecutionCompleted)
1011 {
1012 Scalar scalar;
1013 if (expr_result_valobj_sp->ResolveValue (scalar))
1014 {
1015 command.erase (start_backtick, end_backtick - start_backtick + 1);
1016 StreamString value_strm;
1017 const bool show_type = false;
1018 scalar.GetValue (&value_strm, show_type);
1019 size_t value_string_size = value_strm.GetSize();
1020 if (value_string_size)
1021 {
1022 command.insert (start_backtick, value_strm.GetData(), value_string_size);
1023 pos = start_backtick + value_string_size;
1024 continue;
1025 }
1026 else
1027 {
1028 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
1029 }
1030 }
1031 else
1032 {
1033 error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
1034 }
1035 }
1036 else
1037 {
1038 if (expr_result_valobj_sp)
1039 error = expr_result_valobj_sp->GetError();
1040 if (error.Success())
1041 {
1042
1043 switch (expr_result)
1044 {
1045 case eExecutionSetupError:
1046 error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str());
1047 break;
1048 case eExecutionCompleted:
1049 break;
1050 case eExecutionDiscarded:
1051 error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str());
1052 break;
1053 case eExecutionInterrupted:
1054 error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str());
1055 break;
1056 case eExecutionTimedOut:
1057 error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str());
1058 break;
1059 }
1060 }
1061 }
1062 }
1063 }
1064 if (error.Fail())
1065 break;
1066 }
1067 }
1068 return error;
1069}
1070
1071
Caroline Ticee0da7a52010-12-09 22:52:49 +00001072bool
1073CommandInterpreter::HandleCommand (const char *command_line,
1074 bool add_to_history,
1075 CommandReturnObject &result,
Jim Ingham949d5ac2011-02-18 00:54:25 +00001076 ExecutionContext *override_context,
Johnny Chen8bdf57c2011-10-05 00:42:59 +00001077 bool repeat_on_empty_command,
1078 bool no_context_switching)
Jim Ingham949d5ac2011-02-18 00:54:25 +00001079
Caroline Ticee0da7a52010-12-09 22:52:49 +00001080{
Jim Ingham949d5ac2011-02-18 00:54:25 +00001081
Caroline Ticee0da7a52010-12-09 22:52:49 +00001082 bool done = false;
1083 CommandObject *cmd_obj = NULL;
1084 std::string next_word;
1085 bool wants_raw_input = false;
1086 std::string command_string (command_line);
Jim Ingham6247dbe2011-07-12 03:12:18 +00001087 std::string original_command_string (command_line);
Caroline Ticee0da7a52010-12-09 22:52:49 +00001088
1089 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
Greg Claytone98ac252010-11-10 04:57:04 +00001090 Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line);
1091
1092 // Make a scoped cleanup object that will clear the crash description string
1093 // on exit of this function.
Enrico Granata1a102082011-07-12 00:18:11 +00001094 lldb_utility::CleanUp <const char *> crash_description_cleanup(NULL, Host::SetCrashDescription);
Greg Claytone98ac252010-11-10 04:57:04 +00001095
Caroline Ticee0da7a52010-12-09 22:52:49 +00001096 if (log)
1097 log->Printf ("Processing command: %s", command_line);
Chris Lattner24943d22010-06-08 16:52:24 +00001098
Jim Inghamabab14b2010-11-04 23:08:45 +00001099 Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line);
1100
Johnny Chen8bdf57c2011-10-05 00:42:59 +00001101 if (!no_context_switching)
1102 UpdateExecutionContext (override_context);
Chris Lattner24943d22010-06-08 16:52:24 +00001103
Jim Ingham949d5ac2011-02-18 00:54:25 +00001104 bool empty_command = false;
1105 bool comment_command = false;
1106 if (command_string.empty())
1107 empty_command = true;
1108 else
Chris Lattner24943d22010-06-08 16:52:24 +00001109 {
Jim Ingham949d5ac2011-02-18 00:54:25 +00001110 const char *k_space_characters = "\t\n\v\f\r ";
1111
1112 size_t non_space = command_string.find_first_not_of (k_space_characters);
1113 // Check for empty line or comment line (lines whose first
1114 // non-space character is the comment character for this interpreter)
1115 if (non_space == std::string::npos)
1116 empty_command = true;
1117 else if (command_string[non_space] == m_comment_char)
1118 comment_command = true;
Jim Ingham6247dbe2011-07-12 03:12:18 +00001119 else if (command_string[non_space] == m_repeat_char)
1120 {
1121 const char *history_string = FindHistoryString (command_string.c_str() + non_space);
1122 if (history_string == NULL)
1123 {
1124 result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str());
1125 result.SetStatus(eReturnStatusFailed);
1126 return false;
1127 }
1128 add_to_history = false;
1129 command_string = history_string;
1130 original_command_string = history_string;
1131 }
Jim Ingham949d5ac2011-02-18 00:54:25 +00001132 }
1133
1134 if (empty_command)
1135 {
1136 if (repeat_on_empty_command)
Chris Lattner24943d22010-06-08 16:52:24 +00001137 {
Jim Ingham949d5ac2011-02-18 00:54:25 +00001138 if (m_command_history.empty())
1139 {
1140 result.AppendError ("empty command");
1141 result.SetStatus(eReturnStatusFailed);
1142 return false;
1143 }
1144 else
1145 {
1146 command_line = m_repeat_command.c_str();
1147 command_string = command_line;
Jim Ingham6247dbe2011-07-12 03:12:18 +00001148 original_command_string = command_line;
Jim Ingham949d5ac2011-02-18 00:54:25 +00001149 if (m_repeat_command.empty())
1150 {
1151 result.AppendErrorWithFormat("No auto repeat.\n");
1152 result.SetStatus (eReturnStatusFailed);
1153 return false;
1154 }
1155 }
1156 add_to_history = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001157 }
1158 else
1159 {
Jim Ingham949d5ac2011-02-18 00:54:25 +00001160 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1161 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00001162 }
Jim Ingham949d5ac2011-02-18 00:54:25 +00001163 }
1164 else if (comment_command)
1165 {
1166 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1167 return true;
Chris Lattner24943d22010-06-08 16:52:24 +00001168 }
Caroline Tice649116c2011-05-11 16:07:06 +00001169
Greg Claytonf5c0c722011-10-14 07:41:33 +00001170
1171 Error error (PreprocessCommand (command_string));
1172
1173 if (error.Fail())
1174 {
1175 result.AppendError (error.AsCString());
1176 result.SetStatus(eReturnStatusFailed);
1177 return false;
1178 }
Caroline Ticee0da7a52010-12-09 22:52:49 +00001179 // Phase 1.
1180
1181 // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object
1182 // is for the specified command, and whether or not it wants raw input. This gets complicated by the fact that
1183 // the user could have specified an alias, and in translating the alias there may also be command options and/or
1184 // even data (including raw text strings) that need to be found and inserted into the command line as part of
1185 // the translation. So this first step is plain look-up & replacement, resulting in three things: 1). the command
Greg Clayton5d187e52011-01-08 20:28:42 +00001186 // object whose Execute method will actually be called; 2). a revised command string, with all substitutions &
Caroline Ticee0da7a52010-12-09 22:52:49 +00001187 // replacements taken care of; 3). whether or not the Execute function wants raw input or not.
Caroline Tice44c841d2010-12-07 19:58:26 +00001188
Caroline Ticee0da7a52010-12-09 22:52:49 +00001189 StreamString revised_command_line;
Caroline Ticeea6e3df2010-12-11 08:16:56 +00001190 size_t actual_cmd_name_len = 0;
Caroline Ticee0da7a52010-12-09 22:52:49 +00001191 while (!done)
Chris Lattner24943d22010-06-08 16:52:24 +00001192 {
Caroline Tice649116c2011-05-11 16:07:06 +00001193 bool was_quoted = false;
1194 char quote_char = '\0';
1195 StripFirstWord (command_string, next_word, was_quoted, quote_char);
Caroline Ticee0da7a52010-12-09 22:52:49 +00001196 if (!cmd_obj && AliasExists (next_word.c_str()))
Chris Lattner24943d22010-06-08 16:52:24 +00001197 {
Caroline Ticee0da7a52010-12-09 22:52:49 +00001198 std::string alias_result;
1199 BuildAliasResult (next_word.c_str(), command_string, alias_result, cmd_obj, result);
1200 revised_command_line.Printf ("%s", alias_result.c_str());
1201 if (cmd_obj)
Caroline Tice56d2fc42010-12-14 18:51:39 +00001202 {
Caroline Ticee0da7a52010-12-09 22:52:49 +00001203 wants_raw_input = cmd_obj->WantsRawCommandString ();
Caroline Tice56d2fc42010-12-14 18:51:39 +00001204 actual_cmd_name_len = strlen (cmd_obj->GetCommandName());
1205 }
Caroline Ticee0da7a52010-12-09 22:52:49 +00001206 }
1207 else if (!cmd_obj)
1208 {
1209 cmd_obj = GetCommandObject (next_word.c_str());
1210 if (cmd_obj)
Chris Lattner24943d22010-06-08 16:52:24 +00001211 {
Caroline Ticeea6e3df2010-12-11 08:16:56 +00001212 actual_cmd_name_len += next_word.length();
Caroline Ticee0da7a52010-12-09 22:52:49 +00001213 revised_command_line.Printf ("%s", next_word.c_str());
1214 wants_raw_input = cmd_obj->WantsRawCommandString ();
Chris Lattner24943d22010-06-08 16:52:24 +00001215 }
1216 else
1217 {
Caroline Ticee0da7a52010-12-09 22:52:49 +00001218 revised_command_line.Printf ("%s", next_word.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001219 }
1220 }
Caroline Ticee0da7a52010-12-09 22:52:49 +00001221 else if (cmd_obj->IsMultiwordObject ())
1222 {
1223 CommandObject *sub_cmd_obj = ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (next_word.c_str());
1224 if (sub_cmd_obj)
1225 {
Caroline Ticeea6e3df2010-12-11 08:16:56 +00001226 actual_cmd_name_len += next_word.length() + 1;
Caroline Ticee0da7a52010-12-09 22:52:49 +00001227 revised_command_line.Printf (" %s", next_word.c_str());
1228 cmd_obj = sub_cmd_obj;
1229 wants_raw_input = cmd_obj->WantsRawCommandString ();
1230 }
1231 else
1232 {
Caroline Tice649116c2011-05-11 16:07:06 +00001233 if (was_quoted)
1234 {
1235 if (quote_char == '"')
1236 revised_command_line.Printf (" \"%s\"", next_word.c_str());
1237 else
1238 revised_command_line.Printf (" '%s'", next_word.c_str());
1239 }
1240 else
1241 revised_command_line.Printf (" %s", next_word.c_str());
Caroline Ticee0da7a52010-12-09 22:52:49 +00001242 done = true;
1243 }
1244 }
1245 else
1246 {
Caroline Tice649116c2011-05-11 16:07:06 +00001247 if (was_quoted)
1248 {
1249 if (quote_char == '"')
1250 revised_command_line.Printf (" \"%s\"", next_word.c_str());
1251 else
1252 revised_command_line.Printf (" '%s'", next_word.c_str());
1253 }
1254 else
1255 revised_command_line.Printf (" %s", next_word.c_str());
Caroline Ticee0da7a52010-12-09 22:52:49 +00001256 done = true;
1257 }
1258
1259 if (cmd_obj == NULL)
1260 {
1261 result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str());
1262 result.SetStatus (eReturnStatusFailed);
1263 return false;
1264 }
1265
1266 next_word.erase ();
1267 if (command_string.length() == 0)
1268 done = true;
1269
Chris Lattner24943d22010-06-08 16:52:24 +00001270 }
Caroline Ticee0da7a52010-12-09 22:52:49 +00001271
1272 if (command_string.size() > 0)
1273 revised_command_line.Printf (" %s", command_string.c_str());
1274
1275 // End of Phase 1.
1276 // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command
1277 // specified was valid; revised_command_line contains the complete command line (including command name(s)),
1278 // fully translated with all substitutions & translations taken care of (still in raw text format); and
1279 // wants_raw_input specifies whether the Execute method expects raw input or not.
1280
1281
1282 if (log)
1283 {
1284 log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>");
1285 log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData());
1286 log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False");
1287 }
1288
1289 // Phase 2.
1290 // Take care of things like setting up the history command & calling the appropriate Execute method on the
1291 // CommandObject, with the appropriate arguments.
1292
1293 if (cmd_obj != NULL)
1294 {
1295 if (add_to_history)
1296 {
1297 Args command_args (revised_command_line.GetData());
1298 const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0);
1299 if (repeat_command != NULL)
1300 m_repeat_command.assign(repeat_command);
1301 else
Jim Ingham6247dbe2011-07-12 03:12:18 +00001302 m_repeat_command.assign(original_command_string.c_str());
Caroline Ticee0da7a52010-12-09 22:52:49 +00001303
Jim Ingham6247dbe2011-07-12 03:12:18 +00001304 // Don't keep pushing the same command onto the history...
1305 if (m_command_history.size() == 0 || m_command_history.back() != original_command_string)
1306 m_command_history.push_back (original_command_string);
Caroline Ticee0da7a52010-12-09 22:52:49 +00001307 }
1308
1309 command_string = revised_command_line.GetData();
1310 std::string command_name (cmd_obj->GetCommandName());
Caroline Ticeea6e3df2010-12-11 08:16:56 +00001311 std::string remainder;
1312 if (actual_cmd_name_len < command_string.length())
1313 remainder = command_string.substr (actual_cmd_name_len); // Note: 'actual_cmd_name_len' may be considerably shorter
1314 // than cmd_obj->GetCommandName(), because name completion
1315 // allows users to enter short versions of the names,
1316 // e.g. 'br s' for 'breakpoint set'.
Caroline Ticee0da7a52010-12-09 22:52:49 +00001317
1318 // Remove any initial spaces
1319 std::string white_space (" \t\v");
1320 size_t pos = remainder.find_first_not_of (white_space);
1321 if (pos != 0 && pos != std::string::npos)
Greg Clayton91c9dcf2011-04-22 20:58:45 +00001322 remainder.erase(0, pos);
Caroline Ticee0da7a52010-12-09 22:52:49 +00001323
1324 if (log)
Jason Molenda24c991c2011-08-25 00:20:04 +00001325 log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str());
Caroline Ticee0da7a52010-12-09 22:52:49 +00001326
1327
1328 if (wants_raw_input)
1329 cmd_obj->ExecuteRawCommandString (remainder.c_str(), result);
1330 else
1331 {
1332 Args cmd_args (remainder.c_str());
1333 cmd_obj->ExecuteWithOptions (cmd_args, result);
1334 }
1335 }
1336 else
1337 {
1338 // We didn't find the first command object, so complete the first argument.
1339 Args command_args (revised_command_line.GetData());
1340 StringList matches;
1341 int num_matches;
1342 int cursor_index = 0;
1343 int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0));
1344 bool word_complete;
1345 num_matches = HandleCompletionMatches (command_args,
1346 cursor_index,
1347 cursor_char_position,
1348 0,
1349 -1,
1350 word_complete,
1351 matches);
1352
1353 if (num_matches > 0)
1354 {
1355 std::string error_msg;
1356 error_msg.assign ("ambiguous command '");
1357 error_msg.append(command_args.GetArgumentAtIndex(0));
1358 error_msg.append ("'.");
1359
1360 error_msg.append (" Possible completions:");
1361 for (int i = 0; i < num_matches; i++)
1362 {
1363 error_msg.append ("\n\t");
1364 error_msg.append (matches.GetStringAtIndex (i));
1365 }
1366 error_msg.append ("\n");
1367 result.AppendRawError (error_msg.c_str(), error_msg.size());
1368 }
1369 else
1370 result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0));
1371
1372 result.SetStatus (eReturnStatusFailed);
1373 }
1374
Jason Molenda24c991c2011-08-25 00:20:04 +00001375 if (log)
1376 log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed"));
1377
Chris Lattner24943d22010-06-08 16:52:24 +00001378 return result.Succeeded();
1379}
1380
1381int
1382CommandInterpreter::HandleCompletionMatches (Args &parsed_line,
1383 int &cursor_index,
1384 int &cursor_char_position,
1385 int match_start_point,
1386 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +00001387 bool &word_complete,
Chris Lattner24943d22010-06-08 16:52:24 +00001388 StringList &matches)
1389{
1390 int num_command_matches = 0;
Chris Lattner24943d22010-06-08 16:52:24 +00001391 bool look_for_subcommand = false;
Jim Ingham802f8b02010-06-30 05:02:46 +00001392
1393 // For any of the command completions a unique match will be a complete word.
1394 word_complete = true;
Chris Lattner24943d22010-06-08 16:52:24 +00001395
1396 if (cursor_index == -1)
1397 {
1398 // We got nothing on the command line, so return the list of commands
Jim Inghamd40f8a62010-07-06 22:46:59 +00001399 bool include_aliases = true;
Chris Lattner24943d22010-06-08 16:52:24 +00001400 num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches);
1401 }
1402 else if (cursor_index == 0)
1403 {
1404 // The cursor is in the first argument, so just do a lookup in the dictionary.
Jim Inghamd40f8a62010-07-06 22:46:59 +00001405 CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches);
Chris Lattner24943d22010-06-08 16:52:24 +00001406 num_command_matches = matches.GetSize();
1407
1408 if (num_command_matches == 1
1409 && cmd_obj && cmd_obj->IsMultiwordObject()
1410 && matches.GetStringAtIndex(0) != NULL
1411 && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0)
1412 {
1413 look_for_subcommand = true;
1414 num_command_matches = 0;
1415 matches.DeleteStringAtIndex(0);
1416 parsed_line.AppendArgument ("");
1417 cursor_index++;
1418 cursor_char_position = 0;
1419 }
1420 }
1421
1422 if (cursor_index > 0 || look_for_subcommand)
1423 {
1424 // We are completing further on into a commands arguments, so find the command and tell it
1425 // to complete the command.
1426 // First see if there is a matching initial command:
Jim Inghamd40f8a62010-07-06 22:46:59 +00001427 CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +00001428 if (command_object == NULL)
1429 {
1430 return 0;
1431 }
1432 else
1433 {
1434 parsed_line.Shift();
1435 cursor_index--;
Greg Clayton238c0a12010-09-18 01:14:36 +00001436 num_command_matches = command_object->HandleCompletion (parsed_line,
Greg Clayton63094e02010-06-23 01:19:29 +00001437 cursor_index,
1438 cursor_char_position,
1439 match_start_point,
Jim Ingham802f8b02010-06-30 05:02:46 +00001440 max_return_elements,
1441 word_complete,
Chris Lattner24943d22010-06-08 16:52:24 +00001442 matches);
1443 }
1444 }
1445
1446 return num_command_matches;
1447
1448}
1449
1450int
1451CommandInterpreter::HandleCompletion (const char *current_line,
1452 const char *cursor,
1453 const char *last_char,
1454 int match_start_point,
1455 int max_return_elements,
1456 StringList &matches)
1457{
1458 // We parse the argument up to the cursor, so the last argument in parsed_line is
1459 // the one containing the cursor, and the cursor is after the last character.
1460
1461 Args parsed_line(current_line, last_char - current_line);
1462 Args partial_parsed_line(current_line, cursor - current_line);
1463
Jim Ingham6247dbe2011-07-12 03:12:18 +00001464 // Don't complete comments, and if the line we are completing is just the history repeat character,
1465 // substitute the appropriate history line.
1466 const char *first_arg = parsed_line.GetArgumentAtIndex(0);
1467 if (first_arg)
1468 {
1469 if (first_arg[0] == m_comment_char)
1470 return 0;
1471 else if (first_arg[0] == m_repeat_char)
1472 {
1473 const char *history_string = FindHistoryString (first_arg);
1474 if (history_string != NULL)
1475 {
1476 matches.Clear();
1477 matches.InsertStringAtIndex(0, history_string);
1478 return -2;
1479 }
1480 else
1481 return 0;
1482
1483 }
1484 }
1485
1486
Chris Lattner24943d22010-06-08 16:52:24 +00001487 int num_args = partial_parsed_line.GetArgumentCount();
1488 int cursor_index = partial_parsed_line.GetArgumentCount() - 1;
1489 int cursor_char_position;
1490
1491 if (cursor_index == -1)
1492 cursor_char_position = 0;
1493 else
1494 cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index));
Jim Inghamcf037652010-12-14 19:56:01 +00001495
1496 if (cursor > current_line && cursor[-1] == ' ')
1497 {
1498 // We are just after a space. If we are in an argument, then we will continue
1499 // parsing, but if we are between arguments, then we have to complete whatever the next
1500 // element would be.
1501 // We can distinguish the two cases because if we are in an argument (e.g. because the space is
1502 // protected by a quote) then the space will also be in the parsed argument...
1503
1504 const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index);
1505 if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ')
1506 {
1507 parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '"');
1508 cursor_index++;
1509 cursor_char_position = 0;
1510 }
1511 }
Chris Lattner24943d22010-06-08 16:52:24 +00001512
1513 int num_command_matches;
1514
1515 matches.Clear();
1516
1517 // Only max_return_elements == -1 is supported at present:
1518 assert (max_return_elements == -1);
Jim Ingham802f8b02010-06-30 05:02:46 +00001519 bool word_complete;
Greg Clayton63094e02010-06-23 01:19:29 +00001520 num_command_matches = HandleCompletionMatches (parsed_line,
1521 cursor_index,
1522 cursor_char_position,
1523 match_start_point,
Jim Ingham802f8b02010-06-30 05:02:46 +00001524 max_return_elements,
1525 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +00001526 matches);
Chris Lattner24943d22010-06-08 16:52:24 +00001527
1528 if (num_command_matches <= 0)
1529 return num_command_matches;
1530
1531 if (num_args == 0)
1532 {
1533 // If we got an empty string, insert nothing.
1534 matches.InsertStringAtIndex(0, "");
1535 }
1536 else
1537 {
1538 // Now figure out if there is a common substring, and if so put that in element 0, otherwise
1539 // put an empty string in element 0.
1540 std::string command_partial_str;
1541 if (cursor_index >= 0)
Jim Inghame3663e82010-10-22 18:47:16 +00001542 command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index),
1543 parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position);
Chris Lattner24943d22010-06-08 16:52:24 +00001544
1545 std::string common_prefix;
1546 matches.LongestCommonPrefix (common_prefix);
1547 int partial_name_len = command_partial_str.size();
1548
1549 // If we matched a unique single command, add a space...
Jim Ingham802f8b02010-06-30 05:02:46 +00001550 // Only do this if the completer told us this was a complete word, however...
1551 if (num_command_matches == 1 && word_complete)
Chris Lattner24943d22010-06-08 16:52:24 +00001552 {
1553 char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index);
1554 if (quote_char != '\0')
1555 common_prefix.push_back(quote_char);
1556
1557 common_prefix.push_back(' ');
1558 }
1559 common_prefix.erase (0, partial_name_len);
1560 matches.InsertStringAtIndex(0, common_prefix.c_str());
1561 }
1562 return num_command_matches;
1563}
1564
Chris Lattner24943d22010-06-08 16:52:24 +00001565
1566CommandInterpreter::~CommandInterpreter ()
1567{
1568}
1569
1570const char *
1571CommandInterpreter::GetPrompt ()
1572{
Caroline Tice5bc8c972010-09-20 20:44:43 +00001573 return m_debugger.GetPrompt();
Chris Lattner24943d22010-06-08 16:52:24 +00001574}
1575
1576void
1577CommandInterpreter::SetPrompt (const char *new_prompt)
1578{
Caroline Tice5bc8c972010-09-20 20:44:43 +00001579 m_debugger.SetPrompt (new_prompt);
Chris Lattner24943d22010-06-08 16:52:24 +00001580}
1581
Jim Ingham5e16ef52010-10-04 19:49:29 +00001582size_t
Greg Clayton58928562011-02-09 01:08:52 +00001583CommandInterpreter::GetConfirmationInputReaderCallback
1584(
1585 void *baton,
1586 InputReader &reader,
1587 lldb::InputReaderAction action,
1588 const char *bytes,
1589 size_t bytes_len
1590)
Jim Ingham5e16ef52010-10-04 19:49:29 +00001591{
Greg Clayton58928562011-02-09 01:08:52 +00001592 File &out_file = reader.GetDebugger().GetOutputFile();
Jim Ingham5e16ef52010-10-04 19:49:29 +00001593 bool *response_ptr = (bool *) baton;
1594
1595 switch (action)
1596 {
1597 case eInputReaderActivate:
Greg Clayton58928562011-02-09 01:08:52 +00001598 if (out_file.IsValid())
Jim Ingham5e16ef52010-10-04 19:49:29 +00001599 {
1600 if (reader.GetPrompt())
Caroline Tice22a60092011-02-02 01:17:56 +00001601 {
Greg Clayton58928562011-02-09 01:08:52 +00001602 out_file.Printf ("%s", reader.GetPrompt());
1603 out_file.Flush ();
Caroline Tice22a60092011-02-02 01:17:56 +00001604 }
Jim Ingham5e16ef52010-10-04 19:49:29 +00001605 }
1606 break;
1607
1608 case eInputReaderDeactivate:
1609 break;
1610
1611 case eInputReaderReactivate:
Greg Clayton58928562011-02-09 01:08:52 +00001612 if (out_file.IsValid() && reader.GetPrompt())
Caroline Tice22a60092011-02-02 01:17:56 +00001613 {
Greg Clayton58928562011-02-09 01:08:52 +00001614 out_file.Printf ("%s", reader.GetPrompt());
1615 out_file.Flush ();
Caroline Tice22a60092011-02-02 01:17:56 +00001616 }
Jim Ingham5e16ef52010-10-04 19:49:29 +00001617 break;
Caroline Tice4a348082011-05-02 20:41:46 +00001618
1619 case eInputReaderAsynchronousOutputWritten:
1620 break;
1621
Jim Ingham5e16ef52010-10-04 19:49:29 +00001622 case eInputReaderGotToken:
1623 if (bytes_len == 0)
1624 {
1625 reader.SetIsDone(true);
1626 }
1627 else if (bytes[0] == 'y')
1628 {
1629 *response_ptr = true;
1630 reader.SetIsDone(true);
1631 }
1632 else if (bytes[0] == 'n')
1633 {
1634 *response_ptr = false;
1635 reader.SetIsDone(true);
1636 }
1637 else
1638 {
Greg Clayton58928562011-02-09 01:08:52 +00001639 if (out_file.IsValid() && !reader.IsDone() && reader.GetPrompt())
Jim Ingham5e16ef52010-10-04 19:49:29 +00001640 {
Greg Clayton58928562011-02-09 01:08:52 +00001641 out_file.Printf ("Please answer \"y\" or \"n\"\n%s", reader.GetPrompt());
1642 out_file.Flush ();
Jim Ingham5e16ef52010-10-04 19:49:29 +00001643 }
1644 }
1645 break;
1646
Caroline Ticec4f55fe2010-11-19 20:47:54 +00001647 case eInputReaderInterrupt:
1648 case eInputReaderEndOfFile:
1649 *response_ptr = false; // Assume ^C or ^D means cancel the proposed action
1650 reader.SetIsDone (true);
1651 break;
1652
Jim Ingham5e16ef52010-10-04 19:49:29 +00001653 case eInputReaderDone:
1654 break;
1655 }
1656
1657 return bytes_len;
1658
1659}
1660
1661bool
1662CommandInterpreter::Confirm (const char *message, bool default_answer)
1663{
Jim Ingham93057472010-10-04 22:44:14 +00001664 // Check AutoConfirm first:
1665 if (m_debugger.GetAutoConfirm())
1666 return default_answer;
1667
Jim Ingham5e16ef52010-10-04 19:49:29 +00001668 InputReaderSP reader_sp (new InputReader(GetDebugger()));
1669 bool response = default_answer;
1670 if (reader_sp)
1671 {
1672 std::string prompt(message);
1673 prompt.append(": [");
1674 if (default_answer)
1675 prompt.append ("Y/n] ");
1676 else
1677 prompt.append ("y/N] ");
1678
1679 Error err (reader_sp->Initialize (CommandInterpreter::GetConfirmationInputReaderCallback,
1680 &response, // baton
1681 eInputReaderGranularityLine, // token size, to pass to callback function
1682 NULL, // end token
1683 prompt.c_str(), // prompt
1684 true)); // echo input
1685 if (err.Success())
1686 {
1687 GetDebugger().PushInputReader (reader_sp);
1688 }
1689 reader_sp->WaitOnReaderIsDone();
1690 }
1691 return response;
1692}
1693
1694
Chris Lattner24943d22010-06-08 16:52:24 +00001695void
1696CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type)
1697{
Jim Inghamd40f8a62010-07-06 22:46:59 +00001698 CommandObjectSP cmd_obj_sp = GetCommandSPExact (dest_cmd, true);
Chris Lattner24943d22010-06-08 16:52:24 +00001699
1700 if (cmd_obj_sp != NULL)
1701 {
1702 CommandObject *cmd_obj = cmd_obj_sp.get();
1703 if (cmd_obj->IsCrossRefObject ())
1704 cmd_obj->AddObject (object_type);
1705 }
1706}
1707
Chris Lattner24943d22010-06-08 16:52:24 +00001708OptionArgVectorSP
1709CommandInterpreter::GetAliasOptions (const char *alias_name)
1710{
1711 OptionArgMap::iterator pos;
1712 OptionArgVectorSP ret_val;
1713
1714 std::string alias (alias_name);
1715
1716 if (HasAliasOptions())
1717 {
1718 pos = m_alias_options.find (alias);
1719 if (pos != m_alias_options.end())
1720 ret_val = pos->second;
1721 }
1722
1723 return ret_val;
1724}
1725
1726void
1727CommandInterpreter::RemoveAliasOptions (const char *alias_name)
1728{
1729 OptionArgMap::iterator pos = m_alias_options.find(alias_name);
1730 if (pos != m_alias_options.end())
1731 {
1732 m_alias_options.erase (pos);
1733 }
1734}
1735
1736void
1737CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp)
1738{
1739 m_alias_options[alias_name] = option_arg_vector_sp;
1740}
1741
1742bool
1743CommandInterpreter::HasCommands ()
1744{
1745 return (!m_command_dict.empty());
1746}
1747
1748bool
1749CommandInterpreter::HasAliases ()
1750{
1751 return (!m_alias_dict.empty());
1752}
1753
1754bool
1755CommandInterpreter::HasUserCommands ()
1756{
1757 return (!m_user_dict.empty());
1758}
1759
1760bool
1761CommandInterpreter::HasAliasOptions ()
1762{
1763 return (!m_alias_options.empty());
1764}
1765
Chris Lattner24943d22010-06-08 16:52:24 +00001766void
Caroline Ticebd5c63e2010-10-12 21:57:09 +00001767CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
1768 const char *alias_name,
1769 Args &cmd_args,
Caroline Tice44c841d2010-12-07 19:58:26 +00001770 std::string &raw_input_string,
Caroline Ticebd5c63e2010-10-12 21:57:09 +00001771 CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001772{
1773 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
Caroline Tice44c841d2010-12-07 19:58:26 +00001774
1775 bool wants_raw_input = alias_cmd_obj->WantsRawCommandString();
Chris Lattner24943d22010-06-08 16:52:24 +00001776
Caroline Tice44c841d2010-12-07 19:58:26 +00001777 // Make sure that the alias name is the 0th element in cmd_args
1778 std::string alias_name_str = alias_name;
1779 if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)
1780 cmd_args.Unshift (alias_name);
1781
1782 Args new_args (alias_cmd_obj->GetCommandName());
1783 if (new_args.GetArgumentCount() == 2)
1784 new_args.Shift();
1785
Chris Lattner24943d22010-06-08 16:52:24 +00001786 if (option_arg_vector_sp.get())
1787 {
Caroline Tice44c841d2010-12-07 19:58:26 +00001788 if (wants_raw_input)
1789 {
1790 // We have a command that both has command options and takes raw input. Make *sure* it has a
1791 // " -- " in the right place in the raw_input_string.
1792 size_t pos = raw_input_string.find(" -- ");
1793 if (pos == std::string::npos)
1794 {
1795 // None found; assume it goes at the beginning of the raw input string
1796 raw_input_string.insert (0, " -- ");
1797 }
1798 }
Chris Lattner24943d22010-06-08 16:52:24 +00001799
1800 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
1801 int old_size = cmd_args.GetArgumentCount();
Caroline Ticebd5c63e2010-10-12 21:57:09 +00001802 std::vector<bool> used (old_size + 1, false);
1803
1804 used[0] = true;
Chris Lattner24943d22010-06-08 16:52:24 +00001805
1806 for (int i = 0; i < option_arg_vector->size(); ++i)
1807 {
1808 OptionArgPair option_pair = (*option_arg_vector)[i];
Caroline Tice44c841d2010-12-07 19:58:26 +00001809 OptionArgValue value_pair = option_pair.second;
1810 int value_type = value_pair.first;
Chris Lattner24943d22010-06-08 16:52:24 +00001811 std::string option = option_pair.first;
Caroline Tice44c841d2010-12-07 19:58:26 +00001812 std::string value = value_pair.second;
Chris Lattner24943d22010-06-08 16:52:24 +00001813 if (option.compare ("<argument>") == 0)
Caroline Tice44c841d2010-12-07 19:58:26 +00001814 {
1815 if (!wants_raw_input
1816 || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice
1817 new_args.AppendArgument (value.c_str());
1818 }
Chris Lattner24943d22010-06-08 16:52:24 +00001819 else
1820 {
Caroline Tice44c841d2010-12-07 19:58:26 +00001821 if (value_type != optional_argument)
1822 new_args.AppendArgument (option.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001823 if (value.compare ("<no-argument>") != 0)
1824 {
1825 int index = GetOptionArgumentPosition (value.c_str());
1826 if (index == 0)
Caroline Tice44c841d2010-12-07 19:58:26 +00001827 {
Chris Lattner24943d22010-06-08 16:52:24 +00001828 // value was NOT a positional argument; must be a real value
Caroline Tice44c841d2010-12-07 19:58:26 +00001829 if (value_type != optional_argument)
1830 new_args.AppendArgument (value.c_str());
1831 else
1832 {
1833 char buffer[255];
1834 ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str());
1835 new_args.AppendArgument (buffer);
1836 }
1837
1838 }
Chris Lattner24943d22010-06-08 16:52:24 +00001839 else if (index >= cmd_args.GetArgumentCount())
1840 {
1841 result.AppendErrorWithFormat
1842 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
1843 index);
1844 result.SetStatus (eReturnStatusFailed);
1845 return;
1846 }
1847 else
1848 {
Caroline Tice44c841d2010-12-07 19:58:26 +00001849 // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string
1850 size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
1851 if (strpos != std::string::npos)
1852 {
1853 raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index)));
1854 }
1855
1856 if (value_type != optional_argument)
1857 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index));
1858 else
1859 {
1860 char buffer[255];
1861 ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(),
1862 cmd_args.GetArgumentAtIndex (index));
1863 new_args.AppendArgument (buffer);
1864 }
Caroline Ticebd5c63e2010-10-12 21:57:09 +00001865 used[index] = true;
Chris Lattner24943d22010-06-08 16:52:24 +00001866 }
1867 }
1868 }
1869 }
1870
1871 for (int j = 0; j < cmd_args.GetArgumentCount(); ++j)
1872 {
Caroline Tice44c841d2010-12-07 19:58:26 +00001873 if (!used[j] && !wants_raw_input)
Chris Lattner24943d22010-06-08 16:52:24 +00001874 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j));
1875 }
1876
1877 cmd_args.Clear();
1878 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
1879 }
1880 else
1881 {
1882 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Caroline Tice44c841d2010-12-07 19:58:26 +00001883 // This alias was not created with any options; nothing further needs to be done, unless it is a command that
1884 // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw
1885 // input string.
1886 if (wants_raw_input)
1887 {
1888 cmd_args.Clear();
1889 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
1890 }
Chris Lattner24943d22010-06-08 16:52:24 +00001891 return;
1892 }
1893
1894 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1895 return;
1896}
1897
1898
1899int
1900CommandInterpreter::GetOptionArgumentPosition (const char *in_string)
1901{
1902 int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position
1903 // of zero.
1904
1905 char *cptr = (char *) in_string;
1906
1907 // Does it start with '%'
1908 if (cptr[0] == '%')
1909 {
1910 ++cptr;
1911
1912 // Is the rest of it entirely digits?
1913 if (isdigit (cptr[0]))
1914 {
1915 const char *start = cptr;
1916 while (isdigit (cptr[0]))
1917 ++cptr;
1918
1919 // We've gotten to the end of the digits; are we at the end of the string?
1920 if (cptr[0] == '\0')
1921 position = atoi (start);
1922 }
1923 }
1924
1925 return position;
1926}
1927
1928void
1929CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
1930{
Jim Ingham574c3d62011-08-12 23:34:31 +00001931 FileSpec init_file;
Greg Claytond6edcb52011-09-11 00:01:44 +00001932 if (in_cwd)
Jim Ingham574c3d62011-08-12 23:34:31 +00001933 {
Greg Claytond6edcb52011-09-11 00:01:44 +00001934 // In the current working directory we don't load any program specific
1935 // .lldbinit files, we only look for a "./.lldbinit" file.
1936 if (m_skip_lldbinit_files)
1937 return;
1938
1939 init_file.SetFile ("./.lldbinit", true);
Jim Ingham574c3d62011-08-12 23:34:31 +00001940 }
Greg Claytond6edcb52011-09-11 00:01:44 +00001941 else
Jim Ingham574c3d62011-08-12 23:34:31 +00001942 {
Greg Claytond6edcb52011-09-11 00:01:44 +00001943 // If we aren't looking in the current working directory we are looking
1944 // in the home directory. We will first see if there is an application
1945 // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a
1946 // "-" and the name of the program. If this file doesn't exist, we fall
1947 // back to just the "~/.lldbinit" file. We also obey any requests to not
1948 // load the init files.
1949 const char *init_file_path = "~/.lldbinit";
1950
1951 if (m_skip_app_init_files == false)
1952 {
1953 FileSpec program_file_spec (Host::GetProgramFileSpec());
1954 const char *program_name = program_file_spec.GetFilename().AsCString();
Jim Ingham574c3d62011-08-12 23:34:31 +00001955
Greg Claytond6edcb52011-09-11 00:01:44 +00001956 if (program_name)
1957 {
1958 char program_init_file_name[PATH_MAX];
1959 ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path, program_name);
1960 init_file.SetFile (program_init_file_name, true);
1961 if (!init_file.Exists())
1962 init_file.Clear();
1963 }
1964 }
1965
1966 if (!init_file && !m_skip_lldbinit_files)
1967 init_file.SetFile (init_file_path, true);
1968 }
1969
Chris Lattner24943d22010-06-08 16:52:24 +00001970 // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting
1971 // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details).
1972
1973 if (init_file.Exists())
1974 {
Jim Ingham949d5ac2011-02-18 00:54:25 +00001975 ExecutionContext *exe_ctx = NULL; // We don't have any context yet.
1976 bool stop_on_continue = true;
1977 bool stop_on_error = false;
1978 bool echo_commands = false;
1979 bool print_results = false;
1980
1981 HandleCommandsFromFile (init_file, exe_ctx, stop_on_continue, stop_on_error, echo_commands, print_results, result);
Chris Lattner24943d22010-06-08 16:52:24 +00001982 }
1983 else
1984 {
1985 // nothing to be done if the file doesn't exist
1986 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1987 }
1988}
1989
Greg Claytonb72d0f02011-04-12 05:54:46 +00001990PlatformSP
1991CommandInterpreter::GetPlatform (bool prefer_target_platform)
1992{
1993 PlatformSP platform_sp;
Greg Clayton567e7f32011-09-22 04:58:26 +00001994 if (prefer_target_platform)
1995 {
1996 Target *target = m_exe_ctx.GetTargetPtr();
1997 if (target)
1998 platform_sp = target->GetPlatform();
1999 }
Greg Claytonb72d0f02011-04-12 05:54:46 +00002000
2001 if (!platform_sp)
2002 platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform();
2003 return platform_sp;
2004}
2005
Jim Ingham949d5ac2011-02-18 00:54:25 +00002006void
Jim Inghama4fede32011-03-11 01:51:49 +00002007CommandInterpreter::HandleCommands (const StringList &commands,
Jim Ingham949d5ac2011-02-18 00:54:25 +00002008 ExecutionContext *override_context,
2009 bool stop_on_continue,
2010 bool stop_on_error,
2011 bool echo_commands,
2012 bool print_results,
2013 CommandReturnObject &result)
2014{
2015 size_t num_lines = commands.GetSize();
Jim Ingham949d5ac2011-02-18 00:54:25 +00002016
2017 // If we are going to continue past a "continue" then we need to run the commands synchronously.
2018 // Make sure you reset this value anywhere you return from the function.
2019
2020 bool old_async_execution = m_debugger.GetAsyncExecution();
2021
2022 // If we've been given an execution context, set it at the start, but don't keep resetting it or we will
2023 // cause series of commands that change the context, then do an operation that relies on that context to fail.
2024
2025 if (override_context != NULL)
Greg Claytonb72d0f02011-04-12 05:54:46 +00002026 UpdateExecutionContext (override_context);
Jim Ingham949d5ac2011-02-18 00:54:25 +00002027
2028 if (!stop_on_continue)
2029 {
2030 m_debugger.SetAsyncExecution (false);
2031 }
2032
2033 for (int idx = 0; idx < num_lines; idx++)
2034 {
2035 const char *cmd = commands.GetStringAtIndex(idx);
2036 if (cmd[0] == '\0')
2037 continue;
2038
Jim Ingham949d5ac2011-02-18 00:54:25 +00002039 if (echo_commands)
2040 {
2041 result.AppendMessageWithFormat ("%s %s\n",
2042 GetPrompt(),
2043 cmd);
2044 }
2045
Greg Claytonaa378b12011-02-20 02:15:07 +00002046 CommandReturnObject tmp_result;
Johnny Chen8bdf57c2011-10-05 00:42:59 +00002047 // If override_context is not NULL, pass no_context_switching = true for
2048 // HandleCommand() since we updated our context already.
2049 bool success = HandleCommand(cmd, false, tmp_result,
2050 NULL, /* override_context */
2051 true, /* repeat_on_empty_command */
2052 override_context != NULL /* no_context_switching */);
Jim Ingham949d5ac2011-02-18 00:54:25 +00002053
2054 if (print_results)
2055 {
2056 if (tmp_result.Succeeded())
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00002057 result.AppendMessageWithFormat("%s", tmp_result.GetOutputData());
Jim Ingham949d5ac2011-02-18 00:54:25 +00002058 }
2059
2060 if (!success || !tmp_result.Succeeded())
2061 {
2062 if (stop_on_error)
2063 {
2064 result.AppendErrorWithFormat("Aborting reading of commands after command #%d: '%s' failed.\n",
2065 idx, cmd);
2066 result.SetStatus (eReturnStatusFailed);
2067 m_debugger.SetAsyncExecution (old_async_execution);
2068 return;
2069 }
2070 else if (print_results)
2071 {
2072 result.AppendMessageWithFormat ("Command #%d '%s' failed with error: %s.\n",
2073 idx + 1,
2074 cmd,
Jim Ingham2e8cb8a2011-02-19 02:53:09 +00002075 tmp_result.GetErrorData());
Jim Ingham949d5ac2011-02-18 00:54:25 +00002076 }
2077 }
2078
Caroline Tice4a348082011-05-02 20:41:46 +00002079 if (result.GetImmediateOutputStream())
2080 result.GetImmediateOutputStream()->Flush();
2081
2082 if (result.GetImmediateErrorStream())
2083 result.GetImmediateErrorStream()->Flush();
2084
Jim Ingham949d5ac2011-02-18 00:54:25 +00002085 // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution
2086 // could be running (for instance in Breakpoint Commands.
2087 // So we check the return value to see if it is has running in it.
2088 if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
2089 || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult))
2090 {
2091 if (stop_on_continue)
2092 {
2093 // If we caused the target to proceed, and we're going to stop in that case, set the
2094 // status in our real result before returning. This is an error if the continue was not the
2095 // last command in the set of commands to be run.
2096 if (idx != num_lines - 1)
2097 result.AppendErrorWithFormat("Aborting reading of commands after command #%d: '%s' continued the target.\n",
2098 idx + 1, cmd);
2099 else
2100 result.AppendMessageWithFormat ("Command #%d '%s' continued the target.\n", idx + 1, cmd);
2101
2102 result.SetStatus(tmp_result.GetStatus());
2103 m_debugger.SetAsyncExecution (old_async_execution);
2104
2105 return;
2106 }
2107 }
2108
2109 }
2110
2111 result.SetStatus (eReturnStatusSuccessFinishResult);
2112 m_debugger.SetAsyncExecution (old_async_execution);
2113
2114 return;
2115}
2116
2117void
2118CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
2119 ExecutionContext *context,
2120 bool stop_on_continue,
2121 bool stop_on_error,
2122 bool echo_command,
2123 bool print_result,
2124 CommandReturnObject &result)
2125{
2126 if (cmd_file.Exists())
2127 {
2128 bool success;
2129 StringList commands;
2130 success = commands.ReadFileLines(cmd_file);
2131 if (!success)
2132 {
2133 result.AppendErrorWithFormat ("Error reading commands from file: %s.\n", cmd_file.GetFilename().AsCString());
2134 result.SetStatus (eReturnStatusFailed);
2135 return;
2136 }
2137 HandleCommands (commands, context, stop_on_continue, stop_on_error, echo_command, print_result, result);
2138 }
2139 else
2140 {
2141 result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n",
2142 cmd_file.GetFilename().AsCString());
2143 result.SetStatus (eReturnStatusFailed);
2144 return;
2145 }
2146}
2147
Chris Lattner24943d22010-06-08 16:52:24 +00002148ScriptInterpreter *
2149CommandInterpreter::GetScriptInterpreter ()
2150{
Caroline Tice0aa2e552011-01-14 00:29:16 +00002151 if (m_script_interpreter_ap.get() != NULL)
2152 return m_script_interpreter_ap.get();
Greg Clayton63094e02010-06-23 01:19:29 +00002153
Caroline Tice0aa2e552011-01-14 00:29:16 +00002154 lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage();
2155 switch (script_lang)
Chris Lattner24943d22010-06-08 16:52:24 +00002156 {
Caroline Tice0aa2e552011-01-14 00:29:16 +00002157 case eScriptLanguageNone:
2158 m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this));
2159 break;
2160 case eScriptLanguagePython:
2161 m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this));
2162 break;
2163 default:
2164 break;
2165 };
2166
2167 return m_script_interpreter_ap.get();
Chris Lattner24943d22010-06-08 16:52:24 +00002168}
2169
2170
2171
2172bool
2173CommandInterpreter::GetSynchronous ()
2174{
2175 return m_synchronous_execution;
2176}
2177
2178void
2179CommandInterpreter::SetSynchronous (bool value)
2180{
Johnny Chend7a4eb02010-10-14 01:22:03 +00002181 m_synchronous_execution = value;
Chris Lattner24943d22010-06-08 16:52:24 +00002182}
2183
2184void
2185CommandInterpreter::OutputFormattedHelpText (Stream &strm,
2186 const char *word_text,
2187 const char *separator,
2188 const char *help_text,
2189 uint32_t max_word_len)
2190{
Greg Clayton238c0a12010-09-18 01:14:36 +00002191 const uint32_t max_columns = m_debugger.GetTerminalWidth();
2192
Chris Lattner24943d22010-06-08 16:52:24 +00002193 int indent_size = max_word_len + strlen (separator) + 2;
2194
2195 strm.IndentMore (indent_size);
Greg Claytond284b662011-02-18 01:44:25 +00002196
2197 StreamString text_strm;
2198 text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text);
2199
2200 size_t len = text_strm.GetSize();
2201 const char *text = text_strm.GetData();
Chris Lattner24943d22010-06-08 16:52:24 +00002202 if (text[len - 1] == '\n')
Greg Claytond284b662011-02-18 01:44:25 +00002203 {
2204 text_strm.EOL();
2205 len = text_strm.GetSize();
2206 }
Chris Lattner24943d22010-06-08 16:52:24 +00002207
2208 if (len < max_columns)
2209 {
2210 // Output it as a single line.
2211 strm.Printf ("%s", text);
2212 }
2213 else
2214 {
2215 // We need to break it up into multiple lines.
2216 bool first_line = true;
2217 int text_width;
2218 int start = 0;
2219 int end = start;
2220 int final_end = strlen (text);
2221 int sub_len;
2222
2223 while (end < final_end)
2224 {
2225 if (first_line)
2226 text_width = max_columns - 1;
2227 else
2228 text_width = max_columns - indent_size - 1;
2229
2230 // Don't start the 'text' on a space, since we're already outputting the indentation.
2231 if (!first_line)
2232 {
2233 while ((start < final_end) && (text[start] == ' '))
2234 start++;
2235 }
2236
2237 end = start + text_width;
2238 if (end > final_end)
2239 end = final_end;
2240 else
2241 {
2242 // If we're not at the end of the text, make sure we break the line on white space.
2243 while (end > start
2244 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
2245 end--;
2246 }
2247
2248 sub_len = end - start;
2249 if (start != 0)
2250 strm.EOL();
2251 if (!first_line)
2252 strm.Indent();
2253 else
2254 first_line = false;
2255 assert (start <= final_end);
2256 assert (start + sub_len <= final_end);
2257 if (sub_len > 0)
2258 strm.Write (text + start, sub_len);
2259 start = end + 1;
2260 }
2261 }
2262 strm.EOL();
2263 strm.IndentLess(indent_size);
Chris Lattner24943d22010-06-08 16:52:24 +00002264}
2265
2266void
Enrico Granata1bba6e52011-07-07 00:38:40 +00002267CommandInterpreter::OutputHelpText (Stream &strm,
2268 const char *word_text,
2269 const char *separator,
2270 const char *help_text,
2271 uint32_t max_word_len)
2272{
2273 int indent_size = max_word_len + strlen (separator) + 2;
2274
2275 strm.IndentMore (indent_size);
2276
2277 StreamString text_strm;
2278 text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text);
2279
2280 const uint32_t max_columns = m_debugger.GetTerminalWidth();
2281 bool first_line = true;
2282
2283 size_t len = text_strm.GetSize();
2284 const char *text = text_strm.GetData();
2285
2286 uint32_t chars_left = max_columns;
2287
2288 for (uint32_t i = 0; i < len; i++)
2289 {
2290 if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n')
2291 {
2292 first_line = false;
2293 chars_left = max_columns - indent_size;
2294 strm.EOL();
2295 strm.Indent();
2296 }
2297 else
2298 {
2299 strm.PutChar(text[i]);
2300 chars_left--;
2301 }
2302
2303 }
2304
2305 strm.EOL();
2306 strm.IndentLess(indent_size);
2307}
2308
2309void
Chris Lattner24943d22010-06-08 16:52:24 +00002310CommandInterpreter::AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word,
2311 StringList &commands_found, StringList &commands_help)
2312{
2313 CommandObject::CommandMap::const_iterator pos;
2314 CommandObject::CommandMap sub_cmd_dict = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict;
2315 CommandObject *sub_cmd_obj;
2316
2317 for (pos = sub_cmd_dict.begin(); pos != sub_cmd_dict.end(); ++pos)
2318 {
2319 const char * command_name = pos->first.c_str();
2320 sub_cmd_obj = pos->second.get();
2321 StreamString complete_command_name;
2322
2323 complete_command_name.Printf ("%s %s", prefix, command_name);
2324
Greg Clayton238c0a12010-09-18 01:14:36 +00002325 if (sub_cmd_obj->HelpTextContainsWord (search_word))
Chris Lattner24943d22010-06-08 16:52:24 +00002326 {
2327 commands_found.AppendString (complete_command_name.GetData());
2328 commands_help.AppendString (sub_cmd_obj->GetHelp());
2329 }
2330
2331 if (sub_cmd_obj->IsMultiwordObject())
2332 AproposAllSubCommands (sub_cmd_obj, complete_command_name.GetData(), search_word, commands_found,
2333 commands_help);
2334 }
2335
2336}
2337
2338void
2339CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
2340 StringList &commands_help)
2341{
2342 CommandObject::CommandMap::const_iterator pos;
2343
2344 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
2345 {
2346 const char *command_name = pos->first.c_str();
2347 CommandObject *cmd_obj = pos->second.get();
2348
Greg Clayton238c0a12010-09-18 01:14:36 +00002349 if (cmd_obj->HelpTextContainsWord (search_word))
Chris Lattner24943d22010-06-08 16:52:24 +00002350 {
2351 commands_found.AppendString (command_name);
2352 commands_help.AppendString (cmd_obj->GetHelp());
2353 }
2354
2355 if (cmd_obj->IsMultiwordObject())
2356 AproposAllSubCommands (cmd_obj, command_name, search_word, commands_found, commands_help);
2357
2358 }
2359}
Greg Claytonb72d0f02011-04-12 05:54:46 +00002360
2361
2362void
2363CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
2364{
2365 m_exe_ctx.Clear();
2366
2367 if (override_context != NULL)
2368 {
Greg Clayton567e7f32011-09-22 04:58:26 +00002369 m_exe_ctx = *override_context;
Greg Claytonb72d0f02011-04-12 05:54:46 +00002370 }
2371 else
2372 {
2373 TargetSP target_sp (m_debugger.GetSelectedTarget());
2374 if (target_sp)
2375 {
Greg Clayton567e7f32011-09-22 04:58:26 +00002376 m_exe_ctx.SetTargetSP (target_sp);
2377 ProcessSP process_sp (target_sp->GetProcessSP());
2378 m_exe_ctx.SetProcessSP (process_sp);
2379 if (process_sp && process_sp->IsAlive() && !process_sp->IsRunning())
Greg Claytonb72d0f02011-04-12 05:54:46 +00002380 {
Greg Clayton567e7f32011-09-22 04:58:26 +00002381 ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread().get());
2382 if (thread_sp)
Greg Claytonb72d0f02011-04-12 05:54:46 +00002383 {
Greg Clayton567e7f32011-09-22 04:58:26 +00002384 m_exe_ctx.SetThreadSP (thread_sp);
2385 StackFrameSP frame_sp (thread_sp->GetSelectedFrame());
2386 if (!frame_sp)
Greg Claytonb72d0f02011-04-12 05:54:46 +00002387 {
Greg Clayton567e7f32011-09-22 04:58:26 +00002388 frame_sp = thread_sp->GetStackFrameAtIndex (0);
Greg Claytonb72d0f02011-04-12 05:54:46 +00002389 // If we didn't have a selected frame select one here.
Greg Clayton567e7f32011-09-22 04:58:26 +00002390 if (frame_sp)
2391 thread_sp->SetSelectedFrame(frame_sp.get());
Greg Claytonb72d0f02011-04-12 05:54:46 +00002392 }
Greg Clayton567e7f32011-09-22 04:58:26 +00002393 if (frame_sp)
2394 m_exe_ctx.SetFrameSP (frame_sp);
Greg Claytonb72d0f02011-04-12 05:54:46 +00002395 }
2396 }
2397 }
2398 }
2399}
2400
Jim Ingham6247dbe2011-07-12 03:12:18 +00002401void
2402CommandInterpreter::DumpHistory (Stream &stream, uint32_t count) const
2403{
2404 DumpHistory (stream, 0, count - 1);
2405}
2406
2407void
2408CommandInterpreter::DumpHistory (Stream &stream, uint32_t start, uint32_t end) const
2409{
2410 size_t num_history_elements = m_command_history.size();
2411 if (start > num_history_elements)
2412 return;
2413 for (uint32_t i = start; i < num_history_elements && i <= end; i++)
2414 {
2415 if (!m_command_history[i].empty())
2416 {
2417 stream.Indent();
2418 stream.Printf ("%4d: %s\n", i, m_command_history[i].c_str());
2419 }
2420 }
2421}
2422
2423const char *
2424CommandInterpreter::FindHistoryString (const char *input_str) const
2425{
2426 if (input_str[0] != m_repeat_char)
2427 return NULL;
2428 if (input_str[1] == '-')
2429 {
2430 bool success;
2431 uint32_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
2432 if (!success)
2433 return NULL;
2434 if (idx > m_command_history.size())
2435 return NULL;
2436 idx = m_command_history.size() - idx;
2437 return m_command_history[idx].c_str();
2438
2439 }
2440 else if (input_str[1] == m_repeat_char)
2441 {
2442 if (m_command_history.empty())
2443 return NULL;
2444 else
2445 return m_command_history.back().c_str();
2446 }
2447 else
2448 {
2449 bool success;
2450 uint32_t idx = Args::StringToUInt32 (input_str+1, 0, 0, &success);
2451 if (!success)
2452 return NULL;
2453 if (idx >= m_command_history.size())
2454 return NULL;
2455 return m_command_history[idx].c_str();
2456 }
2457}