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)");
|
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"
|
// Look for bit shift pattern: "1u << N" or "1 << N"
|
||||||
if (std.mem.indexOf(u8, trimmed, "<<")) |shift_pos| {
|
if (std.mem.indexOf(u8, trimmed, "<<")) |shift_pos| {
|
||||||
const after_shift = std.mem.trim(u8, trimmed[shift_pos + 2 ..], " \t)");
|
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;
|
if (trimmed.len == 0) continue;
|
||||||
|
|
||||||
// Find the last identifier (parameter name)
|
// 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
|
// Simple heuristic: last space or * separates type from name
|
||||||
var name_start: usize = 0;
|
var name_start: usize = 0;
|
||||||
var i = trimmed.len;
|
var i = working_param.len;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
i -= 1;
|
i -= 1;
|
||||||
const c = trimmed[i];
|
const c = working_param[i];
|
||||||
if (c == ' ' or c == '*' or c == '\t') {
|
if (c == ' ' or c == '*' or c == '\t') {
|
||||||
name_start = i + 1;
|
name_start = i + 1;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1113,11 +1126,31 @@ pub const Scanner = struct {
|
||||||
// No space found - might be just a type (like "void")
|
// No space found - might be just a type (like "void")
|
||||||
try params_list.append(self.allocator, ParamDecl{
|
try params_list.append(self.allocator, ParamDecl{
|
||||||
.name = "",
|
.name = "",
|
||||||
.type_name = try self.allocator.dupe(u8, trimmed),
|
.type_name = try self.allocator.dupe(u8, working_param),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const param_type = std.mem.trim(u8, trimmed[0..name_start], " \t");
|
var param_type = std.mem.trim(u8, working_param[0..name_start], " \t");
|
||||||
const param_name = std.mem.trim(u8, trimmed[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{
|
try params_list.append(self.allocator, ParamDecl{
|
||||||
.name = try self.allocator.dupe(u8, param_name),
|
.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 **")) 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, "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]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, "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, "const void *")) return try allocator.dupe(u8, "?*const anyopaque");
|
||||||
if (std.mem.eql(u8, trimmed, "void **")) return try allocator.dupe(u8, "[*c]?*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) {
|
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,
|
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 {
|
pub inline fn init(flags: InitFlags) bool {
|
||||||
return c.SDL_Init(@bitCast(flags));
|
return c.SDL_Init(@bitCast(flags));
|
||||||
|
|
@ -80,7 +88,7 @@ pub inline fn isMainThread() bool {
|
||||||
return c.SDL_IsMainThread();
|
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 {
|
pub inline fn runOnMainThread(callback: MainThreadCallback, userdata: ?*anyopaque, wait_complete: bool) bool {
|
||||||
return c.SDL_RunOnMainThread(callback, userdata, wait_complete);
|
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 {
|
pub inline fn getAppMetadataProperty(name: [*c]const u8) [*c]const u8 {
|
||||||
return c.SDL_GetAppMetadataProperty(name);
|
return c.SDL_GetAppMetadataProperty(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,11 @@ pub const Colorspace = enum(c_int) {
|
||||||
pub const PropertiesID = u32;
|
pub const PropertiesID = u32;
|
||||||
|
|
||||||
pub const SurfaceFlags = packed struct(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,
|
rsvd: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue