# SDL3 Header Parser: Dependency Resolution Plan ## Problem Statement The generated `gpu.zig` references types from other SDL headers: - `FColor` (SDL_pixels.h) - `Rect` (SDL_rect.h) - `PropertiesID` (SDL_properties.h) - `Window` (SDL_video.h - opaque type) - `FlipMode` (SDL_surface.h) - `GPUShaderFormat` (special case: #define flags) Without these types, the generated code won't compile. ## Analysis of SDL Header Structure SDL_gpu.h includes: ```c #include // Basic types (Uint32, etc.) #include // SDL_FColor #include // SDL_PropertiesID #include // SDL_Rect #include // SDL_FlipMode #include // SDL_Window (opaque) ``` ## Solution Options ### Option 1: Parse Dependencies Recursively (REJECTED - Too Complex) - Parse all included headers - Build dependency graph - Generate all files in correct order - **Issues**: - SDL has circular dependencies - Would need to parse entire SDL API - Overkill for our use case ### Option 2: Manual Type Imports (REJECTED - Not Maintainable) - Manually copy type definitions - **Issues**: - Not automated - Breaks on SDL updates - Defeats purpose of parser ### Option 3: Hybrid Approach - Parse Referenced Types Only (RECOMMENDED) #### Phase 1: Dependency Detection 1. Parse target header (e.g., SDL_gpu.h) 2. Collect all non-GPU SDL types referenced in signatures 3. Map types to their source headers (from #include directives) #### Phase 2: Selective Type Extraction For each dependency header, extract ONLY referenced types: - Parse dependency header in "extract mode" - Only output declarations that match our needed types - Generate minimal `.zig` files (e.g., `pixels.zig`, `rect.zig`) #### Phase 3: Code Generation Generate main file with imports: ```zig pub const c = @import("c.zig").c; // Import minimal dependencies const pixels = @import("pixels.zig"); const rect = @import("rect.zig"); const properties = @import("properties.zig"); const video = @import("video.zig"); const surface = @import("surface.zig"); // Re-export needed types pub const FColor = pixels.FColor; pub const Rect = rect.Rect; pub const PropertiesID = properties.PropertiesID; pub const Window = video.Window; pub const FlipMode = surface.FlipMode; // Manual override for #define-based types pub const GPUShaderFormat = packed struct(u32) { // ... handwritten }; // Generated GPU declarations follow... ``` ## Implementation Plan ### Step 1: Add Dependency Analysis ```zig const DependencyInfo = struct { types_needed: []const []const u8, source_headers: std.StringHashMap([]const u8), // type -> header }; fn analyzeDependencies(decls: []Declaration) !DependencyInfo { // Scan all function signatures for SDL_ types // Map types to headers based on SDL conventions } ``` ### Step 2: Extract Types from Dependencies ```zig fn extractTypesFromHeader( header_path: []const u8, types_to_extract: []const []const u8, ) ![]Declaration { // Parse dependency header // Filter to only needed types // Return minimal declaration set } ``` ### Step 3: Generate Import Structure ```zig fn generateWithDependencies( main_decls: []Declaration, deps: DependencyInfo, output_dir: []const u8, ) !void { // Generate dependency .zig files // Generate main file with imports } ``` ### Step 4: Handle Special Cases **Opaque Types (e.g., Window)**: - SDL_Window is `typedef struct SDL_Window SDL_Window;` (forward decl) - Generate as: `pub const Window = opaque {};` or `pub const Window = c.SDL_Window;` - Decision: Use `c.SDL_Window` for true opaque types **#define Flags (e.g., GPUShaderFormat)**: - Cannot be auto-parsed - Maintain "overrides" file: `overrides.zig` - User can provide manual definitions for unparseable types ## File Structure ``` v2/ ├── gpu.zig # Main generated file with imports ├── pixels.zig # Minimal: FColor only ├── rect.zig # Minimal: Rect only ├── properties.zig # Minimal: PropertiesID only ├── video.zig # Minimal: Window only ├── surface.zig # Minimal: FlipMode only └── overrides.zig # Manual definitions (GPUShaderFormat) ``` ## Advantages 1. ✅ Automated - no manual copying 2. ✅ Minimal - only extracts needed types 3. ✅ Maintainable - regenerate on SDL updates 4. ✅ Avoids circular dependencies - only extracts leaf types 5. ✅ Flexible - handles special cases via overrides ## Testing Strategy 1. Parse SDL_gpu.h → detect dependencies 2. Parse dependency headers → extract types 3. Generate all files 4. Run `zig build` to verify compilation 5. Compare API compatibility with handwritten version ## Future Enhancements - Cache parsed headers to avoid re-parsing - Support transitive dependencies (if type A needs type B) - Auto-generate overrides file with placeholders - Support multiple target headers in one run