mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-28 07:47:02 -05:00
121 lines
4.3 KiB
C++
121 lines
4.3 KiB
C++
#include <pl.hpp>
|
|
|
|
#include <wolv/io/file.hpp>
|
|
|
|
#include <fmt/format.h>
|
|
#include <cstdlib>
|
|
|
|
#include "../../cmake-build-release/_deps/pattern_language-src/lib/include/pl/core/ast/ast_node_function_definition.hpp"
|
|
|
|
#define EXIT_SKIP 77
|
|
|
|
int main(int argc, char **argv) {
|
|
// Any number of arguments other than 4 are invalid
|
|
if (argc != 4)
|
|
return EXIT_FAILURE;
|
|
|
|
// Extract command line arguments
|
|
const std::string includeName = argv[1];
|
|
const std::fs::path includeFilePath = argv[2];
|
|
const std::fs::path includePath = argv[3];
|
|
|
|
fmt::print("Running test {} on test file {}\n", includeName, includeFilePath.filename().string());
|
|
|
|
// Open pattern file
|
|
wolv::io::File patternFile(includeFilePath, wolv::io::File::Mode::Read);
|
|
if (!patternFile.isValid())
|
|
return EXIT_FAILURE;
|
|
|
|
// Setup Pattern Language Runtime
|
|
pl::PatternLanguage runtime;
|
|
{
|
|
constexpr auto DummyPragmaHandler = [](const auto&, const auto&) {
|
|
return false;
|
|
};
|
|
|
|
runtime.setDataSource(0x00, 0x100000,
|
|
[&](pl::u64 address, pl::u8 *data, size_t size) {
|
|
pl::core::err::E0011.throwError("Include files should never read from memory directly!");
|
|
}
|
|
);
|
|
runtime.setDangerousFunctionCallHandler([]{ return true; });
|
|
runtime.setIncludePaths({ includePath });
|
|
|
|
runtime.addPragma("endian", DummyPragmaHandler);
|
|
runtime.addPragma("MIME", DummyPragmaHandler);
|
|
runtime.addPragma("base_address", DummyPragmaHandler);
|
|
runtime.addPragma("eval_depth", DummyPragmaHandler);
|
|
runtime.addPragma("array_limit", DummyPragmaHandler);
|
|
runtime.addPragma("pattern_limit", DummyPragmaHandler);
|
|
|
|
runtime.addDefine("__PL_UNIT_TESTS__");
|
|
|
|
runtime.setLogCallback([](auto level, const std::string &message) {
|
|
switch (level) {
|
|
using enum pl::core::LogConsole::Level;
|
|
case Debug: fmt::print(" [DEBUG] "); break;
|
|
case Info: fmt::print(" [INFO] "); break;
|
|
case Warning: fmt::print(" [WARN] "); break;
|
|
case Error: fmt::print(" [ERROR] "); break;
|
|
}
|
|
|
|
fmt::print("{}\n", message);
|
|
});
|
|
}
|
|
|
|
// Parse pattern
|
|
const auto ast = runtime.parseString(patternFile.readString(), "<Source Code>");
|
|
if (!ast.has_value()) {
|
|
fmt::println("Error when parsing include file!");
|
|
|
|
if (const auto &compileErrors = runtime.getCompileErrors(); !compileErrors.empty()) {
|
|
for (const auto &error : compileErrors) {
|
|
fmt::println("{}", error.format());
|
|
}
|
|
} else if (const auto &evalError = runtime.getEvalError(); evalError.has_value()) {
|
|
fmt::println("{}:{} {}", evalError->line, evalError->column, evalError->message);
|
|
}
|
|
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
bool missingComments = false;
|
|
for (const std::shared_ptr<pl::core::ast::ASTNode> &node : *ast) {
|
|
if (auto typeDecl = dynamic_cast<pl::core::ast::ASTNodeTypeDecl*>(node.get())) {
|
|
if (typeDecl->getDocComment().empty() && !pl::hlp::containsIgnoreCase(typeDecl->getName(), "impl")) {
|
|
fmt::println("Type {} has no doc comment!", typeDecl->getName());
|
|
missingComments = true;
|
|
}
|
|
} else if (auto functionDef = dynamic_cast<pl::core::ast::ASTNodeFunctionDefinition*>(node.get())) {
|
|
if (functionDef->getDocComment().empty() && !pl::hlp::containsIgnoreCase(functionDef->getName(), "impl")) {
|
|
fmt::println("Function {} has no doc comment!", functionDef->getName());
|
|
missingComments = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (missingComments)
|
|
return EXIT_FAILURE;
|
|
|
|
if (!runtime.executeString(patternFile.readString(), "<Source Code>")) {
|
|
if (const auto &evalError = runtime.getEvalError(); evalError.has_value()) {
|
|
fmt::println("{}:{} {}", evalError->line, evalError->column, evalError->message);
|
|
}
|
|
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if (!runtime.getPatterns().empty()) {
|
|
fmt::println("Library created patterns!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if (!runtime.getSections().empty()) {
|
|
fmt::println("Library created sections!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|