2010-06-08 16:52:24 +00:00
//===-- CommandObjectHelp.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "CommandObjectHelp.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
# include "lldb/Interpreter/CommandObjectMultiword.h"
# include "lldb/Interpreter/CommandInterpreter.h"
2010-06-15 19:49:27 +00:00
# include "lldb/Interpreter/Options.h"
2010-06-08 16:52:24 +00:00
# include "lldb/Interpreter/CommandReturnObject.h"
using namespace lldb ;
using namespace lldb_private ;
//-------------------------------------------------------------------------
// CommandObjectHelp
//-------------------------------------------------------------------------
2010-09-18 01:14:36 +00:00
CommandObjectHelp : : CommandObjectHelp ( CommandInterpreter & interpreter ) :
2012-06-08 21:56:10 +00:00
CommandObjectParsed ( interpreter ,
" help " ,
" Show a list of all debugger commands, or give details about specific commands. " ,
" help [<cmd-name>] " ) , m_options ( interpreter )
2010-06-08 16:52:24 +00:00
{
2010-10-04 22:28:36 +00:00
CommandArgumentEntry arg ;
CommandArgumentData command_arg ;
// Define the first (and only) variant of this arg.
command_arg . arg_type = eArgTypeCommandName ;
command_arg . arg_repetition = eArgRepeatStar ;
// There is only one variant this argument could be; put it into the argument entry.
arg . push_back ( command_arg ) ;
// Push the data for the first argument into the m_arguments vector.
m_arguments . push_back ( arg ) ;
2010-06-08 16:52:24 +00:00
}
CommandObjectHelp : : ~ CommandObjectHelp ( )
{
}
2011-09-09 17:49:36 +00:00
OptionDefinition
CommandObjectHelp : : CommandOptions : : g_option_table [ ] =
{
2015-01-15 00:52:41 +00:00
{ LLDB_OPT_SET_ALL , false , " hide-aliases " , ' a ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Hide aliases in the command list. " } ,
2014-07-09 16:31:49 +00:00
{ LLDB_OPT_SET_ALL , false , " hide-user-commands " , ' u ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Hide user-defined commands from the list. " } ,
2015-01-15 00:52:41 +00:00
{ LLDB_OPT_SET_ALL , false , " show-hidden-commands " , ' h ' , OptionParser : : eNoArgument , NULL , NULL , 0 , eArgTypeNone , " Include commands prefixed with an underscore. " } ,
2015-01-15 02:07:28 +00:00
{ 0 , false , NULL , 0 , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
2011-09-09 17:49:36 +00:00
} ;
2010-06-08 16:52:24 +00:00
bool
2012-06-08 21:56:10 +00:00
CommandObjectHelp : : DoExecute ( Args & command , CommandReturnObject & result )
2010-06-08 16:52:24 +00:00
{
CommandObject : : CommandMap : : iterator pos ;
CommandObject * cmd_obj ;
2013-01-25 18:06:21 +00:00
const size_t argc = command . GetArgumentCount ( ) ;
2010-06-23 01:19:29 +00:00
2011-09-09 17:49:36 +00:00
// 'help' doesn't take any arguments, other than command names. If argc is 0, we show the user
// all commands (aliases and user commands if asked for). Otherwise every argument must be the name of a command or a sub-command.
2010-06-08 16:52:24 +00:00
if ( argc = = 0 )
{
2011-09-09 17:49:36 +00:00
uint32_t cmd_types = CommandInterpreter : : eCommandTypesBuiltin ;
if ( m_options . m_show_aliases )
cmd_types | = CommandInterpreter : : eCommandTypesAliases ;
if ( m_options . m_show_user_defined )
cmd_types | = CommandInterpreter : : eCommandTypesUserDef ;
2015-01-15 00:52:41 +00:00
if ( m_options . m_show_hidden )
cmd_types | = CommandInterpreter : : eCommandTypesHidden ;
2011-09-09 17:49:36 +00:00
2010-06-08 16:52:24 +00:00
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
2011-09-09 17:49:36 +00:00
m_interpreter . GetHelp ( result , cmd_types ) ; // General help
2010-06-08 16:52:24 +00:00
}
else
{
// Get command object for the first command argument. Only search built-in command dictionary.
2010-07-06 22:46:59 +00:00
StringList matches ;
2010-09-18 01:14:36 +00:00
cmd_obj = m_interpreter . GetCommandObject ( command . GetArgumentAtIndex ( 0 ) , & matches ) ;
2010-10-28 23:17:48 +00:00
bool is_alias_command = m_interpreter . AliasExists ( command . GetArgumentAtIndex ( 0 ) ) ;
std : : string alias_name = command . GetArgumentAtIndex ( 0 ) ;
2010-06-23 01:19:29 +00:00
2010-06-08 16:52:24 +00:00
if ( cmd_obj ! = NULL )
{
2010-11-30 22:59:37 +00:00
StringList matches ;
2010-06-08 16:52:24 +00:00
bool all_okay = true ;
CommandObject * sub_cmd_obj = cmd_obj ;
// Loop down through sub_command dictionaries until we find the command object that corresponds
// to the help command entered.
2013-06-19 19:04:53 +00:00
for ( size_t i = 1 ; i < argc & & all_okay ; + + i )
2010-06-08 16:52:24 +00:00
{
std : : string sub_command = command . GetArgumentAtIndex ( i ) ;
2010-11-30 22:59:37 +00:00
matches . Clear ( ) ;
2010-06-08 16:52:24 +00:00
if ( ! sub_cmd_obj - > IsMultiwordObject ( ) )
{
all_okay = false ;
}
else
{
2010-11-30 22:59:37 +00:00
CommandObject * found_cmd ;
2012-10-13 02:07:45 +00:00
found_cmd = sub_cmd_obj - > GetSubcommandObject ( sub_command . c_str ( ) , & matches ) ;
2010-11-30 22:59:37 +00:00
if ( found_cmd = = NULL )
2010-06-23 01:19:29 +00:00
all_okay = false ;
2010-12-01 00:42:17 +00:00
else if ( matches . GetSize ( ) > 1 )
2010-11-30 22:59:37 +00:00
all_okay = false ;
else
sub_cmd_obj = found_cmd ;
2010-06-08 16:52:24 +00:00
}
}
2010-06-23 01:19:29 +00:00
2010-06-08 16:52:24 +00:00
if ( ! all_okay | | ( sub_cmd_obj = = NULL ) )
{
std : : string cmd_string ;
command . GetCommandString ( cmd_string ) ;
2013-06-12 01:50:57 +00:00
if ( matches . GetSize ( ) > = 2 )
2010-11-30 22:59:37 +00:00
{
StreamString s ;
s . Printf ( " ambiguous command %s " , cmd_string . c_str ( ) ) ;
size_t num_matches = matches . GetSize ( ) ;
for ( size_t match_idx = 0 ; match_idx < num_matches ; match_idx + + )
{
s . Printf ( " \n \t %s " , matches . GetStringAtIndex ( match_idx ) ) ;
}
s . Printf ( " \n " ) ;
result . AppendError ( s . GetData ( ) ) ;
2013-06-12 01:50:57 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-11-30 22:59:37 +00:00
}
2013-06-12 01:50:57 +00:00
else if ( ! sub_cmd_obj )
2010-06-08 16:52:24 +00:00
{
2013-06-12 01:50:57 +00:00
result . AppendErrorWithFormat ( " '%s' is not a known command. \n "
2015-01-15 00:52:41 +00:00
" Try '%shelp' to see a current list of commands. \n " ,
cmd_string . c_str ( ) ,
m_interpreter . GetCommandPrefix ( ) ) ;
2013-06-12 01:50:57 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
2010-06-08 16:52:24 +00:00
}
else
{
2013-06-12 01:50:57 +00:00
result . GetOutputStream ( ) . Printf ( " '%s' is not a known command. \n "
2015-01-15 00:52:41 +00:00
" Try '%shelp' to see a current list of commands. \n "
2013-06-12 01:50:57 +00:00
" The closest match is '%s'. Help on it follows. \n \n " ,
cmd_string . c_str ( ) ,
2015-01-15 00:52:41 +00:00
m_interpreter . GetCommandPrefix ( ) ,
2013-06-12 01:50:57 +00:00
sub_cmd_obj - > GetCommandName ( ) ) ;
2010-06-08 16:52:24 +00:00
}
}
2010-10-28 23:17:48 +00:00
2013-06-12 01:50:57 +00:00
sub_cmd_obj - > GenerateHelpText ( result ) ;
2010-10-28 23:17:48 +00:00
if ( is_alias_command )
{
StreamString sstr ;
m_interpreter . GetAliasHelp ( alias_name . c_str ( ) , cmd_obj - > GetCommandName ( ) , sstr ) ;
result . GetOutputStream ( ) . Printf ( " \n '%s' is an abbreviation for %s \n " , alias_name . c_str ( ) , sstr . GetData ( ) ) ;
}
2010-06-08 16:52:24 +00:00
}
2010-07-06 22:46:59 +00:00
else if ( matches . GetSize ( ) > 0 )
{
Stream & output_strm = result . GetOutputStream ( ) ;
output_strm . Printf ( " Help requested with ambiguous command name, possible completions: \n " ) ;
2013-01-25 18:06:21 +00:00
const size_t match_count = matches . GetSize ( ) ;
for ( size_t i = 0 ; i < match_count ; i + + )
2010-07-06 22:46:59 +00:00
{
output_strm . Printf ( " \t %s \n " , matches . GetStringAtIndex ( i ) ) ;
}
}
2010-06-08 16:52:24 +00:00
else
{
2010-10-01 17:46:38 +00:00
// Maybe the user is asking for help about a command argument rather than a command.
const CommandArgumentType arg_type = CommandObject : : LookupArgumentName ( command . GetArgumentAtIndex ( 0 ) ) ;
if ( arg_type ! = eArgTypeLastArg )
{
Stream & output_strm = result . GetOutputStream ( ) ;
CommandObject : : GetArgumentHelp ( output_strm , arg_type , m_interpreter ) ;
result . SetStatus ( eReturnStatusSuccessFinishNoResult ) ;
}
else
{
result . AppendErrorWithFormat
2015-01-15 00:52:41 +00:00
( " '%s' is not a known command. \n Try '%shelp' to see a current list of commands. \n " ,
command . GetArgumentAtIndex ( 0 ) ,
m_interpreter . GetCommandPrefix ( ) ) ;
2010-10-01 17:46:38 +00:00
result . SetStatus ( eReturnStatusFailed ) ;
}
2010-06-08 16:52:24 +00:00
}
}
2010-06-23 01:19:29 +00:00
2010-06-08 16:52:24 +00:00
return result . Succeeded ( ) ;
}
int
CommandObjectHelp : : HandleCompletion
(
Args & input ,
int & cursor_index ,
int & cursor_char_position ,
int match_start_point ,
int max_return_elements ,
2010-06-30 05:02:46 +00:00
bool & word_complete ,
2010-06-08 16:52:24 +00:00
StringList & matches
)
{
// Return the completions of the commands in the help system:
if ( cursor_index = = 0 )
{
2010-09-18 01:14:36 +00:00
return m_interpreter . HandleCompletionMatches ( input ,
cursor_index ,
cursor_char_position ,
match_start_point ,
max_return_elements ,
word_complete ,
matches ) ;
2010-06-08 16:52:24 +00:00
}
else
{
2010-09-18 01:14:36 +00:00
CommandObject * cmd_obj = m_interpreter . GetCommandObject ( input . GetArgumentAtIndex ( 0 ) ) ;
2011-10-26 19:32:01 +00:00
// The command that they are getting help on might be ambiguous, in which case we should complete that,
// otherwise complete with the command the user is getting help on...
if ( cmd_obj )
{
input . Shift ( ) ;
cursor_index - - ;
return cmd_obj - > HandleCompletion ( input ,
cursor_index ,
cursor_char_position ,
match_start_point ,
max_return_elements ,
word_complete ,
matches ) ;
}
else
{
return m_interpreter . HandleCompletionMatches ( input ,
cursor_index ,
cursor_char_position ,
match_start_point ,
max_return_elements ,
word_complete ,
matches ) ;
}
2010-06-08 16:52:24 +00:00
}
}