Parse pointer optional-ness

This commit is contained in:
Robin Voetter
2020-06-11 19:39:35 +02:00
parent 5aba419165
commit 52d1d45948
3 changed files with 20 additions and 3 deletions

View File

@@ -99,6 +99,7 @@ pub const Pointer = struct {
}; };
is_const: bool, is_const: bool,
is_optional: bool,
size: PointerSize, size: PointerSize,
child: *TypeInfo, child: *TypeInfo,
}; };

View File

@@ -382,6 +382,7 @@ fn parseFnPtrSuffix(allocator: *Allocator, xctok: *XmlCTokenizer, return_type: T
.decl_type = .{ .decl_type = .{
.pointer = .{ .pointer = .{
.is_const = true, .is_const = true,
.is_optional = false,
.size = .one, .size = .one,
.child = command, .child = command,
} }
@@ -455,8 +456,9 @@ fn parsePointers(allocator: *Allocator, xctok: *XmlCTokenizer, inner_const: bool
type_info = .{ type_info = .{
.pointer = .{ .pointer = .{
.size = .one, // set elsewhere
.is_const = is_const or first_const, .is_const = is_const or first_const,
.is_optional = false, // set elsewhere
.size = .one, // set elsewhere
.child = child, .child = child,
}, },
}; };

View File

@@ -143,7 +143,7 @@ fn parseHandleType(ty: *xml.Element) !registry.Declaration {
fn parseBaseType(allocator: *Allocator, ty: *xml.Element) !registry.Declaration { fn parseBaseType(allocator: *Allocator, ty: *xml.Element) !registry.Declaration {
const name = ty.getCharData("name") orelse return error.InvalidRegistry; 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); var tok = xmlc.XmlCTokenizer.init(ty);
return try xmlc.parseTypedef(allocator, &tok); return try xmlc.parseTypedef(allocator, &tok);
} else { } else {
@@ -217,6 +217,21 @@ fn parsePointerMeta(type_info: *registry.TypeInfo, elem: *xml.Element) !void {
return error.InvalidRegistry; 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 { 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 // 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 <extension> // given by the `extnumber` field (in the case of a feature), or given in the parent <extension>
// tag. In the latter case its passed via the `ext_nr` parameter. // tag. In the latter case its passed via the `ext_nr` parameter.
// TODO: Handle `offset` elsewhere
if (field.getAttribute("value")) |value| { if (field.getAttribute("value")) |value| {
if (mem.startsWith(u8, value, "0x")) { if (mem.startsWith(u8, value, "0x")) {
break :blk .{.bit_vector = try std.fmt.parseInt(i32, value[2..], 16)}; break :blk .{.bit_vector = try std.fmt.parseInt(i32, value[2..], 16)};