llvm-project/lldb/source/Commands/CommandObjectHelp.cpp
Caroline Tice 3df9a8dfd7 This is a very large commit that completely re-does the way lldb
handles user settable internal variables (the equivalent of set/show
variables in gdb).  In addition to the basic infrastructure (most of
which is defined in UserSettingsController.{h,cpp}, there are examples
of two classes that have been set up to contain user settable
variables (the Debugger and Process classes).  The 'settings' command
has been modified to be a command-subcommand structure, and the 'set',
'show' and 'append' commands have been moved into this sub-commabnd
structure.  The old StateVariable class has been completely replaced
by this, and the state variable dictionary has been removed from the
Command Interpreter.  Places that formerly accessed the state variable
mechanism have been modified to access the variables in this new
structure instead (checking the term-width; getting/checking the
prompt; etc.)

Variables are attached to classes; there are two basic "flavors" of
variables that can be set: "global" variables (static/class-wide), and
"instance" variables (one per instance of the class).  The whole thing
has been set up so that any global or instance variable can be set at
any time (e.g. on start up, in your .lldbinit file), whether or not
any instances actually exist (there's a whole pending and default
values mechanism to help deal with that).

llvm-svn: 113041
2010-09-04 00:03:46 +00:00

172 lines
6.5 KiB
C++

//===-- 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"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandReturnObject.h"
using namespace lldb;
using namespace lldb_private;
//-------------------------------------------------------------------------
// CommandObjectHelp
//-------------------------------------------------------------------------
CommandObjectHelp::CommandObjectHelp () :
CommandObject ("help",
"Shows a list of all debugger commands, or give details about specific commands.",
"help [<cmd-name>]")
{
}
CommandObjectHelp::~CommandObjectHelp()
{
}
bool
CommandObjectHelp::Execute (CommandInterpreter &interpreter, Args& command, CommandReturnObject &result)
{
CommandObject::CommandMap::iterator pos;
CommandObject *cmd_obj;
const int argc = command.GetArgumentCount ();
// 'help' doesn't take any options or arguments, other than command names. If argc is 0, we show the user
// all commands and aliases. Otherwise every argument must be the name of a command or a sub-command.
if (argc == 0)
{
result.SetStatus (eReturnStatusSuccessFinishNoResult);
interpreter.GetHelp (result); // General help, for ALL commands.
}
else
{
// Get command object for the first command argument. Only search built-in command dictionary.
StringList matches;
cmd_obj = interpreter.GetCommandObject (command.GetArgumentAtIndex (0), &matches);
if (cmd_obj != NULL)
{
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.
for (int i = 1; i < argc && all_okay; ++i)
{
std::string sub_command = command.GetArgumentAtIndex(i);
if (! sub_cmd_obj->IsMultiwordObject ())
{
all_okay = false;
}
else
{
pos = ((CommandObjectMultiword *) sub_cmd_obj)->m_subcommand_dict.find (sub_command);
if (pos != ((CommandObjectMultiword *) sub_cmd_obj)->m_subcommand_dict.end())
sub_cmd_obj = pos->second.get();
else
all_okay = false;
}
}
if (!all_okay || (sub_cmd_obj == NULL))
{
std::string cmd_string;
command.GetCommandString (cmd_string);
result.AppendErrorWithFormat
("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
cmd_string.c_str());
result.SetStatus (eReturnStatusFailed);
}
else
{
Stream &output_strm = result.GetOutputStream();
if (sub_cmd_obj->GetOptions() != NULL)
{
interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1);
output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax());
sub_cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, sub_cmd_obj);
const char *long_help = sub_cmd_obj->GetHelpLong();
if ((long_help != NULL)
&& (strlen (long_help) > 0))
output_strm.Printf ("\n%s", long_help);
}
else if (sub_cmd_obj->IsMultiwordObject())
{
interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1);
((CommandObjectMultiword *) sub_cmd_obj)->GenerateHelpText (interpreter, result);
}
else
{
const char *long_help = sub_cmd_obj->GetHelpLong();
if ((long_help != NULL)
&& (strlen (long_help) > 0))
interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelpLong(), 1);
else
interpreter.OutputFormattedHelpText (output_strm, "", "", sub_cmd_obj->GetHelp(), 1);
output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax());
}
}
}
else if (matches.GetSize() > 0)
{
Stream &output_strm = result.GetOutputStream();
output_strm.Printf("Help requested with ambiguous command name, possible completions:\n");
const uint32_t match_count = matches.GetSize();
for (uint32_t i = 0; i < match_count; i++)
{
output_strm.Printf("\t%s\n", matches.GetStringAtIndex(i));
}
}
else
{
result.AppendErrorWithFormat
("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
command.GetArgumentAtIndex(0));
result.SetStatus (eReturnStatusFailed);
}
}
return result.Succeeded();
}
int
CommandObjectHelp::HandleCompletion
(
CommandInterpreter &interpreter,
Args &input,
int &cursor_index,
int &cursor_char_position,
int match_start_point,
int max_return_elements,
bool &word_complete,
StringList &matches
)
{
// Return the completions of the commands in the help system:
if (cursor_index == 0)
{
return interpreter.HandleCompletionMatches(input, cursor_index, cursor_char_position, match_start_point,
max_return_elements, word_complete, matches);
}
else
{
CommandObject *cmd_obj = interpreter.GetCommandObject (input.GetArgumentAtIndex(0));
input.Shift();
cursor_index--;
return cmd_obj->HandleCompletion (interpreter, input, cursor_index, cursor_char_position, match_start_point,
max_return_elements, word_complete, matches);
}
}