diff --git a/.gitignore b/.gitignore index d8c8979..76ce064 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -.zig-cache -zig-out +/.zig-cache/ +/zig-out/ +/zig-pkg/ diff --git a/build.zig.zon b/build.zig.zon index a43a9bf..8b01b85 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -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 diff --git a/src/generate.zig b/src/generate.zig index a8a5510..72ab49e 100644 --- a/src/generate.zig +++ b/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);