Path: blob/main/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp
39587 views
//===-- CommandObjectRegexCommand.cpp -------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "CommandObjectRegexCommand.h"9#include "lldb/Interpreter/CommandInterpreter.h"10#include "lldb/Interpreter/CommandReturnObject.h"1112#include "llvm/Support/Errc.h"13#include "llvm/Support/Error.h"1415using namespace lldb;16using namespace lldb_private;1718// CommandObjectRegexCommand constructor19CommandObjectRegexCommand::CommandObjectRegexCommand(20CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help,21llvm::StringRef syntax, uint32_t completion_type_mask, bool is_removable)22: CommandObjectRaw(interpreter, name, help, syntax),23m_completion_type_mask(completion_type_mask),24m_is_removable(is_removable) {}2526// Destructor27CommandObjectRegexCommand::~CommandObjectRegexCommand() = default;2829llvm::Expected<std::string> CommandObjectRegexCommand::SubstituteVariables(30llvm::StringRef input,31const llvm::SmallVectorImpl<llvm::StringRef> &replacements) {32std::string buffer;33llvm::raw_string_ostream output(buffer);3435llvm::SmallVector<llvm::StringRef, 4> parts;36input.split(parts, '%');3738output << parts[0];39for (llvm::StringRef part : drop_begin(parts)) {40size_t idx = 0;41if (part.consumeInteger(10, idx))42output << '%';43else if (idx < replacements.size())44output << replacements[idx];45else46return llvm::make_error<llvm::StringError>(47llvm::formatv("%{0} is out of range: not enough arguments specified",48idx),49llvm::errc::invalid_argument);50output << part;51}5253return output.str();54}5556void CommandObjectRegexCommand::DoExecute(llvm::StringRef command,57CommandReturnObject &result) {58EntryCollection::const_iterator pos, end = m_entries.end();59for (pos = m_entries.begin(); pos != end; ++pos) {60llvm::SmallVector<llvm::StringRef, 4> matches;61if (pos->regex.Execute(command, &matches)) {62llvm::Expected<std::string> new_command =63SubstituteVariables(pos->command, matches);64if (!new_command) {65result.SetError(new_command.takeError());66return;67}6869// Interpret the new command and return this as the result!70if (m_interpreter.GetExpandRegexAliases())71result.GetOutputStream().Printf("%s\n", new_command->c_str());72// We don't have to pass an override_context here, as the command that73// called us should have set up the context appropriately.74bool force_repeat_command = true;75m_interpreter.HandleCommand(new_command->c_str(), eLazyBoolNo, result,76force_repeat_command);77return;78}79}80result.SetStatus(eReturnStatusFailed);81if (!GetSyntax().empty())82result.AppendError(GetSyntax());83else84result.GetErrorStream() << "Command contents '" << command85<< "' failed to match any "86"regular expression in the '"87<< m_cmd_name << "' regex ";88}8990bool CommandObjectRegexCommand::AddRegexCommand(llvm::StringRef re_cstr,91llvm::StringRef command_cstr) {92m_entries.resize(m_entries.size() + 1);93// Only add the regular expression if it compiles94m_entries.back().regex = RegularExpression(re_cstr);95if (m_entries.back().regex.IsValid()) {96m_entries.back().command = command_cstr.str();97return true;98}99// The regex didn't compile...100m_entries.pop_back();101return false;102}103104void CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {105if (m_completion_type_mask) {106lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(107GetCommandInterpreter(), m_completion_type_mask, request, nullptr);108}109}110111112