forked from mirror/vulkan-zig
provide defaults for struct fields vulkan considers optional
This commit is contained in:
@@ -263,6 +263,7 @@ pub fn parseMember(allocator: Allocator, xctok: *XmlCTokenizer, ptrs_optional: b
|
|||||||
.field_type = decl.decl_type,
|
.field_type = decl.decl_type,
|
||||||
.bits = null,
|
.bits = null,
|
||||||
.is_buffer_len = false,
|
.is_buffer_len = false,
|
||||||
|
.is_optional = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (try xctok.peek()) |tok| {
|
if (try xctok.peek()) |tok| {
|
||||||
|
|||||||
@@ -199,6 +199,15 @@ fn parseContainer(allocator: Allocator, ty: *xml.Element, is_union: bool) !regis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (member.getAttribute("optional")) |optionals| {
|
||||||
|
var optional_it = mem.split(u8, optionals, ",");
|
||||||
|
if (optional_it.next()) |first_optional| {
|
||||||
|
members[i].is_optional = mem.eql(u8, first_optional, "true");
|
||||||
|
} else {
|
||||||
|
// Optional is empty, probably incorrect.
|
||||||
|
return error.InvalidRegistry;
|
||||||
|
}
|
||||||
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +254,7 @@ fn parseFuncPointer(allocator: Allocator, ty: *xml.Element) !registry.Declaratio
|
|||||||
return try cparse.parseTypedef(allocator, &xctok, true);
|
return try cparse.parseTypedef(allocator, &xctok, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For some reason, the DeclarationType cannot be passed to lenToPointerSize, as
|
// For some reason, the DeclarationType cannot be passed to lenToPointer, as
|
||||||
// that causes the Zig compiler to generate invalid code for the function. Using a
|
// that causes the Zig compiler to generate invalid code for the function. Using a
|
||||||
// dedicated enum fixes the issue...
|
// dedicated enum fixes the issue...
|
||||||
const Fields = union(enum) {
|
const Fields = union(enum) {
|
||||||
@@ -253,13 +262,14 @@ const Fields = union(enum) {
|
|||||||
container: []registry.Container.Field,
|
container: []registry.Container.Field,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn lenToPointerSize(fields: Fields, len: []const u8) registry.Pointer.PointerSize {
|
// returns .{ size, nullable }
|
||||||
|
fn lenToPointer(fields: Fields, len: []const u8) std.meta.Tuple(&.{ registry.Pointer.PointerSize, bool }) {
|
||||||
switch (fields) {
|
switch (fields) {
|
||||||
.command => |params| {
|
.command => |params| {
|
||||||
for (params) |*param| {
|
for (params) |*param| {
|
||||||
if (mem.eql(u8, param.name, len)) {
|
if (mem.eql(u8, param.name, len)) {
|
||||||
param.is_buffer_len = true;
|
param.is_buffer_len = true;
|
||||||
return .{ .other_field = param.name };
|
return .{ .{ .other_field = param.name }, false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -267,16 +277,16 @@ fn lenToPointerSize(fields: Fields, len: []const u8) registry.Pointer.PointerSiz
|
|||||||
for (members) |*member| {
|
for (members) |*member| {
|
||||||
if (mem.eql(u8, member.name, len)) {
|
if (mem.eql(u8, member.name, len)) {
|
||||||
member.is_buffer_len = true;
|
member.is_buffer_len = true;
|
||||||
return .{ .other_field = member.name };
|
return .{ .{ .other_field = member.name }, member.is_optional };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mem.eql(u8, len, "null-terminated")) {
|
if (mem.eql(u8, len, "null-terminated")) {
|
||||||
return .zero_terminated;
|
return .{ .zero_terminated, false };
|
||||||
} else {
|
} else {
|
||||||
return .many;
|
return .{ .many, false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +296,11 @@ fn parsePointerMeta(fields: Fields, type_info: *registry.TypeInfo, elem: *xml.El
|
|||||||
var current_type_info = type_info;
|
var current_type_info = type_info;
|
||||||
while (current_type_info.* == .pointer) {
|
while (current_type_info.* == .pointer) {
|
||||||
// TODO: Check altlen
|
// TODO: Check altlen
|
||||||
const size = if (it.next()) |len_str| lenToPointerSize(fields, len_str) else .many;
|
const size = if (it.next()) |len_str| blk: {
|
||||||
|
const size_optional = lenToPointer(fields, len_str);
|
||||||
|
current_type_info.pointer.is_optional = size_optional[1];
|
||||||
|
break :blk size_optional[0];
|
||||||
|
} else .many;
|
||||||
current_type_info.pointer.size = size;
|
current_type_info.pointer.size = size;
|
||||||
current_type_info = current_type_info.pointer.child;
|
current_type_info = current_type_info.pointer.child;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ pub const Container = struct {
|
|||||||
field_type: TypeInfo,
|
field_type: TypeInfo,
|
||||||
bits: ?usize,
|
bits: ?usize,
|
||||||
is_buffer_len: bool,
|
is_buffer_len: bool,
|
||||||
|
is_optional: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
stype: ?[]const u8,
|
stype: ?[]const u8,
|
||||||
|
|||||||
@@ -749,7 +749,9 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try self.renderTypeInfo(field.field_type);
|
try self.renderTypeInfo(field.field_type);
|
||||||
|
if (!container.is_union) {
|
||||||
try self.renderContainerDefaultField(name, container, field);
|
try self.renderContainerDefaultField(name, container, field);
|
||||||
|
}
|
||||||
try self.writer.writeAll(", ");
|
try self.writer.writeAll(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -758,9 +760,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn renderContainerDefaultField(self: *Self, name: []const u8, container: reg.Container, field: reg.Container.Field) !void {
|
fn renderContainerDefaultField(self: *Self, name: []const u8, container: reg.Container, field: reg.Container.Field) !void {
|
||||||
if (mem.eql(u8, field.name, "pNext")) {
|
if (mem.eql(u8, field.name, "sType")) {
|
||||||
try self.writer.writeAll(" = null");
|
|
||||||
} else if (mem.eql(u8, field.name, "sType")) {
|
|
||||||
if (container.stype == null) {
|
if (container.stype == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -776,8 +776,30 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
|
|
||||||
try self.writer.writeAll(" = .");
|
try self.writer.writeAll(" = .");
|
||||||
try self.writeIdentifierWithCase(.snake, stype["VK_STRUCTURE_TYPE_".len..]);
|
try self.writeIdentifierWithCase(.snake, stype["VK_STRUCTURE_TYPE_".len..]);
|
||||||
} else if (field.field_type == .name and !container.is_union and mem.eql(u8, "VkBool32", field.field_type.name) and isFeatureStruct(name, container.extends)) {
|
} else if (field.field_type == .name and mem.eql(u8, "VkBool32", field.field_type.name) and isFeatureStruct(name, container.extends)) {
|
||||||
try self.writer.writeAll(" = FALSE");
|
try self.writer.writeAll(" = FALSE");
|
||||||
|
} else if (field.is_optional) {
|
||||||
|
if (field.field_type == .name) {
|
||||||
|
const field_type_name = field.field_type.name;
|
||||||
|
if (self.resolveDeclaration(field_type_name)) |decl_type| {
|
||||||
|
if (decl_type == .handle) {
|
||||||
|
try self.writer.writeAll(" = .null_handle");
|
||||||
|
} else if (decl_type == .bitmask) {
|
||||||
|
try self.writer.writeAll(" = .{}");
|
||||||
|
} else if (decl_type == .typedef and decl_type.typedef == .command_ptr) {
|
||||||
|
try self.writer.writeAll(" = null");
|
||||||
|
} else if ((decl_type == .typedef and builtin_types.has(decl_type.typedef.name)) or
|
||||||
|
(decl_type == .foreign and builtin_types.has(field_type_name)))
|
||||||
|
{
|
||||||
|
try self.writer.writeAll(" = 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (field.field_type == .pointer) {
|
||||||
|
try self.writer.writeAll(" = null");
|
||||||
|
}
|
||||||
|
} else if (field.field_type == .pointer and field.field_type.pointer.is_optional) {
|
||||||
|
// pointer nullability could be here or above
|
||||||
|
try self.writer.writeAll(" = null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user