diff --git a/lib/sdl3/parser/src/patterns.zig b/lib/sdl3/parser/src/patterns.zig index f03b792..237e288 100644 --- a/lib/sdl3/parser/src/patterns.zig +++ b/lib/sdl3/parser/src/patterns.zig @@ -376,8 +376,8 @@ pub const Scanner = struct { const trimmed = std.mem.trim(u8, line, " \t\r"); if (trimmed.len == 0) continue; - // Track multi-line comments - if (std.mem.indexOf(u8, trimmed, "/**")) |_| { + // Track multi-line comments (both /** and /* styles) + if (std.mem.indexOf(u8, trimmed, "/*")) |_| { in_multiline_comment = true; } if (in_multiline_comment) { @@ -389,7 +389,6 @@ pub const Scanner = struct { // Skip various comment/bracket/preprocessor lines if (std.mem.startsWith(u8, trimmed, "//")) continue; - if (std.mem.startsWith(u8, trimmed, "/*")) continue; if (std.mem.startsWith(u8, trimmed, "*")) continue; // Lines inside comments if (std.mem.startsWith(u8, trimmed, "#")) continue; // Preprocessor directives if (std.mem.startsWith(u8, trimmed, "{")) continue; @@ -581,10 +580,54 @@ pub const Scanner = struct { return null; } - // Parse "type name" - handle pointer types correctly + // Parse "type name" or "type name[size]" - handle pointer types and arrays correctly // Examples: // "SDL_GPUTransferBuffer *transfer_buffer" -> type:"SDL_GPUTransferBuffer *" name:"transfer_buffer" // "Uint32 offset" -> type:"Uint32" name:"offset" + // "Uint8 padding[2]" -> type:"Uint8[2]" name:"padding" + + // Check if this is an array field (has brackets) + if (std.mem.indexOf(u8, field_trimmed, "[")) |bracket_pos| { + // Extract array size and append to type + // Pattern: "Uint8 padding[2]" -> parse as type="Uint8[2]" name="padding" + const before_bracket = std.mem.trimRight(u8, field_trimmed[0..bracket_pos], " \t"); + const bracket_part = field_trimmed[bracket_pos..]; // "[2]" + + // Split before_bracket into type and name + var tokens = std.mem.tokenizeScalar(u8, before_bracket, ' '); + var parts_list: [8][]const u8 = undefined; + var parts_count: usize = 0; + while (tokens.next()) |token| { + if (token.len > 0 and !std.mem.eql(u8, token, "const")) { + if (parts_count >= 8) return null; + parts_list[parts_count] = token; + parts_count += 1; + } + } + + if (parts_count < 2) return null; // Need at least type and name + + const name = parts_list[parts_count - 1]; + const type_parts = parts_list[0..parts_count - 1]; + + // Reconstruct type with array notation + var type_buf: [128]u8 = undefined; + var fbs = std.io.fixedBufferStream(&type_buf); + const writer = fbs.writer(); + for (type_parts, 0..) |part, i| { + if (i > 0) writer.writeByte(' ') catch return null; + writer.writeAll(part) catch return null; + } + writer.writeAll(bracket_part) catch return null; + + const type_str = fbs.getWritten(); + + return FieldDecl{ + .name = try self.allocator.dupe(u8, name), + .type_name = try self.allocator.dupe(u8, type_str), + .comment = comment, + }; + } // Find last identifier by scanning backwards for alphanumeric/_ // The field name is the last contiguous sequence of [a-zA-Z0-9_] diff --git a/lib/sdl3/parser/src/types.zig b/lib/sdl3/parser/src/types.zig index 95b270b..d4fe376 100644 --- a/lib/sdl3/parser/src/types.zig +++ b/lib/sdl3/parser/src/types.zig @@ -6,6 +6,19 @@ const Allocator = std.mem.Allocator; pub fn convertType(c_type: []const u8, allocator: Allocator) ![]const u8 { const trimmed = std.mem.trim(u8, c_type, " \t"); + // Handle array types: "Uint8[2]" -> "[2]u8" + if (std.mem.indexOf(u8, trimmed, "[")) |bracket_pos| { + const base_type = std.mem.trim(u8, trimmed[0..bracket_pos], " \t"); + const array_part = trimmed[bracket_pos..]; // "[2]" + + // Recursively convert the base type + const zig_base = try convertType(base_type, allocator); + defer allocator.free(zig_base); + + // Return Zig array notation: [size]Type + return try std.fmt.allocPrint(allocator, "{s}{s}", .{array_part, zig_base}); + } + // Primitives if (std.mem.eql(u8, trimmed, "void")) return try allocator.dupe(u8, "void"); if (std.mem.eql(u8, trimmed, "bool")) return try allocator.dupe(u8, "bool");