forked from mirror/vulkan-zig
Registry: API constants
This commit is contained in:
@@ -5,22 +5,12 @@ const Allocator = mem.Allocator;
|
|||||||
const SegmentedList = std.SegmentedList;
|
const SegmentedList = std.SegmentedList;
|
||||||
const StringHashMap = std.StringHashMap;
|
const StringHashMap = std.StringHashMap;
|
||||||
|
|
||||||
fn count(haystack: []const u8, needle: u8) usize {
|
|
||||||
var total: usize = 0;
|
|
||||||
for (haystack) |elem| {
|
|
||||||
if (elem == needle) {
|
|
||||||
total += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Registry = struct {
|
pub const Registry = struct {
|
||||||
arena: std.heap.ArenaAllocator,
|
arena: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
declarations: SegmentedList(Declaration, 0),
|
declarations: SegmentedList(Declaration, 0),
|
||||||
declarations_by_name: StringHashMap(*Declaration),
|
declarations_by_name: StringHashMap(*Declaration),
|
||||||
|
api_constants: SegmentedList(ApiConstant, 0),
|
||||||
extensions: SegmentedList(ExtensionInfo, 0),
|
extensions: SegmentedList(ExtensionInfo, 0),
|
||||||
|
|
||||||
fn init(allocator: *Allocator) !*Registry {
|
fn init(allocator: *Allocator) !*Registry {
|
||||||
@@ -34,6 +24,7 @@ pub const Registry = struct {
|
|||||||
.arena = arena,
|
.arena = arena,
|
||||||
.declarations = undefined,
|
.declarations = undefined,
|
||||||
.declarations_by_name = StringHashMap(*Declaration).init(allocator),
|
.declarations_by_name = StringHashMap(*Declaration).init(allocator),
|
||||||
|
.api_constants = undefined,
|
||||||
.extensions = undefined
|
.extensions = undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,6 +32,7 @@ pub const Registry = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
registry.declarations = SegmentedList(Declaration, 0).init(®istry.arena.allocator);
|
registry.declarations = SegmentedList(Declaration, 0).init(®istry.arena.allocator);
|
||||||
|
registry.api_constants = SegmentedList(ApiConstant, 0).init(®istry.arena.allocator);
|
||||||
registry.extensions = SegmentedList(ExtensionInfo, 0).init(®istry.arena.allocator);
|
registry.extensions = SegmentedList(ExtensionInfo, 0).init(®istry.arena.allocator);
|
||||||
|
|
||||||
return registry;
|
return registry;
|
||||||
@@ -67,6 +59,10 @@ pub const Registry = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn addApiConstant(self: *Registry, name: []const u8, expr: []const u8) void {
|
||||||
|
self.api_constants.push(.{.name = name, .expr = expr}) catch unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
fn findDefinitionByName(self: *Registry, name: []const u8) ?*Definition {
|
fn findDefinitionByName(self: *Registry, name: []const u8) ?*Definition {
|
||||||
if (self.declarations_by_name.get(name)) |kv| {
|
if (self.declarations_by_name.get(name)) |kv| {
|
||||||
return &kv.value.definition;
|
return &kv.value.definition;
|
||||||
@@ -84,6 +80,14 @@ pub const Registry = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std.debug.warn("API constants:\n", .{});
|
||||||
|
var it = self.api_constants.iterator(0);
|
||||||
|
while (it.next()) |kv| {
|
||||||
|
std.debug.warn(" {} = {}\n", .{kv.name, kv.expr});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std.debug.warn("Extensions:\n", .{});
|
std.debug.warn("Extensions:\n", .{});
|
||||||
var it = self.extensions.iterator(0);
|
var it = self.extensions.iterator(0);
|
||||||
@@ -94,6 +98,11 @@ pub const Registry = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ApiConstant = struct {
|
||||||
|
name: []const u8,
|
||||||
|
expr: []const u8
|
||||||
|
};
|
||||||
|
|
||||||
const ExtensionInfo = struct {
|
const ExtensionInfo = struct {
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
number: u32,
|
number: u32,
|
||||||
@@ -174,10 +183,6 @@ const TypeInfo = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the constness of each pointer
|
|
||||||
// Beware: the const of the inner pointer is given before the type name
|
|
||||||
// while the others are in the `ptr_text`.
|
|
||||||
|
|
||||||
const pre = switch (elem.children.at(0).*) {
|
const pre = switch (elem.children.at(0).*) {
|
||||||
.CharData => |char_data| char_data,
|
.CharData => |char_data| char_data,
|
||||||
else => ""
|
else => ""
|
||||||
@@ -435,7 +440,7 @@ const CommandInfo = struct {
|
|||||||
|
|
||||||
const EnumInfo = struct {
|
const EnumInfo = struct {
|
||||||
const Value = union(enum) {
|
const Value = union(enum) {
|
||||||
Bitpos: u5, //log2(u32.bit_count)
|
Bitpos: u5, //log2(u32)
|
||||||
Value: i32,
|
Value: i32,
|
||||||
Alias: []const u8,
|
Alias: []const u8,
|
||||||
};
|
};
|
||||||
@@ -462,12 +467,7 @@ const EnumInfo = struct {
|
|||||||
const name = variant.getAttribute("name").?;
|
const name = variant.getAttribute("name").?;
|
||||||
const value = blk: {
|
const value = blk: {
|
||||||
if (variant.getAttribute("value")) |value_str| {
|
if (variant.getAttribute("value")) |value_str| {
|
||||||
const value = if (mem.startsWith(u8, value_str, "0x"))
|
break :blk Value{.Value = parseInt(i32, value_str) catch unreachable};
|
||||||
std.fmt.parseInt(i32, value_str[2..], 16) catch unreachable
|
|
||||||
else
|
|
||||||
std.fmt.parseInt(i32, value_str, 10) catch unreachable;
|
|
||||||
|
|
||||||
break :blk Value{.Value = value};
|
|
||||||
} else if (variant.getAttribute("bitpos")) |bitpos_str| {
|
} else if (variant.getAttribute("bitpos")) |bitpos_str| {
|
||||||
break :blk Value{.Bitpos = std.fmt.parseInt(u5, bitpos_str, 10) catch unreachable};
|
break :blk Value{.Bitpos = std.fmt.parseInt(u5, bitpos_str, 10) catch unreachable};
|
||||||
} else if (variant.getAttribute("alias")) |alias| {
|
} else if (variant.getAttribute("alias")) |alias| {
|
||||||
@@ -600,7 +600,11 @@ fn processEnums(registry: *Registry, root: *xml.Element) void {
|
|||||||
var it = root.findChildrenByTag("enums");
|
var it = root.findChildrenByTag("enums");
|
||||||
while (it.next()) |enums| {
|
while (it.next()) |enums| {
|
||||||
const name = enums.getAttribute("name").?;
|
const name = enums.getAttribute("name").?;
|
||||||
if (!mem.eql(u8, name, "API Constants")) {
|
if (mem.eql(u8, name, "API Constants")) {
|
||||||
|
processApiConstants(registry, enums);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If the declaration hasn't been inserted in processEnumTypes,
|
// If the declaration hasn't been inserted in processEnumTypes,
|
||||||
// its a bitmask enum that is not used, so ignore it
|
// its a bitmask enum that is not used, so ignore it
|
||||||
const def = registry.findDefinitionByName(name) orelse continue;
|
const def = registry.findDefinitionByName(name) orelse continue;
|
||||||
@@ -610,6 +614,14 @@ fn processEnums(registry: *Registry, root: *xml.Element) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn processApiConstants(registry: *Registry, enums: *xml.Element) void {
|
||||||
|
var it = enums.findChildrenByTag("enum");
|
||||||
|
while (it.next()) |constant| {
|
||||||
|
const name = constant.getAttribute("name").?;
|
||||||
|
const expr = constant.getAttribute("value") orelse constant.getAttribute("alias").?;
|
||||||
|
registry.addApiConstant(name, expr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn processCommands(registry: *Registry, root: *xml.Element) void {
|
fn processCommands(registry: *Registry, root: *xml.Element) void {
|
||||||
@@ -688,3 +700,20 @@ fn processFeatures(registry: *Registry, root: *xml.Element) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn count(haystack: []const u8, needle: u8) usize {
|
||||||
|
var total: usize = 0;
|
||||||
|
for (haystack) |elem| {
|
||||||
|
if (elem == needle) total += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse an integer in either base-10 or base-16 when prefixed with '0x'.
|
||||||
|
fn parseInt(comptime T: type, source: []const u8) !T {
|
||||||
|
return if (mem.startsWith(u8, source, "0x"))
|
||||||
|
try std.fmt.parseInt(T, source[2..], 16)
|
||||||
|
else
|
||||||
|
try std.fmt.parseInt(T, source, 10);
|
||||||
|
}
|
||||||
|
|||||||
@@ -202,11 +202,11 @@ const ParseContext = struct {
|
|||||||
|
|
||||||
fn currentLine(self: ParseContext) []const u8 {
|
fn currentLine(self: ParseContext) []const u8 {
|
||||||
var begin: usize = 0;
|
var begin: usize = 0;
|
||||||
if (mem.lastIndexOf(u8, self.source[0 .. self.offset], "\n")) |prev_nl| {
|
if (mem.indexOfScalarPos(u8, self.source[0 .. self.offset], '\n')) |prev_nl| {
|
||||||
begin = prev_nl + 1;
|
begin = prev_nl + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var end = mem.indexOfPos(u8, self.source, self.offset, "\n") orelse self.source.len;
|
var end = mem.indexOfScalarPos(u8, self.source, self.offset, '\n') orelse self.source.len;
|
||||||
return self.source[begin .. end];
|
return self.source[begin .. end];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -571,7 +571,7 @@ fn dupeAndUnescape(alloc: *Allocator, text: []const u8) ![]const u8 {
|
|||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < text.len) : (j += 1) {
|
while (i < text.len) : (j += 1) {
|
||||||
if (text[i] == '&') {
|
if (text[i] == '&') {
|
||||||
const entity_end = 1 + (mem.indexOfPos(u8, text, i, ";") orelse return error.InvalidEntity);
|
const entity_end = 1 + (mem.indexOfScalarPos(u8, text, i, ';') orelse return error.InvalidEntity);
|
||||||
str[j] = try unescapeEntity(text[i .. entity_end]);
|
str[j] = try unescapeEntity(text[i .. entity_end]);
|
||||||
i = entity_end;
|
i = entity_end;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user