1 //===-- CommandObjectMultiword.cpp ------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
12 #include "lldb/Interpreter/CommandObjectMultiword.h"
15 // Other libraries and framework includes
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Interpreter/Options.h"
20 #include "lldb/Interpreter/CommandReturnObject.h"
23 using namespace lldb_private;
25 //-------------------------------------------------------------------------
26 // CommandObjectMultiword
27 //-------------------------------------------------------------------------
29 CommandObjectMultiword::CommandObjectMultiword
31 CommandInterpreter &interpreter,
37 CommandObject (interpreter, name, help, syntax, flags),
38 m_can_be_removed(false)
42 CommandObjectMultiword::~CommandObjectMultiword ()
47 CommandObjectMultiword::GetSubcommandSP (const char *sub_cmd, StringList *matches)
49 CommandObjectSP return_cmd_sp;
50 CommandObject::CommandMap::iterator pos;
52 if (!m_subcommand_dict.empty())
54 pos = m_subcommand_dict.find (sub_cmd);
55 if (pos != m_subcommand_dict.end()) {
56 // An exact match; append the sub_cmd to the 'matches' string list.
58 matches->AppendString(sub_cmd);
59 return_cmd_sp = pos->second;
64 StringList local_matches;
66 matches = &local_matches;
67 int num_matches = CommandObject::AddNamesMatchingPartialString (m_subcommand_dict, sub_cmd, *matches);
71 // Cleaner, but slightly less efficient would be to call back into this function, since I now
72 // know I have an exact match...
74 sub_cmd = matches->GetStringAtIndex(0);
75 pos = m_subcommand_dict.find(sub_cmd);
76 if (pos != m_subcommand_dict.end())
77 return_cmd_sp = pos->second;
85 CommandObjectMultiword::GetSubcommandObject (const char *sub_cmd, StringList *matches)
87 return GetSubcommandSP(sub_cmd, matches).get();
91 CommandObjectMultiword::LoadSubCommand
94 const CommandObjectSP& cmd_obj
97 CommandMap::iterator pos;
100 pos = m_subcommand_dict.find(name);
101 if (pos == m_subcommand_dict.end())
103 m_subcommand_dict[name] = cmd_obj;
112 CommandObjectMultiword::Execute(const char *args_string, CommandReturnObject &result)
114 Args args (args_string);
115 const size_t argc = args.GetArgumentCount();
118 this->CommandObject::GenerateHelpText (result);
122 const char *sub_command = args.GetArgumentAtIndex (0);
126 if (::strcasecmp (sub_command, "help") == 0)
128 this->CommandObject::GenerateHelpText (result);
130 else if (!m_subcommand_dict.empty())
133 CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
134 if (sub_cmd_obj != NULL)
136 // Now call CommandObject::Execute to process and options in 'rest_of_line'. From there
137 // the command-specific version of Execute will be called, with the processed arguments.
141 sub_cmd_obj->Execute (args_string, result);
145 std::string error_msg;
146 const size_t num_subcmd_matches = matches.GetSize();
147 if (num_subcmd_matches > 0)
148 error_msg.assign ("ambiguous command ");
150 error_msg.assign ("invalid command ");
152 error_msg.append ("'");
153 error_msg.append (GetCommandName());
154 error_msg.append (" ");
155 error_msg.append (sub_command);
156 error_msg.append ("'");
158 if (num_subcmd_matches > 0)
160 error_msg.append (" Possible completions:");
161 for (size_t i = 0; i < num_subcmd_matches; i++)
163 error_msg.append ("\n\t");
164 error_msg.append (matches.GetStringAtIndex (i));
167 error_msg.append ("\n");
168 result.AppendRawError (error_msg.c_str());
169 result.SetStatus (eReturnStatusFailed);
174 result.AppendErrorWithFormat ("'%s' does not have any subcommands.\n", GetCommandName());
175 result.SetStatus (eReturnStatusFailed);
180 return result.Succeeded();
184 CommandObjectMultiword::GenerateHelpText (Stream &output_stream)
186 // First time through here, generate the help text for the object and
187 // push it to the return result object as well
189 output_stream.PutCString ("The following subcommands are supported:\n\n");
191 CommandMap::iterator pos;
192 uint32_t max_len = m_interpreter.FindLongestCommandWord (m_subcommand_dict);
195 max_len += 4; // Indent the output by 4 spaces.
197 for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos)
199 std::string indented_command (" ");
200 indented_command.append (pos->first);
201 if (pos->second->WantsRawCommandString ())
203 std::string help_text (pos->second->GetHelp());
204 help_text.append (" This command takes 'raw' input (no need to quote stuff).");
205 m_interpreter.OutputFormattedHelpText (output_stream,
206 indented_command.c_str(),
212 m_interpreter.OutputFormattedHelpText (output_stream,
213 indented_command.c_str(),
215 pos->second->GetHelp(),
219 output_stream.PutCString ("\nFor more help on any particular subcommand, type 'help <command> <subcommand>'.\n");
223 CommandObjectMultiword::HandleCompletion
227 int &cursor_char_position,
228 int match_start_point,
229 int max_return_elements,
234 // Any of the command matches will provide a complete word, otherwise the individual
235 // completers will override this.
236 word_complete = true;
238 if (cursor_index == 0)
240 CommandObject::AddNamesMatchingPartialString (m_subcommand_dict,
241 input.GetArgumentAtIndex(0),
244 if (matches.GetSize() == 1
245 && matches.GetStringAtIndex(0) != NULL
246 && strcmp (input.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0)
248 StringList temp_matches;
249 CommandObject *cmd_obj = GetSubcommandObject (input.GetArgumentAtIndex(0),
253 matches.DeleteStringAtIndex (0);
255 cursor_char_position = 0;
256 input.AppendArgument ("");
257 return cmd_obj->HandleCompletion (input,
259 cursor_char_position,
266 return matches.GetSize();
269 return matches.GetSize();
273 CommandObject *sub_command_object = GetSubcommandObject (input.GetArgumentAtIndex(0),
275 if (sub_command_object == NULL)
277 return matches.GetSize();
281 // Remove the one match that we got from calling GetSubcommandObject.
282 matches.DeleteStringAtIndex(0);
285 return sub_command_object->HandleCompletion (input,
287 cursor_char_position,
298 CommandObjectMultiword::GetRepeatCommand (Args ¤t_command_args, uint32_t index)
301 if (current_command_args.GetArgumentCount() <= index)
303 CommandObject *sub_command_object = GetSubcommandObject (current_command_args.GetArgumentAtIndex(index));
304 if (sub_command_object == NULL)
306 return sub_command_object->GetRepeatCommand(current_command_args, index);
311 CommandObjectMultiword::AproposAllSubCommands (const char *prefix,
312 const char *search_word,
313 StringList &commands_found,
314 StringList &commands_help)
316 CommandObject::CommandMap::const_iterator pos;
318 for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos)
320 const char * command_name = pos->first.c_str();
321 CommandObject *sub_cmd_obj = pos->second.get();
322 StreamString complete_command_name;
324 complete_command_name.Printf ("%s %s", prefix, command_name);
326 if (sub_cmd_obj->HelpTextContainsWord (search_word))
328 commands_found.AppendString (complete_command_name.GetData());
329 commands_help.AppendString (sub_cmd_obj->GetHelp());
332 if (sub_cmd_obj->IsMultiwordObject())
333 sub_cmd_obj->AproposAllSubCommands (complete_command_name.GetData(),
342 CommandObjectProxy::CommandObjectProxy (CommandInterpreter &interpreter,
347 CommandObject (interpreter, name, help, syntax, flags)
351 CommandObjectProxy::~CommandObjectProxy ()
356 CommandObjectProxy::GetHelpLong ()
358 CommandObject *proxy_command = GetProxyCommandObject();
360 return proxy_command->GetHelpLong();
365 CommandObjectProxy::IsRemovable() const
367 const CommandObject *proxy_command = const_cast<CommandObjectProxy *>(this)->GetProxyCommandObject();
369 return proxy_command->IsRemovable();
374 CommandObjectProxy::IsMultiwordObject ()
376 CommandObject *proxy_command = GetProxyCommandObject();
378 return proxy_command->IsMultiwordObject();
382 lldb::CommandObjectSP
383 CommandObjectProxy::GetSubcommandSP (const char *sub_cmd, StringList *matches)
385 CommandObject *proxy_command = GetProxyCommandObject();
387 return proxy_command->GetSubcommandSP(sub_cmd, matches);
388 return lldb::CommandObjectSP();
392 CommandObjectProxy::GetSubcommandObject (const char *sub_cmd, StringList *matches)
394 CommandObject *proxy_command = GetProxyCommandObject();
396 return proxy_command->GetSubcommandObject(sub_cmd, matches);
401 CommandObjectProxy::AproposAllSubCommands (const char *prefix,
402 const char *search_word,
403 StringList &commands_found,
404 StringList &commands_help)
406 CommandObject *proxy_command = GetProxyCommandObject();
408 return proxy_command->AproposAllSubCommands (prefix,
415 CommandObjectProxy::LoadSubCommand (const char *cmd_name,
416 const lldb::CommandObjectSP& command_sp)
418 CommandObject *proxy_command = GetProxyCommandObject();
420 return proxy_command->LoadSubCommand (cmd_name, command_sp);
425 CommandObjectProxy::WantsRawCommandString()
427 CommandObject *proxy_command = GetProxyCommandObject();
429 return proxy_command->WantsRawCommandString();
434 CommandObjectProxy::WantsCompletion()
436 CommandObject *proxy_command = GetProxyCommandObject();
438 return proxy_command->WantsCompletion();
444 CommandObjectProxy::GetOptions ()
446 CommandObject *proxy_command = GetProxyCommandObject();
448 return proxy_command->GetOptions ();
454 CommandObjectProxy::HandleCompletion (Args &input,
456 int &cursor_char_position,
457 int match_start_point,
458 int max_return_elements,
462 CommandObject *proxy_command = GetProxyCommandObject();
464 return proxy_command->HandleCompletion (input,
466 cursor_char_position,
475 CommandObjectProxy::HandleArgumentCompletion (Args &input,
477 int &cursor_char_position,
478 OptionElementVector &opt_element_vector,
479 int match_start_point,
480 int max_return_elements,
484 CommandObject *proxy_command = GetProxyCommandObject();
486 return proxy_command->HandleArgumentCompletion (input,
488 cursor_char_position,
499 CommandObjectProxy::GetRepeatCommand (Args ¤t_command_args,
502 CommandObject *proxy_command = GetProxyCommandObject();
504 return proxy_command->GetRepeatCommand (current_command_args, index);
509 CommandObjectProxy::Execute (const char *args_string,
510 CommandReturnObject &result)
512 CommandObject *proxy_command = GetProxyCommandObject();
514 return proxy_command->Execute (args_string, result);
515 result.AppendError ("command is not implemented");
516 result.SetStatus (eReturnStatusFailed);