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

266 lines
5.4 KiB
Markdown

# Usage Guide
## Installation
```bash
cd lib/sdl3/parser
zig build
```
## Basic Usage
### Parse a Header File
```bash
# Output to stdout
zig build run -- ../SDL/include/SDL3/SDL_gpu.h
# Save to file with --output
zig build run -- ../SDL/include/SDL3/SDL_gpu.h --output=gpu.zig
# Generate with C mocks
zig build run -- ../SDL/include/SDL3/SDL_gpu.h --output=gpu.zig --mocks=gpu_mock.c
# Test mock generation (uses test_small.h)
zig build test-mocks
# Output: zig-out/test_small.zig and zig-out/test_small_mock.c
```
### Command Line Options
- `<header-file>` - Path to C header file to parse (required)
- `--output=<path>` - Write Zig bindings to specified file (optional, defaults to stdout)
- `--mocks=<path>` - Generate C mock implementations at specified path (optional)
### Run Tests
```bash
# All unit tests
zig build test
# Test mock generation
zig build test-mocks
```
## Output Format
The parser outputs Zig code with this structure:
```zig
pub const c = @import("c.zig").c;
// 1. Opaque types
pub const GPUDevice = opaque {};
// 2. Enums
pub const GPUPrimitiveType = enum(c_int) { ... };
// 3. Flags (packed structs)
pub const GPUTextureUsageFlags = packed struct(u32) { ... };
// 4. Structs
pub const GPUViewport = extern struct { ... };
// 5. Functions (inline wrappers)
pub inline fn createGPUDevice(...) ... { ... }
```
## Integration
### Using Generated Bindings
```zig
// Your project
const gpu = @import("gpu.zig");
pub fn main() !void {
// Use opaque types
const device = gpu.createGPUDevice(false, false, null);
defer if (device) |d| gpu.destroyGPUDevice(d);
// Use enums
const prim_type = gpu.GPUPrimitiveType.primitivetypeTrianglelist;
// Use flags
var usage: gpu.GPUTextureUsageFlags = .{};
usage.textureusageSampler = true;
usage.textureusageColorTarget = true;
// Use structs
const viewport = gpu.GPUViewport{
.x = 0.0,
.y = 0.0,
.w = 800.0,
.h = 600.0,
.min_depth = 0.0,
.max_depth = 1.0,
};
}
```
### Required c.zig
The generated bindings expect a `c.zig` file that exports C declarations:
```zig
// c.zig
pub const c = @cImport({
@cInclude("SDL3/SDL.h");
@cInclude("SDL3/SDL_gpu.h");
});
```
Or link with SDL3 directly in your build.zig:
```zig
const exe = b.addExecutable(.{
.name = "my_app",
.root_source_file = b.path("src/main.zig"),
// ...
});
exe.linkSystemLibrary("SDL3");
exe.linkLibC();
```
## Common Patterns
### Handling Opaque Pointers
```zig
// Functions return optional pointers
const device: ?*gpu.GPUDevice = gpu.createGPUDevice(...);
// Check before use
if (device) |d| {
// Use d safely
gpu.destroyGPUDevice(d);
}
```
### Working with Flags
```zig
// Initialize empty
var flags: gpu.GPUTextureUsageFlags = .{};
// Set individual bits
flags.textureusageSampler = true;
flags.textureusageColorTarget = true;
// Pass to functions
const texture = gpu.createGPUTexture(device, &.{
.usage = flags,
// ... other fields
});
```
### Enum Comparisons
```zig
const prim_type = gpu.GPUPrimitiveType.primitivetypeTrianglelist;
if (prim_type == .primitivetypeTrianglelist) {
// Handle triangle list
}
```
## Troubleshooting
### Issue: "error: use of undeclared identifier 'c'"
**Solution**: Create a `c.zig` file that imports SDL3 headers:
```zig
pub const c = @cImport({
@cInclude("SDL3/SDL.h");
});
```
### Issue: Parser crashes on header file
**Cause**: Unsupported C pattern
**Solution**: Check parser output for errors, file an issue with the problematic pattern
### Issue: Generated names don't match expectations
**Cause**: Naming convention mismatch
**Solution**: See [Naming Conventions](naming.md) for the conversion rules
### Issue: Memory leak warnings
**Cause**: Parser bug (should not happen in current version)
**Solution**: Run with GPA to identify leak, file an issue
```bash
zig build run -- header.h 2>&1 | grep -i leak
```
## Performance Tips
### For Large Headers
- Parser is O(n) in source size, typically <500ms
- Memory usage is O(declarations), typically <10MB
- No performance tuning needed for typical SDL3 headers
### Batch Processing
```bash
# Parse multiple headers
for header in ../SDL/include/SDL3/*.h; do
basename="${header##*/}"
zig build run -- "$header" > "output/${basename%.h}.zig"
done
```
## Advanced Usage
### Custom Naming
Edit `naming.zig` to customize conversion rules:
```zig
pub fn typeNameToZig(c_name: []const u8) []const u8 {
// Custom logic here
}
```
### Adding New Patterns
See [Architecture](architecture.md#extension-points) for how to add support for new C patterns.
### Debugging
```bash
# Run with debug info
zig build -Doptimize=Debug
zig-out/bin/sdl-parser header.h
# Check what's being parsed
zig build run -- header.h 2>&1 | head -20
```
## FAQ
**Q: Does the parser support C++?**
A: No, only C headers. C++ requires a full C++ parser.
**Q: Can I use this for non-SDL libraries?**
A: Yes, but it's optimized for SDL3 naming conventions. You may need to adjust naming.zig.
**Q: Does it handle macros?**
A: Only `#define` for flag values. Complex macros are not supported.
**Q: What about function pointers?**
A: Basic support exists but may need refinement for complex signatures.
**Q: Can it generate C code?**
A: Not yet, but mock generation is planned (see TEST_HARNESS_PLAN_V2.md).
**Q: Is it production ready?**
A: Yes for SDL3. It's tested with SDL_gpu.h and generates valid, working bindings.