mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-05-14 01:46:41 +00:00

This reverts commit a01b26fb51c710a3a8ef88cc83b0701461f5b9ab, because it breaks the "finish" command in some way -- the command does not terminate after it steps out, but continues running the target. The exact blast radius is not clear, but it at least affects the usage of the "finish" command in TestGuiBasicDebug.py. The error is *not* gui-related, as the same issue can be reproduced by running the same steps outside of the gui. There is some kind of a race going on, as the test fails only 20% of the time on the buildbot.
91 lines
3.7 KiB
C++
91 lines
3.7 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"
|
|
|
|
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_entries(), m_is_removable(is_removable) {}
|
|
|
|
// Destructor
|
|
CommandObjectRegexCommand::~CommandObjectRegexCommand() {}
|
|
|
|
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)) {
|
|
std::string new_command(pos->command);
|
|
char percent_var[8];
|
|
size_t idx, percent_var_idx;
|
|
for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
|
|
if (match_idx < matches.size()) {
|
|
const std::string match_str = matches[match_idx].str();
|
|
const int percent_var_len =
|
|
::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
|
|
for (idx = 0; (percent_var_idx = new_command.find(
|
|
percent_var, idx)) != std::string::npos;) {
|
|
new_command.erase(percent_var_idx, percent_var_len);
|
|
new_command.insert(percent_var_idx, match_str);
|
|
idx += percent_var_idx + match_str.size();
|
|
}
|
|
}
|
|
}
|
|
// 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, nullptr, true, true);
|
|
}
|
|
}
|
|
result.SetStatus(eReturnStatusFailed);
|
|
if (!GetSyntax().empty())
|
|
result.AppendError(GetSyntax());
|
|
else
|
|
result.GetOutputStream() << "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);
|
|
}
|
|
}
|