forked from OSchip/llvm-project
308 lines
9.9 KiB
C++
308 lines
9.9 KiB
C++
//===-- CommandAlias.cpp ------------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Interpreter/CommandAlias.h"
|
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "lldb/Core/StreamString.h"
|
|
#include "lldb/Interpreter/CommandObject.h"
|
|
#include "lldb/Interpreter/CommandReturnObject.h"
|
|
#include "lldb/Interpreter/Options.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
static bool
|
|
ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp,
|
|
const char *options_args,
|
|
OptionArgVectorSP &option_arg_vector_sp)
|
|
{
|
|
bool success = true;
|
|
OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
|
|
|
|
if (!options_args || (strlen (options_args) < 1))
|
|
return true;
|
|
|
|
std::string options_string (options_args);
|
|
Args args (options_args);
|
|
CommandReturnObject result;
|
|
// Check to see if the command being aliased can take any command options.
|
|
Options *options = cmd_obj_sp->GetOptions ();
|
|
if (options)
|
|
{
|
|
// See if any options were specified as part of the alias; if so, handle them appropriately.
|
|
options->NotifyOptionParsingStarting ();
|
|
args.Unshift ("dummy_arg");
|
|
args.ParseAliasOptions (*options, result, option_arg_vector, options_string);
|
|
args.Shift ();
|
|
if (result.Succeeded())
|
|
options->VerifyPartialOptions (result);
|
|
if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
|
|
{
|
|
result.AppendError ("Unable to create requested alias.\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!options_string.empty())
|
|
{
|
|
if (cmd_obj_sp->WantsRawCommandString ())
|
|
option_arg_vector->push_back (OptionArgPair ("<argument>",
|
|
OptionArgValue (-1,
|
|
options_string)));
|
|
else
|
|
{
|
|
const size_t argc = args.GetArgumentCount();
|
|
for (size_t i = 0; i < argc; ++i)
|
|
if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
|
|
option_arg_vector->push_back
|
|
(OptionArgPair ("<argument>",
|
|
OptionArgValue (-1,
|
|
std::string (args.GetArgumentAtIndex (i)))));
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
CommandAlias::CommandAlias (CommandInterpreter &interpreter,
|
|
lldb::CommandObjectSP cmd_sp,
|
|
const char *options_args,
|
|
const char *name,
|
|
const char *help,
|
|
const char *syntax,
|
|
uint32_t flags) :
|
|
CommandObject(interpreter,
|
|
name,
|
|
help,
|
|
syntax,
|
|
flags),
|
|
m_underlying_command_sp(),
|
|
m_option_string(options_args ? options_args : ""),
|
|
m_option_args_sp(new OptionArgVector),
|
|
m_is_dashdash_alias(eLazyBoolCalculate),
|
|
m_did_set_help(false),
|
|
m_did_set_help_long(false)
|
|
{
|
|
if (ProcessAliasOptionsArgs(cmd_sp, options_args, m_option_args_sp))
|
|
{
|
|
m_underlying_command_sp = cmd_sp;
|
|
for (int i = 0;
|
|
auto cmd_entry = m_underlying_command_sp->GetArgumentEntryAtIndex(i);
|
|
i++)
|
|
{
|
|
m_arguments.push_back(*cmd_entry);
|
|
}
|
|
if (!help || !help[0])
|
|
{
|
|
StreamString sstr;
|
|
StreamString translation_and_help;
|
|
GetAliasExpansion(sstr);
|
|
|
|
translation_and_help.Printf ("(%s) %s", sstr.GetData(), GetUnderlyingCommand()->GetHelp());
|
|
SetHelp(translation_and_help.GetData());
|
|
}
|
|
}
|
|
}
|
|
|
|
bool
|
|
CommandAlias::WantsRawCommandString()
|
|
{
|
|
if (IsValid())
|
|
return m_underlying_command_sp->WantsRawCommandString();
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
CommandAlias::WantsCompletion()
|
|
{
|
|
if (IsValid())
|
|
return m_underlying_command_sp->WantsCompletion();
|
|
return false;
|
|
}
|
|
|
|
int
|
|
CommandAlias::HandleCompletion (Args &input,
|
|
int &cursor_index,
|
|
int &cursor_char_position,
|
|
int match_start_point,
|
|
int max_return_elements,
|
|
bool &word_complete,
|
|
StringList &matches)
|
|
{
|
|
if (IsValid())
|
|
return m_underlying_command_sp->HandleCompletion(input,
|
|
cursor_index,
|
|
cursor_char_position,
|
|
match_start_point,
|
|
max_return_elements,
|
|
word_complete,
|
|
matches);
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
CommandAlias::HandleArgumentCompletion (Args &input,
|
|
int &cursor_index,
|
|
int &cursor_char_position,
|
|
OptionElementVector &opt_element_vector,
|
|
int match_start_point,
|
|
int max_return_elements,
|
|
bool &word_complete,
|
|
StringList &matches)
|
|
{
|
|
if (IsValid())
|
|
return m_underlying_command_sp->HandleArgumentCompletion(input,
|
|
cursor_index,
|
|
cursor_char_position,
|
|
opt_element_vector,
|
|
match_start_point,
|
|
max_return_elements,
|
|
word_complete,
|
|
matches);
|
|
return -1;
|
|
}
|
|
|
|
Options*
|
|
CommandAlias::GetOptions()
|
|
{
|
|
if (IsValid())
|
|
return m_underlying_command_sp->GetOptions();
|
|
return nullptr;
|
|
}
|
|
|
|
bool
|
|
CommandAlias::Execute(const char *args_string, CommandReturnObject &result)
|
|
{
|
|
llvm_unreachable("CommandAlias::Execute is not to be called");
|
|
}
|
|
|
|
void
|
|
CommandAlias::GetAliasExpansion (StreamString &help_string)
|
|
{
|
|
const char* command_name = m_underlying_command_sp->GetCommandName();
|
|
help_string.Printf ("'%s", command_name);
|
|
|
|
if (m_option_args_sp)
|
|
{
|
|
OptionArgVector *options = m_option_args_sp.get();
|
|
for (size_t i = 0; i < options->size(); ++i)
|
|
{
|
|
OptionArgPair cur_option = (*options)[i];
|
|
std::string opt = cur_option.first;
|
|
OptionArgValue value_pair = cur_option.second;
|
|
std::string value = value_pair.second;
|
|
if (opt.compare("<argument>") == 0)
|
|
{
|
|
help_string.Printf (" %s", value.c_str());
|
|
}
|
|
else
|
|
{
|
|
help_string.Printf (" %s", opt.c_str());
|
|
if ((value.compare ("<no-argument>") != 0)
|
|
&& (value.compare ("<need-argument") != 0))
|
|
{
|
|
help_string.Printf (" %s", value.c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
help_string.Printf ("'");
|
|
}
|
|
|
|
bool
|
|
CommandAlias::IsDashDashCommand ()
|
|
{
|
|
if (m_is_dashdash_alias == eLazyBoolCalculate)
|
|
{
|
|
m_is_dashdash_alias = eLazyBoolNo;
|
|
if (IsValid())
|
|
{
|
|
for (const OptionArgPair& opt_arg : *GetOptionArguments())
|
|
{
|
|
if (opt_arg.first == "<argument>" &&
|
|
!opt_arg.second.second.empty() &&
|
|
llvm::StringRef(opt_arg.second.second).endswith("--"))
|
|
{
|
|
m_is_dashdash_alias = eLazyBoolYes;
|
|
break;
|
|
}
|
|
}
|
|
// if this is a nested alias, it may be adding arguments on top of an already dash-dash alias
|
|
if ((m_is_dashdash_alias == eLazyBoolNo) && IsNestedAlias())
|
|
m_is_dashdash_alias = (GetUnderlyingCommand()->IsDashDashCommand() ? eLazyBoolYes : eLazyBoolNo);
|
|
}
|
|
}
|
|
return (m_is_dashdash_alias == eLazyBoolYes);
|
|
}
|
|
|
|
bool
|
|
CommandAlias::IsNestedAlias ()
|
|
{
|
|
if (GetUnderlyingCommand())
|
|
return GetUnderlyingCommand()->IsAlias();
|
|
return false;
|
|
}
|
|
|
|
std::pair<lldb::CommandObjectSP, OptionArgVectorSP>
|
|
CommandAlias::Desugar ()
|
|
{
|
|
auto underlying = GetUnderlyingCommand();
|
|
if (!underlying)
|
|
return {nullptr,nullptr};
|
|
|
|
if (underlying->IsAlias())
|
|
{
|
|
auto desugared = ((CommandAlias*)underlying.get())->Desugar();
|
|
auto options = GetOptionArguments();
|
|
options->insert(options->begin(), desugared.second->begin(), desugared.second->end());
|
|
return {desugared.first,options};
|
|
}
|
|
|
|
return {underlying,GetOptionArguments()};
|
|
}
|
|
|
|
// allow CommandAlias objects to provide their own help, but fallback to the info
|
|
// for the underlying command if no customization has been provided
|
|
void
|
|
CommandAlias::SetHelp (const char * str)
|
|
{
|
|
this->CommandObject::SetHelp(str);
|
|
m_did_set_help = true;
|
|
}
|
|
|
|
void
|
|
CommandAlias::SetHelpLong (const char * str)
|
|
{
|
|
this->CommandObject::SetHelpLong(str);
|
|
m_did_set_help_long = true;
|
|
}
|
|
|
|
const char*
|
|
CommandAlias::GetHelp ()
|
|
{
|
|
if (!m_cmd_help_short.empty() || m_did_set_help)
|
|
return m_cmd_help_short.c_str();
|
|
if (IsValid())
|
|
return m_underlying_command_sp->GetHelp();
|
|
return nullptr;
|
|
}
|
|
|
|
const char*
|
|
CommandAlias::GetHelpLong ()
|
|
{
|
|
if (!m_cmd_help_long.empty() || m_did_set_help_long)
|
|
return m_cmd_help_long.c_str();
|
|
if (IsValid())
|
|
return m_underlying_command_sp->GetHelpLong();
|
|
return nullptr;
|
|
}
|