From 52d1d4594889290e146e24e6589206e6b0a7ae0e Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Thu, 11 Jun 2020 19:39:35 +0200 Subject: [PATCH] Parse pointer optional-ness --- generator/registry.zig | 1 + generator/registry/c-parse.zig | 4 +++- generator/registry/parse.zig | 18 ++++++++++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/generator/registry.zig b/generator/registry.zig index 74b6901..7637f96 100644 --- a/generator/registry.zig +++ b/generator/registry.zig @@ -99,6 +99,7 @@ pub const Pointer = struct { }; is_const: bool, + is_optional: bool, size: PointerSize, child: *TypeInfo, }; diff --git a/generator/registry/c-parse.zig b/generator/registry/c-parse.zig index fef44d7..91fad1c 100644 --- a/generator/registry/c-parse.zig +++ b/generator/registry/c-parse.zig @@ -382,6 +382,7 @@ fn parseFnPtrSuffix(allocator: *Allocator, xctok: *XmlCTokenizer, return_type: T .decl_type = .{ .pointer = .{ .is_const = true, + .is_optional = false, .size = .one, .child = command, } @@ -455,8 +456,9 @@ fn parsePointers(allocator: *Allocator, xctok: *XmlCTokenizer, inner_const: bool type_info = .{ .pointer = .{ - .size = .one, // set elsewhere .is_const = is_const or first_const, + .is_optional = false, // set elsewhere + .size = .one, // set elsewhere .child = child, }, }; diff --git a/generator/registry/parse.zig b/generator/registry/parse.zig index 9f8624e..385fdef 100644 --- a/generator/registry/parse.zig +++ b/generator/registry/parse.zig @@ -143,7 +143,7 @@ fn parseHandleType(ty: *xml.Element) !registry.Declaration { fn parseBaseType(allocator: *Allocator, ty: *xml.Element) !registry.Declaration { const name = ty.getCharData("name") orelse return error.InvalidRegistry; - if (ty.getCharData("type")) |_| { // TODO: Parse as full type? + if (ty.getCharData("type")) |_| { var tok = xmlc.XmlCTokenizer.init(ty); return try xmlc.parseTypedef(allocator, &tok); } else { @@ -217,6 +217,21 @@ fn parsePointerMeta(type_info: *registry.TypeInfo, elem: *xml.Element) !void { return error.InvalidRegistry; } } + + if (elem.getAttribute("optional")) |optionals| { + var it = mem.split(optionals, ","); + var current_type_info = type_info; + while (current_type_info.* == .pointer) { + if (it.next()) |current_optional| { + current_type_info.pointer.is_optional = mem.eql(u8, current_optional, "true"); + } else { + // There is no information for this pointer, probably incorrect. + return error.InvalidRegistry; + } + + current_type_info = current_type_info.pointer.child; + } + } } fn parseEnums(allocator: *Allocator, out: []registry.Declaration, root: *xml.Element) !usize { @@ -278,7 +293,6 @@ fn parseEnumField(field: *xml.Element) !registry.Enum.Field { // The value is given by `1e9 + (extr_nr - 1) * 1e3 + offset`, where `ext_nr` is either // given by the `extnumber` field (in the case of a feature), or given in the parent // tag. In the latter case its passed via the `ext_nr` parameter. - // TODO: Handle `offset` elsewhere if (field.getAttribute("value")) |value| { if (mem.startsWith(u8, value, "0x")) { break :blk .{.bit_vector = try std.fmt.parseInt(i32, value[2..], 16)};