diff --git a/generator/spec-c-parse.zig b/generator/spec-c-parse.zig index be55aad..4760735 100644 --- a/generator/spec-c-parse.zig +++ b/generator/spec-c-parse.zig @@ -233,6 +233,7 @@ pub fn parseTypedef(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Decl return decl; } +// MEMBER = DECLARATION (':' int)? pub fn parseMember(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Container.Field { const decl = try parseDeclaration(allocator, xctok); var field = registry.Container.Field { @@ -261,9 +262,8 @@ pub fn parseMember(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Conta } // DECLARATION = kw_const? type_name DECLARATOR -// DECLARATOR = POINTERS? (id | name) ('[' ARRAY_EXPR ']')* -// | POINTERS? '(' kw_vkapi_ptr '*' name' ')' // TODO -// POINTERS = (kw_const? '*')+ +// DECLARATOR = POINTERS (id | name) ('[' ARRAY_DECLARATOR ']')* +// | POINTERS '(' kw_vkapi_ptr '*' name' ')' // TODO fn parseDeclaration(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Declaration { // Parse declaration constness var tok = try xctok.nextNoEof(); @@ -320,6 +320,7 @@ fn parseDeclaration(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Decl }; } +// POINTERS = (kw_const? '*')* fn parsePointers( allocator: *Allocator, xctok: *XmlCTokenizer, @@ -361,6 +362,7 @@ fn parsePointers( } } +// ARRAY_DECLARATOR = '[' (int | enum_name) ']' fn parseArrayDeclarator(xctok: *XmlCTokenizer) !?ArraySize { const lbracket = try xctok.peek(); if (lbracket == null or lbracket.?.id != .lbracket) { diff --git a/generator/spec-parse.zig b/generator/spec-parse.zig index 55e6eff..2ad103f 100644 --- a/generator/spec-parse.zig +++ b/generator/spec-parse.zig @@ -171,6 +171,7 @@ fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !regi while (it.next()) |member| { var xctok = xmlc.XmlCTokenizer.init(member); members[i] = try xmlc.parseMember(allocator, &xctok); + try parsePointerMeta(&members[i].field_type, member); i += 1; } @@ -185,6 +186,32 @@ fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !regi }; } +fn lenToPointerSize(len: []const u8) registry.Pointer.PointerSize { + if (mem.eql(u8, len, "null-terminated")) { + return .zero_terminated; + } else { + return .many; + } +} + +fn parsePointerMeta(type_info: *registry.TypeInfo, elem: *xml.Element) !void { + if (elem.getAttribute("len")) |lens| { + var it = std.mem.split(lens, ","); + var current_type_info = type_info; + while (current_type_info.* == .pointer) { + const size = if (it.next()) |len_str| lenToPointerSize(len_str) else .one; + current_type_info.pointer.size = size; + current_type_info = current_type_info.pointer.child; + } + + if (it.next()) |_| { + // There are more elements in the `len` attribute than there are pointers + // Something probably went wrong + return error.InvalidRegistry; + } + } +} + fn parseEnums(allocator: *Allocator, out: []registry.Declaration, root: *xml.Element) !usize { var i: usize = 0; var it = root.findChildrenByTag("enums");