Fix pointer-to-const-pointer parsing (SDL_Type *const *)

- Handle cases where parameter name includes leading * characters
- Move * from parameter name to parameter type during parsing
- Support both 'SDL_Type *const *' and 'SDL_Type * const *' patterns
- All SDL3 headers now generate without syntax errors
This commit is contained in:
Peterino2 2026-01-22 19:45:02 -08:00
parent a71d236c0c
commit 2440d81b5c
4 changed files with 27 additions and 19 deletions

View File

@ -1260,11 +1260,19 @@ pub const Scanner = struct {
}); });
} else { } else {
var param_type = std.mem.trim(u8, working_param[0..name_start], " \t"); var param_type = std.mem.trim(u8, working_param[0..name_start], " \t");
const param_name = std.mem.trim(u8, working_param[name_start..], " \t"); var param_name = std.mem.trim(u8, working_param[name_start..], " \t");
// If param_name starts with *, it belongs to the type
// e.g., "SDL_GPUFence *const" and "*fences" should be "SDL_GPUFence *const *" and "fences"
var type_buf: [512]u8 = undefined;
while (param_name.len > 0 and param_name[0] == '*') {
const new_type = try std.fmt.bufPrint(&type_buf, "{s} *", .{param_type});
param_type = new_type;
param_name = std.mem.trimLeft(u8, param_name[1..], " \t");
}
// If this was an array parameter, convert pointer level // If this was an array parameter, convert pointer level
// e.g., "char *" becomes "[*c][*c]char" for argv[] // e.g., "char *" becomes "[*c][*c]char" for argv[]
var type_buf: [256]u8 = undefined;
if (is_array) { if (is_array) {
// For array parameters like argv[], we need pointer-to-pointer // For array parameters like argv[], we need pointer-to-pointer
// Input: "char *argv[]" -> after strip: "char *" // Input: "char *argv[]" -> after strip: "char *"

View File

@ -68,11 +68,17 @@ pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 {
if (std.mem.eql(u8, trimmed, "const int *")) return try allocator.dupe(u8, "[*c]const c_int"); if (std.mem.eql(u8, trimmed, "const int *")) return try allocator.dupe(u8, "[*c]const c_int");
// Handle SDL types with pointers // Handle SDL types with pointers
// Check for double pointers like "SDL_Type **" or "SDL_Type * const *" // Check for double pointers like "SDL_Type **" or "SDL_Type *const *" or "SDL_Type * const *"
if (std.mem.startsWith(u8, trimmed, "SDL_")) { if (std.mem.startsWith(u8, trimmed, "SDL_")) {
// Match "SDL_Type *const *" (no space before const)
if (std.mem.indexOf(u8, trimmed, " *const *")) |pos| {
const base_type = trimmed[4..pos]; // Remove SDL_ prefix and get type
return std.fmt.allocPrint(allocator, "[*c]*const {s}", .{base_type});
}
// Match "SDL_Type * const *" (space before const)
if (std.mem.indexOf(u8, trimmed, " * const *")) |pos| { if (std.mem.indexOf(u8, trimmed, " * const *")) |pos| {
const base_type = trimmed[4..pos]; // Remove SDL_ prefix and get type const base_type = trimmed[4..pos]; // Remove SDL_ prefix and get type
return std.fmt.allocPrint(allocator, "[*c]const *{s}", .{base_type}); return std.fmt.allocPrint(allocator, "[*c]*const {s}", .{base_type});
} }
if (std.mem.indexOf(u8, trimmed, " **")) |pos| { if (std.mem.indexOf(u8, trimmed, " **")) |pos| {
const base_type = trimmed[4..pos]; // Remove SDL_ prefix and get type const base_type = trimmed[4..pos]; // Remove SDL_ prefix and get type

View File

@ -201,7 +201,7 @@ pub inline fn closeAudioDevice(devid: AudioDeviceID) void {
return c.SDL_CloseAudioDevice(devid); return c.SDL_CloseAudioDevice(devid);
} }
pub inline fn bindAudioStreams(devid: AudioDeviceID, streams: [*c]const *AudioStream, num_streams: c_int) bool { pub inline fn bindAudioStreams(devid: AudioDeviceID, streams: [*c]*const AudioStream, num_streams: c_int) bool {
return c.SDL_BindAudioStreams(devid, streams, num_streams); return c.SDL_BindAudioStreams(devid, streams, num_streams);
} }
@ -209,7 +209,7 @@ pub inline fn bindAudioStream(devid: AudioDeviceID, stream: ?*AudioStream) bool
return c.SDL_BindAudioStream(devid, stream); return c.SDL_BindAudioStream(devid, stream);
} }
pub inline fn unbindAudioStreams(streams: [*c]const *AudioStream, num_streams: c_int) void { pub inline fn unbindAudioStreams(streams: [*c]*const AudioStream, num_streams: c_int) void {
return c.SDL_UnbindAudioStreams(streams, num_streams); return c.SDL_UnbindAudioStreams(streams, num_streams);
} }

20
lib/sdl3/v2/gpu.zig vendored
View File

@ -144,7 +144,7 @@ pub const GPUDevice = opaque {
return c.SDL_WaitForGPUIdle(gpudevice); return c.SDL_WaitForGPUIdle(gpudevice);
} }
pub inline fn waitForGPUFences(gpudevice: *GPUDevice, wait_all: bool, fences: ?*GPUFence *const, num_fences: u32) bool { pub inline fn waitForGPUFences(gpudevice: *GPUDevice, wait_all: bool, fences: [*c]*const GPUFence, num_fences: u32) bool {
return c.SDL_WaitForGPUFences(gpudevice, wait_all, fences, num_fences); return c.SDL_WaitForGPUFences(gpudevice, wait_all, fences, num_fences);
} }
@ -171,7 +171,6 @@ pub const GPUDevice = opaque {
pub inline fn gdkResumeGPU(gpudevice: *GPUDevice) void { pub inline fn gdkResumeGPU(gpudevice: *GPUDevice) void {
return c.SDL_GDKResumeGPU(gpudevice); return c.SDL_GDKResumeGPU(gpudevice);
} }
}; };
pub const GPUBuffer = opaque {}; pub const GPUBuffer = opaque {};
@ -252,7 +251,6 @@ pub const GPUCommandBuffer = opaque {
pub inline fn cancelGPUCommandBuffer(gpucommandbuffer: *GPUCommandBuffer) bool { pub inline fn cancelGPUCommandBuffer(gpucommandbuffer: *GPUCommandBuffer) bool {
return c.SDL_CancelGPUCommandBuffer(gpucommandbuffer); return c.SDL_CancelGPUCommandBuffer(gpucommandbuffer);
} }
}; };
pub const GPURenderPass = opaque { pub const GPURenderPass = opaque {
@ -288,11 +286,11 @@ pub const GPURenderPass = opaque {
return c.SDL_BindGPUVertexSamplers(gpurenderpass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings); return c.SDL_BindGPUVertexSamplers(gpurenderpass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings);
} }
pub inline fn bindGPUVertexStorageTextures(gpurenderpass: *GPURenderPass, first_slot: u32, storage_textures: ?*GPUTexture *const, num_bindings: u32) void { pub inline fn bindGPUVertexStorageTextures(gpurenderpass: *GPURenderPass, first_slot: u32, storage_textures: [*c]*const GPUTexture, num_bindings: u32) void {
return c.SDL_BindGPUVertexStorageTextures(gpurenderpass, first_slot, storage_textures, num_bindings); return c.SDL_BindGPUVertexStorageTextures(gpurenderpass, first_slot, storage_textures, num_bindings);
} }
pub inline fn bindGPUVertexStorageBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, storage_buffers: ?*GPUBuffer *const, num_bindings: u32) void { pub inline fn bindGPUVertexStorageBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, storage_buffers: [*c]*const GPUBuffer, num_bindings: u32) void {
return c.SDL_BindGPUVertexStorageBuffers(gpurenderpass, first_slot, storage_buffers, num_bindings); return c.SDL_BindGPUVertexStorageBuffers(gpurenderpass, first_slot, storage_buffers, num_bindings);
} }
@ -300,11 +298,11 @@ pub const GPURenderPass = opaque {
return c.SDL_BindGPUFragmentSamplers(gpurenderpass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings); return c.SDL_BindGPUFragmentSamplers(gpurenderpass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings);
} }
pub inline fn bindGPUFragmentStorageTextures(gpurenderpass: *GPURenderPass, first_slot: u32, storage_textures: ?*GPUTexture *const, num_bindings: u32) void { pub inline fn bindGPUFragmentStorageTextures(gpurenderpass: *GPURenderPass, first_slot: u32, storage_textures: [*c]*const GPUTexture, num_bindings: u32) void {
return c.SDL_BindGPUFragmentStorageTextures(gpurenderpass, first_slot, storage_textures, num_bindings); return c.SDL_BindGPUFragmentStorageTextures(gpurenderpass, first_slot, storage_textures, num_bindings);
} }
pub inline fn bindGPUFragmentStorageBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, storage_buffers: ?*GPUBuffer *const, num_bindings: u32) void { pub inline fn bindGPUFragmentStorageBuffers(gpurenderpass: *GPURenderPass, first_slot: u32, storage_buffers: [*c]*const GPUBuffer, num_bindings: u32) void {
return c.SDL_BindGPUFragmentStorageBuffers(gpurenderpass, first_slot, storage_buffers, num_bindings); return c.SDL_BindGPUFragmentStorageBuffers(gpurenderpass, first_slot, storage_buffers, num_bindings);
} }
@ -327,7 +325,6 @@ pub const GPURenderPass = opaque {
pub inline fn endGPURenderPass(gpurenderpass: *GPURenderPass) void { pub inline fn endGPURenderPass(gpurenderpass: *GPURenderPass) void {
return c.SDL_EndGPURenderPass(gpurenderpass); return c.SDL_EndGPURenderPass(gpurenderpass);
} }
}; };
pub const GPUComputePass = opaque { pub const GPUComputePass = opaque {
@ -339,11 +336,11 @@ pub const GPUComputePass = opaque {
return c.SDL_BindGPUComputeSamplers(gpucomputepass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings); return c.SDL_BindGPUComputeSamplers(gpucomputepass, first_slot, @ptrCast(texture_sampler_bindings), num_bindings);
} }
pub inline fn bindGPUComputeStorageTextures(gpucomputepass: *GPUComputePass, first_slot: u32, storage_textures: ?*GPUTexture *const, num_bindings: u32) void { pub inline fn bindGPUComputeStorageTextures(gpucomputepass: *GPUComputePass, first_slot: u32, storage_textures: [*c]*const GPUTexture, num_bindings: u32) void {
return c.SDL_BindGPUComputeStorageTextures(gpucomputepass, first_slot, storage_textures, num_bindings); return c.SDL_BindGPUComputeStorageTextures(gpucomputepass, first_slot, storage_textures, num_bindings);
} }
pub inline fn bindGPUComputeStorageBuffers(gpucomputepass: *GPUComputePass, first_slot: u32, storage_buffers: ?*GPUBuffer *const, num_bindings: u32) void { pub inline fn bindGPUComputeStorageBuffers(gpucomputepass: *GPUComputePass, first_slot: u32, storage_buffers: [*c]*const GPUBuffer, num_bindings: u32) void {
return c.SDL_BindGPUComputeStorageBuffers(gpucomputepass, first_slot, storage_buffers, num_bindings); return c.SDL_BindGPUComputeStorageBuffers(gpucomputepass, first_slot, storage_buffers, num_bindings);
} }
@ -358,7 +355,6 @@ pub const GPUComputePass = opaque {
pub inline fn endGPUComputePass(gpucomputepass: *GPUComputePass) void { pub inline fn endGPUComputePass(gpucomputepass: *GPUComputePass) void {
return c.SDL_EndGPUComputePass(gpucomputepass); return c.SDL_EndGPUComputePass(gpucomputepass);
} }
}; };
pub const GPUCopyPass = opaque { pub const GPUCopyPass = opaque {
@ -389,7 +385,6 @@ pub const GPUCopyPass = opaque {
pub inline fn endGPUCopyPass(gpucopypass: *GPUCopyPass) void { pub inline fn endGPUCopyPass(gpucopypass: *GPUCopyPass) void {
return c.SDL_EndGPUCopyPass(gpucopypass); return c.SDL_EndGPUCopyPass(gpucopypass);
} }
}; };
pub const GPUFence = opaque {}; pub const GPUFence = opaque {};
@ -981,4 +976,3 @@ pub inline fn gpuTextureFormatTexelBlockSize(format: GPUTextureFormat) u32 {
pub inline fn calculateGPUTextureFormatSize(format: GPUTextureFormat, width: u32, height: u32, depth_or_layer_count: u32) u32 { pub inline fn calculateGPUTextureFormatSize(format: GPUTextureFormat, width: u32, height: u32, depth_or_layer_count: u32) u32 {
return c.SDL_CalculateGPUTextureFormatSize(@bitCast(format), width, height, depth_or_layer_count); return c.SDL_CalculateGPUTextureFormatSize(@bitCast(format), width, height, depth_or_layer_count);
} }