Compare commits

..
1 Commits
Author SHA1 Message Date
Duncan Ogilvie a15241cf80 Add 32-bit support 2026-03-15 16:22:14 +01:00
6 changed files with 124 additions and 52 deletions

No files matched your search

+8
View File
@@ -112,7 +112,11 @@ DataExplorerDialog::DataExplorerDialog(QWidget* parent) : QDialog(parent), ui(ne
// Restore settings
{
#ifdef _WIN64
QSettings settings("DataExplorer");
#else
QSettings settings("DataExplorer32");
#endif // _WIN64
auto cursor = ui->codeEdit->textCursor();
auto savedPosition = settings.value("cursor", cursor.position()).toInt();
@@ -136,7 +140,11 @@ DataExplorerDialog::~DataExplorerDialog()
void DataExplorerDialog::closeEvent(QCloseEvent* event)
{
#ifdef _WIN64
QSettings settings("DataExplorer");
#else
QSettings settings("DataExplorer32");
#endif // _WIN64
settings.setValue("code", ui->codeEdit->toPlainText());
settings.setValue("cursor", ui->codeEdit->textCursor().position());
settings.setValue("geometry", saveGeometry());
+13 -2
View File
@@ -7,6 +7,9 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build")
endif()
# Enable support for MSVC_RUNTIME_LIBRARY
cmake_policy(SET CMP0091 NEW)
set(CMKR_ROOT_PROJECT OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(CMKR_ROOT_PROJECT ON)
@@ -22,6 +25,10 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
# Create a configure-time dependency on cmake.toml to improve IDE support
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS cmake.toml)
if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
endif()
# Options
@@ -29,18 +36,22 @@ option(LIBPL_ENABLE_CLI "" OFF)
project(PatternLanguage)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
add_compile_definitions(FMT_USE_CONSTEVAL=0)
endif()
include(FetchContent)
# Fix warnings about DOWNLOAD_EXTRACT_TIMESTAMP
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
message(STATUS "Fetching PatternLanguage (4e74b705f68a24377144d11c9e5143e4935cf1e0)...")
message(STATUS "Fetching PatternLanguage (a9a93ab56b7808cb5d551ff94d7bad8a3c963618)...")
FetchContent_Declare(PatternLanguage
GIT_REPOSITORY
"https://github.com/WerWolv/PatternLanguage"
GIT_TAG
4e74b705f68a24377144d11c9e5143e4935cf1e0
a9a93ab56b7808cb5d551ff94d7bad8a3c963618
)
FetchContent_MakeAvailable(PatternLanguage)
+14 -3
View File
@@ -1,7 +1,7 @@
# PatternLanguage
Requirements:
- Zig 0.13 (installed in `PATH`)
- Zig 0.15 (installed in `PATH`)
- CMake
- Ninja
@@ -9,6 +9,17 @@ Compilation:
```sh
git clone https://github.com/mrexodia/zig-cross
cmake -B build -G Ninja --toolchain zig-cross/x86_64-windows-gnu.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build
cmake -B build64 -G Ninja --toolchain zig-cross/x86_64-windows-gnu.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build64
cmake -B build32 -G Ninja --toolchain zig-cross/x86-windows-gnu.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build32
```
With Visual Studio:
```
cmake -B build-vs64 -A x64
cmake --build build-vs64 --config Release
cmake -B build-vs32 -A Win32
cmake --build build-vs32 --config Release
```
+7 -1
View File
@@ -1,9 +1,15 @@
[project]
name = "PatternLanguage"
msvc-runtime = "static"
cmake-after = """
if(CMAKE_CXX_COMPILER_ID MATCHES \"Clang\" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
add_compile_definitions(FMT_USE_CONSTEVAL=0)
endif()
"""
[fetch-content.PatternLanguage]
git = "https://github.com/WerWolv/PatternLanguage"
tag = "4e74b705f68a24377144d11c9e5143e4935cf1e0"
tag = "a9a93ab56b7808cb5d551ff94d7bad8a3c963618"
[options]
LIBPL_ENABLE_CLI = false
+81 -44
View File
@@ -160,30 +160,28 @@ public:
private:
static std::string debugPattern(const char *title, const ptrn::Pattern *pattern)
{
using ::fmt::format;
std::string p;
p += format("{}(\n", title);
p += format(" offset = {:#x}\n", pattern->getOffset());
p += format(" size = {:#x}\n", pattern->getSize());
p += format(" variableName = {}\n", pattern->getVariableName()); // name of the variable (or var[array_idx])
p += format(" displayName = {}\n",
p += fmt::format("{}(\n", title);
p += fmt::format(" offset = {:#x}\n", pattern->getOffset());
p += fmt::format(" size = {:#x}\n", pattern->getSize());
p += fmt::format(" variableName = {}\n", pattern->getVariableName()); // name of the variable (or var[array_idx])
p += fmt::format(" displayName = {}\n",
pattern->getDisplayName()); // [[name("Whatever")]] (falls back to variable name)
p += format(" formattedName = {}\n",
p += fmt::format(" formattedName = {}\n",
pattern->getFormattedName()); // formatted type name (falls back to type name)
p += format(" typeName = {}\n", pattern->getTypeName()); // name of the type (without struct or array size)
p += format(" line = {}\n", pattern->getLine()); // source line
p += format(" visibility = {}\n", (int) pattern->getVisibility());
p += fmt::format(" typeName = {}\n", pattern->getTypeName()); // name of the type (without struct or array size)
p += fmt::format(" line = {}\n", pattern->getLine()); // source line
p += fmt::format(" visibility = {}\n", (int) pattern->getVisibility());
//p += format(" endian = {}\n", (int) pattern->getEndian());
//p += format(" section = {}\n", pattern->getSection());
p += format(" comment = {}\n", pattern->getComment());
p += format(" color = {:#x}\n", pattern->getColor());
p += format(" sealed = {}\n", pattern->isSealed());
p += format(")");
p += fmt::format(" comment = {}\n", pattern->getComment());
p += fmt::format(" color = {:#x}\n", pattern->getColor());
p += fmt::format(" sealed = {}\n", pattern->isSealed());
p += fmt::format(")");
return p;
}
TreeNode apiVisit(const char *reason, const ptrn::Pattern *pattern, const std::string &value)
TreeNode apiVisit(const char *reason, ptrn::Pattern *pattern, const std::string &value)
{
// TODO: array elements,
auto formattedTypeName = pattern->getFormattedName();
@@ -204,7 +202,7 @@ private:
return m_args->visit(m_args->userdata, treeTop(), &info);
}
static std::string readFormatter(const ptrn::Pattern *pattern)
static std::string readFormatter(ptrn::Pattern *pattern)
{
if (const auto &functionName = pattern->getReadFormatterFunction(); !functionName.empty())
{
@@ -216,7 +214,7 @@ private:
}
}
void formatValue(const ptrn::Pattern *pattern)
void formatValue(ptrn::Pattern *pattern)
{
if (pattern->getVisibility() == ptrn::Visibility::Hidden) return;
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) return;
@@ -228,25 +226,25 @@ private:
value = std::visit(wolv::util::overloaded{
// TODO: print full-width
[&](std::integral auto value) -> std::string
{ return ::fmt::format("0x{:0{}X}\t{}", value, pattern->getSize() * 2, value); },
[&](pl::integral auto value) -> std::string
{ return fmt::format("0x{:0{}X}\t{}", value, pattern->getSize() * 2, value); },
[&](std::floating_point auto value) -> std::string
{ return ::fmt::format("{}", value); },
{ return fmt::format("{}", value); },
[&](const std::string &value) -> std::string
{ return ::fmt::format("\"{}\"", value); },
{ return fmt::format("\"{}\"", value); },
[&](bool value) -> std::string
{ return value ? "true" : "false"; },
[&](char value) -> std::string
{ return ::fmt::format("'{}'", value); },
{ return fmt::format("'{}'", value); },
[&](const std::shared_ptr<ptrn::Pattern> &value) -> std::string
{ return ::fmt::format("\"{}\"", value->toString()); },
{ return fmt::format("\"{}\"", value->toString()); },
}, pattern->getValue());
}
apiVisit("formatValue", pattern, value);
}
void formatString(const ptrn::Pattern *pattern)
void formatString(ptrn::Pattern *pattern)
{
if (pattern->getVisibility() == ptrn::Visibility::Hidden) return;
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) return;
@@ -333,16 +331,16 @@ PatternStatus PatternRun(const PatternRunArgs *args)
enum core::LogConsole::Level;
case Debug:
::fmt::print("[DEBUG] {}\n", stripped);
fmt::print("[DEBUG] {}\n", stripped);
break;
case Info:
::fmt::print("[INFO] {}\n", stripped);
fmt::print("[INFO] {}\n", stripped);
break;
case Warning:
::fmt::print("[WARN] {}\n", stripped);
fmt::print("[WARN] {}\n", stripped);
break;
case Error:
::fmt::print("[ERROR] {}\n", stripped);
fmt::print("[ERROR] {}\n", stripped);
break;
}
}
@@ -353,7 +351,26 @@ PatternStatus PatternRun(const PatternRunArgs *args)
for (size_t i = 0; i < includePaths.size(); i++)
{
#ifdef _WIN32
includePaths[i] = wolv::util::utf8ToWstring(args->includes_data[i], {});
const auto setIncludePath = [&](const auto &includePath)
{
using IncludePathType = std::remove_cvref_t<decltype(includePath)>;
if constexpr (requires(const IncludePathType &path) { path.has_value(); })
{
if (includePath.has_value())
{
includePaths[i] = *includePath;
}
else
{
includePaths[i] = args->includes_data[i];
}
}
else
{
includePaths[i] = includePath;
}
};
setIncludePath(wolv::util::utf8ToWstring(args->includes_data[i]));
#else
includePaths[i] = args->includes_data[i];
#endif
@@ -385,7 +402,7 @@ PatternStatus PatternRun(const PatternRunArgs *args)
{
filename = api::Source::DefaultSource;
}
if (!runtime.executeString(args->source, filename))
if (const auto exitCode = runtime.executeString(args->source, filename); exitCode != 0)
{
auto compileErrors = runtime.getCompileErrors();
if (!compileErrors.empty())
@@ -423,22 +440,35 @@ PatternStatus PatternRun(const PatternRunArgs *args)
}
else
{
auto error = runtime.getEvalError().value();
if (args->eval_error == nullptr)
std::string pretty;
EvalError cerror = {
.location = {
.file = filename,
.line = 0,
.column = 0,
.length = 0,
},
.pretty = nullptr,
};
if (const auto &error = runtime.getEvalError(); error.has_value())
{
fmt::print("Pattern Error: {}:{} -> {}\n", error.line, error.column, error.message);
cerror.location.line = error->line;
cerror.location.column = error->column;
pretty = error->message;
}
else
{
pretty = fmt::format("Pattern execution failed with exit code {} without an evaluation error.", exitCode);
}
cerror.pretty = pretty.c_str();
if (args->eval_error == nullptr)
{
fmt::print("Pattern Error: {}:{} -> {}\n", cerror.location.line, cerror.location.column, pretty);
}
else
{
EvalError cerror = {
.location = {
.file = filename,
.line = error.line,
.column = error.column,
.length = 0,
},
.pretty = error.message.c_str(),
};
args->eval_error(args->userdata, &cerror);
}
@@ -457,7 +487,14 @@ PatternStatus PatternRun(const PatternRunArgs *args)
}
catch (const std::exception &e)
{
args->log_handler(args->userdata, LogLevelError, e.what());
if (args->log_handler != nullptr)
{
args->log_handler(args->userdata, LogLevelError, e.what());
}
else
{
fmt::print("[ERROR] {}\n", e.what());
}
return PatternEvalError;
}
}
+1 -2
View File
@@ -10,7 +10,6 @@ The DataExplorer plugin integrates the [pattern language](https://docs.werwolv.n
- Install the plugin so you have:
```
<x64dbg-dir>/x64/plugins/DataExplorer/DataExplorer.dp64
<x64dbg-dir>/x32/plugins/DataExplorer/DataExplorer.dp32
```
- Launch x64dbg and open the plugin via `Plugins -> DataExplorer -> Open` (Ctrl+Shift+D)
**Note**: There is no 32-bit support and it is not planned.