aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/bindings/header-gen.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-07-21 02:07:07 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-07-21 02:07:07 -0700
commita8a4f280469d4d3baf8ea6e9dbce9ec06bd3d868 (patch)
tree8a10690daafe99a8d908119f9bb855cd0f3d368a /src/javascript/jsc/bindings/header-gen.zig
parentf2ea2027300949b919f9d595ce3039c8bc82d21a (diff)
downloadbun-a8a4f280469d4d3baf8ea6e9dbce9ec06bd3d868.tar.gz
bun-a8a4f280469d4d3baf8ea6e9dbce9ec06bd3d868.tar.zst
bun-a8a4f280469d4d3baf8ea6e9dbce9ec06bd3d868.zip
most of the bindings!
Diffstat (limited to 'src/javascript/jsc/bindings/header-gen.zig')
-rw-r--r--src/javascript/jsc/bindings/header-gen.zig559
1 files changed, 444 insertions, 115 deletions
diff --git a/src/javascript/jsc/bindings/header-gen.zig b/src/javascript/jsc/bindings/header-gen.zig
index 6155c5d1a..7b664785d 100644
--- a/src/javascript/jsc/bindings/header-gen.zig
+++ b/src/javascript/jsc/bindings/header-gen.zig
@@ -6,16 +6,71 @@ const StructMeta = std.builtin.TypeInfo.Struct;
const EnumMeta = std.builtin.TypeInfo.Enum;
const UnionMeta = std.builtin.TypeInfo.Union;
const warn = std.debug.warn;
+const StaticExport = @import("./static_export.zig");
+
+const TypeNameMap = std.StringHashMap([]const u8);
fn isCppObject(comptime Type: type) bool {
return switch (@typeInfo(Type)) {
.Struct, .Union, .Opaque => true,
+ .Enum => |Enum| @hasDecl(Type, "Type"),
else => false,
};
}
+pub fn cTypeLabel(comptime Type: type) ?[]const u8 {
+ return switch (comptime Type) {
+ void => "void",
+ bool => "bool",
+ usize => "size_t",
+ isize => "int",
+ u8 => "char",
+ u16 => "uint16_t",
+ u32 => "uint32_t",
+ u64 => "uint64_t",
+ i8 => "int8_t",
+ i16 => "int16_t",
+ i24 => "int24_t",
+ i32 => "int32_t",
+ i64 => "int64_t",
+ f64 => "double",
+ f32 => "float",
+ *c_void => "void*",
+ [*]bool => "bool*",
+ [*]usize => "size_t*",
+ [*]isize => "int*",
+ [*]u8 => "char*",
+ [*]u16 => "uint16_t*",
+ [*]u32 => "uint32_t*",
+ [*]u64 => "uint64_t*",
+ [*]i8 => "int8_t*",
+ [*]i16 => "int16_t*",
+ [*]i32 => "int32_t*",
+ [*]i64 => "int64_t*",
+ [*]const bool => "const bool*",
+ [*]const usize => "const size_t*",
+ [*]const isize => "const int*",
+ [*]const u8 => "const char*",
+ [*]const u16 => "const uint16_t*",
+ [*]const u32 => "const uint32_t*",
+ [*]const u64 => "const uint64_t*",
+ [*]const i8 => "const int8_t*",
+ [*]const i16 => "const int16_t*",
+ [*]const i32 => "const int32_t*",
+ [*]const i64 => "const int64_t*",
+ else => null,
+ };
+}
+
+var buffer = std.ArrayList(u8).init(std.heap.c_allocator);
+var writer = buffer.writer();
+var impl_buffer = std.ArrayList(u8).init(std.heap.c_allocator);
+var impl_writer = impl_buffer.writer();
+var bufset = std.BufSet.init(std.heap.c_allocator);
+var type_names = TypeNameMap.init(std.heap.c_allocator);
+var size_map = std.StringHashMap(u32).init(std.heap.c_allocator);
+
pub const C_Generator = struct {
- file: std.fs.File,
filebase: []const u8,
direction: Direction = .export_cpp,
@@ -26,8 +81,8 @@ pub const C_Generator = struct {
export_zig,
};
- pub fn init(comptime src_file: []const u8, file: std.fs.File) Self {
- var res = Self{ .file = file, .filebase = src_file };
+ pub fn init(comptime src_file: []const u8, comptime Writer: type, file: Writer) Self {
+ var res = Self{ .filebase = src_file };
return res;
}
@@ -38,7 +93,13 @@ pub const C_Generator = struct {
// self.file.writeAll("> ****/\n\n") catch unreachable;
}
- pub fn gen_func(self: *Self, comptime name: []const u8, comptime func: FnDecl, comptime meta: FnMeta, comptime arg_names: []const []const u8) void {
+ pub fn gen_func(
+ self: *Self,
+ comptime name: []const u8,
+ comptime func: FnDecl,
+ comptime meta: FnMeta,
+ comptime arg_names: []const []const u8,
+ ) void {
switch (meta.calling_convention) {
.Naked => self.write("__attribute__((naked)) "),
.Stdcall => self.write("__attribute__((stdcall)) "),
@@ -48,26 +109,38 @@ pub const C_Generator = struct {
}
switch (self.direction) {
- .export_cpp => self.write("CPP_DECL \"C\" "),
- .export_zig => self.write("ZIG_DECL \"C\" "),
+ .export_cpp => self.write("CPP_DECL "),
+ .export_zig => self.write("ZIG_DECL "),
}
self.writeType(func.return_type);
self.write(" " ++ name ++ "(");
inline for (meta.args) |arg, i| {
- self.writeType(arg.arg_type.?);
- if (func.arg_names.len > i) {
- self.write(comptime arg_names[i]);
- } else {
- const ArgType = arg.arg_type.?;
- if (@typeInfo(ArgType) == .Enum) {
- self.write(comptime std.fmt.comptimePrint(" {s}{d}", .{ @typeName(ArgType), i }));
- } else {
- self.write(comptime std.fmt.comptimePrint(" arg{d}", .{i}));
- }
+ const ArgType = arg.arg_type.?;
+
+ switch (@typeInfo(ArgType)) {
+ .Fn => {
+ self.gen_closure(comptime arg.arg_type.?, comptime std.fmt.comptimePrint(" ArgFn{d}", .{i}));
+ },
+ else => {
+ self.writeType(arg.arg_type.?);
+ switch (@typeInfo(ArgType)) {
+ .Enum => {
+ self.write(comptime std.fmt.comptimePrint(" {s}{d}", .{ @typeName(ArgType), i }));
+ },
+
+ else => {
+ self.write(comptime std.fmt.comptimePrint(" arg{d}", .{i}));
+ },
+ }
+ },
}
+ // if (comptime func.arg_names.len > 0 and func.arg_names.len > i) {
+ // self.write(comptime arg_names[i]);
+ // } else {
+
//TODO: Figure out how to get arg names; for now just do arg0..argN
if (i != meta.args.len - 1)
self.write(", ");
@@ -85,6 +158,43 @@ pub const C_Generator = struct {
// }
}
+ pub fn gen_closure(
+ self: *Self,
+ comptime Function: type,
+ comptime name: []const u8,
+ ) void {
+ const func: std.builtin.TypeInfo.Fn = @typeInfo(Function).Fn;
+ self.writeType(func.return_type orelse void);
+ self.write(" (*" ++ name ++ ")(");
+ inline for (func.args) |arg, i| {
+ self.writeType(arg.arg_type.?);
+ // if (comptime func.arg_names.len > 0 and func.arg_names.len > i) {
+ // self.write(comptime arg_names[i]);
+ // } else {
+ const ArgType = arg.arg_type.?;
+ if (@typeInfo(ArgType) == .Enum) {
+ self.write(comptime std.fmt.comptimePrint(" {s}{d}", .{ @typeName(ArgType), i }));
+ } else {
+ self.write(comptime std.fmt.comptimePrint(" arg{d}", .{i}));
+ }
+ // }
+
+ //TODO: Figure out how to get arg names; for now just do arg0..argN
+ if (i != func.args.len - 1)
+ self.write(", ");
+ }
+
+ self.write(")");
+ // const ReturnTypeInfo: std.builtin.TypeInfo = comptime @typeInfo(func.return_type);
+ // switch (comptime ReturnTypeInfo) {
+ // .Pointer => |Pointer| {
+ // self.write(" __attribute__((returns_nonnull))");
+ // },
+ // .Optional => |Optional| {},
+ // else => {},
+ // }
+ }
+
pub fn gen_struct(self: *Self, comptime name: []const u8, comptime meta: StructMeta) void {
self.write("typedef struct ");
@@ -107,7 +217,7 @@ pub const C_Generator = struct {
self.write(" " ++ field.name);
if (info == .Array) {
- _ = self.file.writer().print("[{}]", .{info.Array.len}) catch unreachable;
+ writer.print("[{}]", .{info.Array.len}) catch unreachable;
}
self.write(";\n");
@@ -115,7 +225,11 @@ pub const C_Generator = struct {
self.write("} " ++ name ++ "_t;\n\n");
}
- pub fn gen_enum(self: *Self, comptime name: []const u8, comptime meta: EnumMeta) void {
+ pub fn gen_enum(
+ self: *Self,
+ comptime name: []const u8,
+ comptime meta: EnumMeta,
+ ) void {
self.write("enum " ++ name ++ " {\n");
comptime var last = 0;
@@ -124,7 +238,7 @@ pub const C_Generator = struct {
// if field value is unexpected/custom, manually define it
if ((i == 0 and field.value != 0) or (i > 0 and field.value > last + 1)) {
- _ = self.file.writer().print(" = {}", .{field.value}) catch unreachable;
+ writer.print(" = {}", .{field.value}) catch unreachable;
}
self.write(",\n");
@@ -135,7 +249,11 @@ pub const C_Generator = struct {
self.write("};\n\n");
}
- pub fn gen_union(self: *Self, comptime name: []const u8, comptime meta: UnionMeta) void {
+ pub fn gen_union(
+ self: *Self,
+ comptime name: []const u8,
+ comptime meta: UnionMeta,
+ ) void {
self.write("typedef union ");
self.write(name ++ " {\n");
@@ -148,7 +266,10 @@ pub const C_Generator = struct {
self.write("} " ++ name ++ "_t;\n\n");
}
- fn writeType(self: *Self, comptime T: type) void {
+ fn writeType(
+ self: *Self,
+ comptime T: type,
+ ) void {
const TT = comptime if (@typeInfo(T) == .Pointer) @typeInfo(T).Pointer.child else T;
if (comptime (isCppObject(TT)) and @hasDecl(TT, "name")) {
@@ -158,7 +279,38 @@ pub const C_Generator = struct {
}
}
- self.write(comptime TT.name);
+ const _formatted_name = comptime brk: {
+ var original: [TT.name.len]u8 = undefined;
+ _ = std.mem.replace(u8, TT.name, ":", "_", &original);
+ break :brk original;
+ };
+ const formatted_name = comptime std.mem.span(&_formatted_name);
+
+ if (@hasDecl(TT, "is_pointer") and !TT.is_pointer) {
+ if (cTypeLabel(TT.Type)) |label| {
+ type_names.put(comptime label, formatted_name) catch unreachable;
+ if (@typeInfo(TT) == .Struct and @hasField(TT, "bytes")) {
+ size_map.put(comptime formatted_name, @as(u32, TT.shim.byte_size)) catch unreachable;
+ }
+ } else {
+ type_names.put(comptime TT.name, formatted_name) catch unreachable;
+ if (@typeInfo(TT) == .Struct and @hasField(TT, "bytes")) {
+ size_map.put(comptime formatted_name, @as(u32, TT.shim.byte_size)) catch unreachable;
+ }
+ }
+ } else {
+ type_names.put(comptime TT.name, formatted_name) catch unreachable;
+ if (@typeInfo(TT) == .Struct and @hasField(TT, "bytes")) {
+ size_map.put(comptime formatted_name, @as(u32, TT.shim.byte_size)) catch unreachable;
+ }
+ }
+
+ if (TT == T and @hasField(T, "bytes")) {
+ write(self, comptime "b" ++ formatted_name);
+ } else {
+ write(self, comptime formatted_name);
+ }
+
if (@typeInfo(T) == .Pointer or @hasDecl(TT, "Type") and @typeInfo(TT.Type) == .Pointer) {
if (@hasDecl(TT, "is_pointer") and !TT.is_pointer) {} else {
write(self, "*");
@@ -167,73 +319,35 @@ pub const C_Generator = struct {
return;
}
- switch (T) {
- void => self.write("void"),
- bool => self.write("bool"),
- usize => self.write("size_t"),
- isize => self.write("int"),
- u8 => self.write("char"),
- u16 => self.write("uint16_t"),
- u32 => self.write("uint32_t"),
- u64 => self.write("uint64_t"),
- i8 => self.write("int8_t"),
- i16 => self.write("int16_t"),
- i24 => self.write("int24_t"),
- i32 => self.write("int32_t"),
- i64 => self.write("int64_t"),
- f64 => self.write("double"),
- f32 => self.write("float"),
- *c_void => self.write("void*"),
- [*]bool => self.write("bool*"),
- [*]usize => self.write("size_t*"),
- [*]isize => self.write("int*"),
- [*]u8 => self.write("char*"),
- [*]u16 => self.write("uint16_t*"),
- [*]u32 => self.write("uint32_t*"),
- [*]u64 => self.write("uint64_t*"),
- [*]i8 => self.write("int8_t*"),
- [*]i16 => self.write("int16_t*"),
- [*]i32 => self.write("int32_t*"),
- [*]i64 => self.write("int64_t*"),
- [*]const bool => self.write("const bool*"),
- [*]const usize => self.write("const size_t*"),
- [*]const isize => self.write("const int*"),
- [*]const u8 => self.write("const char*"),
- [*]const u16 => self.write("const uint16_t*"),
- [*]const u32 => self.write("const uint32_t*"),
- [*]const u64 => self.write("const uint64_t*"),
- [*]const i8 => self.write("const int8_t*"),
- [*]const i16 => self.write("const int16_t*"),
- [*]const i32 => self.write("const int32_t*"),
- [*]const i64 => self.write("const int64_t*"),
- else => {
- const meta = @typeInfo(T);
- switch (meta) {
- .Pointer => |Pointer| {
- const child = Pointer.child;
- const childmeta = @typeInfo(child);
- // if (childmeta == .Struct and childmeta.Struct.layout != .Extern) {
- // self.write("void");
- // } else {
- self.writeType(child);
- // }
- self.write("*");
- },
- .Optional => self.writeType(meta.Optional.child),
- .Array => @compileError("Handle goofy looking C Arrays in the calling function"),
- .Enum => |Enum| {
- self.writeType(Enum.tag_type);
- },
- else => {
- return self.write(@typeName(T));
- },
- }
- },
+ if (comptime cTypeLabel(T)) |label| {
+ self.write(comptime label);
+ } else {
+ const meta = @typeInfo(T);
+ switch (meta) {
+ .Pointer => |Pointer| {
+ const child = Pointer.child;
+ const childmeta = @typeInfo(child);
+ // if (childmeta == .Struct and childmeta.Struct.layout != .Extern) {
+ // self.write("void");
+ // } else {
+ self.writeType(child);
+ // }
+ self.write("*");
+ },
+ .Optional => self.writeType(meta.Optional.child),
+ .Array => @compileError("Handle goofy looking C Arrays in the calling function"),
+ .Enum => |Enum| {
+ self.writeType(Enum.tag_type);
+ },
+ else => {
+ return self.write(@typeName(T));
+ },
+ }
}
}
fn write(self: *Self, comptime str: []const u8) void {
- _ = self.file.writeAll(str) catch {};
+ _ = writer.write(str) catch {};
}
};
@@ -295,32 +409,62 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
return struct {
source_file: []const u8 = fname,
gen: C_Generator = undefined,
+
const Self = @This();
pub fn init() Self {
return Self{};
}
- pub fn startFile(comptime self: Self, comptime Type: type, comptime prefix: []const u8, file: std.fs.File) void {
+ pub fn startFile(
+ comptime self: Self,
+ comptime Type: type,
+ comptime prefix: []const u8,
+ file: anytype,
+ other: std.fs.File,
+ ) void {
if (comptime std.meta.trait.hasDecls(Type, .{"include"})) {
comptime var new_name = std.mem.zeroes([Type.include.len]u8);
comptime {
_ = std.mem.replace(u8, Type.include, "/", "_", std.mem.span(&new_name));
_ = std.mem.replace(u8, &new_name, ".", "_", std.mem.span(&new_name));
+ _ = std.mem.replace(u8, &new_name, "<", "_", std.mem.span(&new_name));
+ _ = std.mem.replace(u8, &new_name, ">", "_", std.mem.span(&new_name));
+ _ = std.mem.replace(u8, &new_name, "\"", "_", std.mem.span(&new_name));
+ }
+ file.writeAll("\n#pragma mark - " ++ Type.name ++ "\n\n") catch unreachable;
+
+ if (@hasDecl(Type, "include")) {
+ other.writer().print(
+ \\
+ \\#ifndef INCLUDED_{s}
+ \\#define INCLUDED_{s}
+ \\#include {s}
+ \\#endif
+ \\
+ \\extern "C" const size_t {s} = sizeof({s});
+ \\
+ ,
+ .{ new_name, new_name, Type.include, Type.shim.size_of_symbol, Type.name },
+ ) catch unreachable;
}
- const inner_name = comptime std.mem.trim(u8, &new_name, "<>\"");
- file.writeAll("\n#pragma mark - " ++ Type.name ++ "\n") catch unreachable;
- file.writeAll("\n#ifndef BINDINGS__decls__" ++ inner_name ++ "\n") catch {};
- file.writeAll("#define BINDINGS__decls__" ++ inner_name ++ "\n") catch {};
- file.writeAll("#include " ++ Type.include ++ "\n") catch {};
- file.writeAll("namespace " ++ Type.namespace ++ " {\n class " ++ prefix ++ ";\n}\n") catch {};
- file.writeAll("#endif\n\n") catch {};
}
}
+
+ pub fn processStaticExport(comptime self: Self, file: anytype, gen: *C_Generator, comptime static_export: StaticExport) void {
+ const fn_meta = comptime @typeInfo(static_export.Type).Fn;
+ gen.gen_func(
+ comptime static_export.symbol_name,
+ comptime static_export.Decl().data.Fn,
+ comptime fn_meta,
+ comptime std.mem.zeroes([]const []const u8),
+ );
+ }
+
pub fn processDecl(
comptime self: Self,
- file: std.fs.File,
+ file: anytype,
gen: *C_Generator,
comptime Container: type,
comptime Decl: std.builtin.TypeInfo.Declaration,
@@ -332,14 +476,20 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
switch (@typeInfo(Type)) {
.Enum => |Enum| {
const layout = Enum.layout;
- gen.gen_enum(prefix ++ "__" ++ name, Enum);
+ gen.gen_enum(
+ prefix ++ "__" ++ name,
+ Enum,
+ );
},
.Struct => |Struct| {
- gen.gen_struct(decl.name, Struct);
+ gen.gen_struct(decl.name, Struct, file);
},
.Union => |Union| {
const layout = Union.layout;
- gen.gen_union(prefix ++ "__" ++ name, Union);
+ gen.gen_union(
+ prefix ++ "__" ++ name,
+ Union,
+ );
},
.Fn => |func| {
// if (func.) {
@@ -370,41 +520,136 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
}
}
- pub fn exec(comptime self: Self, file: std.fs.File) void {
+ pub fn exec(comptime self: Self, file: std.fs.File, impl: std.fs.File) void {
const Generator = C_Generator;
validateGenerator(Generator);
-
- file.writeAll("#pragma once\n#include <stddef.h>\n#include <stdint.h>\n#include <stdbool.h>\n#define ZIG_DECL extern\n#define CPP_DECL extern \n\n") catch {};
- var bufset = std.BufSet.init(std.heap.c_allocator);
+ var file_writer = file.writer();
+ file_writer.print("//-- AUTOGENERATED FILE -- {d}\n", .{std.time.timestamp()}) catch unreachable;
+ file.writeAll(
+ \\#pragma once
+ \\
+ \\#include <stddef.h>
+ \\#include <stdint.h>
+ \\#include <stdbool.h>
+ \\
+ \\#ifdef __cplusplus
+ \\ #define AUTO_EXTERN_C extern "C"
+ \\#else
+ \\ #define AUTO_EXTERN_C
+ \\#endif
+ \\#define ZIG_DECL AUTO_EXTERN_C
+ \\#define CPP_DECL AUTO_EXTERN_C
+ \\#define CPP_SIZE AUTO_EXTERN_C
+ \\
+ \\
+ ) catch {};
+
+ impl.writer().print("//-- AUTOGENERATED FILE -- {d}\n", .{std.time.timestamp()}) catch unreachable;
+ impl.writer().writeAll(
+ \\#pragma once
+ \\
+ \\#include <stddef.h>
+ \\#include <stdint.h>
+ \\#include <stdbool.h>
+ \\
+ \\#include "root.h"
+ \\
+ ) catch {};
+
+ var impl_second_buffer = std.ArrayList(u8).init(std.heap.c_allocator);
+ var impl_second_writer = impl_second_buffer.writer();
+
+ var impl_third_buffer = std.ArrayList(u8).init(std.heap.c_allocator);
+ var impl_third_writer = impl_third_buffer.writer();
+
+ var to_get_sizes: usize = 0;
inline for (all_decls) |_decls| {
if (comptime _decls.is_pub) {
switch (_decls.data) {
.Type => |Type| {
@setEvalBranchQuota(99999);
- if (@hasDecl(Type, "Extern")) {
+
+ if (@hasDecl(Type, "Extern") or @hasDecl(Type, "Export")) {
const identifier = comptime std.fmt.comptimePrint("{s}_{s}", .{ Type.shim.name, Type.shim.namespace });
if (!bufset.contains(identifier)) {
- self.startFile(Type, Type.shim.name, file);
+ self.startFile(
+ Type,
+ Type.shim.name,
+ writer,
+ impl,
+ );
+
bufset.insert(identifier) catch unreachable;
- var gen = C_Generator.init(Type.name, file);
+ var gen = C_Generator.init(Type.name, @TypeOf(writer), writer);
defer gen.deinit();
- inline for (Type.Extern) |extern_decl| {
- if (@hasDecl(Type, extern_decl)) {
- const normalized_name = comptime brk: {
- var _normalized_name: [Type.name.len]u8 = undefined;
- _ = std.mem.replace(u8, Type.name, ":", "_", std.mem.span(&_normalized_name));
- break :brk _normalized_name;
+
+ if (@hasDecl(Type, "Extern")) {
+ if (to_get_sizes > 0) {
+ impl_second_writer.writeAll(", ") catch unreachable;
+ impl_third_writer.writeAll(", ") catch unreachable;
+ }
+
+ const formatted_name = comptime brk: {
+ var original: [Type.name.len]u8 = undefined;
+ _ = std.mem.replace(u8, Type.name, ":", "_", &original);
+ break :brk original;
+ };
+
+ impl_third_writer.print("sizeof({s})", .{comptime Type.name}) catch unreachable;
+ impl_second_writer.print("\"{s}\"", .{formatted_name}) catch unreachable;
+ to_get_sizes += 1;
+ const ExternList = comptime brk: {
+ const Sorder = struct {
+ pub fn lessThan(context: @This(), lhs: []const u8, rhs: []const u8) bool {
+ return std.ascii.orderIgnoreCase(lhs, rhs) == std.math.Order.lt;
+ }
};
+ var extern_list = Type.Extern;
+ std.sort.sort([]const u8, &extern_list, Sorder{}, Sorder.lessThan);
+ break :brk extern_list;
+ };
+ // impl_writer.print(" #include {s}\n", .{Type.include}) catch unreachable;
+ inline for (&ExternList) |extern_decl| {
+ if (@hasDecl(Type, extern_decl)) {
+ const normalized_name = comptime brk: {
+ var _normalized_name: [Type.name.len]u8 = undefined;
+ _ = std.mem.replace(u8, Type.name, ":", "_", std.mem.span(&_normalized_name));
+ break :brk _normalized_name;
+ };
+
+ processDecl(
+ self,
+ writer,
+ &gen,
+ Type,
+ comptime std.meta.declarationInfo(Type, extern_decl),
+ comptime extern_decl,
+ comptime std.mem.span(&normalized_name),
+ );
+ }
+ }
+ }
- processDecl(
+ if (@hasDecl(Type, "Export")) {
+ const ExportLIst = comptime brk: {
+ const Sorder = struct {
+ pub fn lessThan(context: @This(), comptime lhs: StaticExport, comptime rhs: StaticExport) bool {
+ return std.ascii.orderIgnoreCase(lhs.symbol_name, rhs.symbol_name) == std.math.Order.lt;
+ }
+ };
+ var extern_list = Type.Export;
+ std.sort.sort(StaticExport, &extern_list, Sorder{}, Sorder.lessThan);
+ break :brk extern_list;
+ };
+
+ gen.direction = C_Generator.Direction.export_zig;
+ inline for (ExportLIst) |static_export| {
+ processStaticExport(
self,
file,
&gen,
- Type,
- comptime std.meta.declarationInfo(Type, extern_decl),
- comptime extern_decl,
- comptime std.mem.span(&normalized_name),
+ comptime static_export,
);
}
}
@@ -415,6 +660,90 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
}
}
}
+ impl.writer().print("\nconst size_t sizes[{d}] = {{", .{to_get_sizes}) catch unreachable;
+ impl.writeAll(impl_third_buffer.items) catch unreachable;
+ impl.writeAll("};\n") catch unreachable;
+ impl.writer().print("\nconst char* names[{d}] = {{", .{to_get_sizes}) catch unreachable;
+ impl.writeAll(impl_second_buffer.items) catch unreachable;
+ impl.writeAll("};\n") catch unreachable;
+
+ var iter = type_names.iterator();
+
+ const NamespaceMap = std.StringArrayHashMap(std.BufMap);
+ var namespaces = NamespaceMap.init(std.heap.c_allocator);
+
+ file_writer.writeAll("\n#ifndef __cplusplus\n") catch unreachable;
+ while (iter.next()) |entry| {
+ const key = entry.key_ptr.*;
+ const value = entry.value_ptr.*;
+ if (std.mem.indexOfScalar(u8, entry.key_ptr.*, ':')) |namespace_start| {
+ const namespace = entry.key_ptr.*[0..namespace_start];
+ file_writer.print(" typedef struct {s} {s}; // {s}\n", .{
+ value,
+ value,
+ key,
+ }) catch unreachable;
+ if (!namespaces.contains(namespace)) {
+ namespaces.put(namespace, std.BufMap.init(std.heap.c_allocator)) catch unreachable;
+ }
+ const class = key[namespace_start + 2 ..];
+ namespaces.getPtr(namespace).?.put(class, value) catch unreachable;
+ } else {
+ file_writer.print(" typedef {s} {s};\n", .{
+ key,
+ value,
+ }) catch unreachable;
+
+ impl_writer.print(" typedef {s} {s};\n", .{
+ key,
+ value,
+ }) catch unreachable;
+ }
+ }
+
+ file_writer.writeAll("\n#endif\n") catch unreachable;
+ var size_iter = size_map.iterator();
+ while (size_iter.next()) |size| {
+ file_writer.print(" typedef struct b{s} {{ char bytes[{d}]; }} b{s};\n", .{
+ size.key_ptr.*,
+ size.value_ptr.*,
+ size.key_ptr.*,
+ }) catch unreachable;
+ }
+
+ file_writer.writeAll("\n#ifdef __cplusplus\n") catch unreachable;
+
+ iter = type_names.iterator();
+ var namespace_iter = namespaces.iterator();
+ while (namespace_iter.next()) |map| {
+ file_writer.print(" namespace {s} {{\n", .{map.key_ptr.*}) catch unreachable;
+ var classes = map.value_ptr.iterator();
+ while (classes.next()) |class| {
+ file_writer.print(" class {s};\n", .{class.key_ptr.*}) catch unreachable;
+ }
+ file_writer.writeAll(" }\n") catch unreachable;
+ }
+
+ file_writer.writeAll("\n") catch unreachable;
+
+ file_writer.writeAll(impl_buffer.items) catch unreachable;
+
+ iter = type_names.iterator();
+ namespace_iter = namespaces.iterator();
+ while (namespace_iter.next()) |map| {
+ var classes = map.value_ptr.iterator();
+ while (classes.next()) |class| {
+ file_writer.print(" using {s} = {s}::{s};\n", .{
+ class.value_ptr.*,
+ map.key_ptr.*,
+ class.key_ptr.*,
+ }) catch unreachable;
+ }
+ }
+
+ file_writer.writeAll("\n#endif\n\n") catch unreachable;
+
+ file.writeAll(buffer.items) catch unreachable;
// processDecls(
// self,