diff options
| author | Glenn Smith <glenn@vector35.com> | 2024-03-28 17:09:23 -0400 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2024-04-03 16:04:50 -0400 |
| commit | 6320364130513117734495793886487928062891 (patch) | |
| tree | d8a0aeb7a03a26d31abf9e99c1d71bc9b48a583f | |
| parent | 6c514eaae5d2fed93738f91c85ca78343ff3c69b (diff) | |
Switch TypeParser to use TypeContainer for its external type source
| -rw-r--r-- | binaryninjaapi.h | 28 | ||||
| -rw-r--r-- | binaryninjacore.h | 17 | ||||
| -rw-r--r-- | python/typeparser.py | 96 | ||||
| -rw-r--r-- | typeparser.cpp | 141 |
4 files changed, 120 insertions, 162 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index b27c8ca8..f723cb54 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -14572,14 +14572,14 @@ namespace BinaryNinja { static bool GetOptionTextCallback(void* ctxt, BNTypeParserOption option, const char* value, char** result); static bool PreprocessSourceCallback(void* ctxt, const char* source, const char* fileName, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, const char* const* options, size_t optionCount, const char* const* includeDirs, size_t includeDirCount, char** output, BNTypeParserError** errors, size_t* errorCount ); static bool ParseTypesFromSourceCallback(void* ctxt, const char* source, const char* fileName, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, const char* const* options, size_t optionCount, const char* const* includeDirs, size_t includeDirCount, const char* autoTypeSource, BNTypeParserResult* result, @@ -14587,7 +14587,7 @@ namespace BinaryNinja { ); static bool ParseTypeStringCallback(void* ctxt, const char* source, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, BNQualifiedNameAndType* result, BNTypeParserError** errors, size_t* errorCount ); @@ -14629,7 +14629,7 @@ namespace BinaryNinja { \param source Source code to process \param fileName Name of the file containing the source (does not need to exist on disk) \param platform Platform to assume the source is relevant to - \param existingTypes Map of all existing types to use for parsing context + \param existingTypes Container of all existing types to use for parsing context \param options String arguments to pass as options, e.g. command line arguments \param includeDirs List of directories to include in the header search path \param output Reference to a string into which the preprocessed source will be written @@ -14640,7 +14640,7 @@ namespace BinaryNinja { const std::string& source, const std::string& fileName, Ref<Platform> platform, - const std::map<QualifiedName, TypeAndId>& existingTypes, + std::optional<TypeContainer> existingTypes, const std::vector<std::string>& options, const std::vector<std::string>& includeDirs, std::string& output, @@ -14652,7 +14652,7 @@ namespace BinaryNinja { \param source Source code to parse \param fileName Name of the file containing the source (optional: exists on disk) \param platform Platform to assume the types are relevant to - \param existingTypes Map of all existing types to use for parsing context + \param existingTypes Container of all existing types to use for parsing context \param options String arguments to pass as options, e.g. command line arguments \param includeDirs List of directories to include in the header search path \param autoTypeSource Optional source of types if used for automatically generated types @@ -14664,7 +14664,7 @@ namespace BinaryNinja { const std::string& source, const std::string& fileName, Ref<Platform> platform, - const std::map<QualifiedName, TypeAndId>& existingTypes, + std::optional<TypeContainer> existingTypes, const std::vector<std::string>& options, const std::vector<std::string>& includeDirs, const std::string& autoTypeSource, @@ -14676,7 +14676,7 @@ namespace BinaryNinja { Parse an entire source file into types, variables, and functions \param fileName Name of the file on disk containing the source \param platform Platform to assume the types are relevant to - \param existingTypes Map of all existing types to use for parsing context + \param existingTypes Container of all existing types to use for parsing context \param options String arguments to pass as options, e.g. command line arguments \param includeDirs List of directories to include in the header search path \param autoTypeSource Optional source of types if used for automatically generated types @@ -14687,7 +14687,7 @@ namespace BinaryNinja { bool ParseTypesFromSourceFile( const std::string& fileName, Ref<Platform> platform, - const std::map<QualifiedName, TypeAndId>& existingTypes, + std::optional<TypeContainer> existingTypes, const std::vector<std::string>& options, const std::vector<std::string>& includeDirs, const std::string& autoTypeSource, @@ -14699,7 +14699,7 @@ namespace BinaryNinja { Parse a single type and name from a string containing their definition. \param source Source code to parse \param platform Platform to assume the types are relevant to - \param existingTypes Map of all existing types to use for parsing context + \param existingTypes Container of all existing types to use for parsing context \param result Reference into which the resulting type and name will be written \param errors Reference to a list into which any parse errors will be written \return True if parsing was successful @@ -14707,7 +14707,7 @@ namespace BinaryNinja { virtual bool ParseTypeString( const std::string& source, Ref<Platform> platform, - const std::map<QualifiedName, TypeAndId>& existingTypes, + std::optional<TypeContainer> existingTypes, QualifiedNameAndType& result, std::vector<TypeParserError>& errors ) = 0; @@ -14728,7 +14728,7 @@ namespace BinaryNinja { const std::string& source, const std::string& fileName, Ref<Platform> platform, - const std::map<QualifiedName, TypeAndId>& existingTypes, + std::optional<TypeContainer> existingTypes, const std::vector<std::string>& options, const std::vector<std::string>& includeDirs, std::string& output, @@ -14739,7 +14739,7 @@ namespace BinaryNinja { const std::string& source, const std::string& fileName, Ref<Platform> platform, - const std::map<QualifiedName, TypeAndId>& existingTypes, + std::optional<TypeContainer> existingTypes, const std::vector<std::string>& options, const std::vector<std::string>& includeDirs, const std::string& autoTypeSource, @@ -14750,7 +14750,7 @@ namespace BinaryNinja { virtual bool ParseTypeString( const std::string& source, Ref<Platform> platform, - const std::map<QualifiedName, TypeAndId>& existingTypes, + std::optional<TypeContainer> existingTypes, QualifiedNameAndType& result, std::vector<TypeParserError>& errors ) override; diff --git a/binaryninjacore.h b/binaryninjacore.h index 6e2309dd..0533c5b7 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,14 +37,14 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 57 +#define BN_CURRENT_CORE_ABI_VERSION 58 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and // will require rebuilding. The minimum version is increased when there are // incompatible changes that break binary compatibility, such as changes to // existing types or functions. -#define BN_MINIMUM_CORE_ABI_VERSION 57 +#define BN_MINIMUM_CORE_ABI_VERSION 58 #ifdef __GNUC__ #ifdef BINARYNINJACORE_LIBRARY @@ -2723,14 +2723,14 @@ extern "C" bool (*getOptionText)(void* ctxt, BNTypeParserOption option, const char* value, char** result); bool (*preprocessSource)(void* ctxt, const char* source, const char* fileName, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, const char* const* options, size_t optionCount, const char* const* includeDirs, size_t includeDirCount, char** output, BNTypeParserError** errors, size_t* errorCount ); bool (*parseTypesFromSource)(void* ctxt, const char* source, const char* fileName, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, const char* const* options, size_t optionCount, const char* const* includeDirs, size_t includeDirCount, const char* autoTypeSource, BNTypeParserResult* result, @@ -2738,7 +2738,7 @@ extern "C" ); bool (*parseTypeString)(void* ctxt, const char* source, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, BNQualifiedNameAndType* result, BNTypeParserError** errors, size_t* errorCount ); @@ -3140,6 +3140,7 @@ extern "C" TypeArchiveTypeContainerType, DebugInfoTypeContainerType, PlatformTypeContainerType, + OtherTypeContainerType } BNTypeContainerType; typedef enum BNSyncStatus @@ -5987,14 +5988,14 @@ extern "C" const char* value, char** result); BINARYNINJACOREAPI bool BNTypeParserPreprocessSource(BNTypeParser* parser, const char* source, const char* fileName, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, const char* const* options, size_t optionCount, const char* const* includeDirs, size_t includeDirCount, char** output, BNTypeParserError** errors, size_t* errorCount ); BINARYNINJACOREAPI bool BNTypeParserParseTypesFromSource(BNTypeParser* parser, const char* source, const char* fileName, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, const char* const* options, size_t optionCount, const char* const* includeDirs, size_t includeDirCount, const char* autoTypeSource, BNTypeParserResult* result, @@ -6002,7 +6003,7 @@ extern "C" ); BINARYNINJACOREAPI bool BNTypeParserParseTypeString(BNTypeParser* parser, const char* source, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, BNQualifiedNameAndType* result, BNTypeParserError** errors, size_t* errorCount ); diff --git a/python/typeparser.py b/python/typeparser.py index d56f6b59..98c83029 100644 --- a/python/typeparser.py +++ b/python/typeparser.py @@ -32,7 +32,9 @@ import binaryninja import binaryninja._binaryninjacore as core from .settings import Settings +from . import binaryview from . import platform +from . import typecontainer from . import types from . import deprecation from .log import log_error @@ -257,7 +259,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): return False def _preprocess_source( - self, ctxt, source, fileName, platform_, existingTypes, existingTypeCount, + self, ctxt, source, fileName, platform_, existingTypes, options, optionCount, includeDirs, includeDirCount, output, errors, errorCount ) -> bool: @@ -266,9 +268,9 @@ class TypeParser(metaclass=_TypeParserMetaclass): file_name_py = core.pyNativeStr(fileName) platform_py = platform.Platform(handle=core.BNNewPlatformReference(platform_)) - existing_types_py = [] - for i in range(existingTypeCount): - existing_types_py.append(QualifiedNameTypeAndId._from_core_struct(existingTypes[i])) + existing_types_py = None + if existingTypes: + existing_types_py = typecontainer.TypeContainer(handle=core.BNDuplicateTypeContainer(existingTypes)) options_py = [] for i in range(optionCount): @@ -301,7 +303,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): return False def _parse_types_from_source( - self, ctxt, source, fileName, platform_, existingTypes, existingTypeCount, + self, ctxt, source, fileName, platform_, existingTypes, options, optionCount, includeDirs, includeDirCount, autoTypeSource, result, errors, errorCount ) -> bool: @@ -310,9 +312,9 @@ class TypeParser(metaclass=_TypeParserMetaclass): file_name_py = core.pyNativeStr(fileName) platform_py = platform.Platform(handle=core.BNNewPlatformReference(platform_)) - existing_types_py = [] - for i in range(existingTypeCount): - existing_types_py.append(QualifiedNameTypeAndId._from_core_struct(existingTypes[i])) + existing_types_py = None + if existingTypes: + existing_types_py = typecontainer.TypeContainer(handle=core.BNDuplicateTypeContainer(existingTypes)) options_py = [] for i in range(optionCount): @@ -352,16 +354,16 @@ class TypeParser(metaclass=_TypeParserMetaclass): return False def _parse_type_string( - self, ctxt, source, platform_, existingTypes, existingTypeCount, + self, ctxt, source, platform_, existingTypes, result, errors, errorCount ) -> bool: try: source_py = core.pyNativeStr(source) platform_py = platform.Platform(handle=core.BNNewPlatformReference(platform_)) - existing_types_py = [] - for i in range(existingTypeCount): - existing_types_py.append(QualifiedNameTypeAndId._from_core_struct(existingTypes[i])) + existing_types_py = None + if existingTypes: + existing_types_py = typecontainer.TypeContainer(handle=core.BNDuplicateTypeContainer(existingTypes)) (result_py, errors_py) = self.parse_type_string( source_py, platform_py, existing_types_py) @@ -434,7 +436,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): def preprocess_source( self, source: str, file_name: str, platform: 'platform.Platform', - existing_types: Optional[List[QualifiedNameTypeAndId]] = None, + existing_types: Optional['types.TypeContainerType'] = None, options: Optional[List[str]] = None, include_dirs: Optional[List[str]] = None ) -> Tuple[Optional[str], List[TypeParserError]]: """ @@ -443,7 +445,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): :param source: Source code to process :param file_name: Name of the file containing the source (does not need to exist on disk) :param platform: Platform to assume the source is relevant to - :param existing_types: Optional map of all existing types to use for parsing context + :param existing_types: Optional collection of all existing types to use for parsing context :param options: Optional string arguments to pass as options, e.g. command line arguments :param include_dirs: Optional list of directories to include in the header search path :return: A tuple of (preproccessed source, errors), where the preproccessed source @@ -453,7 +455,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): def parse_types_from_source( self, source: str, file_name: str, platform: 'platform.Platform', - existing_types: Optional[List[QualifiedNameTypeAndId]] = None, + existing_types: Optional['types.TypeContainerType'] = None, options: Optional[List[str]] = None, include_dirs: Optional[List[str]] = None, auto_type_source: str = "" ) -> Tuple[Optional[TypeParserResult], List[TypeParserError]]: @@ -463,7 +465,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): :param source: Source code to parse :param file_name: Name of the file containing the source (optional: exists on disk) :param platform: Platform to assume the types are relevant to - :param existing_types: Optional map of all existing types to use for parsing context + :param existing_types: Optional container of all existing types to use for parsing context :param options: Optional string arguments to pass as options, e.g. command line arguments :param include_dirs: Optional list of directories to include in the header search path :param auto_type_source: Optional source of types if used for automatically generated types @@ -473,14 +475,14 @@ class TypeParser(metaclass=_TypeParserMetaclass): def parse_type_string( self, source: str, platform: 'platform.Platform', - existing_types: Optional[List[QualifiedNameTypeAndId]] = None + existing_types: Optional['types.TypeContainerType'] = None ) -> Tuple[Optional[Tuple['types.QualifiedNameType', 'types.Type']], List[TypeParserError]]: """ Parse a single type and name from a string containing their definition. :param source: Source code to parse :param platform: Platform to assume the types are relevant to - :param existing_types: Optional map of all existing types to use for parsing context + :param existing_types: Optional container of all existing types to use for parsing context :return: A tuple of (result, errors) where result is a tuple of (type, name) or None of there was a fatal error. """ @@ -499,19 +501,22 @@ class CoreTypeParser(TypeParser): def preprocess_source( self, source: str, file_name: str, platform: 'platform.Platform', - existing_types: Optional[List[QualifiedNameTypeAndId]] = None, + existing_types: Optional['types.TypeContainerType'] = None, options: Optional[List[str]] = None, include_dirs: Optional[List[str]] = None ) -> Tuple[Optional[str], List[TypeParserError]]: - if existing_types is None: - existing_types = [] if options is None: options = [] if include_dirs is None: include_dirs = [] - existing_types_cpp = (core.BNQualifiedNameTypeAndId * len(existing_types))() - for (i, qnatid) in enumerate(existing_types): - existing_types_cpp[i] = qnatid._to_core_struct() + existing_types_cpp = None + if existing_types is not None: + if isinstance(existing_types, (binaryview.BinaryView,)): + existing_types_cpp = existing_types.type_container + elif isinstance(existing_types, (typecontainer.TypeContainer,)): + existing_types_cpp = existing_types + else: + assert False, "Unexpected type container type" options_cpp = (ctypes.c_char_p * len(options))() for (i, s) in enumerate(options): @@ -527,8 +532,8 @@ class CoreTypeParser(TypeParser): success = core.BNTypeParserPreprocessSource( self.handle, source, file_name, platform.handle, - existing_types_cpp, len(existing_types), options_cpp, len(options), - include_dirs_cpp, len(include_dirs), + existing_types_cpp.handle if existing_types_cpp is not None else None, + options_cpp, len(options), include_dirs_cpp, len(include_dirs), output_cpp, errors_cpp, error_count ) @@ -547,20 +552,23 @@ class CoreTypeParser(TypeParser): def parse_types_from_source( self, source: str, file_name: str, platform: 'platform.Platform', - existing_types: Optional[List[QualifiedNameTypeAndId]] = None, + existing_types: Optional['types.TypeContainerType'] = None, options: Optional[List[str]] = None, include_dirs: Optional[List[str]] = None, auto_type_source: str = "" ) -> Tuple[Optional[TypeParserResult], List[TypeParserError]]: - if existing_types is None: - existing_types = [] if options is None: options = [] if include_dirs is None: include_dirs = [] - existing_types_cpp = (core.BNQualifiedNameTypeAndId * len(existing_types))() - for (i, qnatid) in enumerate(existing_types): - existing_types_cpp[i] = qnatid._to_core_struct() + existing_types_cpp = None + if existing_types is not None: + if isinstance(existing_types, (binaryview.BinaryView,)): + existing_types_cpp = existing_types.type_container + elif isinstance(existing_types, (typecontainer.TypeContainer,)): + existing_types_cpp = existing_types + else: + assert False, "Unexpected type container type" options_cpp = (ctypes.c_char_p * len(options))() for (i, s) in enumerate(options): @@ -576,9 +584,9 @@ class CoreTypeParser(TypeParser): success = core.BNTypeParserParseTypesFromSource( self.handle, source, file_name, platform.handle, - existing_types_cpp, len(existing_types), options_cpp, len(options), - include_dirs_cpp, len(include_dirs), auto_type_source, - result_cpp, errors_cpp, error_count + existing_types_cpp.handle if existing_types_cpp is not None else None, + options_cpp, len(options), include_dirs_cpp, len(include_dirs), + auto_type_source, result_cpp, errors_cpp, error_count ) if success: @@ -597,13 +605,17 @@ class CoreTypeParser(TypeParser): def parse_type_string( self, source: str, platform: 'platform.Platform', - existing_types: Optional[List[QualifiedNameTypeAndId]] = None + existing_types: Optional['types.TypeContainerType'] = None ) -> Tuple[Optional[Tuple['types.QualifiedNameType', 'types.Type']], List[TypeParserError]]: - if existing_types is None: - existing_types = [] - existing_types_cpp = (core.BNQualifiedNameTypeAndId * len(existing_types))() - for (i, qnatid) in enumerate(existing_types): - existing_types_cpp[i] = qnatid._to_core_struct() + + existing_types_cpp = None + if existing_types is not None: + if isinstance(existing_types, (binaryview.BinaryView,)): + existing_types_cpp = existing_types.type_container + elif isinstance(existing_types, (typecontainer.TypeContainer,)): + existing_types_cpp = existing_types + else: + assert False, "Unexpected type container type" result_cpp = core.BNQualifiedNameAndType() errors_cpp = ctypes.POINTER(core.BNTypeParserError)() @@ -611,7 +623,7 @@ class CoreTypeParser(TypeParser): success = core.BNTypeParserParseTypeString( self.handle, source, platform.handle, - existing_types_cpp, len(existing_types), + existing_types_cpp.handle if existing_types_cpp is not None else None, result_cpp, errors_cpp, error_count ) diff --git a/typeparser.cpp b/typeparser.cpp index bb076507..8aaf02c4 100644 --- a/typeparser.cpp +++ b/typeparser.cpp @@ -122,7 +122,7 @@ bool TypeParser::GetOptionTextCallback(void* ctxt, BNTypeParserOption option, co bool TypeParser::PreprocessSourceCallback(void* ctxt, const char* source, const char* fileName, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, const char* const* options, size_t optionCount, const char* const* includeDirs, size_t includeDirCount, char** output, BNTypeParserError** errors, size_t* errorCount @@ -130,17 +130,6 @@ bool TypeParser::PreprocessSourceCallback(void* ctxt, { TypeParser* parser = (TypeParser*)ctxt; - map<QualifiedName, TypeAndId> existingTypesCpp; - for (size_t i = 0; i < existingTypeCount; i ++) - { - QualifiedName qname = QualifiedName::FromAPIObject(&existingTypes[i].name); - TypeAndId type = { - existingTypes[i].id, - new Type(existingTypes[i].type), - }; - existingTypesCpp.insert({qname, type}); - } - vector<string> optionsCpp; for (size_t i = 0; i < optionCount; i ++) { @@ -155,8 +144,16 @@ bool TypeParser::PreprocessSourceCallback(void* ctxt, std::string outputCpp; vector<TypeParserError> errorsCpp; - bool success = parser->PreprocessSource(source, fileName, new Platform(platform), - existingTypesCpp, optionsCpp, includeDirsCpp, outputCpp, errorsCpp); + bool success = parser->PreprocessSource( + source, + fileName, + new Platform(platform), + TypeContainer{BNDuplicateTypeContainer(existingTypes)}, + optionsCpp, + includeDirsCpp, + outputCpp, + errorsCpp + ); if (success) { @@ -184,7 +181,7 @@ bool TypeParser::PreprocessSourceCallback(void* ctxt, bool TypeParser::ParseTypesFromSourceCallback(void* ctxt, const char* source, const char* fileName, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, const char* const* options, size_t optionCount, const char* const* includeDirs, size_t includeDirCount, const char* autoTypeSource, BNTypeParserResult* result, @@ -193,17 +190,6 @@ bool TypeParser::ParseTypesFromSourceCallback(void* ctxt, { TypeParser* parser = (TypeParser*)ctxt; - map<QualifiedName, TypeAndId> existingTypesCpp; - for (size_t i = 0; i < existingTypeCount; i ++) - { - QualifiedName qname = QualifiedName::FromAPIObject(&existingTypes[i].name); - TypeAndId type = { - existingTypes[i].id, - new Type(existingTypes[i].type), - }; - existingTypesCpp.insert({qname, type}); - } - vector<string> optionsCpp; for (size_t i = 0; i < optionCount; i ++) { @@ -218,8 +204,17 @@ bool TypeParser::ParseTypesFromSourceCallback(void* ctxt, TypeParserResult resultCpp; vector<TypeParserError> errorsCpp; - bool success = parser->ParseTypesFromSource(source, fileName, new Platform(platform), - existingTypesCpp, optionsCpp, includeDirsCpp, autoTypeSource, resultCpp, errorsCpp); + bool success = parser->ParseTypesFromSource( + source, + fileName, + new Platform(platform), + TypeContainer{BNDuplicateTypeContainer(existingTypes)}, + optionsCpp, + includeDirsCpp, + autoTypeSource, + resultCpp, + errorsCpp + ); result->typeCount = resultCpp.types.size(); result->variableCount = resultCpp.variables.size(); @@ -272,28 +267,22 @@ bool TypeParser::ParseTypesFromSourceCallback(void* ctxt, bool TypeParser::ParseTypeStringCallback(void* ctxt, const char* source, BNPlatform* platform, - const BNQualifiedNameTypeAndId* existingTypes, size_t existingTypeCount, + BNTypeContainer* existingTypes, BNQualifiedNameAndType* result, BNTypeParserError** errors, size_t* errorCount ) { TypeParser* parser = (TypeParser*)ctxt; - map<QualifiedName, TypeAndId> existingTypesCpp; - for (size_t i = 0; i < existingTypeCount; i ++) - { - QualifiedName qname = QualifiedName::FromAPIObject(&existingTypes[i].name); - TypeAndId type = { - existingTypes[i].id, - new Type(existingTypes[i].type), - }; - existingTypesCpp.insert({qname, type}); - } - QualifiedNameAndType resultCpp; vector<TypeParserError> errorsCpp; - bool success = parser->ParseTypeString(source, new Platform(platform), existingTypesCpp, - resultCpp, errorsCpp); + bool success = parser->ParseTypeString( + source, + new Platform(platform), + TypeContainer{BNDuplicateTypeContainer(existingTypes)}, + resultCpp, + errorsCpp + ); result->name = resultCpp.name.GetAPIObject(); result->type = BNNewTypeReference(resultCpp.type->GetObject()); @@ -354,7 +343,7 @@ 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, + std::optional<TypeContainer> existingTypes, const vector<string>& options, const vector<string>& includeDirs, const string& autoTypeSource, TypeParserResult& result, vector<TypeParserError>& errors) { @@ -417,10 +406,12 @@ bool CoreTypeParser::GetOptionText(BNTypeParserOption option, std::string value, bool CoreTypeParser::PreprocessSource(const std::string& source, const std::string& fileName, - Ref<Platform> platform, const std::map<QualifiedName, TypeAndId>& existingTypes, + Ref<Platform> platform, std::optional<TypeContainer> existingTypes, const std::vector<std::string>& options, const std::vector<std::string>& includeDirs, std::string& output, std::vector<TypeParserError>& errors) { + BNTypeContainer* apiExistingTypes = (existingTypes.has_value() ? existingTypes->GetObject() : nullptr); + const char** apiOptions = new const char*[options.size()]; for (size_t i = 0; i < options.size(); ++i) { @@ -432,35 +423,18 @@ bool CoreTypeParser::PreprocessSource(const std::string& source, const std::stri apiIncludeDirs[i] = includeDirs[i].c_str(); } - BNQualifiedNameTypeAndId* apiExistingTypes = new BNQualifiedNameTypeAndId[existingTypes.size()]; - size_t i = 0; - for (const auto& pair: existingTypes) - { - apiExistingTypes[i].name = pair.first.GetAPIObject(); - apiExistingTypes[i].id = BNAllocString(pair.second.id.c_str()); - apiExistingTypes[i].type = pair.second.type->GetObject(); - i++; - } - char* apiOutput; BNTypeParserError* apiErrors; size_t errorCount; auto success = BNTypeParserPreprocessSource(m_object, source.c_str(), fileName.c_str(), - platform->GetObject(), apiExistingTypes, existingTypes.size(), + platform->GetObject(), apiExistingTypes, apiOptions, options.size(), apiIncludeDirs, includeDirs.size(), &apiOutput, &apiErrors, &errorCount); delete [] apiOptions; delete [] apiIncludeDirs; - for (size_t j = 0; j < existingTypes.size(); j ++) - { - QualifiedName::FreeAPIObject(&apiExistingTypes[j].name); - BNFreeString(apiExistingTypes[j].id); - } - delete [] apiExistingTypes; - for (size_t j = 0; j < errorCount; j ++) { TypeParserError error; @@ -485,10 +459,12 @@ bool CoreTypeParser::PreprocessSource(const std::string& source, const std::stri bool CoreTypeParser::ParseTypesFromSource(const std::string& source, const std::string& fileName, - Ref<Platform> platform, const std::map<QualifiedName, TypeAndId>& existingTypes, + Ref<Platform> platform, std::optional<TypeContainer> existingTypes, const std::vector<std::string>& options, const std::vector<std::string>& includeDirs, const std::string& autoTypeSource, TypeParserResult& result, std::vector<TypeParserError>& errors) { + BNTypeContainer* apiExistingTypes = (existingTypes.has_value() ? existingTypes->GetObject() : nullptr); + const char** apiOptions = new const char*[options.size()]; for (size_t i = 0; i < options.size(); ++i) { @@ -500,35 +476,18 @@ bool CoreTypeParser::ParseTypesFromSource(const std::string& source, const std:: apiIncludeDirs[i] = includeDirs[i].c_str(); } - BNQualifiedNameTypeAndId* apiExistingTypes = new BNQualifiedNameTypeAndId[existingTypes.size()]; - size_t i = 0; - for (const auto& pair: existingTypes) - { - apiExistingTypes[i].name = pair.first.GetAPIObject(); - apiExistingTypes[i].id = BNAllocString(pair.second.id.c_str()); - apiExistingTypes[i].type = pair.second.type->GetObject(); - i++; - } - BNTypeParserResult apiResult; BNTypeParserError* apiErrors; size_t errorCount; auto success = BNTypeParserParseTypesFromSource(m_object, source.c_str(), fileName.c_str(), - platform->GetObject(), apiExistingTypes, existingTypes.size(), + platform->GetObject(), apiExistingTypes, apiOptions, options.size(), apiIncludeDirs, includeDirs.size(), autoTypeSource.c_str(), &apiResult, &apiErrors, &errorCount); delete [] apiOptions; delete [] apiIncludeDirs; - for (size_t j = 0; j < existingTypes.size(); j ++) - { - QualifiedName::FreeAPIObject(&apiExistingTypes[j].name); - BNFreeString(apiExistingTypes[j].id); - } - delete [] apiExistingTypes; - for (size_t j = 0; j < errorCount; j ++) { TypeParserError error; @@ -582,33 +541,19 @@ bool CoreTypeParser::ParseTypesFromSource(const std::string& source, const std:: bool CoreTypeParser::ParseTypeString(const std::string& source, Ref<Platform> platform, - const std::map<QualifiedName, TypeAndId>& existingTypes, + std::optional<TypeContainer> existingTypes, QualifiedNameAndType& result, std::vector<TypeParserError>& errors) { - BNQualifiedNameTypeAndId* apiExistingTypes = new BNQualifiedNameTypeAndId[existingTypes.size()]; - size_t i = 0; - for (const auto& pair: existingTypes) - { - apiExistingTypes[i].name = pair.first.GetAPIObject(); - apiExistingTypes[i].id = BNAllocString(pair.second.id.c_str()); - apiExistingTypes[i].type = pair.second.type->GetObject(); - } + BNTypeContainer* apiExistingTypes = (existingTypes.has_value() ? existingTypes->GetObject() : nullptr); BNQualifiedNameAndType apiResult; BNTypeParserError* apiErrors; size_t errorCount; auto success = BNTypeParserParseTypeString(m_object, source.c_str(), platform->GetObject(), - apiExistingTypes, existingTypes.size(), &apiResult, + apiExistingTypes, &apiResult, &apiErrors, &errorCount); - for (size_t j = 0; j < existingTypes.size(); j ++) - { - QualifiedName::FreeAPIObject(&apiExistingTypes[j].name); - BNFreeString(apiExistingTypes[j].id); - } - delete [] apiExistingTypes; - for (size_t j = 0; j < errorCount; j ++) { TypeParserError error; |
