diff options
| author | Glenn Smith <glenn@vector35.com> | 2022-11-07 21:39:41 -0500 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2022-11-11 16:11:48 -0500 |
| commit | 1a565da676a7d1be45bfde1a5f40252838ccf5d8 (patch) | |
| tree | 6f22e0dabb94d4a27960ddfc73bc3451071da3ee /typeparser.cpp | |
| parent | 14d91ab76f7bcee588bcbb7e89639adae90c9f62 (diff) | |
Convenience helpers for type parsing in c++
Diffstat (limited to 'typeparser.cpp')
| -rw-r--r-- | typeparser.cpp | 91 |
1 files changed, 90 insertions, 1 deletions
diff --git a/typeparser.cpp b/typeparser.cpp index c93c03b3..6124004c 100644 --- a/typeparser.cpp +++ b/typeparser.cpp @@ -1,8 +1,9 @@ #include "binaryninjaapi.h" +#include <filesystem> using namespace BinaryNinja; using namespace std; - +namespace fs = std::filesystem; TypeParser::TypeParser(const string& name) : m_nameForRegister(name) {} @@ -57,6 +58,48 @@ void TypeParser::Register(TypeParser* parser) } +std::vector<std::string> TypeParser::ParseOptionsText(const std::string& optionsText) +{ + size_t count; + char** options = BNParseTypeParserOptionsText(optionsText.c_str(), &count); + + std::vector<std::string> result; + for (size_t i = 0; i < count; i++) + { + result.push_back(options[i]); + } + + BNFreeStringList(options, count); + return result; +} + + +std::string TypeParser::FormatParseErrors(const std::vector<TypeParserError>& errors) +{ + std::vector<BNTypeParserError> apiErrors; + for (const auto& error: errors) + { + BNTypeParserError apiError; + apiError.severity = error.severity; + apiError.message = BNAllocString(error.message.c_str()); + apiError.fileName = BNAllocString(error.fileName.c_str()); + apiError.line = error.line; + apiError.column = error.column; + apiErrors.push_back(apiError); + } + + char* string = BNFormatTypeParserParseErrors(apiErrors.data(), apiErrors.size()); + + for (auto& apiError: apiErrors) + { + BNFreeString(apiError.message); + BNFreeString(apiError.fileName); + } + + return string; +} + + bool TypeParser::GetOptionText(BNTypeParserOption option, std::string value, std::string& result) const { // Default: Don't accept anything @@ -311,6 +354,52 @@ void TypeParser::FreeErrorListCallback(void* ctxt, BNTypeParserError* errors, si } +bool TypeParser::ParseTypesFromSourceFile(const string& fileName, Ref<Platform> platform, + const map<QualifiedName, TypeAndId>& existingTypes, const vector<string>& options, + const vector<string>& includeDirs, const string& autoTypeSource, TypeParserResult& result, + vector<TypeParserError>& errors) +{ + if (!fs::is_regular_file(fileName)) + { + errors.push_back(TypeParserError(FatalSeverity, string("error: argument '") + fileName + "' is not a file")); + return false; + } + + // Read file contents, then parse them + FILE* fp = fopen(fileName.c_str(), "rb"); + if (!fp) + { + errors.push_back(TypeParserError(FatalSeverity, string("file '") + fileName + "' not found")); + return false; + } + + fseek(fp, 0, SEEK_END); + long size = ftell(fp); + if(size == -1) + { + errors.push_back(TypeParserError(FatalSeverity, string("error: unable to open '") + fileName)); + return false; + } + fseek(fp, 0, SEEK_SET); + + char* data = new char[size + 2]; + if (fread(data, 1, size, fp) != (size_t)size) + { + errors.push_back(TypeParserError(FatalSeverity, string("error: file '") + fileName + "' could not be read")); + delete[] data; + fclose(fp); + return false; + } + data[size++] = '\n'; + data[size] = 0; + fclose(fp); + + bool ok = ParseTypesFromSource(data, fileName, platform, existingTypes, options, includeDirs, autoTypeSource, result, errors); + delete[] data; + return ok; +} + + CoreTypeParser::CoreTypeParser(BNTypeParser* parser): TypeParser(parser) { |
