Move vulkan/util.zig to id_render.zig, and make it more generic

This commit is contained in:
Robin Voetter
2020-08-11 18:07:21 +02:00
parent 74d6846d68
commit c708f01e3a
4 changed files with 61 additions and 57 deletions

View File

@@ -1,5 +1,4 @@
const std = @import("std"); const std = @import("std");
const reg = @import("registry.zig");
const mem = std.mem; const mem = std.mem;
const Allocator = mem.Allocator; const Allocator = mem.Allocator;
@@ -65,35 +64,6 @@ pub const CaseStyle = enum {
camel, camel,
}; };
pub fn trimVkNamespace(id: []const u8) []const u8 {
const prefixes = [_][]const u8{"VK_", "vk", "Vk", "PFN_vk"};
for (prefixes) |prefix| {
if (mem.startsWith(u8, id, prefix)) {
return id[prefix.len..];
}
}
return id;
}
pub fn getAuthorTag(id: []const u8, tags: []const reg.Tag) ?[]const u8 {
for (tags) |tag| {
if (mem.endsWith(u8, id, tag.name)) {
return tag.name;
}
}
return null;
}
pub fn stripAuthorTag(id: []const u8, tags: []const reg.Tag) []const u8 {
if (getAuthorTag(id, tags)) |tag| {
return mem.trimRight(u8, id[0 .. id.len - tag.len], "_");
}
return id;
}
pub const SegmentIterator = struct { pub const SegmentIterator = struct {
text: []const u8, text: []const u8,
offset: usize, offset: usize,
@@ -151,10 +121,10 @@ pub const SegmentIterator = struct {
}; };
pub const IdRenderer = struct { pub const IdRenderer = struct {
tags: []const reg.Tag, tags: []const []const u8,
text_cache: std.ArrayList(u8), text_cache: std.ArrayList(u8),
pub fn init(allocator: *Allocator, tags: []const reg.Tag) IdRenderer { pub fn init(allocator: *Allocator, tags: []const []const u8) IdRenderer {
return .{ return .{
.tags = tags, .tags = tags,
.text_cache = std.ArrayList(u8).init(allocator), .text_cache = std.ArrayList(u8).init(allocator),
@@ -234,7 +204,8 @@ pub const IdRenderer = struct {
} }
pub fn renderWithCase(self: *IdRenderer, out: anytype, case_style: CaseStyle, id: []const u8) !void { pub fn renderWithCase(self: *IdRenderer, out: anytype, case_style: CaseStyle, id: []const u8) !void {
const tag = getAuthorTag(id, self.tags); const tag = self.getAuthorTag(id);
// The trailing underscore doesn't need to be removed here as its removed by the SegmentIterator.
const adjusted_id = if (tag) |name| id[0 .. id.len - name.len] else id; const adjusted_id = if (tag) |name| id[0 .. id.len - name.len] else id;
self.text_cache.items.len = 0; self.text_cache.items.len = 0;
@@ -248,4 +219,22 @@ pub const IdRenderer = struct {
try writeIdentifier(out, self.text_cache.items); try writeIdentifier(out, self.text_cache.items);
} }
pub fn getAuthorTag(self: IdRenderer, id: []const u8) ?[]const u8 {
for (self.tags) |tag| {
if (mem.endsWith(u8, id, tag)) {
return tag;
}
}
return null;
}
pub fn stripAuthorTag(self: IdRenderer, id: []const u8) []const u8 {
if (self.getAuthorTag(id)) |tag| {
return mem.trimRight(u8, id[0 .. id.len - tag.len], "_");
}
return id;
}
}; };

View File

@@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const registry = @import("registry.zig"); const registry = @import("registry.zig");
const xml = @import("../xml.zig"); const xml = @import("../xml.zig");
const cparse = @import("c-parse.zig"); const cparse = @import("c_parse.zig");
const mem = std.mem; const mem = std.mem;
const Allocator = mem.Allocator; const Allocator = mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator; const ArenaAllocator = std.heap.ArenaAllocator;

View File

@@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const reg = @import("registry.zig"); const reg = @import("registry.zig");
const util = @import("util.zig"); const id_render = @import("../id_render.zig");
const cparse = @import("c-parse.zig"); const cparse = @import("c_parse.zig");
const mem = std.mem; const mem = std.mem;
const Allocator = mem.Allocator; const Allocator = mem.Allocator;
@@ -112,6 +112,17 @@ fn eqlIgnoreCase(lhs: []const u8, rhs: []const u8) bool {
return true; return true;
} }
pub fn trimVkNamespace(id: []const u8) []const u8 {
const prefixes = [_][]const u8{"VK_", "vk", "Vk", "PFN_vk"};
for (prefixes) |prefix| {
if (mem.startsWith(u8, id, prefix)) {
return id[prefix.len..];
}
}
return id;
}
fn Renderer(comptime WriterType: type) type { fn Renderer(comptime WriterType: type) type {
return struct { return struct {
const Self = @This(); const Self = @This();
@@ -156,18 +167,22 @@ fn Renderer(comptime WriterType: type) type {
writer: WriterType, writer: WriterType,
allocator: *Allocator, allocator: *Allocator,
registry: *const reg.Registry, registry: *const reg.Registry,
id_renderer: util.IdRenderer, id_renderer: id_render.IdRenderer,
fn init(writer: WriterType, allocator: *Allocator, registry: *const reg.Registry) Self { fn init(writer: WriterType, allocator: *Allocator, registry: *const reg.Registry) !Self {
return .{ const tags = try allocator.alloc([]const u8, registry.tags.len);
for (tags) |*tag, i| tag.* = registry.tags[i].name;
return Self{
.writer = writer, .writer = writer,
.allocator = allocator, .allocator = allocator,
.registry = registry, .registry = registry,
.id_renderer = util.IdRenderer.init(allocator, registry.tags), .id_renderer = id_render.IdRenderer.init(allocator, tags),
}; };
} }
fn deinit(self: Self) void { fn deinit(self: Self) void {
self.allocator.free(self.id_renderer.tags);
self.id_renderer.deinit(); self.id_renderer.deinit();
} }
@@ -175,7 +190,7 @@ fn Renderer(comptime WriterType: type) type {
try self.id_renderer.render(self.writer, id); try self.id_renderer.render(self.writer, id);
} }
fn writeIdentifierWithCase(self: *Self, case: util.CaseStyle, id: []const u8) !void { fn writeIdentifierWithCase(self: *Self, case: id_render.CaseStyle, id: []const u8) !void {
try self.id_renderer.renderWithCase(self.writer, case, id); try self.id_renderer.renderWithCase(self.writer, case, id);
} }
@@ -184,10 +199,10 @@ fn Renderer(comptime WriterType: type) type {
} }
fn extractEnumFieldName(self: Self, enum_name: []const u8, field_name: []const u8) ![]const u8 { fn extractEnumFieldName(self: Self, enum_name: []const u8, field_name: []const u8) ![]const u8 {
const adjusted_enum_name = util.stripAuthorTag(enum_name, self.registry.tags); const adjusted_enum_name = self.id_renderer.stripAuthorTag(enum_name);
var enum_it = util.SegmentIterator.init(adjusted_enum_name); var enum_it = id_render.SegmentIterator.init(adjusted_enum_name);
var field_it = util.SegmentIterator.init(field_name); var field_it = id_render.SegmentIterator.init(field_name);
while (true) { while (true) {
const rest = field_it.rest(); const rest = field_it.rest();
@@ -201,7 +216,7 @@ fn Renderer(comptime WriterType: type) type {
} }
fn extractBitflagName(self: Self, name: []const u8) ?BitflagName { fn extractBitflagName(self: Self, name: []const u8) ?BitflagName {
const tag = util.getAuthorTag(name, self.registry.tags); const tag = self.id_renderer.getAuthorTag(name);
const base_name = if (tag) |tag_name| name[0 .. name.len - tag_name.len] else name; const base_name = if (tag) |tag_name| name[0 .. name.len - tag_name.len] else name;
if (!mem.endsWith(u8, base_name, "FlagBits")) { if (!mem.endsWith(u8, base_name, "FlagBits")) {
@@ -215,7 +230,7 @@ fn Renderer(comptime WriterType: type) type {
} }
fn isFlags(self: Self, name: []const u8) bool { fn isFlags(self: Self, name: []const u8) bool {
const tag = util.getAuthorTag(name, self.registry.tags); const tag = self.id_renderer.getAuthorTag(name);
const base_name = if (tag) |tag_name| name[0 .. name.len - tag_name.len] else name; const base_name = if (tag) |tag_name| name[0 .. name.len - tag_name.len] else name;
return mem.endsWith(u8, base_name, "Flags"); return mem.endsWith(u8, base_name, "Flags");
@@ -236,7 +251,7 @@ fn Renderer(comptime WriterType: type) type {
const child_name = ptr.child.name; const child_name = ptr.child.name;
if (mem.eql(u8, child_name, "void")) { if (mem.eql(u8, child_name, "void")) {
return .other; return .other;
} else if (builtin_types.get(child_name) == null and util.trimVkNamespace(child_name).ptr == child_name.ptr) { } else if (builtin_types.get(child_name) == null and trimVkNamespace(child_name).ptr == child_name.ptr) {
return .other; // External type return .other; // External type
} }
} }
@@ -414,7 +429,7 @@ fn Renderer(comptime WriterType: type) type {
return; return;
} else if (self.extractBitflagName(name)) |bitflag_name| { } else if (self.extractBitflagName(name)) |bitflag_name| {
try self.writeIdentifierFmt("{}Flags{}", .{ try self.writeIdentifierFmt("{}Flags{}", .{
util.trimVkNamespace(bitflag_name.base_name), trimVkNamespace(bitflag_name.base_name),
@as([]const u8, if (bitflag_name.tag) |tag| tag else "") @as([]const u8, if (bitflag_name.tag) |tag| tag else "")
}); });
return; return;
@@ -453,7 +468,7 @@ fn Renderer(comptime WriterType: type) type {
if (param.param_type == .name) { if (param.param_type == .name) {
if (self.extractBitflagName(param.param_type.name)) |bitflag_name| { if (self.extractBitflagName(param.param_type.name)) |bitflag_name| {
try self.writeIdentifierFmt("{}Flags{}", .{ try self.writeIdentifierFmt("{}Flags{}", .{
util.trimVkNamespace(bitflag_name.base_name), trimVkNamespace(bitflag_name.base_name),
@as([]const u8, if (bitflag_name.tag) |tag| tag else "") @as([]const u8, if (bitflag_name.tag) |tag| tag else "")
}); });
try self.writer.writeAll(".IntType"); try self.writer.writeAll(".IntType");
@@ -568,7 +583,7 @@ fn Renderer(comptime WriterType: type) type {
try self.writer.writeAll(" = null"); try self.writer.writeAll(" = null");
} else if (mem.eql(u8, field.name, "sType")) { } else if (mem.eql(u8, field.name, "sType")) {
try self.writer.writeAll(" = ."); try self.writer.writeAll(" = .");
try self.writeIdentifierWithCase(.snake, util.trimVkNamespace(name)); try self.writeIdentifierWithCase(.snake, trimVkNamespace(name));
} }
} }
@@ -728,7 +743,7 @@ fn Renderer(comptime WriterType: type) type {
} }
fn renderCommandPtrName(self: *Self, name: []const u8) !void { fn renderCommandPtrName(self: *Self, name: []const u8) !void {
try self.writeIdentifierFmt("Pfn{}", .{util.trimVkNamespace(name)}); try self.writeIdentifierFmt("Pfn{}", .{trimVkNamespace(name)});
} }
fn renderCommandPtrs(self: *Self) !void { fn renderCommandPtrs(self: *Self) !void {
@@ -755,7 +770,7 @@ fn Renderer(comptime WriterType: type) type {
); );
for (self.registry.extensions) |ext| { for (self.registry.extensions) |ext| {
try self.writer.writeAll("pub const "); try self.writer.writeAll("pub const ");
try self.writeIdentifierWithCase(.snake, util.trimVkNamespace(ext.name)); try self.writeIdentifierWithCase(.snake, trimVkNamespace(ext.name));
try self.writer.writeAll("= Info {\n"); try self.writer.writeAll("= Info {\n");
try self.writer.print(".name = \"{}\", .version = {},", .{ext.name, ext.version}); try self.writer.print(".name = \"{}\", .version = {},", .{ext.name, ext.version});
try self.writer.writeAll("};\n"); try self.writer.writeAll("};\n");
@@ -822,7 +837,7 @@ fn Renderer(comptime WriterType: type) type {
} }
fn derefName(name: []const u8) []const u8 { fn derefName(name: []const u8) []const u8 {
var it = util.SegmentIterator.init(name); var it = id_render.SegmentIterator.init(name);
return if (mem.eql(u8, it.next().?, "p")) return if (mem.eql(u8, it.next().?, "p"))
name[1..] name[1..]
else else
@@ -831,7 +846,7 @@ fn Renderer(comptime WriterType: type) type {
fn renderWrapperPrototype(self: *Self, name: []const u8, command: reg.Command, returns: []const ReturnValue) !void { fn renderWrapperPrototype(self: *Self, name: []const u8, command: reg.Command, returns: []const ReturnValue) !void {
try self.writer.writeAll("pub fn "); try self.writer.writeAll("pub fn ");
try self.writeIdentifierWithCase(.camel, util.trimVkNamespace(name)); try self.writeIdentifierWithCase(.camel, trimVkNamespace(name));
try self.writer.writeAll("(self: Self, "); try self.writer.writeAll("(self: Self, ");
for (command.params) |param| { for (command.params) |param| {
@@ -946,7 +961,7 @@ fn Renderer(comptime WriterType: type) type {
} }
fn renderReturnStructName(self: *Self, command_name: []const u8) !void { fn renderReturnStructName(self: *Self, command_name: []const u8) !void {
try self.writeIdentifierFmt("{}Result", .{util.trimVkNamespace(command_name)}); try self.writeIdentifierFmt("{}Result", .{trimVkNamespace(command_name)});
} }
fn renderReturnStruct(self: *Self, command_name: []const u8, returns: []const ReturnValue) !void { fn renderReturnStruct(self: *Self, command_name: []const u8, returns: []const ReturnValue) !void {
@@ -1076,14 +1091,14 @@ fn Renderer(comptime WriterType: type) type {
} else { } else {
// Apparently some commands (VkAcquireProfilingLockInfoKHR) return // Apparently some commands (VkAcquireProfilingLockInfoKHR) return
// success codes as error... // success codes as error...
try self.writeIdentifierWithCase(.title, util.trimVkNamespace(name)); try self.writeIdentifierWithCase(.title, trimVkNamespace(name));
} }
} }
}; };
} }
pub fn render(writer: anytype, allocator: *Allocator, registry: *const reg.Registry) !void { pub fn render(writer: anytype, allocator: *Allocator, registry: *const reg.Registry) !void {
var renderer = Renderer(@TypeOf(writer)).init(writer, allocator, registry); var renderer = try Renderer(@TypeOf(writer)).init(writer, allocator, registry);
defer renderer.deinit(); defer renderer.deinit();
try renderer.render(); try renderer.render();
} }