diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp')
-rw-r--r-- | gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp b/gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp new file mode 100644 index 00000000000..5209a7bcbc4 --- /dev/null +++ b/gnu/llvm/lldb/source/Interpreter/CommandAlias.cpp @@ -0,0 +1,246 @@ +//===-- CommandAlias.cpp -----------------------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Interpreter/CommandAlias.h" + +#include "llvm/Support/ErrorHandling.h" + +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/Options.h" +#include "lldb/Utility/StreamString.h" + +using namespace lldb; +using namespace lldb_private; + +static bool ProcessAliasOptionsArgs(lldb::CommandObjectSP &cmd_obj_sp, + llvm::StringRef options_args, + OptionArgVectorSP &option_arg_vector_sp) { + bool success = true; + OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); + + if (options_args.size() < 1) + return true; + + Args args(options_args); + std::string options_string(options_args); + // TODO: Find a way to propagate errors in this CommandReturnObject up the + // stack. + 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. + ExecutionContext exe_ctx = + cmd_obj_sp->GetCommandInterpreter().GetExecutionContext(); + options->NotifyOptionParsingStarting(&exe_ctx); + + llvm::Expected<Args> args_or = + options->ParseAlias(args, option_arg_vector, options_string); + if (!args_or) { + result.AppendError(toString(args_or.takeError())); + result.AppendError("Unable to create requested alias.\n"); + result.SetStatus(eReturnStatusFailed); + return false; + } + args = std::move(*args_or); + 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->emplace_back("<argument>", -1, options_string); + else { + for (auto &entry : args.entries()) { + if (!entry.ref().empty()) + option_arg_vector->emplace_back(std::string("<argument>"), -1, + std::string(entry.ref())); + } + } + } + + return success; +} + +CommandAlias::CommandAlias(CommandInterpreter &interpreter, + lldb::CommandObjectSP cmd_sp, + llvm::StringRef options_args, llvm::StringRef name, + llvm::StringRef help, llvm::StringRef syntax, + uint32_t flags) + : CommandObject(interpreter, name, help, syntax, flags), + m_underlying_command_sp(), m_option_string(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.empty()) { + StreamString sstr; + StreamString translation_and_help; + GetAliasExpansion(sstr); + + translation_and_help.Printf( + "(%s) %s", sstr.GetData(), + GetUnderlyingCommand()->GetHelp().str().c_str()); + SetHelp(translation_and_help.GetString()); + } + } +} + +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; +} + +void CommandAlias::HandleCompletion(CompletionRequest &request) { + if (IsValid()) + m_underlying_command_sp->HandleCompletion(request); +} + +void CommandAlias::HandleArgumentCompletion( + CompletionRequest &request, OptionElementVector &opt_element_vector) { + if (IsValid()) + m_underlying_command_sp->HandleArgumentCompletion(request, + opt_element_vector); +} + +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 { + llvm::StringRef command_name = m_underlying_command_sp->GetCommandName(); + help_string.Printf("'%*s", (int)command_name.size(), command_name.data()); + + if (!m_option_args_sp) { + help_string.Printf("'"); + return; + } + + OptionArgVector *options = m_option_args_sp.get(); + std::string opt; + std::string value; + + for (const auto &opt_entry : *options) { + std::tie(opt, std::ignore, value) = opt_entry; + if (opt == "<argument>") { + help_string.Printf(" %s", value.c_str()); + } else { + help_string.Printf(" %s", opt.c_str()); + if ((value != "<no-argument>") && (value != "<need-argument")) { + help_string.Printf(" %s", value.c_str()); + } + } + } + + help_string.Printf("'"); +} + +bool CommandAlias::IsDashDashCommand() { + if (m_is_dashdash_alias != eLazyBoolCalculate) + return (m_is_dashdash_alias == eLazyBoolYes); + m_is_dashdash_alias = eLazyBoolNo; + if (!IsValid()) + return false; + + std::string opt; + std::string value; + + for (const auto &opt_entry : *GetOptionArguments()) { + std::tie(opt, std::ignore, value) = opt_entry; + if (opt == "<argument>" && !value.empty() && + llvm::StringRef(value).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(llvm::StringRef str) { + this->CommandObject::SetHelp(str); + m_did_set_help = true; +} + +void CommandAlias::SetHelpLong(llvm::StringRef str) { + this->CommandObject::SetHelpLong(str); + m_did_set_help_long = true; +} + +llvm::StringRef CommandAlias::GetHelp() { + if (!m_cmd_help_short.empty() || m_did_set_help) + return m_cmd_help_short; + if (IsValid()) + return m_underlying_command_sp->GetHelp(); + return llvm::StringRef(); +} + +llvm::StringRef CommandAlias::GetHelpLong() { + if (!m_cmd_help_long.empty() || m_did_set_help_long) + return m_cmd_help_long; + if (IsValid()) + return m_underlying_command_sp->GetHelpLong(); + return llvm::StringRef(); +} |