forked from OSchip/llvm-project
112 lines
4.0 KiB
C++
112 lines
4.0 KiB
C++
//===-- CommandObjectRegexCommand.cpp -------------------------------------===//
|
|
//
|
|
// 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 "CommandObjectRegexCommand.h"
|
|
#include "lldb/Interpreter/CommandInterpreter.h"
|
|
#include "lldb/Interpreter/CommandReturnObject.h"
|
|
|
|
#include "llvm/Support/Errc.h"
|
|
#include "llvm/Support/Error.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
// CommandObjectRegexCommand constructor
|
|
CommandObjectRegexCommand::CommandObjectRegexCommand(
|
|
CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help,
|
|
llvm::StringRef syntax, uint32_t max_matches, uint32_t completion_type_mask,
|
|
bool is_removable)
|
|
: CommandObjectRaw(interpreter, name, help, syntax),
|
|
m_max_matches(max_matches), m_completion_type_mask(completion_type_mask),
|
|
m_is_removable(is_removable) {}
|
|
|
|
// Destructor
|
|
CommandObjectRegexCommand::~CommandObjectRegexCommand() = default;
|
|
|
|
llvm::Expected<std::string> CommandObjectRegexCommand::SubstituteVariables(
|
|
llvm::StringRef input,
|
|
const llvm::SmallVectorImpl<llvm::StringRef> &replacements) {
|
|
std::string buffer;
|
|
llvm::raw_string_ostream output(buffer);
|
|
|
|
llvm::SmallVector<llvm::StringRef, 4> parts;
|
|
input.split(parts, '%');
|
|
|
|
output << parts[0];
|
|
for (llvm::StringRef part : drop_begin(parts)) {
|
|
size_t idx = 0;
|
|
if (part.consumeInteger(10, idx))
|
|
output << '%';
|
|
else if (idx < replacements.size())
|
|
output << replacements[idx];
|
|
else
|
|
return llvm::make_error<llvm::StringError>(
|
|
llvm::formatv("%{0} is out of range: not enough arguments specified",
|
|
idx),
|
|
llvm::errc::invalid_argument);
|
|
output << part;
|
|
}
|
|
|
|
return output.str();
|
|
}
|
|
|
|
bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
|
|
CommandReturnObject &result) {
|
|
EntryCollection::const_iterator pos, end = m_entries.end();
|
|
for (pos = m_entries.begin(); pos != end; ++pos) {
|
|
llvm::SmallVector<llvm::StringRef, 4> matches;
|
|
if (pos->regex.Execute(command, &matches)) {
|
|
llvm::Expected<std::string> new_command =
|
|
SubstituteVariables(pos->command, matches);
|
|
if (!new_command) {
|
|
result.SetError(new_command.takeError());
|
|
return false;
|
|
}
|
|
|
|
// Interpret the new command and return this as the result!
|
|
if (m_interpreter.GetExpandRegexAliases())
|
|
result.GetOutputStream().Printf("%s\n", new_command->c_str());
|
|
// Pass in true for "no context switching". The command that called us
|
|
// should have set up the context appropriately, we shouldn't have to
|
|
// redo that.
|
|
return m_interpreter.HandleCommand(new_command->c_str(),
|
|
eLazyBoolCalculate, result);
|
|
}
|
|
}
|
|
result.SetStatus(eReturnStatusFailed);
|
|
if (!GetSyntax().empty())
|
|
result.AppendError(GetSyntax());
|
|
else
|
|
result.GetErrorStream() << "Command contents '" << command
|
|
<< "' failed to match any "
|
|
"regular expression in the '"
|
|
<< m_cmd_name << "' regex ";
|
|
return false;
|
|
}
|
|
|
|
bool CommandObjectRegexCommand::AddRegexCommand(llvm::StringRef re_cstr,
|
|
llvm::StringRef command_cstr) {
|
|
m_entries.resize(m_entries.size() + 1);
|
|
// Only add the regular expression if it compiles
|
|
m_entries.back().regex = RegularExpression(re_cstr);
|
|
if (m_entries.back().regex.IsValid()) {
|
|
m_entries.back().command = command_cstr.str();
|
|
return true;
|
|
}
|
|
// The regex didn't compile...
|
|
m_entries.pop_back();
|
|
return false;
|
|
}
|
|
|
|
void CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
|
|
if (m_completion_type_mask) {
|
|
CommandCompletions::InvokeCommonCompletionCallbacks(
|
|
GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
|
|
}
|
|
}
|