blob: f6fd9f63c2e1ad308e294aafaaeabb7e2ba706c3 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectHelp.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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectHelp.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Interpreter/CommandObjectMultiword.h"
19#include "lldb/Interpreter/CommandInterpreter.h"
Jim Ingham40af72e2010-06-15 19:49:27 +000020#include "lldb/Interpreter/Options.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Interpreter/CommandReturnObject.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
26//-------------------------------------------------------------------------
27// CommandObjectHelp
28//-------------------------------------------------------------------------
29
Greg Claytona7015092010-09-18 01:14:36 +000030CommandObjectHelp::CommandObjectHelp (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +000031 CommandObjectParsed (interpreter,
32 "help",
33 "Show a list of all debugger commands, or give details about specific commands.",
34 "help [<cmd-name>]"), m_options (interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035{
Caroline Tice405fe672010-10-04 22:28:36 +000036 CommandArgumentEntry arg;
37 CommandArgumentData command_arg;
38
39 // Define the first (and only) variant of this arg.
40 command_arg.arg_type = eArgTypeCommandName;
41 command_arg.arg_repetition = eArgRepeatStar;
42
43 // There is only one variant this argument could be; put it into the argument entry.
44 arg.push_back (command_arg);
45
46 // Push the data for the first argument into the m_arguments vector.
47 m_arguments.push_back (arg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048}
49
50CommandObjectHelp::~CommandObjectHelp()
51{
52}
53
Enrico Granata08633ee2011-09-09 17:49:36 +000054OptionDefinition
55CommandObjectHelp::CommandOptions::g_option_table[] =
56{
Kate Stonea487aa42015-01-15 00:52:41 +000057 { LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Hide aliases in the command list."},
Zachary Turnerd37221d2014-07-09 16:31:49 +000058 { LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Hide user-defined commands from the list."},
Kate Stonea487aa42015-01-15 00:52:41 +000059 { LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Include commands prefixed with an underscore."},
60 { 0, false, NULL, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Enrico Granata08633ee2011-09-09 17:49:36 +000061};
62
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063bool
Jim Ingham5a988412012-06-08 21:56:10 +000064CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065{
66 CommandObject::CommandMap::iterator pos;
67 CommandObject *cmd_obj;
Greg Claytonc7bece562013-01-25 18:06:21 +000068 const size_t argc = command.GetArgumentCount ();
Greg Clayton66111032010-06-23 01:19:29 +000069
Enrico Granata08633ee2011-09-09 17:49:36 +000070 // 'help' doesn't take any arguments, other than command names. If argc is 0, we show the user
71 // all commands (aliases and user commands if asked for). Otherwise every argument must be the name of a command or a sub-command.
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072 if (argc == 0)
73 {
Enrico Granata08633ee2011-09-09 17:49:36 +000074 uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin;
75 if (m_options.m_show_aliases)
76 cmd_types |= CommandInterpreter::eCommandTypesAliases;
77 if (m_options.m_show_user_defined)
78 cmd_types |= CommandInterpreter::eCommandTypesUserDef;
Kate Stonea487aa42015-01-15 00:52:41 +000079 if (m_options.m_show_hidden)
80 cmd_types |= CommandInterpreter::eCommandTypesHidden;
Enrico Granata08633ee2011-09-09 17:49:36 +000081
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Enrico Granata08633ee2011-09-09 17:49:36 +000083 m_interpreter.GetHelp (result, cmd_types); // General help
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084 }
85 else
86 {
87 // Get command object for the first command argument. Only search built-in command dictionary.
Jim Ingham279a6c22010-07-06 22:46:59 +000088 StringList matches;
Greg Claytona7015092010-09-18 01:14:36 +000089 cmd_obj = m_interpreter.GetCommandObject (command.GetArgumentAtIndex (0), &matches);
Caroline Ticee7941792010-10-28 23:17:48 +000090 bool is_alias_command = m_interpreter.AliasExists (command.GetArgumentAtIndex (0));
91 std::string alias_name = command.GetArgumentAtIndex(0);
Greg Clayton66111032010-06-23 01:19:29 +000092
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093 if (cmd_obj != NULL)
94 {
Jim Ingham271ad292010-11-30 22:59:37 +000095 StringList matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096 bool all_okay = true;
97 CommandObject *sub_cmd_obj = cmd_obj;
98 // Loop down through sub_command dictionaries until we find the command object that corresponds
99 // to the help command entered.
Andy Gibbsa297a972013-06-19 19:04:53 +0000100 for (size_t i = 1; i < argc && all_okay; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101 {
102 std::string sub_command = command.GetArgumentAtIndex(i);
Jim Ingham271ad292010-11-30 22:59:37 +0000103 matches.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104 if (! sub_cmd_obj->IsMultiwordObject ())
105 {
106 all_okay = false;
107 }
108 else
109 {
Jim Ingham271ad292010-11-30 22:59:37 +0000110 CommandObject *found_cmd;
Greg Clayton998255b2012-10-13 02:07:45 +0000111 found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches);
Jim Ingham271ad292010-11-30 22:59:37 +0000112 if (found_cmd == NULL)
Greg Clayton66111032010-06-23 01:19:29 +0000113 all_okay = false;
Jim Ingham97253e62010-12-01 00:42:17 +0000114 else if (matches.GetSize() > 1)
Jim Ingham271ad292010-11-30 22:59:37 +0000115 all_okay = false;
116 else
117 sub_cmd_obj = found_cmd;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118 }
119 }
Greg Clayton66111032010-06-23 01:19:29 +0000120
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121 if (!all_okay || (sub_cmd_obj == NULL))
122 {
123 std::string cmd_string;
124 command.GetCommandString (cmd_string);
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000125 if (matches.GetSize() >= 2)
Jim Ingham271ad292010-11-30 22:59:37 +0000126 {
127 StreamString s;
128 s.Printf ("ambiguous command %s", cmd_string.c_str());
129 size_t num_matches = matches.GetSize();
130 for (size_t match_idx = 0; match_idx < num_matches; match_idx++)
131 {
132 s.Printf ("\n\t%s", matches.GetStringAtIndex(match_idx));
133 }
134 s.Printf ("\n");
135 result.AppendError(s.GetData());
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000136 result.SetStatus (eReturnStatusFailed);
137 return false;
Jim Ingham271ad292010-11-30 22:59:37 +0000138 }
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000139 else if (!sub_cmd_obj)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140 {
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000141 result.AppendErrorWithFormat("'%s' is not a known command.\n"
Kate Stonea487aa42015-01-15 00:52:41 +0000142 "Try '%shelp' to see a current list of commands.\n",
143 cmd_string.c_str(),
144 m_interpreter.GetCommandPrefix());
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000145 result.SetStatus (eReturnStatusFailed);
146 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 }
148 else
149 {
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000150 result.GetOutputStream().Printf("'%s' is not a known command.\n"
Kate Stonea487aa42015-01-15 00:52:41 +0000151 "Try '%shelp' to see a current list of commands.\n"
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000152 "The closest match is '%s'. Help on it follows.\n\n",
153 cmd_string.c_str(),
Kate Stonea487aa42015-01-15 00:52:41 +0000154 m_interpreter.GetCommandPrefix(),
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000155 sub_cmd_obj->GetCommandName());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156 }
157 }
Caroline Ticee7941792010-10-28 23:17:48 +0000158
Enrico Granata9b62d1d2013-06-12 01:50:57 +0000159 sub_cmd_obj->GenerateHelpText(result);
160
Caroline Ticee7941792010-10-28 23:17:48 +0000161 if (is_alias_command)
162 {
163 StreamString sstr;
164 m_interpreter.GetAliasHelp (alias_name.c_str(), cmd_obj->GetCommandName(), sstr);
165 result.GetOutputStream().Printf ("\n'%s' is an abbreviation for %s\n", alias_name.c_str(), sstr.GetData());
166 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 }
Jim Ingham279a6c22010-07-06 22:46:59 +0000168 else if (matches.GetSize() > 0)
169 {
170 Stream &output_strm = result.GetOutputStream();
171 output_strm.Printf("Help requested with ambiguous command name, possible completions:\n");
Greg Claytonc7bece562013-01-25 18:06:21 +0000172 const size_t match_count = matches.GetSize();
173 for (size_t i = 0; i < match_count; i++)
Jim Ingham279a6c22010-07-06 22:46:59 +0000174 {
175 output_strm.Printf("\t%s\n", matches.GetStringAtIndex(i));
176 }
177 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178 else
179 {
Caroline Ticee139cf22010-10-01 17:46:38 +0000180 // Maybe the user is asking for help about a command argument rather than a command.
181 const CommandArgumentType arg_type = CommandObject::LookupArgumentName (command.GetArgumentAtIndex (0));
182 if (arg_type != eArgTypeLastArg)
183 {
184 Stream &output_strm = result.GetOutputStream ();
185 CommandObject::GetArgumentHelp (output_strm, arg_type, m_interpreter);
186 result.SetStatus (eReturnStatusSuccessFinishNoResult);
187 }
188 else
189 {
190 result.AppendErrorWithFormat
Kate Stonea487aa42015-01-15 00:52:41 +0000191 ("'%s' is not a known command.\nTry '%shelp' to see a current list of commands.\n",
192 command.GetArgumentAtIndex(0),
193 m_interpreter.GetCommandPrefix());
Caroline Ticee139cf22010-10-01 17:46:38 +0000194 result.SetStatus (eReturnStatusFailed);
195 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196 }
197 }
Greg Clayton66111032010-06-23 01:19:29 +0000198
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199 return result.Succeeded();
200}
201
202int
203CommandObjectHelp::HandleCompletion
204(
205 Args &input,
206 int &cursor_index,
207 int &cursor_char_position,
208 int match_start_point,
209 int max_return_elements,
Jim Ingham558ce122010-06-30 05:02:46 +0000210 bool &word_complete,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 StringList &matches
212)
213{
214 // Return the completions of the commands in the help system:
215 if (cursor_index == 0)
216 {
Greg Claytona7015092010-09-18 01:14:36 +0000217 return m_interpreter.HandleCompletionMatches (input,
218 cursor_index,
219 cursor_char_position,
220 match_start_point,
221 max_return_elements,
222 word_complete,
223 matches);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224 }
225 else
226 {
Greg Claytona7015092010-09-18 01:14:36 +0000227 CommandObject *cmd_obj = m_interpreter.GetCommandObject (input.GetArgumentAtIndex(0));
Jim Ingham1d18ebf2011-10-26 19:32:01 +0000228
229 // The command that they are getting help on might be ambiguous, in which case we should complete that,
230 // otherwise complete with the command the user is getting help on...
231
232 if (cmd_obj)
233 {
234 input.Shift();
235 cursor_index--;
236 return cmd_obj->HandleCompletion (input,
237 cursor_index,
238 cursor_char_position,
239 match_start_point,
240 max_return_elements,
241 word_complete,
242 matches);
243 }
244 else
245 {
246 return m_interpreter.HandleCompletionMatches (input,
247 cursor_index,
248 cursor_char_position,
249 match_start_point,
250 max_return_elements,
251 word_complete,
252 matches);
253 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254 }
255}