Backlog/lib/sdl3/parser/docs/API_REFERENCE.md

7.5 KiB
Raw Blame History

API Reference

Complete reference for the SDL3 header parser command-line interface.

Command Syntax

zig build run -- <header_file> [options]

Arguments

Required

<header_file> - Path to SDL C header file

Examples:

zig build run -- ../SDL/include/SDL3/SDL_gpu.h
zig build run -- /full/path/to/SDL_video.h
zig build run -- relative/path/to/header.h

Optional

--output=<file> - Write output to file instead of stdout

Examples:

--output=gpu.zig
--output=bindings/video.zig
--output=/tmp/test.zig

--mocks=<file> - Generate C mock implementations

Examples:

--mocks=gpu_mock.c
--mocks=test/mocks.c

Output Formats

Zig Bindings (Default)

Generated when --output is specified (or to stdout if not):

pub const c = @import("c.zig").c;

pub const GPUDevice = opaque {
    pub inline fn createGPUDevice(debug_mode: bool) ?*GPUDevice {
        return c.SDL_CreateGPUDevice(debug_mode);
    }
};

Features:

  • Type conversions (C → Zig)
  • Method organization
  • Dependency inclusion
  • Doc comments preserved

C Mocks (Optional)

Generated when --mocks is specified:

// Auto-generated C mock implementations
#include <SDL3/SDL_gpu.h>

SDL_GPUDevice* SDL_CreateGPUDevice(bool debug_mode) {
    return NULL;  // Mock: always returns null
}

void SDL_DestroyGPUDevice(SDL_GPUDevice *device) {
    // Mock: no-op
}

Use Case: Testing without real SDL implementation

Build System Integration

In build.zig

const parser_dep = b.dependency("sdl3_parser", .{
    .target = target,
    .optimize = optimize,
});
const parser_exe = parser_dep.artifact("sdl-parser");

const gen = b.addRunArtifact(parser_exe);
gen.addFileArg(b.path("SDL/include/SDL3/SDL_gpu.h"));
gen.addArg("--output=src/gpu.zig");

const gen_step = b.step("generate", "Generate SDL bindings");
gen_step.dependOn(&gen.step);

Then run:

zig build generate

Parser Behavior

Dependency Resolution

Automatic - No configuration needed

When the parser detects missing types, it:

  1. Parses #include directives from the header
  2. Searches each included header
  3. Extracts matching type definitions
  4. Includes them in the output

Progress Reporting:

Analyzing dependencies...
Found 5 missing types:
  - SDL_Window
  - SDL_Rect
  ...

Resolving dependencies...
  ✓ Found SDL_Window in SDL_video.h
  ✓ Found SDL_Rect in SDL_rect.h

Type Filtering

Only SDL types are processed:

  • Types starting with SDL_
  • Known SDL types (Window, Rect, etc.)

Primitive types are ignored:

  • bool, int, float, void, etc.

Pattern Matching Order

