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-cache/
|
||||||
zig-out
|
/zig-out/
|
||||||
|
/zig-pkg/
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
.name = .dear_imgui,
|
.name = .dear_imgui,
|
||||||
.fingerprint = 0xc1cc609af54040bd,
|
.fingerprint = 0xc1cc609af54040bd,
|
||||||
.version = "1.0.0",
|
.version = "1.0.0",
|
||||||
.minimum_zig_version = "0.16.0-dev.2193+fc517bd01",
|
.minimum_zig_version = "0.16.0-dev.3153+d6f43caad",
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.@"dear-imgui" = .{
|
.@"dear-imgui" = .{
|
||||||
// Using a patched version of v1.92.5-docking that has a UBSAN fix. The equivalent to
|
// Using a patched version of v1.92.5-docking that has a UBSAN fix. The equivalent to
|
||||||
|
|
|
||||||
115
src/generate.zig
115
src/generate.zig
|
|
@ -9,29 +9,27 @@ const DeclarationKind = enum {
|
||||||
import, // Assumed to be normal, but external
|
import, // Assumed to be normal, but external
|
||||||
};
|
};
|
||||||
|
|
||||||
const Declarations = std.StringArrayHashMap(DeclarationKind);
|
const Declarations = std.array_hash_map.String(DeclarationKind);
|
||||||
|
|
||||||
const Symbols = struct {
|
const Symbols = struct {
|
||||||
public: std.StringArrayHashMap(void),
|
public: std.array_hash_map.String(void),
|
||||||
front_buf: std.StringArrayHashMap(void),
|
front_buf: std.array_hash_map.String(void),
|
||||||
|
|
||||||
pub fn init(allocator: Allocator) @This() {
|
pub const empty: @This() = .{
|
||||||
return .{
|
.public = .empty,
|
||||||
.public = .init(allocator),
|
.front_buf = .empty,
|
||||||
.front_buf = .init(allocator),
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This(), gpa: Allocator) void {
|
||||||
self.public.deinit();
|
self.public.deinit(gpa);
|
||||||
self.front_buf.deinit();
|
self.front_buf.deinit(gpa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if there's already a public symbol with this name.
|
/// 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, "_");
|
const trimmed = std.mem.trimEnd(u8, name, "_");
|
||||||
if (self.public.contains(trimmed)) return false;
|
if (self.public.contains(trimmed)) return false;
|
||||||
try self.front_buf.put(trimmed, {});
|
try self.front_buf.put(gpa, trimmed, {});
|
||||||
return true;
|
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
|
// Build a list of symbols so we can skip duplicates of public symbols in the internal headers
|
||||||
var symbols: Symbols = .init(allocator);
|
var symbols: Symbols = .empty;
|
||||||
defer symbols.deinit();
|
defer symbols.deinit(allocator);
|
||||||
|
|
||||||
// Write the source
|
// Write the source
|
||||||
const main_source = try Dir.cwd().readFileAlloc(io, in_path, allocator, .limited(max_size));
|
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(
|
fn writeSource(
|
||||||
allocator: Allocator,
|
gpa: Allocator,
|
||||||
source: []const u8,
|
source: []const u8,
|
||||||
writer: *Io.Writer,
|
writer: *Io.Writer,
|
||||||
symbols: *Symbols,
|
symbols: *Symbols,
|
||||||
internal: bool,
|
internal: bool,
|
||||||
) !void {
|
) !void {
|
||||||
const header = try std.json.parseFromSlice(Header, allocator, source, .{
|
const header = try std.json.parseFromSlice(Header, gpa, source, .{
|
||||||
.ignore_unknown_fields = true,
|
.ignore_unknown_fields = true,
|
||||||
});
|
});
|
||||||
defer header.deinit();
|
defer header.deinit();
|
||||||
|
|
||||||
// We need the list of declarations up front.
|
// We need the list of declarations up front.
|
||||||
var declarations = try getDeclarations(allocator, &header.value);
|
var declarations = try getDeclarations(gpa, &header.value);
|
||||||
defer declarations.deinit();
|
defer declarations.deinit(gpa);
|
||||||
|
|
||||||
// Write all defines as private constants.
|
// 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.
|
// 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.
|
// 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.
|
// 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
|
// Get a list of cimgui methods. These were already written as externs, and can be aliased
|
||||||
// when we write their respective types.
|
// when we write their respective types.
|
||||||
var methods = try Methods.get(allocator, &header.value);
|
var methods = try Methods.get(gpa, &header.value);
|
||||||
defer methods.deinit(allocator);
|
defer methods.deinit(gpa);
|
||||||
|
|
||||||
// Write cimgui enums as Zig enums.
|
// 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.
|
// 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
|
// 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
|
// 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 {
|
fn getDeclarations(gpa: Allocator, header: *const Header) !Declarations {
|
||||||
var declarations = Declarations.init(allocator);
|
var declarations: Declarations = .empty;
|
||||||
errdefer declarations.deinit();
|
errdefer declarations.deinit(gpa);
|
||||||
for (header.structs) |ty| {
|
for (header.structs) |ty| {
|
||||||
if (skip(ty.conditionals)) continue;
|
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| {
|
for (header.enums) |e| {
|
||||||
if (skip(e.conditionals)) continue;
|
if (skip(e.conditionals)) continue;
|
||||||
|
|
||||||
const trimmed = std.mem.trimEnd(u8, e.name, "_");
|
const trimmed = std.mem.trimEnd(u8, e.name, "_");
|
||||||
try declarations.put(trimmed, .normal);
|
try declarations.put(gpa, trimmed, .normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return declarations;
|
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
|
// We skip defines from the internal namespace for now
|
||||||
if (internal) return;
|
if (internal) return;
|
||||||
|
|
||||||
|
|
@ -358,7 +356,7 @@ fn writeDefines(writer: anytype, internal: bool, symbols: *Symbols, header: *con
|
||||||
if (define.is_internal != internal) continue;
|
if (define.is_internal != internal) continue;
|
||||||
if (skip(define.conditionals)) continue;
|
if (skip(define.conditionals)) continue;
|
||||||
if (define.content) |content| {
|
if (define.content) |content| {
|
||||||
if (try symbols.put(define.name)) {
|
if (try symbols.put(gpa, define.name)) {
|
||||||
if (std.mem.startsWith(u8, content, "(")) {
|
if (std.mem.startsWith(u8, content, "(")) {
|
||||||
const end = std.mem.indexOfScalar(u8, content, ')').?;
|
const end = std.mem.indexOfScalar(u8, content, ')').?;
|
||||||
const ty = content[1..end];
|
const ty = content[1..end];
|
||||||
|
|
@ -375,6 +373,7 @@ fn writeDefines(writer: anytype, internal: bool, symbols: *Symbols, header: *con
|
||||||
}
|
}
|
||||||
|
|
||||||
fn writeTypedefs(
|
fn writeTypedefs(
|
||||||
|
gpa: Allocator,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
header: *const Header,
|
header: *const Header,
|
||||||
symbols: *Symbols,
|
symbols: *Symbols,
|
||||||
|
|
@ -392,7 +391,7 @@ fn writeTypedefs(
|
||||||
std.mem.eql(u8, typedef.name, typedef.type.declaration.?)) continue;
|
std.mem.eql(u8, typedef.name, typedef.type.declaration.?)) continue;
|
||||||
|
|
||||||
// Write the typedef prefix
|
// Write the typedef prefix
|
||||||
if (try symbols.put(typedef.name)) {
|
if (try symbols.put(gpa, typedef.name)) {
|
||||||
try writer.writeAll("pub const ");
|
try writer.writeAll("pub const ");
|
||||||
try writeTypeName(writer, typedef.name);
|
try writeTypeName(writer, typedef.name);
|
||||||
try writer.writeAll(" = ");
|
try writer.writeAll(" = ");
|
||||||
|
|
@ -403,6 +402,7 @@ fn writeTypedefs(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn writeExternFunctions(
|
fn writeExternFunctions(
|
||||||
|
gpa: Allocator,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
header: *const Header,
|
header: *const Header,
|
||||||
symbols: *Symbols,
|
symbols: *Symbols,
|
||||||
|
|
@ -412,7 +412,7 @@ fn writeExternFunctions(
|
||||||
if (skip(function.conditionals)) continue;
|
if (skip(function.conditionals)) continue;
|
||||||
if (argsContainsVaList(function.arguments)) 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});
|
try writer.print("extern fn {s}(", .{function.name});
|
||||||
for (function.arguments) |argument| {
|
for (function.arguments) |argument| {
|
||||||
if (argument.type) |ty| {
|
if (argument.type) |ty| {
|
||||||
|
|
@ -446,13 +446,13 @@ fn argsContainsVaList(arguments: []const Header.Function.Argument) bool {
|
||||||
return false;
|
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| {
|
for (header.functions) |function| {
|
||||||
if (skip(function.conditionals)) continue;
|
if (skip(function.conditionals)) continue;
|
||||||
if (function.original_class != null) continue;
|
if (function.original_class != null) continue;
|
||||||
if (argsContainsVaList(function.arguments)) 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 writer.writeAll("pub const ");
|
||||||
try writeFunctionName(writer, function.name);
|
try writeFunctionName(writer, function.name);
|
||||||
try writer.print(" = {s};\n", .{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 {
|
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
|
// Initialize an empty method list for each type
|
||||||
var types = std.StringArrayHashMap(std.ArrayList([]const u8)).init(allocator);
|
var types: std.array_hash_map.String(std.ArrayList([]const u8)) = .empty;
|
||||||
errdefer types.deinit();
|
errdefer types.deinit(gpa);
|
||||||
errdefer for (types.values()) |*methods| {
|
errdefer for (types.values()) |*methods| {
|
||||||
methods.deinit(allocator);
|
methods.deinit(gpa);
|
||||||
};
|
};
|
||||||
for (header.structs) |ty| {
|
for (header.structs) |ty| {
|
||||||
var methods: std.ArrayList([]const u8) = .empty;
|
var methods: std.ArrayList([]const u8) = .empty;
|
||||||
errdefer methods.deinit(allocator);
|
errdefer methods.deinit(gpa);
|
||||||
try types.put(ty.name, methods);
|
try types.put(gpa, ty.name, methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the method lists
|
// Fill in the method lists
|
||||||
|
|
@ -483,24 +483,24 @@ const Methods = struct {
|
||||||
|
|
||||||
if (function.original_class) |class| {
|
if (function.original_class) |class| {
|
||||||
const methods = types.getPtr(class).?;
|
const methods = types.getPtr(class).?;
|
||||||
try methods.append(allocator, function.name);
|
try methods.append(gpa, function.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{ .types = types };
|
return .{ .types = types };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(self: *Methods, allocator: Allocator) void {
|
fn deinit(self: *Methods, gpa: Allocator) void {
|
||||||
for (self.types.values()) |*methods| {
|
for (self.types.values()) |*methods| {
|
||||||
methods.deinit(allocator);
|
methods.deinit(gpa);
|
||||||
}
|
}
|
||||||
self.types.deinit();
|
self.types.deinit(gpa);
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn writeEnums(
|
fn writeEnums(
|
||||||
allocator: Allocator,
|
gpa: Allocator,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
internal: bool,
|
internal: bool,
|
||||||
header: *const Header,
|
header: *const Header,
|
||||||
|
|
@ -509,7 +509,7 @@ fn writeEnums(
|
||||||
for (header.enums) |e| {
|
for (header.enums) |e| {
|
||||||
if (skip(e.conditionals)) continue;
|
if (skip(e.conditionals)) continue;
|
||||||
|
|
||||||
if (try symbols.put(e.name)) {
|
if (try symbols.put(gpa, e.name)) {
|
||||||
try writer.writeAll("pub const ");
|
try writer.writeAll("pub const ");
|
||||||
try writeTypeName(writer, e.name);
|
try writeTypeName(writer, e.name);
|
||||||
try writer.writeAll(" = ");
|
try writer.writeAll(" = ");
|
||||||
|
|
@ -517,7 +517,7 @@ fn writeEnums(
|
||||||
if (e.is_flags_enum) {
|
if (e.is_flags_enum) {
|
||||||
try writeFlagsEnum(writer, internal, e);
|
try writeFlagsEnum(writer, internal, e);
|
||||||
} else {
|
} 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(
|
fn writeNormalEnum(
|
||||||
allocator: Allocator,
|
gpa: Allocator,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
internal: bool,
|
internal: bool,
|
||||||
e: Header.Enum,
|
e: Header.Enum,
|
||||||
) !void {
|
) !void {
|
||||||
var values = std.AutoArrayHashMap(i64, void).init(allocator);
|
var values: std.array_hash_map.Auto(i64, void) = .empty;
|
||||||
defer values.deinit();
|
defer values.deinit(gpa);
|
||||||
|
|
||||||
try writer.writeAll("enum(");
|
try writer.writeAll("enum(");
|
||||||
switch (e.storage_type.declaration) {
|
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
|
// 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.
|
// contains the mods enum and therefore two "none" options that are identical.
|
||||||
if (values.contains(element.value)) continue;
|
if (values.contains(element.value)) continue;
|
||||||
try values.put(element.value, {});
|
try values.put(gpa, element.value, {});
|
||||||
|
|
||||||
// Write the element
|
// Write the element
|
||||||
try writer.writeAll(" ");
|
try writer.writeAll(" ");
|
||||||
|
|
@ -632,6 +632,7 @@ fn writeNormalEnum(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn writeStructs(
|
fn writeStructs(
|
||||||
|
gpa: Allocator,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
header: *const Header,
|
header: *const Header,
|
||||||
declarations: *const Declarations,
|
declarations: *const Declarations,
|
||||||
|
|
@ -648,7 +649,7 @@ fn writeStructs(
|
||||||
const decl_kind = declarations.get(ty.name).?;
|
const decl_kind = declarations.get(ty.name).?;
|
||||||
if (decl_kind == .import) continue;
|
if (decl_kind == .import) continue;
|
||||||
|
|
||||||
if (try symbols.put(ty.name)) {
|
if (try symbols.put(gpa, ty.name)) {
|
||||||
// Write the struct
|
// Write the struct
|
||||||
try writer.writeAll("pub const ");
|
try writer.writeAll("pub const ");
|
||||||
try writeTypeName(writer, ty.name);
|
try writeTypeName(writer, ty.name);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue