blob: ed85b33bab30e74725f573e89512105177673eec [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>
11
12#include <getopt.h>
13#include <stdlib.h>
14
15#include "CommandObjectAdd.h"
16#include "CommandObjectAlias.h"
17#include "CommandObjectAppend.h"
18#include "CommandObjectApropos.h"
19#include "CommandObjectArgs.h"
20#include "CommandObjectBreakpoint.h"
21#include "CommandObjectCall.h"
22#include "CommandObjectDelete.h"
23#include "CommandObjectDisassemble.h"
24#include "CommandObjectExpression.h"
25#include "CommandObjectFile.h"
26#include "CommandObjectFrame.h"
27#include "CommandObjectHelp.h"
28#include "CommandObjectImage.h"
29#include "CommandObjectInfo.h"
30#include "CommandObjectLog.h"
31#include "CommandObjectMemory.h"
32#include "CommandObjectProcess.h"
33#include "CommandObjectQuit.h"
34#include "CommandObjectRegexCommand.h"
35#include "CommandObjectRegister.h"
36#include "CommandObjectRemove.h"
37#include "CommandObjectScript.h"
38#include "CommandObjectSelect.h"
39#include "CommandObjectSet.h"
40#include "CommandObjectSettings.h"
41#include "CommandObjectShow.h"
42#include "CommandObjectSource.h"
43#include "CommandObjectSourceFile.h"
44#include "CommandObjectStatus.h"
45#include "CommandObjectSyntax.h"
46#include "CommandObjectTarget.h"
47#include "CommandObjectThread.h"
48#include "CommandObjectTranslate.h"
49#include "CommandObjectUnalias.h"
50#include "CommandObjectVariable.h"
51
52#include "lldb/Core/Args.h"
53#include "lldb/Core/Debugger.h"
54#include "lldb/Core/Stream.h"
55#include "lldb/Core/Timer.h"
56#include "lldb/Target/Process.h"
57#include "lldb/Target/Thread.h"
58#include "lldb/Target/TargetList.h"
59
60#include "lldb/Interpreter/CommandReturnObject.h"
61#include "lldb/Interpreter/CommandInterpreter.h"
62
63using namespace lldb;
64using namespace lldb_private;
65
66CommandInterpreter::CommandInterpreter
67(
68 ScriptLanguage script_language,
69 bool synchronous_execution,
70 Listener *listener,
71 SourceManager& source_manager
72) :
73 Broadcaster ("CommandInterpreter"),
74 m_script_language (script_language),
75 m_synchronous_execution (synchronous_execution),
76 m_listener (listener),
77 m_source_manager (source_manager)
78{
79}
80
81void
82CommandInterpreter::Initialize ()
83{
84 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
85
86 CommandReturnObject result;
87
88 LoadCommandDictionary ();
89
90 InitializeVariables ();
91
92 // Set up some initial aliases.
93 result.Clear(); HandleCommand ("alias q quit", false, result);
94 result.Clear(); HandleCommand ("alias run process launch", false, result);
95 result.Clear(); HandleCommand ("alias r process launch", false, result);
96 result.Clear(); HandleCommand ("alias c process continue", false, result);
97 result.Clear(); HandleCommand ("alias continue process continue", false, result);
98 result.Clear(); HandleCommand ("alias expr expression", false, result);
99 result.Clear(); HandleCommand ("alias exit quit", false, result);
100 result.Clear(); HandleCommand ("alias bt thread backtrace", false, result);
101 result.Clear(); HandleCommand ("alias si thread step-inst", false, result);
102 result.Clear(); HandleCommand ("alias step thread step-in", false, result);
103 result.Clear(); HandleCommand ("alias s thread step-in", false, result);
104 result.Clear(); HandleCommand ("alias next thread step-over", false, result);
105 result.Clear(); HandleCommand ("alias n thread step-over", false, result);
106 result.Clear(); HandleCommand ("alias finish thread step-out", false, result);
107 result.Clear(); HandleCommand ("alias x memory read", false, result);
108 result.Clear(); HandleCommand ("alias l source-file", false, result);
109 result.Clear(); HandleCommand ("alias list source-file", false, result);
110}
111
112void
113CommandInterpreter::InitializeVariables ()
114{
115 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
116
117 m_variables["prompt"] =
118 StateVariableSP (new StateVariable ("prompt",
119 "(lldb) ",
120 false,
121 "The debugger prompt displayed for the user.",
122 StateVariable::BroadcastPromptChange));
123
124 m_variables["run-args"] =
125 StateVariableSP (new StateVariable ("run-args",
126 (Args*)NULL,
127 "An argument list containing the arguments to be passed to the executable when it is launched."));
128
129
130 m_variables["env-vars"] =
131 StateVariableSP (new StateVariable ("env-vars",
132 (Args*)NULL,
133 "A list of strings containing the environment variables to be passed to the executable's environment."));
134
135 m_variables["input-path"] =
136 StateVariableSP (new StateVariable ("input-path",
137 "/dev/stdin",
138 false,
139 "The file/path to be used by the executable program for reading its input."));
140
141 m_variables["output-path"] =
142 StateVariableSP (new StateVariable ( "output-path",
143 "/dev/stdout",
144 false,
145 "The file/path to be used by the executable program for writing its output."));
146
147 m_variables["error-path"] =
148 StateVariableSP (new StateVariable ("error-path",
149 "/dev/stderr",
150 false,
151 "The file/path to be used by the executable program for writing its error messages."));
152
153 m_variables["arch"] =
154 StateVariableSP (new StateVariable ("arch",
155 "",
156 false,
157 "The architecture to be used for running the executable (e.g. i386, x86_64, etc)."));
158
159 m_variables["script-lang"] =
160 StateVariableSP (new StateVariable ("script-lang",
161 "Python",
162 false,
163 "The script language to be used for evaluating user-written scripts.",
164 StateVariable::VerifyScriptLanguage));
165
166 m_variables["term-width"] =
167 StateVariableSP (new StateVariable ("term-width",
168 80,
169 "The maximum number of columns to use for displaying text."));
170
171}
172
173const char *
174CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg)
175{
176 // This function has not yet been implemented.
177
178 // Look for any embedded script command
179 // If found,
180 // get interpreter object from the command dictionary,
181 // call execute_one_command on it,
182 // get the results as a string,
183 // substitute that string for current stuff.
184
185 return arg;
186}
187
188
189void
190CommandInterpreter::LoadCommandDictionary ()
191{
192 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
193
194 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
195 //
196 // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref)
197 // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use
198 // the cross-referencing stuff) are created!!!
199 //
200 // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
201
202
203 // Command objects that inherit from CommandObjectCrossref must be created before other command objects
204 // are created. This is so that when another command is created that needs to go into a crossref object,
205 // the crossref object exists and is ready to take the cross reference. Put the cross referencing command
206 // objects into the CommandDictionary now, so they are ready for use when the other commands get created.
207
208 m_command_dict["select"] = CommandObjectSP (new CommandObjectSelect ());
209 m_command_dict["info"] = CommandObjectSP (new CommandObjectInfo ());
210 m_command_dict["delete"] = CommandObjectSP (new CommandObjectDelete ());
211
212 // Non-CommandObjectCrossref commands can now be created.
213
214 //m_command_dict["add"] = CommandObjectSP (new CommandObjectAdd ());
215 m_command_dict["alias"] = CommandObjectSP (new CommandObjectAlias ());
216 m_command_dict["append"] = CommandObjectSP (new CommandObjectAppend ());
217 m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos ());
218 //m_command_dict["args"] = CommandObjectSP (new CommandObjectArgs ());
219 m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (this));
220 m_command_dict["call"] = CommandObjectSP (new CommandObjectCall ());
221 m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble ());
222 m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression ());
223 m_command_dict["file"] = CommandObjectSP (new CommandObjectFile ());
224 m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (this));
225 m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp ());
226 m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (this));
227 m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (this));
228 m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (this));
229 m_command_dict["process"] = CommandObjectSP (new CommandObjectMultiwordProcess (this));
230 m_command_dict["quit"] = CommandObjectSP (new CommandObjectQuit ());
231 m_command_dict["register"] = CommandObjectSP (new CommandObjectRegister (this));
232 //m_command_dict["remove"] = CommandObjectSP (new CommandObjectRemove ());
233 m_command_dict["script"] = CommandObjectSP (new CommandObjectScript (m_script_language));
234 m_command_dict["set"] = CommandObjectSP (new CommandObjectSet ());
235 m_command_dict["settings"] = CommandObjectSP (new CommandObjectSettings ());
236 m_command_dict["show"] = CommandObjectSP (new CommandObjectShow ());
237 m_command_dict["source"] = CommandObjectSP (new CommandObjectSource ());
238 m_command_dict["source-file"] = CommandObjectSP (new CommandObjectSourceFile ());
239 //m_command_dict["syntax"] = CommandObjectSP (new CommandObjectSyntax ());
240 m_command_dict["status"] = CommandObjectSP (new CommandObjectStatus ());
241 m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (this));
242 m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (this));
243 //m_command_dict["translate"] = CommandObjectSP (new CommandObjectTranslate ());
244 m_command_dict["unalias"] = CommandObjectSP (new CommandObjectUnalias ());
245 m_command_dict["variable"] = CommandObjectSP (new CommandObjectVariable (this));
246
247 std::auto_ptr<CommandObjectRegexCommand>
248 break_regex_cmd_ap(new CommandObjectRegexCommand ("regexp-break",
249 "Smart breakpoint command (using regular expressions).",
250 "regexp-break [<file>:<line>]\nregexp-break [<address>]\nregexp-break <...>", 2));
251 if (break_regex_cmd_ap.get())
252 {
253 if (break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2") &&
254 break_regex_cmd_ap->AddRegexCommand("^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1") &&
255 break_regex_cmd_ap->AddRegexCommand("^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'") &&
256 break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list") &&
257 break_regex_cmd_ap->AddRegexCommand("^(-.*)$", "breakpoint set %1") &&
258 break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"))
259 {
260 CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release());
261 m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp;
262 }
263 }
264}
265
266int
267CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases,
268 StringList &matches)
269{
270 CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches);
271
272 if (include_aliases)
273 {
274 CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches);
275 }
276
277 return matches.GetSize();
278}
279
280CommandObjectSP
281CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches)
282{
283 CommandObject::CommandMap::iterator pos;
284 CommandObjectSP ret_val;
285
286 std::string cmd(cmd_cstr);
287
288 if (HasCommands())
289 {
290 pos = m_command_dict.find(cmd);
291 if (pos != m_command_dict.end())
292 ret_val = pos->second;
293 }
294
295 if (include_aliases && HasAliases())
296 {
297 pos = m_alias_dict.find(cmd);
298 if (pos != m_alias_dict.end())
299 ret_val = pos->second;
300 }
301
302 if (HasUserCommands())
303 {
304 pos = m_user_dict.find(cmd);
305 if (pos != m_user_dict.end())
306 ret_val = pos->second;
307 }
308
309 if (!exact && ret_val == NULL)
310 {
311 StringList local_matches;
312 if (matches == NULL)
313 matches = &local_matches;
314
315 int num_cmd_matches = 0;
316 int num_alias_matches = 0;
317 int num_user_matches = 0;
318 if (HasCommands())
319 {
320 num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches);
321 }
322
323 if (num_cmd_matches == 1)
324 {
325 cmd.assign(matches->GetStringAtIndex(0));
326 pos = m_command_dict.find(cmd);
327 if (pos != m_command_dict.end())
328 ret_val = pos->second;
329 }
330
331 if (num_cmd_matches != 1 && include_aliases && HasAliases())
332 {
333 num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches);
334
335 }
336
337 if (num_alias_matches == 1)
338 {
339 cmd.assign(matches->GetStringAtIndex (num_cmd_matches));
340 pos = m_alias_dict.find(cmd);
341 if (pos != m_alias_dict.end())
342 {
343 matches->Clear();
344 matches->AppendString (cmd.c_str());
345
346 ret_val = pos->second;
347 }
348 }
349
350 if (num_cmd_matches != 1 && num_alias_matches != 1 && HasUserCommands())
351 {
352 num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches);
353 }
354
355 if (num_user_matches == 1)
356 {
357 cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches));
358
359 pos = m_user_dict.find (cmd);
360 if (pos != m_user_dict.end())
361 {
362 matches->Clear();
363 matches->AppendString (cmd.c_str());
364
365 ret_val = pos->second;
366 }
367 }
368 }
369 else {
370 if (matches)
371 matches->AppendString (cmd_cstr);
372 }
373
374
375 return ret_val;
376}
377
378CommandObject *
379CommandInterpreter::GetCommandObject (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches)
380{
381 return GetCommandSP (cmd_cstr, include_aliases, exact, matches).get();
382}
383
384bool
385CommandInterpreter::CommandExists (const char *cmd)
386{
387 return m_command_dict.find(cmd) != m_command_dict.end();
388}
389
390bool
391CommandInterpreter::AliasExists (const char *cmd)
392{
393 return m_alias_dict.find(cmd) != m_alias_dict.end();
394}
395
396bool
397CommandInterpreter::UserCommandExists (const char *cmd)
398{
399 return m_user_dict.find(cmd) != m_user_dict.end();
400}
401
402void
403CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp)
404{
405 m_alias_dict[alias_name] = command_obj_sp;
406}
407
408bool
409CommandInterpreter::RemoveAlias (const char *alias_name)
410{
411 CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name);
412 if (pos != m_alias_dict.end())
413 {
414 m_alias_dict.erase(pos);
415 return true;
416 }
417 return false;
418}
419bool
420CommandInterpreter::RemoveUser (const char *alias_name)
421{
422 CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name);
423 if (pos != m_user_dict.end())
424 {
425 m_user_dict.erase(pos);
426 return true;
427 }
428 return false;
429}
430
431StateVariable *
432CommandInterpreter::GetStateVariable(const char *name)
433{
434 VariableMap::const_iterator pos = m_variables.find(name);
435 if (pos != m_variables.end())
436 return pos->second.get();
437 return NULL;
438}
439
440void
441CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string)
442{
443 help_string.Printf ("'%s", command_name);
444 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
445
446 if (option_arg_vector_sp != NULL)
447 {
448 OptionArgVector *options = option_arg_vector_sp.get();
449 for (int i = 0; i < options->size(); ++i)
450 {
451 OptionArgPair cur_option = (*options)[i];
452 std::string opt = cur_option.first;
453 std::string value = cur_option.second;
454 if (opt.compare("<argument>") == 0)
455 {
456 help_string.Printf (" %s", value.c_str());
457 }
458 else
459 {
460 help_string.Printf (" %s", opt.c_str());
461 if ((value.compare ("<no-argument>") != 0)
462 && (value.compare ("<need-argument") != 0))
463 {
464 help_string.Printf (" %s", value.c_str());
465 }
466 }
467 }
468 }
469
470 help_string.Printf ("'");
471}
472
473std::string
474CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict)
475{
476 CommandObject::CommandMap::const_iterator pos;
477 int max_len = 0;
478 CommandObjectSP cmd_sp;
479 std::string longest_word;
480
481 for (pos = dict.begin(); pos != dict.end(); ++pos)
482 {
483 if ((max_len == 0)
484 || (strlen (pos->first.c_str()) > max_len))
485 {
486 longest_word = pos->first;
487 max_len = strlen (longest_word.c_str());
488 }
489 }
490
491 return longest_word;
492}
493
494void
495CommandInterpreter::GetHelp (CommandReturnObject &result)
496{
497 CommandObject::CommandMap::const_iterator pos;
498 result.AppendMessage("The following is a list of built-in, permanent debugger commands:");
499 result.AppendMessage("");
500 std::string longest_word = FindLongestCommandWord (m_command_dict);
501 uint32_t max_len = strlen (longest_word.c_str());
502
503 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
504 {
505 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
506 max_len);
507 }
508 result.AppendMessage("");
509
510 if (m_alias_dict.size() > 0)
511 {
512 result.AppendMessage("The following is a list of your current command abbreviations (see 'alias' for more info):");
513 result.AppendMessage("");
514 longest_word = FindLongestCommandWord (m_alias_dict);
515 max_len = strlen (longest_word.c_str());
516 for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos)
517 {
518 StreamString sstr;
519 StreamString translation_and_help;
520 std::string entry_name = pos->first;
521 std::string second_entry = pos->second.get()->GetCommandName();
522 GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr);
523
524 translation_and_help.Printf ("(%s) %s", sstr.GetData(), pos->second->GetHelp());
525 OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--",
526 translation_and_help.GetData(), max_len);
527 }
528 result.AppendMessage("");
529 }
530
531 if (m_user_dict.size() > 0)
532 {
533 result.AppendMessage ("The following is a list of your current user-defined commands:");
534 result.AppendMessage("");
535 for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
536 {
537 result.AppendMessageWithFormat ("%s -- %s\n", pos->first.c_str(), pos->second->GetHelp());
538 }
539 result.AppendMessage("");
540 }
541
542 result.AppendMessage("For more information on any particular command, try 'help <command-name>'.");
543}
544
545void
546CommandInterpreter::ShowVariableValues (CommandReturnObject &result)
547{
548 result.AppendMessage ("Below is a list of all the debugger setting variables and their values:");
549
550 for (VariableMap::const_iterator pos = m_variables.begin(); pos != m_variables.end(); ++pos)
551 {
552 StateVariable *var = pos->second.get();
553 var->AppendVariableInformation (result);
554 }
555}
556
557void
558CommandInterpreter::ShowVariableHelp (CommandReturnObject &result)
559{
560 result.AppendMessage ("Below is a list of all the internal debugger variables that are settable:");
561 for (VariableMap::const_iterator pos = m_variables.begin(); pos != m_variables.end(); ++pos)
562 {
563 StateVariable *var = pos->second.get();
564 result.AppendMessageWithFormat (" %s -- %s \n", var->GetName(), var->GetHelp());
565 }
566}
567
568// Main entry point into the command_interpreter; this function takes a text
569// line containing a debugger command, with all its flags, options, etc,
570// parses the line and takes the appropriate actions.
571
572bool
573CommandInterpreter::HandleCommand (const char *command_line, bool add_to_history, CommandReturnObject &result,
574 ExecutionContext *override_context)
575{
576 // FIXME: there should probably be a mutex to make sure only one thread can
577 // run the interpreter at a time.
578
579 // TODO: this should be a logging channel in lldb.
580// if (DebugSelf())
581// {
582// result.AppendMessageWithFormat ("Processing command: %s\n", command_line);
583// }
584
585 m_current_context.Update (override_context);
586
587 if (command_line == NULL || command_line[0] == '\0')
588 {
589 if (m_command_history.empty())
590 {
591 result.AppendError ("empty command");
592 result.SetStatus(eReturnStatusFailed);
593 return false;
594 }
595 else
596 {
597 command_line = m_command_history.back().c_str();
598 }
599 add_to_history = false;
600 }
601
602 Args command_args(command_line);
603
604 if (command_args.GetArgumentCount() > 0)
605 {
606 const char *command_cstr = command_args.GetArgumentAtIndex(0);
607 if (command_cstr)
608 {
609
610 // We're looking up the command object here. So first find an exact match to the
611 // command in the commands.
612
613 CommandObject *command_obj = GetCommandObject (command_cstr, false, true);
614
615 // If we didn't find an exact match to the command string in the commands, look in
616 // the aliases.
617
618 if (command_obj == NULL)
619 {
620 command_obj = GetCommandObject (command_cstr, true, true);
621 if (command_obj != NULL)
622 {
623 BuildAliasCommandArgs (command_obj, command_cstr, command_args, result);
624 if (!result.Succeeded())
625 return false;
626 }
627 }
628
629 // Finally, if there wasn't an exact match among the aliases, look for an inexact match.
630
631 if (command_obj == NULL)
632 command_obj = GetCommandObject(command_cstr, false, false);
633
634 if (command_obj)
635 {
636 if (command_obj->WantsRawCommandString())
637 {
638 const char *stripped_command = ::strstr (command_line, command_cstr);
639 if (stripped_command)
640 {
641 stripped_command += strlen(command_cstr);
642 while (isspace(*stripped_command))
643 ++stripped_command;
644 command_obj->ExecuteRawCommandString(stripped_command, Context(), this, result);
645 }
646 }
647 else
648 {
649 if (add_to_history)
650 m_command_history.push_back (command_line);
651
652 // Remove the command from the args.
653 command_args.Shift();
654 command_obj->ExecuteWithOptions (command_args, Context(), this, result);
655 }
656 }
657 else
658 {
659 StringList matches;
660 int num_matches;
661 int cursor_index = command_args.GetArgumentCount() - 1;
662 int cursor_char_position = strlen (command_args.GetArgumentAtIndex(command_args.GetArgumentCount() - 1));
663 num_matches = HandleCompletionMatches (command_args, cursor_index,
664 cursor_char_position,
665 0, -1, matches);
666
667 if (num_matches > 0)
668 {
669 std::string error_msg;
670 error_msg.assign ("ambiguous command '");
671 error_msg.append(command_cstr);
672 error_msg.append ("'.");
673
674 error_msg.append (" Possible completions:");
675 for (int i = 0; i < num_matches; i++)
676 {
677 error_msg.append ("\n\t");
678 error_msg.append (matches.GetStringAtIndex (i));
679 }
680 error_msg.append ("\n");
681 result.AppendRawError (error_msg.c_str(), error_msg.size());
682 }
683 else
684 result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_cstr);
685
686 result.SetStatus (eReturnStatusFailed);
687 }
688 }
689 }
690 return result.Succeeded();
691}
692
693int
694CommandInterpreter::HandleCompletionMatches (Args &parsed_line,
695 int &cursor_index,
696 int &cursor_char_position,
697 int match_start_point,
698 int max_return_elements,
699 StringList &matches)
700{
701 int num_command_matches = 0;
702 bool include_aliases = true;
703 bool look_for_subcommand = false;
704
705 if (cursor_index == -1)
706 {
707 // We got nothing on the command line, so return the list of commands
708 num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches);
709 }
710 else if (cursor_index == 0)
711 {
712 // The cursor is in the first argument, so just do a lookup in the dictionary.
713 CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), include_aliases, false,
714 &matches);
715 num_command_matches = matches.GetSize();
716
717 if (num_command_matches == 1
718 && cmd_obj && cmd_obj->IsMultiwordObject()
719 && matches.GetStringAtIndex(0) != NULL
720 && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0)
721 {
722 look_for_subcommand = true;
723 num_command_matches = 0;
724 matches.DeleteStringAtIndex(0);
725 parsed_line.AppendArgument ("");
726 cursor_index++;
727 cursor_char_position = 0;
728 }
729 }
730
731 if (cursor_index > 0 || look_for_subcommand)
732 {
733 // We are completing further on into a commands arguments, so find the command and tell it
734 // to complete the command.
735 // First see if there is a matching initial command:
736 CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0), include_aliases, false);
737 if (command_object == NULL)
738 {
739 return 0;
740 }
741 else
742 {
743 parsed_line.Shift();
744 cursor_index--;
745 num_command_matches = command_object->HandleCompletion (parsed_line, cursor_index, cursor_char_position,
746 match_start_point, max_return_elements, this,
747 matches);
748 }
749 }
750
751 return num_command_matches;
752
753}
754
755int
756CommandInterpreter::HandleCompletion (const char *current_line,
757 const char *cursor,
758 const char *last_char,
759 int match_start_point,
760 int max_return_elements,
761 StringList &matches)
762{
763 // We parse the argument up to the cursor, so the last argument in parsed_line is
764 // the one containing the cursor, and the cursor is after the last character.
765
766 Args parsed_line(current_line, last_char - current_line);
767 Args partial_parsed_line(current_line, cursor - current_line);
768
769 int num_args = partial_parsed_line.GetArgumentCount();
770 int cursor_index = partial_parsed_line.GetArgumentCount() - 1;
771 int cursor_char_position;
772
773 if (cursor_index == -1)
774 cursor_char_position = 0;
775 else
776 cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index));
777
778 int num_command_matches;
779
780 matches.Clear();
781
782 // Only max_return_elements == -1 is supported at present:
783 assert (max_return_elements == -1);
784 num_command_matches = HandleCompletionMatches (parsed_line, cursor_index, cursor_char_position, match_start_point,
785 max_return_elements, matches);
786
787 if (num_command_matches <= 0)
788 return num_command_matches;
789
790 if (num_args == 0)
791 {
792 // If we got an empty string, insert nothing.
793 matches.InsertStringAtIndex(0, "");
794 }
795 else
796 {
797 // Now figure out if there is a common substring, and if so put that in element 0, otherwise
798 // put an empty string in element 0.
799 std::string command_partial_str;
800 if (cursor_index >= 0)
801 command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index), parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position);
802
803 std::string common_prefix;
804 matches.LongestCommonPrefix (common_prefix);
805 int partial_name_len = command_partial_str.size();
806
807 // If we matched a unique single command, add a space...
808 if (num_command_matches == 1)
809 {
810 char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index);
811 if (quote_char != '\0')
812 common_prefix.push_back(quote_char);
813
814 common_prefix.push_back(' ');
815 }
816 common_prefix.erase (0, partial_name_len);
817 matches.InsertStringAtIndex(0, common_prefix.c_str());
818 }
819 return num_command_matches;
820}
821
822CommandContext *
823CommandInterpreter::Context ()
824{
825 return &m_current_context;
826}
827
828const Args *
829CommandInterpreter::GetProgramArguments ()
830{
831 if (! HasInterpreterVariables())
832 return NULL;
833
834 VariableMap::const_iterator pos = m_variables.find("run-args");
835 if (pos == m_variables.end())
836 return NULL;
837
838 StateVariable *var = pos->second.get();
839
840 if (var)
841 return &var->GetArgs();
842 return NULL;
843}
844
845const Args *
846CommandInterpreter::GetEnvironmentVariables ()
847{
848 if (! HasInterpreterVariables())
849 return NULL;
850
851 VariableMap::const_iterator pos = m_variables.find("env-vars");
852 if (pos == m_variables.end())
853 return NULL;
854
855 StateVariable *var = pos->second.get();
856 if (var)
857 return &var->GetArgs();
858 return NULL;
859}
860
861
862CommandInterpreter::~CommandInterpreter ()
863{
864}
865
866const char *
867CommandInterpreter::GetPrompt ()
868{
869 VariableMap::iterator pos;
870
871 if (! HasInterpreterVariables())
872 return NULL;
873
874 pos = m_variables.find("prompt");
875 if (pos == m_variables.end())
876 return NULL;
877
878 StateVariable *var = pos->second.get();
879
880 return ((char *) var->GetStringValue());
881}
882
883void
884CommandInterpreter::SetPrompt (const char *new_prompt)
885{
886 VariableMap::iterator pos;
887 CommandReturnObject result;
888
889 if (! HasInterpreterVariables())
890 return;
891
892 pos = m_variables.find ("prompt");
893 if (pos == m_variables.end())
894 return;
895
896 StateVariable *var = pos->second.get();
897
898 if (var->VerifyValue (this, (void *) new_prompt, result))
899 var->SetStringValue (new_prompt);
900}
901
902void
903CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type)
904{
905 CommandObjectSP cmd_obj_sp = GetCommandSP (dest_cmd);
906
907 if (cmd_obj_sp != NULL)
908 {
909 CommandObject *cmd_obj = cmd_obj_sp.get();
910 if (cmd_obj->IsCrossRefObject ())
911 cmd_obj->AddObject (object_type);
912 }
913}
914
915void
916CommandInterpreter::SetScriptLanguage (ScriptLanguage lang)
917{
918 m_script_language = lang;
919}
920
921Listener *
922CommandInterpreter::GetListener ()
923{
924 return m_listener;
925}
926
927SourceManager &
928CommandInterpreter::GetSourceManager ()
929{
930 return m_source_manager;
931}
932
933
934
935OptionArgVectorSP
936CommandInterpreter::GetAliasOptions (const char *alias_name)
937{
938 OptionArgMap::iterator pos;
939 OptionArgVectorSP ret_val;
940
941 std::string alias (alias_name);
942
943 if (HasAliasOptions())
944 {
945 pos = m_alias_options.find (alias);
946 if (pos != m_alias_options.end())
947 ret_val = pos->second;
948 }
949
950 return ret_val;
951}
952
953void
954CommandInterpreter::RemoveAliasOptions (const char *alias_name)
955{
956 OptionArgMap::iterator pos = m_alias_options.find(alias_name);
957 if (pos != m_alias_options.end())
958 {
959 m_alias_options.erase (pos);
960 }
961}
962
963void
964CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp)
965{
966 m_alias_options[alias_name] = option_arg_vector_sp;
967}
968
969bool
970CommandInterpreter::HasCommands ()
971{
972 return (!m_command_dict.empty());
973}
974
975bool
976CommandInterpreter::HasAliases ()
977{
978 return (!m_alias_dict.empty());
979}
980
981bool
982CommandInterpreter::HasUserCommands ()
983{
984 return (!m_user_dict.empty());
985}
986
987bool
988CommandInterpreter::HasAliasOptions ()
989{
990 return (!m_alias_options.empty());
991}
992
993bool
994CommandInterpreter::HasInterpreterVariables ()
995{
996 return (!m_variables.empty());
997}
998
999void
1000CommandInterpreter::BuildAliasCommandArgs
1001(
1002 CommandObject *alias_cmd_obj,
1003 const char *alias_name,
1004 Args &cmd_args,
1005 CommandReturnObject &result
1006)
1007{
1008 OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
1009
1010 if (option_arg_vector_sp.get())
1011 {
1012 // Make sure that the alias name is the 0th element in cmd_args
1013 std::string alias_name_str = alias_name;
1014 if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)
1015 cmd_args.Unshift (alias_name);
1016
1017 Args new_args (alias_cmd_obj->GetCommandName());
1018 if (new_args.GetArgumentCount() == 2)
1019 new_args.Shift();
1020
1021 OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
1022 int old_size = cmd_args.GetArgumentCount();
1023 int *used = (int *) malloc ((old_size + 1) * sizeof (int));
1024
1025 memset (used, 0, (old_size + 1) * sizeof (int));
1026 used[0] = 1;
1027
1028 for (int i = 0; i < option_arg_vector->size(); ++i)
1029 {
1030 OptionArgPair option_pair = (*option_arg_vector)[i];
1031 std::string option = option_pair.first;
1032 std::string value = option_pair.second;
1033 if (option.compare ("<argument>") == 0)
1034 new_args.AppendArgument (value.c_str());
1035 else
1036 {
1037 new_args.AppendArgument (option.c_str());
1038 if (value.compare ("<no-argument>") != 0)
1039 {
1040 int index = GetOptionArgumentPosition (value.c_str());
1041 if (index == 0)
1042 // value was NOT a positional argument; must be a real value
1043 new_args.AppendArgument (value.c_str());
1044 else if (index >= cmd_args.GetArgumentCount())
1045 {
1046 result.AppendErrorWithFormat
1047 ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
1048 index);
1049 result.SetStatus (eReturnStatusFailed);
1050 return;
1051 }
1052 else
1053 {
1054 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index));
1055 used[index] = 1;
1056 }
1057 }
1058 }
1059 }
1060
1061 for (int j = 0; j < cmd_args.GetArgumentCount(); ++j)
1062 {
1063 if (!used[j])
1064 new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j));
1065 }
1066
1067 cmd_args.Clear();
1068 cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
1069 }
1070 else
1071 {
1072 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1073 // This alias was not created with any options; nothing further needs to be done.
1074 return;
1075 }
1076
1077 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1078 return;
1079}
1080
1081
1082int
1083CommandInterpreter::GetOptionArgumentPosition (const char *in_string)
1084{
1085 int position = 0; // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position
1086 // of zero.
1087
1088 char *cptr = (char *) in_string;
1089
1090 // Does it start with '%'
1091 if (cptr[0] == '%')
1092 {
1093 ++cptr;
1094
1095 // Is the rest of it entirely digits?
1096 if (isdigit (cptr[0]))
1097 {
1098 const char *start = cptr;
1099 while (isdigit (cptr[0]))
1100 ++cptr;
1101
1102 // We've gotten to the end of the digits; are we at the end of the string?
1103 if (cptr[0] == '\0')
1104 position = atoi (start);
1105 }
1106 }
1107
1108 return position;
1109}
1110
1111void
1112CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
1113{
1114 const char *init_file_path = in_cwd ? "./.lldbinit" : "~/.lldbinit";
1115 FileSpec init_file (init_file_path);
1116 // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting
1117 // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details).
1118
1119 if (init_file.Exists())
1120 {
1121 char path[PATH_MAX];
1122 init_file.GetPath(path, sizeof(path));
1123 StreamString source_command;
1124 source_command.Printf ("source '%s'", path);
1125 HandleCommand (source_command.GetData(), false, result);
1126 }
1127 else
1128 {
1129 // nothing to be done if the file doesn't exist
1130 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1131 }
1132}
1133
1134ScriptInterpreter *
1135CommandInterpreter::GetScriptInterpreter ()
1136{
1137 CommandObject::CommandMap::iterator pos;
1138
1139 pos = m_command_dict.find ("script");
1140 if (pos != m_command_dict.end())
1141 {
1142 CommandObject *script_cmd_obj = pos->second.get();
1143 return ((CommandObjectScript *) script_cmd_obj)->GetInterpreter ();
1144 }
1145 else
1146 return NULL;
1147}
1148
1149
1150
1151bool
1152CommandInterpreter::GetSynchronous ()
1153{
1154 return m_synchronous_execution;
1155}
1156
1157void
1158CommandInterpreter::SetSynchronous (bool value)
1159{
1160 static bool value_set_once = false;
1161 if (!value_set_once)
1162 {
1163 value_set_once = true;
1164 m_synchronous_execution = value;
1165 }
1166}
1167
1168void
1169CommandInterpreter::OutputFormattedHelpText (Stream &strm,
1170 const char *word_text,
1171 const char *separator,
1172 const char *help_text,
1173 uint32_t max_word_len)
1174{
1175 StateVariable *var = GetStateVariable ("term-width");
1176 int max_columns = var->GetIntValue();
1177 // Sanity check max_columns, to cope with emacs shell mode with TERM=dumb
1178 // (0 rows; 0 columns;).
1179 if (max_columns <= 0) max_columns = 80;
1180
1181 int indent_size = max_word_len + strlen (separator) + 2;
1182
1183 strm.IndentMore (indent_size);
1184
1185 int len = indent_size + strlen (help_text) + 1;
1186 char *text = (char *) malloc (len);
1187 sprintf (text, "%-*s %s %s", max_word_len, word_text, separator, help_text);
1188 if (text[len - 1] == '\n')
1189 text[--len] = '\0';
1190
1191 if (len < max_columns)
1192 {
1193 // Output it as a single line.
1194 strm.Printf ("%s", text);
1195 }
1196 else
1197 {
1198 // We need to break it up into multiple lines.
1199 bool first_line = true;
1200 int text_width;
1201 int start = 0;
1202 int end = start;
1203 int final_end = strlen (text);
1204 int sub_len;
1205
1206 while (end < final_end)
1207 {
1208 if (first_line)
1209 text_width = max_columns - 1;
1210 else
1211 text_width = max_columns - indent_size - 1;
1212
1213 // Don't start the 'text' on a space, since we're already outputting the indentation.
1214 if (!first_line)
1215 {
1216 while ((start < final_end) && (text[start] == ' '))
1217 start++;
1218 }
1219
1220 end = start + text_width;
1221 if (end > final_end)
1222 end = final_end;
1223 else
1224 {
1225 // If we're not at the end of the text, make sure we break the line on white space.
1226 while (end > start
1227 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
1228 end--;
1229 }
1230
1231 sub_len = end - start;
1232 if (start != 0)
1233 strm.EOL();
1234 if (!first_line)
1235 strm.Indent();
1236 else
1237 first_line = false;
1238 assert (start <= final_end);
1239 assert (start + sub_len <= final_end);
1240 if (sub_len > 0)
1241 strm.Write (text + start, sub_len);
1242 start = end + 1;
1243 }
1244 }
1245 strm.EOL();
1246 strm.IndentLess(indent_size);
1247 free (text);
1248}
1249
1250void
1251CommandInterpreter::AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word,
1252 StringList &commands_found, StringList &commands_help)
1253{
1254 CommandObject::CommandMap::const_iterator pos;
1255 CommandObject::CommandMap sub_cmd_dict = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict;
1256 CommandObject *sub_cmd_obj;
1257
1258 for (pos = sub_cmd_dict.begin(); pos != sub_cmd_dict.end(); ++pos)
1259 {
1260 const char * command_name = pos->first.c_str();
1261 sub_cmd_obj = pos->second.get();
1262 StreamString complete_command_name;
1263
1264 complete_command_name.Printf ("%s %s", prefix, command_name);
1265
1266 if (sub_cmd_obj->HelpTextContainsWord (search_word))
1267 {
1268 commands_found.AppendString (complete_command_name.GetData());
1269 commands_help.AppendString (sub_cmd_obj->GetHelp());
1270 }
1271
1272 if (sub_cmd_obj->IsMultiwordObject())
1273 AproposAllSubCommands (sub_cmd_obj, complete_command_name.GetData(), search_word, commands_found,
1274 commands_help);
1275 }
1276
1277}
1278
1279void
1280CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
1281 StringList &commands_help)
1282{
1283 CommandObject::CommandMap::const_iterator pos;
1284
1285 for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
1286 {
1287 const char *command_name = pos->first.c_str();
1288 CommandObject *cmd_obj = pos->second.get();
1289
1290 if (cmd_obj->HelpTextContainsWord (search_word))
1291 {
1292 commands_found.AppendString (command_name);
1293 commands_help.AppendString (cmd_obj->GetHelp());
1294 }
1295
1296 if (cmd_obj->IsMultiwordObject())
1297 AproposAllSubCommands (cmd_obj, command_name, search_word, commands_found, commands_help);
1298
1299 }
1300}