Patterns are tried in this order:

  1. Opaque types (typedef struct X X;)
  2. Enums (typedef enum {...} X;)
  3. Structs (typedef struct {...} X;)
  4. Flags (typedef Uint32 SDL_Flags; + #define values)
  5. Typedefs (typedef Type SDL_Alias;)
  6. Functions (extern SDL_DECLSPEC ...)

Note: Order matters! Flags must be tried before simple typedefs.

Naming Conventions

Types:

  • SDL_GPUDeviceGPUDevice (strip SDL_ prefix)
  • SDL_GPU_PRIMITIVE_TYPEGPUPrimitiveType (remove first underscore)

Functions:

  • SDL_CreateGPUDevicecreateGPUDevice (strip SDL_, camelCase)

Enum Values:

  • SDL_GPU_PRIMITIVETYPE_TRIANGLELISTprimitiveTypeTrianglelist

Parameters:

  • SDL_GPUDevice *devicedevice: ?*GPUDevice

Exit Codes

  • 0 - Success
  • 1 - Error (file not found, out of memory, invalid arguments)

Console Output

Normal Operation

SDL3 Header Parser
==================

Parsing: header.h

Found N declarations
  - Opaque types: X
  - Typedefs: X
  - Enums: X
  - Structs: X
  - Flags: X
  - Functions: X

Analyzing dependencies...
[dependency information]

Generated: output.zig

With Warnings

Resolving dependencies...
  ✓ Found SDL_Window in SDL_video.h
  ⚠ Warning: Could not find definition for type: SDL_Unknown

With Errors

Error: 5 syntax errors detected in generated code
  Line 10: expected_comma_after_field
  Line 12: expected_type_expr
  ...

File is still written, but may need manual fixes.

Type Conversion Reference

Integer Types

C Type Zig Type
Uint8 u8
Uint16 u16
Uint32 u32
Uint64 u64
Sint8 i8
Sint16 i16
Sint32 i32
Sint64 i64
int c_int
unsigned int c_uint
size_t usize

Pointer Types

C Type Zig Type
SDL_Type* ?*Type (nullable)
const SDL_Type* *const Type
SDL_Type** ?*?*Type
void* ?*anyopaque
const void* *const anyopaque
const char* [*c]const u8

Special Types

C Type Zig Type
bool bool
float f32
double f64
size_t usize

Examples

Example 1: Simple Header

Input (simple.h):

typedef struct SDL_Thing SDL_Thing;
typedef Uint32 SDL_ThingID;

extern SDL_DECLSPEC SDL_ThingID SDLCALL SDL_CreateThing(void);
extern SDL_DECLSPEC void SDLCALL SDL_DestroyThing(SDL_Thing *thing);

Command:

zig build run -- simple.h --output=thing.zig

Output (thing.zig):

pub const c = @import("c.zig").c;

pub const ThingID = u32;

pub const Thing = opaque {
    pub inline fn destroyThing(thing: *Thing) void {
        return c.SDL_DestroyThing(thing);
    }
};

pub inline fn createThing() ThingID {
    return c.SDL_CreateThing();
}

Example 2: With Dependencies

Input (depends.h):

#include <SDL3/SDL_rect.h>

extern void SDL_UseRect(SDL_Rect *rect);

Command:

zig build run -- depends.h --output=depends.zig

Output:

pub const c = @import("c.zig").c;

// Dependency automatically included
pub const Rect = extern struct {
    x: c_int,
    y: c_int,
    w: c_int,
    h: c_int,
};

pub inline fn useRect(rect: *Rect) void {
    return c.SDL_UseRect(rect);
}

Example 3: With Mocks

Command:

zig build run -- simple.h --output=thing.zig --mocks=thing_mock.c

Output (thing_mock.c):

#include <SDL3/SDL.h>

SDL_ThingID SDL_CreateThing(void) {
    return 0;
}

void SDL_DestroyThing(SDL_Thing *thing) {
    // No-op
}

Performance Characteristics

Timing

Operation Time (SDL_gpu.h)
Parse primary header ~50ms
Analyze dependencies ~10ms
Extract dependencies ~300ms
Generate code ~150ms
Total ~520ms

Memory

Component Memory
Source files ~150KB
Declarations ~2MB
Output ~53KB
Peak Total ~2.2MB

Scaling

  • Time: O(n + h×d) where n=lines, h=headers, d=declarations
  • Memory: O(d) where d=total declarations
  • Linear scaling with input size

Advanced Usage

Batch Processing

for header in SDL/include/SDL3/SDL_*.h; do
    name=$(basename "$header" .h)
    zig build run -- "$header" --output="bindings/${name}.zig"
done

CI/CD Integration

- name: Generate SDL bindings
  run: |
    cd lib/sdl3
    zig build regenerate-zig
    git diff --exit-code v2/*.zig || echo "Bindings updated"    

Validation

# Generate and validate
zig build run -- header.h --output=test.zig
zig ast-check test.zig

See Also: