Ignore name of typedef struct pointer declaration, recursively create directories for output. (#172)
* Do not use the name of typedef to pointer for a struct (Closes 157).
* Recursively create folders for output (Closes 171).
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cfb41c4..366939a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 2.0.3
+- Ignore typedef to struct pointer when possible.
+- Recursively create directories for output file.
+
# 2.0.2
- Fixed illegal use of `const` in name, crash due to unnamed inline structs and
structs having `Opaque` members.
diff --git a/lib/src/code_generator/library.dart b/lib/src/code_generator/library.dart
index fd16446..893289d 100644
--- a/lib/src/code_generator/library.dart
+++ b/lib/src/code_generator/library.dart
@@ -87,6 +87,7 @@
///
/// If format is true(default), 'dartfmt -w $PATH' will be called to format the generated file.
void generateFile(File file, {bool format = true}) {
+ if (!file.existsSync()) file.createSync(recursive: true);
file.writeAsStringSync(generate());
if (format) {
_dartFmt(file.path);
diff --git a/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart b/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
index 57ab11c..7c74aec 100644
--- a/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
@@ -17,9 +17,25 @@
/// Holds temporary information regarding a typedef referenced [Binding]
/// while parsing.
+///
+/// Notes:
+/// - Pointer to Typedefs structs are skipped if the struct is seen.
+/// - If there are multiple typedefs for a declaration (struct/enum), the last
+/// seen name is used.
+/// - Typerefs are completely ignored.
+///
+/// Libclang marks them as following -
+/// ```C
+/// typedef struct A{
+/// int a
+/// } B, *pB; // Typedef(s).
+///
+/// typedef A D; // Typeref.
+/// ```
class _ParsedTypedef {
Binding? binding;
String? typedefName;
+ bool typedefToPointer = false;
_ParsedTypedef();
}
@@ -28,6 +44,12 @@
/// Parses a typedef declaration.
Binding? parseTypedefDeclaration(clang_types.CXCursor cursor) {
_stack.push(_ParsedTypedef());
+
+ /// Check if typedef declaration is to a pointer.
+ _stack.top.typedefToPointer =
+ (clang.clang_getTypedefDeclUnderlyingType(cursor).kind ==
+ clang_types.CXTypeKind.CXType_Pointer);
+
// Name of typedef.
_stack.top.typedefName = cursor.spelling();
final resultCode = clang.clang_visitChildren(
@@ -54,8 +76,15 @@
switch (clang.clang_getCursorKind(cursor)) {
case clang_types.CXCursorKind.CXCursor_StructDecl:
- _stack.top.binding =
- parseStructDeclaration(cursor, name: _stack.top.typedefName);
+ if (_stack.top.typedefToPointer &&
+ bindingsIndex.isSeenStruct(cursor.usr())) {
+ // Skip a typedef pointer if struct is seen.
+ _stack.top.binding = bindingsIndex.getSeenStruct(cursor.usr());
+ } else {
+ // This will update the name of struct if already seen.
+ _stack.top.binding =
+ parseStructDeclaration(cursor, name: _stack.top.typedefName);
+ }
break;
case clang_types.CXCursorKind.CXCursor_EnumDecl:
_stack.top.binding =
diff --git a/pubspec.yaml b/pubspec.yaml
index bdc549d..1207053 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
name: ffigen
-version: 2.0.2
+version: 2.0.3
homepage: https://github.com/dart-lang/ffigen
description: Generator for FFI bindings, using LibClang to parse C header files.
diff --git a/test/header_parser_tests/typedef.h b/test/header_parser_tests/typedef.h
index 68ad426..a8e9cd6 100644
--- a/test/header_parser_tests/typedef.h
+++ b/test/header_parser_tests/typedef.h
@@ -40,13 +40,13 @@
typedef enum
{
- a=0
+ a = 0
} AnonymousEnumInTypedef;
// Name from global namespace is used.
typedef enum _NamedEnumInTypedef
{
- b=0
+ b = 0
} NamedEnumInTypedef;
// Should be treated as IntPtr when used.
@@ -54,3 +54,8 @@
typedef specified_type_as_IntPtr nesting_a_specified_type;
void func3(specified_type_as_IntPtr, nesting_a_specified_type b);
+
+// Struct3 is used. `pStruct2` and `pStruct3` are ignored.
+typedef struct
+{
+} Struct2, Struct3, *pStruct2, *pStruct3;
diff --git a/test/header_parser_tests/typedef_test.dart b/test/header_parser_tests/typedef_test.dart
index 182b622..8f2abc7 100644
--- a/test/header_parser_tests/typedef_test.dart
+++ b/test/header_parser_tests/typedef_test.dart
@@ -122,6 +122,7 @@
),
],
),
+ Struc(name: 'Struct3'),
],
);
}