fix: handle hex flag values with 'u' suffix and array parameters
- Strip 'u'/'U' suffix from hex literals before parsing bit positions - Fixed array parameter syntax (argv[]) -> converted to pointer-to-pointer - Added type conversion for char ** and char** - SDL_init.h now parses successfully (15/16 headers working) Still unsupported: - SDL_iostream.h: function pointer fields in structs (complex C syntax)
This commit is contained in:
parent
724b5e1a05
commit
0c548e053a
|
|
@ -603,6 +603,11 @@ pub const CodeGen = struct {
|
|||
trimmed = std.mem.trim(u8, trimmed[inner_start..], " \t)");
|
||||
}
|
||||
|
||||
// Strip 'u' or 'U' suffix from C literals (e.g., "0x00000010u" -> "0x00000010")
|
||||
if (trimmed.len > 0 and (trimmed[trimmed.len - 1] == 'u' or trimmed[trimmed.len - 1] == 'U')) {
|
||||
trimmed = trimmed[0 .. trimmed.len - 1];
|
||||
}
|
||||
|
||||
// Look for bit shift pattern: "1u << N" or "1 << N"
|
||||
if (std.mem.indexOf(u8, trimmed, "<<")) |shift_pos| {
|
||||
const after_shift = std.mem.trim(u8, trimmed[shift_pos + 2 ..], " \t)");
|
||||
|
|
|
|||
|
|
@ -1097,12 +1097,25 @@ pub const Scanner = struct {
|
|||
if (trimmed.len == 0) continue;
|
||||
|
||||
// Find the last identifier (parameter name)
|
||||
// Handle array syntax like "char *argv[]" -> type:"char **" name:"argv"
|
||||
var working_param = trimmed;
|
||||
var is_array = false;
|
||||
|
||||
// Check for array brackets [] and remove them
|
||||
if (std.mem.lastIndexOfScalar(u8, working_param, '[')) |bracket_pos| {
|
||||
// Find matching ]
|
||||
if (std.mem.indexOfScalar(u8, working_param[bracket_pos..], ']')) |_| {
|
||||
is_array = true;
|
||||
working_param = std.mem.trimRight(u8, working_param[0..bracket_pos], " \t");
|
||||
}
|
||||
}
|
||||
|
||||
// Simple heuristic: last space or * separates type from name
|
||||
var name_start: usize = 0;
|
||||
var i = trimmed.len;
|
||||
var i = working_param.len;
|
||||
while (i > 0) {
|
||||
i -= 1;
|
||||
const c = trimmed[i];
|
||||
const c = working_param[i];
|
||||
if (c == ' ' or c == '*' or c == '\t') {
|
||||
name_start = i + 1;
|
||||
break;
|
||||
|
|
@ -1113,11 +1126,31 @@ pub const Scanner = struct {
|
|||
// No space found - might be just a type (like "void")
|
||||
try params_list.append(self.allocator, ParamDecl{
|
||||
.name = "",
|
||||
.type_name = try self.allocator.dupe(u8, trimmed),
|
||||
.type_name = try self.allocator.dupe(u8, working_param),
|
||||
});
|
||||
} else {
|
||||
const param_type = std.mem.trim(u8, trimmed[0..name_start], " \t");
|
||||
const param_name = std.mem.trim(u8, trimmed[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");
|
||||
|
||||
// If this was an array parameter, convert pointer level
|
||||
// e.g., "char *" becomes "[*c][*c]char" for argv[]
|
||||
var type_buf: [256]u8 = undefined;
|
||||
if (is_array) {
|
||||
// For array parameters like argv[], we need pointer-to-pointer
|
||||
// Input: "char *argv[]" -> after strip: "char *"
|
||||
// Output type should be: "[*c][*c]char"
|
||||
// But for simplicity in generated code, we can use the original type + pointer
|
||||
// Check if type already ends with *
|
||||
const trimmed_type = std.mem.trimRight(u8, param_type, " \t");
|
||||
if (std.mem.endsWith(u8, trimmed_type, "*")) {
|
||||
// Already has pointer, add another without space
|
||||
const type_copy = try std.fmt.bufPrint(&type_buf, "{s}*", .{trimmed_type});
|
||||
param_type = type_copy;
|
||||
} else {
|
||||
const type_copy = try std.fmt.bufPrint(&type_buf, "{s} *", .{param_type});
|
||||
param_type = type_copy;
|
||||
}
|
||||
}
|
||||
|
||||
try params_list.append(self.allocator, ParamDecl{
|
||||
.name = try self.allocator.dupe(u8, param_name),
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 {
|
|||
if (std.mem.eql(u8, trimmed, "const char **")) return try allocator.dupe(u8, "[*c][*c]const u8");
|
||||
if (std.mem.eql(u8, trimmed, "const char * const *")) return try allocator.dupe(u8, "[*c]const [*c]const u8");
|
||||
if (std.mem.eql(u8, trimmed, "char *")) return try allocator.dupe(u8, "[*c]u8");
|
||||
if (std.mem.eql(u8, trimmed, "char **")) return try allocator.dupe(u8, "[*c][*c]u8");
|
||||
if (std.mem.eql(u8, trimmed, "char**")) return try allocator.dupe(u8, "[*c][*c]u8");
|
||||
if (std.mem.eql(u8, trimmed, "void *")) return try allocator.dupe(u8, "?*anyopaque");
|
||||
if (std.mem.eql(u8, trimmed, "const void *")) return try allocator.dupe(u8, "?*const anyopaque");
|
||||
if (std.mem.eql(u8, trimmed, "void **")) return try allocator.dupe(u8, "[*c]?*anyopaque");
|
||||
|
|
|
|||
|
|
@ -44,17 +44,25 @@ pub const Event = extern union {
|
|||
};
|
||||
|
||||
pub const InitFlags = packed struct(u32) {
|
||||
pad0: u31 = 0,
|
||||
initAudio: bool = false, // `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS`
|
||||
initVideo: bool = false, // `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread
|
||||
initJoystick: bool = false, // `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`, should be initialized on the same thread as SDL_INIT_VIDEO on Windows if you don't set SDL_HINT_JOYSTICK_THREAD
|
||||
initHaptic: bool = false,
|
||||
initGamepad: bool = false, // `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK`
|
||||
initEvents: bool = false,
|
||||
initSensor: bool = false, // `SDL_INIT_SENSOR` implies `SDL_INIT_EVENTS`
|
||||
initCamera: bool = false, // `SDL_INIT_CAMERA` implies `SDL_INIT_EVENTS`
|
||||
pad0: u23 = 0,
|
||||
rsvd: bool = false,
|
||||
};
|
||||
|
||||
pub const AppInit_func = *const fn(appstate: [*c]?*anyopaque, argc: c_int, argv[]: [*c]u8) callconv(.C) AppResult;
|
||||
pub const AppInit_func = *const fn (appstate: [*c]?*anyopaque, argc: c_int, argv: [*c][*c]u8) callconv(.C) AppResult;
|
||||
|
||||
pub const AppIterate_func = *const fn(appstate: ?*anyopaque) callconv(.C) AppResult;
|
||||
pub const AppIterate_func = *const fn (appstate: ?*anyopaque) callconv(.C) AppResult;
|
||||
|
||||
pub const AppEvent_func = *const fn(appstate: ?*anyopaque, event: ?*Event) callconv(.C) AppResult;
|
||||
pub const AppEvent_func = *const fn (appstate: ?*anyopaque, event: ?*Event) callconv(.C) AppResult;
|
||||
|
||||
pub const AppQuit_func = *const fn(appstate: ?*anyopaque, result: AppResult) callconv(.C) void;
|
||||
pub const AppQuit_func = *const fn (appstate: ?*anyopaque, result: AppResult) callconv(.C) void;
|
||||
|
||||
pub inline fn init(flags: InitFlags) bool {
|
||||
return c.SDL_Init(@bitCast(flags));
|
||||
|
|
@ -80,7 +88,7 @@ pub inline fn isMainThread() bool {
|
|||
return c.SDL_IsMainThread();
|
||||
}
|
||||
|
||||
pub const MainThreadCallback = *const fn(userdata: ?*anyopaque) callconv(.C) void;
|
||||
pub const MainThreadCallback = *const fn (userdata: ?*anyopaque) callconv(.C) void;
|
||||
|
||||
pub inline fn runOnMainThread(callback: MainThreadCallback, userdata: ?*anyopaque, wait_complete: bool) bool {
|
||||
return c.SDL_RunOnMainThread(callback, userdata, wait_complete);
|
||||
|
|
@ -97,4 +105,3 @@ pub inline fn setAppMetadataProperty(name: [*c]const u8, value: [*c]const u8) bo
|
|||
pub inline fn getAppMetadataProperty(name: [*c]const u8) [*c]const u8 {
|
||||
return c.SDL_GetAppMetadataProperty(name);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,11 @@ pub const Colorspace = enum(c_int) {
|
|||
pub const PropertiesID = u32;
|
||||
|
||||
pub const SurfaceFlags = packed struct(u32) {
|
||||
pad0: u31 = 0,
|
||||
surfacePreallocated: bool = false, // Surface uses preallocated pixel memory
|
||||
surfaceLockNeeded: bool = false, // Surface needs to be locked to access pixels
|
||||
surfaceLocked: bool = false, // Surface is currently locked
|
||||
surfaceSimdAligned: bool = false, // Surface uses pixel memory allocated with SDL_aligned_alloc()
|
||||
pad0: u27 = 0,
|
||||
rsvd: bool = false,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue