Updates Zig
This commit is contained in:
parent
1673ed636a
commit
a6bdcb3836
3 changed files with 63 additions and 61 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
.zig-cache
|
||||
zig-out
|
||||
/.zig-cache/
|
||||
/zig-out/
|
||||
/zig-pkg/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.name = .dear_imgui,
|
||||
.fingerprint = 0xc1cc609af54040bd,
|
||||
.version = "1.0.0",
|
||||
.minimum_zig_version = "0.16.0-dev.2193+fc517bd01",
|
||||
.minimum_zig_version = "0.16.0-dev.3153+d6f43caad",
|
||||
.dependencies = .{
|
||||
.@"dear-imgui" = .{
|
||||
// Using a patched version of v1.92.5-docking that has a UBSAN fix. The equivalent to
|
||||
|
|
|
|||
117
src/generate.zig
117
src/generate.zig
|
|
@ -9,29 +9,27 @@ const DeclarationKind = enum {
|
|||
import, // Assumed to be normal, but external
|
||||
};
|
||||
|
||||
const Declarations = std.StringArrayHashMap(DeclarationKind);
|
||||
const Declarations = std.array_hash_map.String(DeclarationKind);
|
||||
|
||||
const Symbols = struct {
|
||||
public: std.StringArrayHashMap(void),
|
||||
front_buf: std.StringArrayHashMap(void),
|
||||
public: std.array_hash_map.String(void),
|
||||
front_buf: std.array_hash_map.String(void),
|
||||
|
||||
pub fn init(allocator: Allocator) @This() {
|
||||
return .{
|
||||
.public = .init(allocator),
|
||||
.front_buf = .init(allocator),
|
||||
};
|
||||
}
|
||||
pub const empty: @This() = .{
|
||||
.public = .empty,
|
||||
.front_buf = .empty,
|
||||
};
|
||||
|
||||
pub fn deinit(self: *@This()) void {
|
||||
self.public.deinit();
|
||||
self.front_buf.deinit();
|
||||
pub fn deinit(self: *@This(), gpa: Allocator) void {
|
||||
self.public.deinit(gpa);
|
||||
self.front_buf.deinit(gpa);
|
||||
}
|
||||
|
||||
/// Returns true if there's already a public symbol with this name.
|
||||
pub fn put(self: *@This(), name: []const u8) !bool {
|
||||
pub fn put(self: *@This(), gpa: Allocator, name: []const u8) !bool {
|
||||
const trimmed = std.mem.trimEnd(u8, name, "_");
|
||||
if (self.public.contains(trimmed)) return false;
|
||||
try self.front_buf.put(trimmed, {});
|
||||
try self.front_buf.put(gpa, trimmed, {});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -207,8 +205,8 @@ pub fn main(init: std.process.Init) !void {
|
|||
}
|
||||
|
||||
// Build a list of symbols so we can skip duplicates of public symbols in the internal headers
|
||||
var symbols: Symbols = .init(allocator);
|
||||
defer symbols.deinit();
|
||||
var symbols: Symbols = .empty;
|
||||
defer symbols.deinit(allocator);
|
||||
|
||||
// Write the source
|
||||
const main_source = try Dir.cwd().readFileAlloc(io, in_path, allocator, .limited(max_size));
|
||||
|
|
@ -254,43 +252,43 @@ pub fn main(init: std.process.Init) !void {
|
|||
}
|
||||
|
||||
fn writeSource(
|
||||
allocator: Allocator,
|
||||
gpa: Allocator,
|
||||
source: []const u8,
|
||||
writer: *Io.Writer,
|
||||
symbols: *Symbols,
|
||||
internal: bool,
|
||||
) !void {
|
||||
const header = try std.json.parseFromSlice(Header, allocator, source, .{
|
||||
const header = try std.json.parseFromSlice(Header, gpa, source, .{
|
||||
.ignore_unknown_fields = true,
|
||||
});
|
||||
defer header.deinit();
|
||||
|
||||
// We need the list of declarations up front.
|
||||
var declarations = try getDeclarations(allocator, &header.value);
|
||||
defer declarations.deinit();
|
||||
var declarations = try getDeclarations(gpa, &header.value);
|
||||
defer declarations.deinit(gpa);
|
||||
|
||||
// Write all defines as private constants.
|
||||
try writeDefines(writer, internal, symbols, &header.value);
|
||||
try writeDefines(gpa, writer, internal, symbols, &header.value);
|
||||
|
||||
// Write all typedefs as private constants.
|
||||
try writeTypedefs(writer, &header.value, symbols, &declarations);
|
||||
try writeTypedefs(gpa, writer, &header.value, symbols, &declarations);
|
||||
|
||||
// Write all cimgui functions as private extern functions.
|
||||
try writeExternFunctions(writer, &header.value, symbols, &declarations);
|
||||
try writeExternFunctions(gpa, writer, &header.value, symbols, &declarations);
|
||||
|
||||
// Alias cimgui free functions under Zig friendly names.
|
||||
try writeFreeFunctions(writer, &header.value, symbols);
|
||||
try writeFreeFunctions(gpa, writer, &header.value, symbols);
|
||||
|
||||
// Get a list of cimgui methods. These were already written as externs, and can be aliased
|
||||
// when we write their respective types.
|
||||
var methods = try Methods.get(allocator, &header.value);
|
||||
defer methods.deinit(allocator);
|
||||
var methods = try Methods.get(gpa, &header.value);
|
||||
defer methods.deinit(gpa);
|
||||
|
||||
// Write cimgui enums as Zig enums.
|
||||
try writeEnums(allocator, writer, internal, &header.value, symbols);
|
||||
try writeEnums(gpa, writer, internal, &header.value, symbols);
|
||||
|
||||
// Write cimgui structs as Zig structs and unions.
|
||||
try writeStructs(writer, &header.value, &declarations, &methods, symbols);
|
||||
try writeStructs(gpa, writer, &header.value, &declarations, &methods, symbols);
|
||||
|
||||
// Write helpers used by the other generated code. We skip this for the internal header
|
||||
// since we're going to concatenate it with the main header, so this stuff will already be
|
||||
|
|
@ -300,9 +298,9 @@ fn writeSource(
|
|||
}
|
||||
}
|
||||
|
||||
fn getDeclarations(allocator: Allocator, header: *const Header) !Declarations {
|
||||
var declarations = Declarations.init(allocator);
|
||||
errdefer declarations.deinit();
|
||||
fn getDeclarations(gpa: Allocator, header: *const Header) !Declarations {
|
||||
var declarations: Declarations = .empty;
|
||||
errdefer declarations.deinit(gpa);
|
||||
for (header.structs) |ty| {
|
||||
if (skip(ty.conditionals)) continue;
|
||||
|
||||
|
|
@ -337,20 +335,20 @@ fn getDeclarations(allocator: Allocator, header: *const Header) !Declarations {
|
|||
};
|
||||
}
|
||||
|
||||
try declarations.put(trimmed, kind);
|
||||
try declarations.put(gpa, trimmed, kind);
|
||||
}
|
||||
|
||||
for (header.enums) |e| {
|
||||
if (skip(e.conditionals)) continue;
|
||||
|
||||
const trimmed = std.mem.trimEnd(u8, e.name, "_");
|
||||
try declarations.put(trimmed, .normal);
|
||||
try declarations.put(gpa, trimmed, .normal);
|
||||
}
|
||||
|
||||
return declarations;
|
||||
}
|
||||
|
||||
fn writeDefines(writer: anytype, internal: bool, symbols: *Symbols, header: *const Header) !void {
|
||||
fn writeDefines(gpa: Allocator, writer: anytype, internal: bool, symbols: *Symbols, header: *const Header) !void {
|
||||
// We skip defines from the internal namespace for now
|
||||
if (internal) return;
|
||||
|
||||
|
|
@ -358,7 +356,7 @@ fn writeDefines(writer: anytype, internal: bool, symbols: *Symbols, header: *con
|
|||
if (define.is_internal != internal) continue;
|
||||
if (skip(define.conditionals)) continue;
|
||||
if (define.content) |content| {
|
||||
if (try symbols.put(define.name)) {
|
||||
if (try symbols.put(gpa, define.name)) {
|
||||
if (std.mem.startsWith(u8, content, "(")) {
|
||||
const end = std.mem.indexOfScalar(u8, content, ')').?;
|
||||
const ty = content[1..end];
|
||||
|
|
@ -375,6 +373,7 @@ fn writeDefines(writer: anytype, internal: bool, symbols: *Symbols, header: *con
|
|||
}
|
||||
|
||||
fn writeTypedefs(
|
||||
gpa: Allocator,
|
||||
writer: anytype,
|
||||
header: *const Header,
|
||||
symbols: *Symbols,
|
||||
|
|
@ -392,7 +391,7 @@ fn writeTypedefs(
|
|||
std.mem.eql(u8, typedef.name, typedef.type.declaration.?)) continue;
|
||||
|
||||
// Write the typedef prefix
|
||||
if (try symbols.put(typedef.name)) {
|
||||
if (try symbols.put(gpa, typedef.name)) {
|
||||
try writer.writeAll("pub const ");
|
||||
try writeTypeName(writer, typedef.name);
|
||||
try writer.writeAll(" = ");
|
||||
|
|
@ -403,6 +402,7 @@ fn writeTypedefs(
|
|||
}
|
||||
|
||||
fn writeExternFunctions(
|
||||
gpa: Allocator,
|
||||
writer: anytype,
|
||||
header: *const Header,
|
||||
symbols: *Symbols,
|
||||
|
|
@ -412,7 +412,7 @@ fn writeExternFunctions(
|
|||
if (skip(function.conditionals)) continue;
|
||||
if (argsContainsVaList(function.arguments)) continue;
|
||||
|
||||
if (try symbols.put(function.name)) {
|
||||
if (try symbols.put(gpa, function.name)) {
|
||||
try writer.print("extern fn {s}(", .{function.name});
|
||||
for (function.arguments) |argument| {
|
||||
if (argument.type) |ty| {
|
||||
|
|
@ -446,13 +446,13 @@ fn argsContainsVaList(arguments: []const Header.Function.Argument) bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
fn writeFreeFunctions(writer: anytype, header: *const Header, symbols: *Symbols) !void {
|
||||
fn writeFreeFunctions(gpa: Allocator, writer: anytype, header: *const Header, symbols: *Symbols) !void {
|
||||
for (header.functions) |function| {
|
||||
if (skip(function.conditionals)) continue;
|
||||
if (function.original_class != null) continue;
|
||||
if (argsContainsVaList(function.arguments)) continue;
|
||||
|
||||
if (try symbols.put(function.name)) {
|
||||
if (try symbols.put(gpa, function.name)) {
|
||||
try writer.writeAll("pub const ");
|
||||
try writeFunctionName(writer, function.name);
|
||||
try writer.print(" = {s};\n", .{function.name});
|
||||
|
|
@ -461,19 +461,19 @@ fn writeFreeFunctions(writer: anytype, header: *const Header, symbols: *Symbols)
|
|||
}
|
||||
|
||||
const Methods = struct {
|
||||
types: std.StringArrayHashMap(std.ArrayList([]const u8)),
|
||||
types: std.array_hash_map.String(std.ArrayList([]const u8)),
|
||||
|
||||
fn get(allocator: Allocator, header: *const Header) !Methods {
|
||||
fn get(gpa: Allocator, header: *const Header) !Methods {
|
||||
// Initialize an empty method list for each type
|
||||
var types = std.StringArrayHashMap(std.ArrayList([]const u8)).init(allocator);
|
||||
errdefer types.deinit();
|
||||
var types: std.array_hash_map.String(std.ArrayList([]const u8)) = .empty;
|
||||
errdefer types.deinit(gpa);
|
||||
errdefer for (types.values()) |*methods| {
|
||||
methods.deinit(allocator);
|
||||
methods.deinit(gpa);
|
||||
};
|
||||
for (header.structs) |ty| {
|
||||
var methods: std.ArrayList([]const u8) = .empty;
|
||||
errdefer methods.deinit(allocator);
|
||||
try types.put(ty.name, methods);
|
||||
errdefer methods.deinit(gpa);
|
||||
try types.put(gpa, ty.name, methods);
|
||||
}
|
||||
|
||||
// Fill in the method lists
|
||||
|
|
@ -483,24 +483,24 @@ const Methods = struct {
|
|||
|
||||
if (function.original_class) |class| {
|
||||
const methods = types.getPtr(class).?;
|
||||
try methods.append(allocator, function.name);
|
||||
try methods.append(gpa, function.name);
|
||||
}
|
||||
}
|
||||
|
||||
return .{ .types = types };
|
||||
}
|
||||
|
||||
fn deinit(self: *Methods, allocator: Allocator) void {
|
||||
fn deinit(self: *Methods, gpa: Allocator) void {
|
||||
for (self.types.values()) |*methods| {
|
||||
methods.deinit(allocator);
|
||||
methods.deinit(gpa);
|
||||
}
|
||||
self.types.deinit();
|
||||
self.types.deinit(gpa);
|
||||
self.* = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
fn writeEnums(
|
||||
allocator: Allocator,
|
||||
gpa: Allocator,
|
||||
writer: anytype,
|
||||
internal: bool,
|
||||
header: *const Header,
|
||||
|
|
@ -509,7 +509,7 @@ fn writeEnums(
|
|||
for (header.enums) |e| {
|
||||
if (skip(e.conditionals)) continue;
|
||||
|
||||
if (try symbols.put(e.name)) {
|
||||
if (try symbols.put(gpa, e.name)) {
|
||||
try writer.writeAll("pub const ");
|
||||
try writeTypeName(writer, e.name);
|
||||
try writer.writeAll(" = ");
|
||||
|
|
@ -517,7 +517,7 @@ fn writeEnums(
|
|||
if (e.is_flags_enum) {
|
||||
try writeFlagsEnum(writer, internal, e);
|
||||
} else {
|
||||
try writeNormalEnum(allocator, writer, internal, e);
|
||||
try writeNormalEnum(gpa, writer, internal, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -572,13 +572,13 @@ fn writeFlagsEnum(writer: anytype, internal: bool, e: Header.Enum) !void {
|
|||
}
|
||||
|
||||
fn writeNormalEnum(
|
||||
allocator: Allocator,
|
||||
gpa: Allocator,
|
||||
writer: anytype,
|
||||
internal: bool,
|
||||
e: Header.Enum,
|
||||
) !void {
|
||||
var values = std.AutoArrayHashMap(i64, void).init(allocator);
|
||||
defer values.deinit();
|
||||
var values: std.array_hash_map.Auto(i64, void) = .empty;
|
||||
defer values.deinit(gpa);
|
||||
|
||||
try writer.writeAll("enum(");
|
||||
switch (e.storage_type.declaration) {
|
||||
|
|
@ -602,7 +602,7 @@ fn writeNormalEnum(
|
|||
// We skip duplicate values, these are sometimes present e.g. in the keys enum which
|
||||
// contains the mods enum and therefore two "none" options that are identical.
|
||||
if (values.contains(element.value)) continue;
|
||||
try values.put(element.value, {});
|
||||
try values.put(gpa, element.value, {});
|
||||
|
||||
// Write the element
|
||||
try writer.writeAll(" ");
|
||||
|
|
@ -632,6 +632,7 @@ fn writeNormalEnum(
|
|||
}
|
||||
|
||||
fn writeStructs(
|
||||
gpa: Allocator,
|
||||
writer: anytype,
|
||||
header: *const Header,
|
||||
declarations: *const Declarations,
|
||||
|
|
@ -648,7 +649,7 @@ fn writeStructs(
|
|||
const decl_kind = declarations.get(ty.name).?;
|
||||
if (decl_kind == .import) continue;
|
||||
|
||||
if (try symbols.put(ty.name)) {
|
||||
if (try symbols.put(gpa, ty.name)) {
|
||||
// Write the struct
|
||||
try writer.writeAll("pub const ");
|
||||
try writeTypeName(writer, ty.name);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue