forked from mirror/vulkan-zig
Move vulkan/util.zig to id_render.zig, and make it more generic
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user