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'),
     ],
   );
 }