From 7e71509b9f5b7a43ce04b7bffe0b0c68da00ca27 Mon Sep 17 00:00:00 2001 From: rimuspp <19101das@gmail.com> Date: Thu, 6 Jul 2023 21:33:19 -0500 Subject: [PATCH 1/2] Fixed generation, used zig fmt and Json changes --- src/cameltosnake.zig | 36 +- src/common.zig | 52 +-- src/genzig.zig | 971 ++++++++++++++++++++++-------------------- src/handletypes.zig | 2 +- src/pass1.zig | 60 ++- src/stringpool.zig | 13 +- src/windowlongptr.zig | 5 +- src/zig.zig | 64 ++- 8 files changed, 617 insertions(+), 586 deletions(-) diff --git a/src/cameltosnake.zig b/src/cameltosnake.zig index 0ad0a03..09672ec 100644 --- a/src/cameltosnake.zig +++ b/src/cameltosnake.zig @@ -10,11 +10,14 @@ pub fn camelToSnakeAlloc(a: std.mem.Allocator, camel: []const u8) ![]u8 { pub fn camelToSnakeLen(camel: []const u8) usize { var snake_len = camel.len; - {var i : usize = 1; while (i < camel.len) : (i += 1) { - if (std.ascii.isUpper(camel[i]) and std.ascii.isLower(camel[i-1])) { - snake_len += 1; + { + var i: usize = 1; + while (i < camel.len) : (i += 1) { + if (std.ascii.isUpper(camel[i]) and std.ascii.isLower(camel[i - 1])) { + snake_len += 1; + } } - }} + } return snake_len; } @@ -23,23 +26,26 @@ pub fn camelToSnake(snake: []u8, camel: []const u8) void { snake[0] = asciiCharToLower(camel[0]); - var snake_index : usize = 1; - {var i: usize = 1; while (i < camel.len) : (i += 1) { - const is_upper = std.ascii.isUpper(camel[i]); - if (is_upper and std.ascii.isLower(camel[i-1])) { - snake[snake_index] = '_'; + var snake_index: usize = 1; + { + var i: usize = 1; + while (i < camel.len) : (i += 1) { + const is_upper = std.ascii.isUpper(camel[i]); + if (is_upper and std.ascii.isLower(camel[i - 1])) { + snake[snake_index] = '_'; + snake_index += 1; + } + snake[snake_index] = asciiCharToLower(camel[i]); snake_index += 1; } - snake[snake_index] = asciiCharToLower(camel[i]); - snake_index += 1; - }} + } std.debug.assert(snake_index == snake.len); } fn testCamelToSnake(camel: []const u8, expected_snake: []const u8) void { const actual_snake = camelToSnakeAlloc(std.testing.allocator, camel) catch @panic("out of memory"); defer std.testing.allocator.free(actual_snake); - std.debug.print("test '{s}' expect '{s}'\n", .{camel, expected_snake}); + std.debug.print("test '{s}' expect '{s}'\n", .{ camel, expected_snake }); std.debug.print("actual '{s}'\n", .{actual_snake}); std.testing.expect(std.mem.eql(u8, expected_snake, actual_snake)); } @@ -54,7 +60,7 @@ test "cameltosnake" { testCamelToSnake("Abc", "abc"); testCamelToSnake("aBc", "a_bc"); testCamelToSnake("abC", "ab_c"); - + testCamelToSnake("AbC", "ab_c"); testCamelToSnake("aBC", "a_bc"); @@ -63,5 +69,5 @@ test "cameltosnake" { // TODO: this should already exist somewhere? fn asciiCharToLower(c: u8) u8 { - return c + (if (std.ascii.isUpper(c)) @as(u8, 'a'-'A') else 0); + return c + (if (std.ascii.isUpper(c)) @as(u8, 'a' - 'A') else 0); } diff --git a/src/common.zig b/src/common.zig index 808a39d..f0d6dd5 100644 --- a/src/common.zig +++ b/src/common.zig @@ -21,7 +21,7 @@ pub fn getModifyTime(dir: std.fs.Dir, path: []const u8) !?Time { } pub fn win32jsonIsNewerThan(win32json_dir: std.fs.Dir, time: Time) !bool { - var api_dir = try win32json_dir.openIterableDir("api", .{}) ; + var api_dir = try win32json_dir.openIterableDir("api", .{}); defer api_dir.close(); var dir_it = api_dir.iterate(); @@ -44,7 +44,7 @@ pub fn win32jsonIsNewerThan(win32json_dir: std.fs.Dir, time: Time) !bool { } pub fn getcwd(a: std.mem.Allocator) ![]u8 { - var path_buf : [std.fs.MAX_PATH_BYTES]u8 = undefined; + var path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; const path = try std.os.getcwd(&path_buf); const path_allocated = try a.alloc(u8, path.len); std.mem.copy(u8, path_allocated, path); @@ -66,27 +66,29 @@ pub fn asciiLessThanIgnoreCase(_: Nothing, lhs: []const u8, rhs: []const u8) boo return std.ascii.lessThanIgnoreCase(lhs, rhs); } -fn SliceFormatter(comptime T: type, comptime spec: []const u8) type { return struct { - slice: []const T, - pub fn format( - self: @This(), - comptime fmt: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - _ = fmt; - _ = options; - var first : bool = true; - for (self.slice) |e| { - if (first) { - first = false; - } else { - try writer.writeAll(", "); +fn SliceFormatter(comptime T: type, comptime spec: []const u8) type { + return struct { + slice: []const T, + pub fn format( + self: @This(), + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = fmt; + _ = options; + var first: bool = true; + for (self.slice) |e| { + if (first) { + first = false; + } else { + try writer.writeAll(", "); + } + try std.fmt.format(writer, "{" ++ spec ++ "}", .{e}); } - try std.fmt.format(writer, "{" ++ spec ++ "}", .{e}); } - } -};} + }; +} pub fn formatSliceT(comptime T: type, comptime spec: []const u8, slice: []const T) SliceFormatter(T, spec) { return .{ .slice = slice }; } @@ -120,7 +122,7 @@ pub fn jsonObjEnforceKnownFieldsOnly(map: std.json.ObjectMap, known_fields: []co if (std.mem.eql(u8, known_field, kv.key_ptr.*)) continue :fieldLoop; } - std.log.err("{s}: JSON object has unknown field '{s}', expected one of: {}\n", .{file_for_error, kv.key_ptr.*, formatSliceT([]const u8, "s", known_fields)}); + std.log.err("{s}: JSON object has unknown field '{s}', expected one of: {}\n", .{ file_for_error, kv.key_ptr.*, formatSliceT([]const u8, "s", known_fields) }); jsonPanic(); } } @@ -140,13 +142,13 @@ const JsonFormatter = struct { }; pub fn fmtJson(value: anytype) JsonFormatter { if (@TypeOf(value) == std.json.ObjectMap) { - return .{ .value = .{ .Object = value } }; + return .{ .value = .{ .object = value } }; } if (@TypeOf(value) == std.json.Array) { - return .{ .value = .{ .Array = value } }; + return .{ .value = .{ .array = value } }; } if (@TypeOf(value) == []std.json.Value) { - return .{ .value = .{ .Array = std.json.Array { .items = value, .capacity = value.len, .allocator = undefined } } }; + return .{ .value = .{ .array = std.json.Array{ .items = value, .capacity = value.len, .allocator = undefined } } }; } return .{ .value = value }; } diff --git a/src/genzig.zig b/src/genzig.zig index cbe8fbd..d95961a 100644 --- a/src/genzig.zig +++ b/src/genzig.zig @@ -26,8 +26,8 @@ const autogen_header = "//! NOTE: this file is autogenerated, DO NOT MODIFY\n"; var global_symbol_pool = StringPool.init(allocator); -var global_symbol_none : StringPool.Val = undefined; -var global_symbol_None : StringPool.Val = undefined; +var global_symbol_none: StringPool.Val = undefined; +var global_symbol_None: StringPool.Val = undefined; var global_pass1: json.ObjectMap = undefined; var global_notnull: json.ObjectMap = undefined; @@ -58,11 +58,11 @@ const global_value_type_map = std.ComptimeStringMap(ValueType, .{ }); fn valueTypeToZigType(t: ValueType) []const u8 { return switch (t) { - .Byte => return "u8", + .Byte => return "u8", .UInt16 => return "u16", - .Int32 => return "i32", + .Int32 => return "i32", .UInt32 => return "u32", - .Int64 => return "i64", + .Int64 => return "i64", .UInt64 => return "u64", .Single => return "f32", .Double => return "f64", @@ -158,10 +158,10 @@ const Module = struct { file: ?SdkFile, pub fn alloc(optional_parent: ?*Module, name: StringPool.Val) !*Module { var module = try allocator.create(Module); - module.* = Module { + module.* = Module{ .optional_parent = optional_parent, .name = name, - .zig_basename = try std.mem.concat(allocator, u8, &[_][]const u8 { name.slice, ".zig" }), + .zig_basename = try std.mem.concat(allocator, u8, &[_][]const u8{ name.slice, ".zig" }), .children = StringPool.HashMap(*Module).init(allocator), .file = null, }; @@ -169,7 +169,7 @@ const Module = struct { } }; -const import_prefix_table = &[_][]const u8 { +const import_prefix_table = &[_][]const u8{ "", "../", "../../", @@ -198,10 +198,10 @@ fn failAllocatorAlloc(_: *anyopaque, n: usize, alignment: u8, ra: usize) ?[*]u8 _ = ra; return null; } -const empty_json_object_map = json.ObjectMap { - .ctx = .{ }, +const empty_json_object_map = json.ObjectMap{ + .ctx = .{}, .allocator = fail_allocator, - .unmanaged = .{ }, + .unmanaged = .{}, }; fn StringPoolArrayHashMap(comptime T: type) type { @@ -209,8 +209,8 @@ fn StringPoolArrayHashMap(comptime T: type) type { } const AvoidLookupFn = switch (builtin.zig_backend) { - .stage1 => fn(s: []const u8) ?Nothing, - else => *const fn(s: []const u8) ?Nothing, + .stage1 => fn (s: []const u8) ?Nothing, + else => *const fn (s: []const u8) ?Nothing, }; const SdkFile = struct { @@ -240,18 +240,17 @@ const SdkFile = struct { pub fn addApiImport(self: *SdkFile, arches: ArchFlags, name: []const u8, api: []const u8, parents: json.Array) !void { if (!std.mem.eql(u8, self.json_name, api)) { - const top_level_symbol = try global_symbol_pool.add( - if (parents.items.len == 0) name else parents.items[0].String); + const top_level_symbol = try global_symbol_pool.add(if (parents.items.len == 0) name else parents.items[0].string); const pool_api = try global_symbol_pool.add(api); if (self.top_level_api_imports.getPtr(top_level_symbol)) |import| { - jsonEnforceMsg(pool_api.eql(import.api), "symbol conflict '{s}', api mismatch '{s}' and '{s}'", .{name, pool_api, import.api}); + jsonEnforceMsg(pool_api.eql(import.api), "symbol conflict '{s}', api mismatch '{s}' and '{s}'", .{ name, pool_api, import.api }); //jsonEnforceMsg(other.parents.len == 0, "symbol conflict '{s}', parents mismatch", .{name}); const new_flags = import.arches.flags | arches.flags; if (new_flags != import.arches.flags) { import.arches.flags = new_flags; } } else { - try self.top_level_api_imports.put(top_level_symbol, .{ .arches = arches, .api = pool_api } ); + try self.top_level_api_imports.put(top_level_symbol, .{ .arches = arches, .api = pool_api }); } } } @@ -260,11 +259,11 @@ const SdkFile = struct { const notnull_filename: []const u8 = "notnull.json"; const Times = struct { - parse_time_millis : i64 = 0, - read_time_millis : i64 = 0, - generate_time_millis : i64 = 0, + parse_time_millis: i64 = 0, + read_time_millis: i64 = 0, + generate_time_millis: i64 = 0, }; -var global_times = Times {}; +var global_times = Times{}; pub fn main() !u8 { const main_start_millis = std.time.milliTimestamp(); @@ -273,16 +272,15 @@ pub fn main() !u8 { if (print_time_summary) { var total_millis = std.time.milliTimestamp() - main_start_millis; if (total_millis == 0) total_millis = 1; // prevent divide by 0 - std.debug.print("Parse Time: {} millis ({}%)\n", .{global_times.parse_time_millis, @divTrunc(100 * global_times.parse_time_millis, total_millis)}); - std.debug.print("Read Time : {} millis ({}%)\n", .{global_times.read_time_millis , @divTrunc(100 * global_times.read_time_millis, total_millis)}); - std.debug.print("Gen Time : {} millis ({}%)\n", .{global_times.generate_time_millis , @divTrunc(100 * global_times.generate_time_millis, total_millis)}); + std.debug.print("Parse Time: {} millis ({}%)\n", .{ global_times.parse_time_millis, @divTrunc(100 * global_times.parse_time_millis, total_millis) }); + std.debug.print("Read Time : {} millis ({}%)\n", .{ global_times.read_time_millis, @divTrunc(100 * global_times.read_time_millis, total_millis) }); + std.debug.print("Gen Time : {} millis ({}%)\n", .{ global_times.generate_time_millis, @divTrunc(100 * global_times.generate_time_millis, total_millis) }); std.debug.print("Total Time: {} millis\n", .{total_millis}); } } global_symbol_none = try global_symbol_pool.add("none"); global_symbol_None = try global_symbol_pool.add("None"); - const all_args = try std.process.argsAlloc(allocator); // don't care about freeing args @@ -293,7 +291,6 @@ pub fn main() !u8 { } const win32json_path = cmd_args[0]; - var win32json_dir = try std.fs.cwd().openDir(win32json_path, .{}); defer win32json_dir.close(); @@ -303,9 +300,7 @@ pub fn main() !u8 { cwd.access(zigwin32_dir_name, .{}) catch |e| switch (e) { error.FileNotFound => { std.debug.print("error: repository '{s}' does not exist, clone it with:\n", .{zigwin32_dir_name}); - std.debug.print(" git clone https://github.com/marlersoft/zigwin32 {s}" ++ path_sep ++ zigwin32_dir_name ++ "\n", .{ - try common.getcwd(allocator) - }); + std.debug.print(" git clone https://github.com/marlersoft/zigwin32 {s}" ++ path_sep ++ zigwin32_dir_name ++ "\n", .{try common.getcwd(allocator)}); std.os.exit(0xff); }, else => return e, @@ -324,7 +319,7 @@ pub fn main() !u8 { var out_win32_dir = try out_dir.openDir("win32", .{}); defer out_win32_dir.close(); - const src_modules = &[_][]const u8 { + const src_modules = &[_][]const u8{ "zig", "missing", "windowlongptr", @@ -333,7 +328,7 @@ pub fn main() !u8 { const root_module = try Module.alloc(null, try global_symbol_pool.add("win32")); { - var api_dir = try win32json_dir.openIterableDir("api", .{}) ; + var api_dir = try win32json_dir.openIterableDir("api", .{}); defer api_dir.close(); var api_list = std.ArrayList([]const u8).init(allocator); @@ -346,14 +341,14 @@ pub fn main() !u8 { try common.readApiList(api_dir, &api_list); // sort the list of APIs so our api order is not dependent on the file-system ordering - std.sort.sort([]const u8, api_list.items, Nothing {}, common.asciiLessThanIgnoreCase); + std.sort.block([]const u8, api_list.items, Nothing{}, common.asciiLessThanIgnoreCase); std.debug.print("-----------------------------------------------------------------------\n", .{}); std.debug.print("loading {} api json files...\n", .{api_list.items.len}); for (api_list.items, 0..) |api_json_basename, api_index| { const api_num = api_index + 1; - std.debug.print("{}/{}: loading '{s}'\n", .{api_num, api_list.items.len, api_json_basename}); + std.debug.print("{}/{}: loading '{s}'\n", .{ api_num, api_list.items.len, api_json_basename }); // // TODO: would things run faster if I just memory mapped the file? // @@ -362,7 +357,7 @@ pub fn main() !u8 { try readAndGenerateApiFile(root_module, out_win32_dir, api_json_basename, file); } - for (src_modules ++ &[_][]const u8 { + for (src_modules ++ &[_][]const u8{ "everything", }) |submodule_str| { const submodule = try global_symbol_pool.add(submodule_str); @@ -385,7 +380,6 @@ pub fn main() !u8 { return 0; } - fn readJson(filename: []const u8) !std.json.ObjectMap { const content = blk: { const file = try std.fs.cwd().openFile(filename, .{}); @@ -394,15 +388,14 @@ fn readJson(filename: []const u8) !std.json.ObjectMap { }; var json_tree = blk: { - var parser = json.Parser.init(allocator, false); // false is copy_strings + const start = if (std.mem.startsWith(u8, content, "\xEF\xBB\xBF")) 3 else @as(usize, 0); + var parser = json.Scanner.initCompleteInput(allocator, content[start..]); // false is copy_strings defer parser.deinit(); - const start = if (std.mem.startsWith(u8, content, "\xEF\xBB\xBF")) 3 else @as(usize, 0); - const json_content = content[start..]; std.log.info("parsing '{s}'...", .{filename}); - break :blk try parser.parse(json_content); + break :blk try json.Value.jsonParse(allocator, &parser, .{}); }; - return json_tree.root.Object; + return json_tree.object; } fn gatherSdkFiles(sdk_files: *ArrayList(*SdkFile), module: *Module) anyerror!void { @@ -411,7 +404,7 @@ fn gatherSdkFiles(sdk_files: *ArrayList(*SdkFile), module: *Module) anyerror!voi } const children = try common.allocMapValues(allocator, *Module, module.children); defer allocator.free(children); - std.sort.sort(*Module, children, {}, moduleLessThan); // sort so the order is predictable + std.sort.block(*Module, children, {}, moduleLessThan); // sort so the order is predictable for (children) |child| { try gatherSdkFiles(sdk_files, child); } @@ -462,37 +455,34 @@ fn generateEverythingModule(out_win32_dir: std.fs.Dir, root_module: *Module) !vo } for (sdk_files.items) |sdk_file| { - try writer.print("// {s} exports {} constants:\n", .{sdk_file.zig_name, sdk_file.const_exports.items.len}); + try writer.print("// {s} exports {} constants:\n", .{ sdk_file.zig_name, sdk_file.const_exports.items.len }); for (sdk_file.const_exports.items) |constant| { if (shared_export_map.get(constant)) |other_sdk_file| { - try writer.print("// WARNING: redifinition of constant symbol '{s}' in module '{s}' (going with module '{s}')\n", .{ - constant, sdk_file.zig_name, other_sdk_file.zig_name}); + try writer.print("// WARNING: redifinition of constant symbol '{s}' in module '{s}' (going with module '{s}')\n", .{ constant, sdk_file.zig_name, other_sdk_file.zig_name }); } else { - try writer.print("pub const {s} = @import(\"../win32.zig\").{s}.{0s};\n", .{constant, sdk_file.zig_name}); + try writer.print("pub const {s} = @import(\"../win32.zig\").{s}.{0s};\n", .{ constant, sdk_file.zig_name }); try shared_export_map.put(constant, sdk_file); } } - try writer.print("// {s} exports {} types:\n", .{sdk_file.zig_name, sdk_file.type_exports.count()}); + try writer.print("// {s} exports {} types:\n", .{ sdk_file.zig_name, sdk_file.type_exports.count() }); var export_it = sdk_file.type_exports.iterator(); while (export_it.next()) |kv| { const type_name = kv.key_ptr.*; const first_type_sdk = shared_export_map.get(type_name) orelse unreachable; if (first_type_sdk != sdk_file) { - try writer.print("// WARNING: redefinition of type symbol '{s}' from '{s}', going with '{s}'\n", .{ - type_name, sdk_file.zig_name, first_type_sdk.zig_name}); + try writer.print("// WARNING: redefinition of type symbol '{s}' from '{s}', going with '{s}'\n", .{ type_name, sdk_file.zig_name, first_type_sdk.zig_name }); } else { - try writer.print("pub const {s} = @import(\"../win32.zig\").{s}.{0s};\n", .{type_name, sdk_file.zig_name}); + try writer.print("pub const {s} = @import(\"../win32.zig\").{s}.{0s};\n", .{ type_name, sdk_file.zig_name }); } } - try writer.print("// {s} exports {} functions:\n", .{sdk_file.zig_name, sdk_file.func_exports.count()}); + try writer.print("// {s} exports {} functions:\n", .{ sdk_file.zig_name, sdk_file.func_exports.count() }); var func_it = sdk_file.func_exports.iterator(); while (func_it.next()) |kv| { const func = kv.key_ptr.*; if (shared_export_map.get(func)) |other_sdk_file| { - try writer.print("// WARNING: redifinition of function '{s}' in module '{s}' (going with module '{s}')\n", .{ - func, sdk_file.zig_name, other_sdk_file.zig_name}); + try writer.print("// WARNING: redifinition of function '{s}' in module '{s}' (going with module '{s}')\n", .{ func, sdk_file.zig_name, other_sdk_file.zig_name }); } else { - try writer.print("pub const {s} = @import(\"../win32.zig\").{s}.{0s};\n", .{func, sdk_file.zig_name}); + try writer.print("pub const {s} = @import(\"../win32.zig\").{s}.{0s};\n", .{ func, sdk_file.zig_name }); try shared_export_map.put(func, sdk_file); } } @@ -522,11 +512,10 @@ fn generateContainerModules(dir: std.fs.Dir, module: *Module) anyerror!void { defer buffered_writer.flush() catch @panic("flush failed"); const writer = buffered_writer.writer(); - const children = try common.allocMapValues(allocator, *Module, module.children); defer allocator.free(children); - std.sort.sort(*Module, children, {}, moduleLessThan); + std.sort.block(*Module, children, {}, moduleLessThan); if (module.file) |_| { try writer.print("//--------------------------------------------------------------------------------\n", .{}); try writer.print("// Section: SubModules ({})\n", .{children.len}); @@ -535,10 +524,10 @@ fn generateContainerModules(dir: std.fs.Dir, module: *Module) anyerror!void { try writer.writeAll(autogen_header); } for (children) |child| { - try writer.print("pub const {s} = @import(\"{s}/{0s}.zig\");\n", .{child.name, module.name.slice}); + try writer.print("pub const {s} = @import(\"{s}/{0s}.zig\");\n", .{ child.name, module.name.slice }); } - if (module.file) |_| { } else { + if (module.file) |_| {} else { try writer.writeAll(comptime removeCr( \\test { \\ @import("std").testing.refAllDecls(@This()); @@ -556,7 +545,6 @@ fn generateContainerModules(dir: std.fs.Dir, module: *Module) anyerror!void { } fn readAndGenerateApiFile(root_module: *Module, out_dir: std.fs.Dir, json_basename: []const u8, file: std.fs.File) !void { - const read_start_millis = std.time.milliTimestamp(); const content = try file.readToEndAlloc(allocator, std.math.maxInt(usize)); const read_end_millis = std.time.milliTimestamp(); @@ -566,16 +554,14 @@ fn readAndGenerateApiFile(root_module: *Module, out_dir: std.fs.Dir, json_basena // Parsing the JSON is VERY VERY SLOW!!!!!! var json_tree = blk: { - var parser = json.Parser.init(allocator, false); // false is copy_strings + var parser = json.Scanner.initCompleteInput(allocator, content); // false is copy_strings defer parser.deinit(); - break :blk try parser.parse(content); + break :blk try json.Value.jsonParse(allocator, &parser, .{}); }; - defer json_tree.deinit(); global_times.parse_time_millis += std.time.milliTimestamp() - read_end_millis; - const json_basename_copy = try allocator.dupe(u8, json_basename); - const json_name = json_basename_copy[0..json_basename_copy.len - ".json".len]; + const json_name = json_basename_copy[0 .. json_basename_copy.len - ".json".len]; const zig_name = try cameltosnake.camelToSnakeAlloc(allocator, json_name); errdefer allocator.free(zig_name); @@ -616,12 +602,12 @@ fn readAndGenerateApiFile(root_module: *Module, out_dir: std.fs.Dir, json_basena var not_null_funcs = empty_json_object_map; if (global_notnull.get(json_name)) |*api_node| { - const api_obj = api_node.Object; - try jsonObjEnforceKnownFieldsOnly(api_obj, &[_][]const u8 {"Functions"}, notnull_filename); - not_null_funcs = (try jsonObjGetRequired(api_obj, "Functions", notnull_filename)).Object; + const api_obj = api_node.object; + try jsonObjEnforceKnownFieldsOnly(api_obj, &[_][]const u8{"Functions"}, notnull_filename); + not_null_funcs = (try jsonObjGetRequired(api_obj, "Functions", notnull_filename)).object; } - module.file = SdkFile { + module.file = SdkFile{ .json_basename = json_basename_copy, .json_name = json_name, .zig_name = zig_name, @@ -638,42 +624,47 @@ fn readAndGenerateApiFile(root_module: *Module, out_dir: std.fs.Dir, json_basena }; const generate_start_millis = std.time.milliTimestamp(); - try generateFile(module_dir, module, json_tree); + try generateFile(module_dir, module, json.Parsed(json.Value){ .value = json_tree, .arena = &arena }); global_times.generate_time_millis += std.time.milliTimestamp() - generate_start_millis; } -pub fn EmptyComptimeStringMap(comptime V: type) type { return struct { - pub fn get(str: []const u8) ?V { _ = str; return null; } -};} +pub fn EmptyComptimeStringMap(comptime V: type) type { + return struct { + pub fn get(str: []const u8) ?V { + _ = str; + return null; + } + }; +} fn ArchSpecificMap(comptime T: type) type { return StringPoolArrayHashMap(ArchSpecificObjects(T)); } -fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) !void { +fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.Parsed(json.Value)) !void { const sdk_file = &module.file.?; var out_file = try module_dir.createFile(module.zig_basename, .{}); defer out_file.close(); var buffered_writer = BufferedWriter{ .unbuffered_writer = out_file.writer() }; defer buffered_writer.flush() catch @panic("flush failed"); - var code_writer = CodeWriter { .writer = buffered_writer.writer(), .depth = 0, .midline = false }; + var code_writer = CodeWriter{ .writer = buffered_writer.writer(), .depth = 0, .midline = false }; // need to specify type explicitly because of https://github.com/ziglang/zig/issues/12795 const writer: *CodeWriter = &code_writer; try writer.writeBlock(autogen_header); // We can't import the everything module because it will re-introduce the same symbols we are exporting //try writer.print("usingnamespace @import(\"everything.zig\");\n", .{}); - const root_obj = tree.root.Object; - const constants_array = (try jsonObjGetRequired(root_obj, "Constants", sdk_file)).Array; - const types_array = (try jsonObjGetRequired(root_obj, "Types", sdk_file)).Array; - const functions_array = (try jsonObjGetRequired(root_obj, "Functions", sdk_file)).Array; - const unicode_aliases = (try jsonObjGetRequired(root_obj, "UnicodeAliases", sdk_file)).Array; + const root_obj = tree.value.object; + const constants_array = (try jsonObjGetRequired(root_obj, "Constants", sdk_file)).array; + const types_array = (try jsonObjGetRequired(root_obj, "Types", sdk_file)).array; + const functions_array = (try jsonObjGetRequired(root_obj, "Functions", sdk_file)).array; + const unicode_aliases = (try jsonObjGetRequired(root_obj, "UnicodeAliases", sdk_file)).array; try writer.line("//--------------------------------------------------------------------------------"); try writer.linef("// Section: Constants ({})", .{constants_array.items.len}); try writer.line("//--------------------------------------------------------------------------------"); for (constants_array.items) |*constant_node_ptr| { - try generateConstant(sdk_file, writer, constant_node_ptr.Object); + try generateConstant(sdk_file, writer, constant_node_ptr.object); } std.debug.assert(constants_array.items.len == sdk_file.const_exports.items.len); try writer.line(""); @@ -686,19 +677,19 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! var enum_alias_conflicts = StringPool.HashMap(StringPool.Val).init(allocator); defer enum_alias_conflicts.deinit(); for (types_array.items) |*type_node_ptr| { - try generateType(sdk_file, writer, &arch_specific_types, type_node_ptr.Object, &enum_alias_conflicts); + try generateType(sdk_file, writer, &arch_specific_types, type_node_ptr.object, &enum_alias_conflicts); try writer.line(""); } var it = arch_specific_types.iterator(); while (it.next()) |entry| { const name = entry.key_ptr.*; - try writer.linef("pub const {s} = switch(@import(\"{s}zig.zig\").arch) {{", .{name, import_prefix_table[sdk_file.depth]}); + try writer.linef("pub const {s} = switch(@import(\"{s}zig.zig\").arch) {{", .{ name, import_prefix_table[sdk_file.depth] }); var combined_arches: u8 = 0; for (entry.value_ptr.getItemsConst()) |object| { combined_arches |= object.arches.flags; var buf: [40]u8 = undefined; - const def_prefix = buf[0 .. try object.arches.formatCase(&buf)]; - const kind = (try jsonObjGetRequired(object.obj, "Kind", sdk_file)).String; + const def_prefix = buf[0..try object.arches.formatCase(&buf)]; + const kind = (try jsonObjGetRequired(object.obj, "Kind", sdk_file)).string; writer.depth += 1; defer writer.depth -= 1; try generateTypeDefinition(sdk_file, writer, object.obj, &enum_alias_conflicts, object.arches, kind, name, def_prefix, ","); @@ -715,7 +706,7 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! try writer.linef("// Section: Functions ({})", .{functions_array.items.len}); try writer.line("//--------------------------------------------------------------------------------"); for (functions_array.items) |*function_node_ptr| { - try generateFunction(sdk_file, writer, function_node_ptr.Object, .fixed); + try generateFunction(sdk_file, writer, function_node_ptr.object, .fixed); try writer.line(""); } std.debug.assert(functions_array.items.len >= sdk_file.func_exports.count()); @@ -724,7 +715,7 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! try writer.linef("// Section: Unicode Aliases ({})", .{unicode_aliases.items.len}); try writer.line("//--------------------------------------------------------------------------------"); try generateUnicodeAliases(sdk_file, writer, unicode_aliases.items); - const import_total = @boolToInt(sdk_file.uses_guid) + sdk_file.top_level_api_imports.count(); + const import_total = @intFromBool(sdk_file.uses_guid) + sdk_file.top_level_api_imports.count(); try writer.line("//--------------------------------------------------------------------------------"); try writer.linef("// Section: Imports ({})", .{import_total}); try writer.line("//--------------------------------------------------------------------------------"); @@ -750,7 +741,7 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! try sorted_imports.append(.{ .name = entry.key_ptr.*, .import = entry.value_ptr.* }); } } - std.sort.sort(NamedApiImport, sorted_imports.items, Nothing {}, NamedApiImport.asciiLessThanIgnoreCase); + std.sort.block(NamedApiImport, sorted_imports.items, Nothing{}, NamedApiImport.asciiLessThanIgnoreCase); // print the arch-agnostic imports first for (sorted_imports.items) |import| { @@ -763,8 +754,7 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! // TODO: should I cache this mapping from api ref to api import path? const api_path = try allocApiImportPathFromRef(api_upper.slice); defer allocator.free(api_path); - try writer.linef("const {s} = @import(\"{s}{s}.zig\").{0s};", - .{import.name, sdk_file.getWin32DirImportPrefix(), api_path}); + try writer.linef("const {s} = @import(\"{s}{s}.zig\").{0s};", .{ import.name, sdk_file.getWin32DirImportPrefix(), api_path }); } } if (arch_specific_imports.count() > 0) { @@ -772,18 +762,17 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! var arch_imports_it = arch_specific_imports.iterator(); while (arch_imports_it.next()) |arch_import_node| { const name = arch_import_node.key_ptr.*; - try writer.linef("const {s} = switch(@import(\"{s}zig.zig\").arch) {{", .{name, import_prefix_table[sdk_file.depth]}); + try writer.linef("const {s} = switch(@import(\"{s}zig.zig\").arch) {{", .{ name, import_prefix_table[sdk_file.depth] }); var combined_arches: u8 = 0; for (arch_import_node.value_ptr.getItemsConst()) |object| { combined_arches |= object.arches.flags; var buf: [40]u8 = undefined; - const def_prefix = buf[0 .. try object.arches.formatCase(&buf)]; + const def_prefix = buf[0..try object.arches.formatCase(&buf)]; const api_upper = object.obj; // TODO: should I cache this mapping from api ref to api import path? const api_path = try allocApiImportPathFromRef(api_upper.slice); defer allocator.free(api_path); - try writer.linef(" {s}@import(\"{s}{s}.zig\").{s},", - .{def_prefix, sdk_file.getWin32DirImportPrefix(), api_path, name}); + try writer.linef(" {s}@import(\"{s}{s}.zig\").{s},", .{ def_prefix, sdk_file.getWin32DirImportPrefix(), api_path, name }); } if (combined_arches != ArchFlags.all.flags) { //try writer.line(" else => @compileError(\"unsupported on this arch\"),"); @@ -825,11 +814,11 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! // check that all notnull stuff was applied { var it = sdk_file.not_null_funcs.iterator(); - var error_count : u32 = 0; + var error_count: u32 = 0; while (it.next()) |api| { const pool_name = try global_symbol_pool.add(api.key_ptr.*); - if (sdk_file.not_null_funcs_applied.get(pool_name)) |_| { } else { - std.log.err("notnull.json api '{s}' function '{s}' was not applied", .{sdk_file.json_name, pool_name}); + if (sdk_file.not_null_funcs_applied.get(pool_name)) |_| {} else { + std.log.err("notnull.json api '{s}' function '{s}' was not applied", .{ sdk_file.json_name, pool_name }); error_count += 1; } } @@ -841,9 +830,9 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! } fn typeIsVoid(type_obj: json.ObjectMap, sdk_file: *SdkFile) !bool { - const kind = (try jsonObjGetRequired(type_obj, "Kind", sdk_file)).String; + const kind = (try jsonObjGetRequired(type_obj, "Kind", sdk_file)).string; if (std.mem.eql(u8, kind, "Native")) { - const name = (try jsonObjGetRequired(type_obj, "Name", sdk_file)).String; + const name = (try jsonObjGetRequired(type_obj, "Name", sdk_file)).string; return std.mem.eql(u8, name, "void"); } return false; @@ -869,10 +858,10 @@ fn addTypeRefs(sdk_file: *SdkFile, arches: ArchFlags, type_ref: json.ObjectMap, } fn addTypeRefsNoFormatter(sdk_file: *SdkFile, arches: ArchFlags, type_ref: json.ObjectMap) anyerror!void { - const kind = (try jsonObjGetRequired(type_ref, "Kind", sdk_file)).String; + const kind = (try jsonObjGetRequired(type_ref, "Kind", sdk_file)).string; if (std.mem.eql(u8, kind, "Native")) { - try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8 {"Kind", "Name"}, sdk_file); - const name = (try jsonObjGetRequired(type_ref, "Name", sdk_file)).String; + try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8{ "Kind", "Name" }, sdk_file); + const name = (try jsonObjGetRequired(type_ref, "Name", sdk_file)).string; if (std.mem.eql(u8, name, "Void")) { // void is special } else if (std.mem.eql(u8, name, "Guid")) { @@ -881,22 +870,22 @@ fn addTypeRefsNoFormatter(sdk_file: *SdkFile, arches: ArchFlags, type_ref: json. std.debug.panic("unknown Native type '{s}'", .{name}); } } else if (std.mem.eql(u8, kind, "ApiRef")) { - try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8 {"Kind", "Name", "TargetKind", "Api", "Parents"}, sdk_file); - const tmp_name = (try jsonObjGetRequired(type_ref, "Name", sdk_file)).String; - const api = (try jsonObjGetRequired(type_ref, "Api", sdk_file)).String; - const parents = (try jsonObjGetRequired(type_ref, "Parents", sdk_file)).Array; + try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8{ "Kind", "Name", "TargetKind", "Api", "Parents" }, sdk_file); + const tmp_name = (try jsonObjGetRequired(type_ref, "Name", sdk_file)).string; + const api = (try jsonObjGetRequired(type_ref, "Api", sdk_file)).string; + const parents = (try jsonObjGetRequired(type_ref, "Parents", sdk_file)).array; try sdk_file.addApiImport(arches, tmp_name, api, parents); } else if (std.mem.eql(u8, kind, "PointerTo")) { - try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8 {"Kind", "Child"}, sdk_file); - try addTypeRefsNoFormatter(sdk_file, arches, (try jsonObjGetRequired(type_ref, "Child", sdk_file)).Object); + try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8{ "Kind", "Child" }, sdk_file); + try addTypeRefsNoFormatter(sdk_file, arches, (try jsonObjGetRequired(type_ref, "Child", sdk_file)).object); } else if (std.mem.eql(u8, kind, "Array")) { - try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8 {"Kind", "Shape", "Child"}, sdk_file); - try addTypeRefsNoFormatter(sdk_file, arches, (try jsonObjGetRequired(type_ref, "Child", sdk_file)).Object); + try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8{ "Kind", "Shape", "Child" }, sdk_file); + try addTypeRefsNoFormatter(sdk_file, arches, (try jsonObjGetRequired(type_ref, "Child", sdk_file)).object); } else if (std.mem.eql(u8, kind, "LPArray")) { - try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8 {"Kind", "NullNullTerm", "CountConst", "CountParamIndex", "Child"}, sdk_file); - try addTypeRefsNoFormatter(sdk_file, arches, (try jsonObjGetRequired(type_ref, "Child", sdk_file)).Object); + try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8{ "Kind", "NullNullTerm", "CountConst", "CountParamIndex", "Child" }, sdk_file); + try addTypeRefsNoFormatter(sdk_file, arches, (try jsonObjGetRequired(type_ref, "Child", sdk_file)).object); } else if (std.mem.eql(u8, kind, "MissingClrType")) { - try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8 {"Kind", "Name", "Namespace"}, sdk_file); + try jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8{ "Kind", "Name", "Namespace" }, sdk_file); } else { jsonPanicMsg("kind '{s}' is not implemented", .{kind}); } @@ -905,10 +894,10 @@ fn addTypeRefsNoFormatter(sdk_file: *SdkFile, arches: ArchFlags, type_ref: json. const ContainerKind = enum { Struct, Union }; pub fn getAnonKind(s: []const u8) ?ContainerKind { //if (std.mem.startsWith(u8, s, "_Anonymous")) { - if (std.mem.endsWith(u8, s, "_e__Struct")) - return .Struct; - if (std.mem.endsWith(u8, s, "_e__Union")) - return .Union; + if (std.mem.endsWith(u8, s, "_e__Struct")) + return .Struct; + if (std.mem.endsWith(u8, s, "_e__Union")) + return .Union; // jsonPanicMsg("type '{s}' starts with '_Anonymous' but does not have an expected end", .{s}); //} return null; @@ -922,8 +911,8 @@ const NestedContext = struct { pub fn contains(self: NestedContext, name: []const u8) bool { std.debug.assert(self.nested_types.items.len > 0); for (self.nested_types.items) |*nested_type_node_ptr| { - const nested_type_obj = nested_type_node_ptr.Object; - const nested_name = (nested_type_obj.get("Name") orelse jsonPanic()).String; + const nested_type_obj = nested_type_node_ptr.object; + const nested_name = (nested_type_obj.get("Name") orelse jsonPanic()).string; if (std.mem.eql(u8, nested_name, name)) return true; } @@ -939,7 +928,7 @@ const NullModifier = u3; // to void types must become pointers to the `anyopaque` type. // Need to know if it is an array specifically because array pointers cannot point to opaque types // with an unknown size. -const DepthContext = enum {top_level, child, array}; +const DepthContext = enum { top_level, child, array }; const TypeRefFormatter = struct { pub const Reason = enum { var_decl, direct_type_access }; pub const Options = struct { @@ -979,11 +968,11 @@ fn generateTypeRef(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefFormatt try generateTypeRefRec(sdk_file, writer, self, .top_level); } fn generateTypeRefRec(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefFormatter, depth_context: DepthContext) anyerror!void { - const kind = (try jsonObjGetRequired(self.type_ref, "Kind", sdk_file)).String; + const kind = (try jsonObjGetRequired(self.type_ref, "Kind", sdk_file)).string; if (std.mem.eql(u8, kind, "Native")) { - try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8 {"Kind", "Name"}, sdk_file); - const name = (try jsonObjGetRequired(self.type_ref, "Name", sdk_file)).String; + try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8{ "Kind", "Name" }, sdk_file); + const name = (try jsonObjGetRequired(self.type_ref, "Name", sdk_file)).string; if (std.mem.eql(u8, name, "Void")) { const type_name: []const u8 = switch (depth_context) { .top_level => "void", @@ -992,17 +981,17 @@ fn generateTypeRefRec(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefForm // because most void pointers in C are measured in terms of u8 bytes .array => "u8", }; - try writer.writef("{s}", .{type_name}, .{.start=.any,.nl=false}); + try writer.writef("{s}", .{type_name}, .{ .start = .any, .nl = false }); } else if (std.mem.eql(u8, name, "Guid")) { - try writer.write("Guid", .{.start=.any,.nl=false}); + try writer.write("Guid", .{ .start = .any, .nl = false }); } else { const native_type = global_native_type_map.get(name) orelse std.debug.panic("unknown Native type '{s}'", .{name}); - try writer.writef("{s}", .{nativeTypeToZigType(native_type)}, .{.start=.any,.nl=false}); + try writer.writef("{s}", .{nativeTypeToZigType(native_type)}, .{ .start = .any, .nl = false }); } } else if (std.mem.eql(u8, kind, "ApiRef")) { - try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8 {"Kind", "Name", "TargetKind", "Api", "Parents"}, sdk_file); - const name = (try jsonObjGetRequired(self.type_ref, "Name", sdk_file)).String; - const api = (try jsonObjGetRequired(self.type_ref, "Api", sdk_file)).String; + try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8{ "Kind", "Name", "TargetKind", "Api", "Parents" }, sdk_file); + const name = (try jsonObjGetRequired(self.type_ref, "Name", sdk_file)).string; + const api = (try jsonObjGetRequired(self.type_ref, "Api", sdk_file)).string; if (getAnonKind(name)) |anon_kind| { const anon_types = self.options.anon_types orelse @@ -1011,27 +1000,27 @@ fn generateTypeRefRec(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefForm const type_obj = anon_types.types.get(name_pool) orelse jsonPanicMsg("missing anonymous type '{s}'!", .{name}); try generateStructOrUnionDef(sdk_file, writer, type_obj, self.arches, anon_kind, self.nested_context); - try writer.write("}", .{.nl=false}); + try writer.write("}", .{ .nl = false }); return; } - const parents = (try jsonObjGetRequired(self.type_ref, "Parents", sdk_file)).Array; + const parents = (try jsonObjGetRequired(self.type_ref, "Parents", sdk_file)).array; const type_kind_category = blk: { const pass1_api_map = (global_pass1.get(api) orelse - jsonPanicMsg("type '{s}' is from API '{s}' that is missing from pass1 data", .{name, api})).Object; + jsonPanicMsg("type '{s}' is from API '{s}' that is missing from pass1 data", .{ name, api })).object; const pass1_type_obj = (pass1_api_map.get(name) orelse { if (parents.items.len == 0) { const in_nested_context = if (self.nested_context) |c| c.contains(name) else false; if (!in_nested_context) { - jsonPanicMsg("type '{s}' from API '{s}' is missing from pass1 data, has no parents and is not in the current nested context!", .{name, api}); + jsonPanicMsg("type '{s}' from API '{s}' is missing from pass1 data, has no parents and is not in the current nested context!", .{ name, api }); } } // this means its a nested type which are always structs/unions break :blk Pass1TypeKindCategory.default; - }).Object; - try jsonObjEnforceKnownFieldsOnly(pass1_type_obj, &[_][]const u8 {"Kind"}, sdk_file); - const type_kind = (try jsonObjGetRequired(pass1_type_obj, "Kind", sdk_file)).String; + }).object; + try jsonObjEnforceKnownFieldsOnly(pass1_type_obj, &[_][]const u8{"Kind"}, sdk_file); + const type_kind = (try jsonObjGetRequired(pass1_type_obj, "Kind", sdk_file)).string; break :blk pass1_type_kind_info.get(type_kind) orelse jsonPanicMsg("unknown pass1 type kind '{s}'", .{type_kind}); }; @@ -1041,14 +1030,14 @@ fn generateTypeRefRec(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefForm .default => {}, .ptr => { if (self.options.null_modifier & 1 == 0) { - try writer.write("?", .{.start=.any,.nl=false}); + try writer.write("?", .{ .start = .any, .nl = false }); } }, .com => { if (self.options.null_modifier & 1 == 0) { - try writer.write("?", .{.start=.any,.nl=false}); + try writer.write("?", .{ .start = .any, .nl = false }); } - try writer.write("*", .{.start=.any,.nl=false}); + try writer.write("*", .{ .start = .any, .nl = false }); }, } } @@ -1059,7 +1048,7 @@ fn generateTypeRefRec(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefForm // If there are more cases that behave like this, I will likely need to implement a 2-pass // system where the first pass I gather all the type definitions so that on the second pass // I'll know whether each type is a pointer like this and can fix things like this. - const special : enum { pstr, pwstr, other } = blk: { + const special: enum { pstr, pwstr, other } = blk: { if (std.mem.eql(u8, name, "PSTR")) break :blk .pstr; if (std.mem.eql(u8, name, "PWSTR")) break :blk .pwstr; break :blk .other; @@ -1072,7 +1061,7 @@ fn generateTypeRefRec(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefForm const base_type = if (special == .pstr) "u8" else "u16"; const sentinel_suffix = if (self.options.not_null_term) "" else ":0"; const const_str = if (self.options.is_const) "const " else ""; - try writer.writef("[*{s}]{s}{s}", .{sentinel_suffix, const_str, base_type}, .{.start=.any,.nl=false}); + try writer.writef("[*{s}]{s}{s}", .{ sentinel_suffix, const_str, base_type }, .{ .start = .any, .nl = false }); return; } } @@ -1083,52 +1072,54 @@ fn generateTypeRefRec(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefForm // try writer.writef("{s}", .{parent_ptr.String}, .{.start=.any,.nl=false}); // try writer.write(".", .{.start=.any,.nl=false}); //} - try writer.writef("{s}", .{name}, .{.start=.any,.nl=false}); + try writer.writef("{s}", .{name}, .{ .start = .any, .nl = false }); } else if (std.mem.eql(u8, kind, "PointerTo")) { - try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8 {"Kind", "Child"}, sdk_file); - const child = (try jsonObjGetRequired(self.type_ref, "Child", sdk_file)).Object; + try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8{ "Kind", "Child" }, sdk_file); + const child = (try jsonObjGetRequired(self.type_ref, "Child", sdk_file)).object; var child_options = self.options; if (self.options.reason == .var_decl and self.options.null_modifier & 1 == 0) { - try writer.write("?", .{.start=.any,.nl=false}); + try writer.write("?", .{ .start = .any, .nl = false }); } child_options.null_modifier = self.options.null_modifier >> 1; - try writer.write("*", .{.start=.any,.nl=false}); + try writer.write("*", .{ .start = .any, .nl = false }); if (self.options.is_const) { child_options.is_const = false; // TODO: is this right? - try writer.write("const ", .{.start=.any,.nl=false}); + try writer.write("const ", .{ .start = .any, .nl = false }); } try generateTypeRefRec(sdk_file, writer, fmtTypeRef(child, self.arches, child_options, self.nested_context), .child); } else if (std.mem.eql(u8, kind, "Array")) { - try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8 {"Kind", "Shape", "Child"}, sdk_file); - const child = (try jsonObjGetRequired(self.type_ref, "Child", sdk_file)).Object; - const shape_size = init: { switch (try jsonObjGetRequired(self.type_ref, "Shape", sdk_file)) { - // TODO: should we use size 1 here? - .Null => break :init 1, - .Object => |shape_obj| { - try jsonObjEnforceKnownFieldsOnly(shape_obj, &[_][]const u8 {"Size"}, sdk_file); - break :init (try jsonObjGetRequired(shape_obj, "Size", sdk_file)).Integer; - }, - else => jsonPanic(), - }}; - try writer.writef("[{}]", .{shape_size}, .{.start=.any,.nl=false}); + try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8{ "Kind", "Shape", "Child" }, sdk_file); + const child = (try jsonObjGetRequired(self.type_ref, "Child", sdk_file)).object; + const shape_size = init: { + switch (try jsonObjGetRequired(self.type_ref, "Shape", sdk_file)) { + // TODO: should we use size 1 here? + .null => break :init 1, + .object => |shape_obj| { + try jsonObjEnforceKnownFieldsOnly(shape_obj, &[_][]const u8{"Size"}, sdk_file); + break :init (try jsonObjGetRequired(shape_obj, "Size", sdk_file)).integer; + }, + else => jsonPanic(), + } + }; + try writer.writef("[{}]", .{shape_size}, .{ .start = .any, .nl = false }); try generateTypeRefRec(sdk_file, writer, fmtTypeRef(child, self.arches, self.options, self.nested_context), .child); } else if (std.mem.eql(u8, kind, "LPArray")) { - try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8 {"Kind", "NullNullTerm", "CountConst", "CountParamIndex", "Child"}, sdk_file); - const null_null_term = (try jsonObjGetRequired(self.type_ref, "NullNullTerm", sdk_file)).Bool; - const count_const = (try jsonObjGetRequired(self.type_ref, "CountConst", sdk_file)).Integer; - const count_param_index = (try jsonObjGetRequired(self.type_ref, "CountParamIndex", sdk_file)).Integer; + try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8{ "Kind", "NullNullTerm", "CountConst", "CountParamIndex", "Child" }, sdk_file); + const null_null_term = (try jsonObjGetRequired(self.type_ref, "NullNullTerm", sdk_file)).bool; + const count_const = (try jsonObjGetRequired(self.type_ref, "CountConst", sdk_file)).integer; + const count_param_index = (try jsonObjGetRequired(self.type_ref, "CountParamIndex", sdk_file)).integer; _ = count_param_index; // ignored for now - const type_ref_kind = (try jsonObjGetRequired(self.type_ref, "Kind", sdk_file)).String; + const type_ref_kind = (try jsonObjGetRequired(self.type_ref, "Kind", sdk_file)).string; _ = type_ref_kind; // ignored for now // TODO: can Zig use count_param_index? - const child = (try jsonObjGetRequired(self.type_ref, "Child", sdk_file)).Object; + const child = (try jsonObjGetRequired(self.type_ref, "Child", sdk_file)).object; var child_options = self.options; if (self.options.optional) { child_options.optional = false; - try writer.write("?", .{.start=.any,.nl=false}); + try writer.write("?", .{ .start = .any, .nl = false }); } if (null_null_term) { - try writer.write("*extern struct{{comment:[*]const u8=\"TODO: LPArray with null_null_term\"}}", .{.start=.any,.nl=false}); + try writer.write("*extern struct{{comment:[*]const u8=\"TODO: LPArray with null_null_term\"}}", .{ .start = .any, .nl = false }); } else { var sentinel_suffix: []const u8 = ""; if ((!self.options.not_null_term) and isByteOrCharOrUInt16Type(child, sdk_file)) { @@ -1136,30 +1127,30 @@ fn generateTypeRefRec(sdk_file: *SdkFile, writer: *CodeWriter, self: TypeRefForm } if (count_const == -1 or count_const == 0) { - try writer.writef("[*{s}]", .{sentinel_suffix}, .{.start=.any,.nl=false}); + try writer.writef("[*{s}]", .{sentinel_suffix}, .{ .start = .any, .nl = false }); } else { - try writer.writef("*[{}]", .{count_const}, .{.start=.any,.nl=false}); + try writer.writef("*[{}]", .{count_const}, .{ .start = .any, .nl = false }); } if (count_const <= 0 and self.options.is_const) - try writer.write("const ", .{.start=.any,.nl=false}); + try writer.write("const ", .{ .start = .any, .nl = false }); try generateTypeRefRec(sdk_file, writer, fmtTypeRef(child, self.arches, child_options, self.nested_context), .array); } } else if (std.mem.eql(u8, kind, "MissingClrType")) { - try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8 {"Kind", "Name", "Namespace"}, sdk_file); - const name = (try jsonObjGetRequired(self.type_ref, "Name", sdk_file)).String; - const namespace = (try jsonObjGetRequired(self.type_ref, "Namespace", sdk_file)).String; - try writer.writef("*struct{{comment: []const u8 = \"MissingClrType {s}.{s}\"}}", .{name, namespace}, .{.start=.any,.nl=false}); + try jsonObjEnforceKnownFieldsOnly(self.type_ref, &[_][]const u8{ "Kind", "Name", "Namespace" }, sdk_file); + const name = (try jsonObjGetRequired(self.type_ref, "Name", sdk_file)).string; + const namespace = (try jsonObjGetRequired(self.type_ref, "Namespace", sdk_file)).string; + try writer.writef("*struct{{comment: []const u8 = \"MissingClrType {s}.{s}\"}}", .{ name, namespace }, .{ .start = .any, .nl = false }); } else { jsonPanicMsg("fmtTypeRef kind '{s}' is not implemented", .{kind}); } } fn isByteOrCharOrUInt16Type(type_obj: json.ObjectMap, sdk_file: *SdkFile) bool { - const kind = (try jsonObjGetRequired(type_obj, "Kind", sdk_file)).String; + const kind = (try jsonObjGetRequired(type_obj, "Kind", sdk_file)).string; if (!std.mem.eql(u8, kind, "Native")) return false; - const name = (try jsonObjGetRequired(type_obj, "Name", sdk_file)).String; + const name = (try jsonObjGetRequired(type_obj, "Name", sdk_file)).string; if (std.mem.eql(u8, name, "Void")) return false; const native_type = global_native_type_map.get(name) orelse jsonPanicMsg("unknown Native type '{s}'", .{name}); @@ -1191,7 +1182,7 @@ const ConstValueFormatter = struct { const zig_type = valueTypeToZigType(self.value_type); if (self.value_type == .Single or self.value_type == .Double) { switch (self.value) { - .String => |float_str| { + .string => |float_str| { if (std.mem.eql(u8, float_str, "inf")) { try writer.print("@import(\"std\").math.inf({s})", .{zig_type}); return; @@ -1209,7 +1200,7 @@ const ConstValueFormatter = struct { else => {}, } } - try writer.print("@as({s}, {})", .{zig_type, fmtJson(self.value)}); + try writer.print("@as({s}, {})", .{ zig_type, fmtJson(self.value) }); } }; @@ -1268,13 +1259,13 @@ const constants_to_skip = std.ComptimeStringMap(Nothing, .{ .{ "HWND_TOP", .{} }, }); fn generateConstant(sdk_file: *SdkFile, writer: *CodeWriter, constant_obj: json.ObjectMap) !void { - try jsonObjEnforceKnownFieldsOnly(constant_obj, &[_][]const u8 {"Name", "Type", "Value", "ValueType", "Attrs"}, sdk_file); - const name_tmp = (try jsonObjGetRequired(constant_obj, "Name", sdk_file)).String; - const type_ref = (try jsonObjGetRequired(constant_obj, "Type", sdk_file)).Object; - const value_type_str = (try jsonObjGetRequired(constant_obj, "ValueType", sdk_file)).String; + try jsonObjEnforceKnownFieldsOnly(constant_obj, &[_][]const u8{ "Name", "Type", "Value", "ValueType", "Attrs" }, sdk_file); + const name_tmp = (try jsonObjGetRequired(constant_obj, "Name", sdk_file)).string; + const type_ref = (try jsonObjGetRequired(constant_obj, "Type", sdk_file)).object; + const value_type_str = (try jsonObjGetRequired(constant_obj, "ValueType", sdk_file)).string; const value_node = try jsonObjGetRequired(constant_obj, "Value", sdk_file); - const attrs_node = (try jsonObjGetRequired(constant_obj, "Attrs", sdk_file)).Array; + const attrs_node = (try jsonObjGetRequired(constant_obj, "Attrs", sdk_file)).array; _ = attrs_node; // TODO: handle Attrs const name_pool = try global_symbol_pool.add(name_tmp); @@ -1287,45 +1278,41 @@ fn generateConstant(sdk_file: *SdkFile, writer: *CodeWriter, constant_obj: json. try writer.linef("// skipped '{}'", .{name_pool}); return; } - const zig_type_formatter = try addTypeRefs(sdk_file, ArchFlags.all, type_ref, .{ - .reason = .direct_type_access, .is_const = true, .in = false, .out = false, .anon_types = null, .null_modifier = 0 }, null); + const zig_type_formatter = try addTypeRefs(sdk_file, ArchFlags.all, type_ref, .{ .reason = .direct_type_access, .is_const = true, .in = false, .out = false, .anon_types = null, .null_modifier = 0 }, null); - const kind = (jsonObjGetRequired(type_ref, "Kind", sdk_file) catch unreachable).String; + const kind = (jsonObjGetRequired(type_ref, "Kind", sdk_file) catch unreachable).string; if (std.mem.eql(u8, kind, "Native")) { jsonEnforce(value_type != .PropertyKey); - jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8 {"Kind", "Name"}, sdk_file) catch unreachable; - const name = (jsonObjGetRequired(type_ref, "Name", sdk_file) catch unreachable).String; + jsonObjEnforceKnownFieldsOnly(type_ref, &[_][]const u8{ "Kind", "Name" }, sdk_file) catch unreachable; + const name = (jsonObjGetRequired(type_ref, "Name", sdk_file) catch unreachable).string; const native_type = global_native_type_map.get(name) orelse std.debug.panic("unknown Native type '{s}'", .{name}); if (native_type == .Guid) { - try writer.linef("pub const {s} = Guid.initString({});", .{name_pool, fmtConstValue(value_type, value_node, sdk_file)}); + try writer.linef("pub const {s} = Guid.initString({});", .{ name_pool, fmtConstValue(value_type, value_node, sdk_file) }); } else { - try writer.linef("pub const {s} = {};", .{name_pool, fmtConstValue(value_type, value_node, sdk_file)}); + try writer.linef("pub const {s} = {};", .{ name_pool, fmtConstValue(value_type, value_node, sdk_file) }); } } else { if (value_type == .PropertyKey) { const value_obj = switch (value_node) { - .Object => |obj| obj, + .object => |obj| obj, else => jsonPanicMsg("expected PropertyKey to be an object but got: {s}", .{fmtJson(value_node)}), }; - try jsonObjEnforceKnownFieldsOnly(value_obj, &[_][]const u8 {"Fmtid", "Pid"}, sdk_file); - const fmtid = (try jsonObjGetRequired(value_obj, "Fmtid", sdk_file)).String; - const pid = (try jsonObjGetRequired(value_obj, "Pid", sdk_file)).Integer; - try writer.writef("pub const {s} = ", .{name_pool}, .{.nl=false}); + try jsonObjEnforceKnownFieldsOnly(value_obj, &[_][]const u8{ "Fmtid", "Pid" }, sdk_file); + const fmtid = (try jsonObjGetRequired(value_obj, "Fmtid", sdk_file)).string; + const pid = (try jsonObjGetRequired(value_obj, "Pid", sdk_file)).integer; + try writer.writef("pub const {s} = ", .{name_pool}, .{ .nl = false }); try generateTypeRef(sdk_file, writer, zig_type_formatter); sdk_file.uses_guid = true; - try writer.writef(" {{ .fmtid = Guid.initString(\"{s}\"), .pid = {} }};", .{ - fmtid, - pid - }, .{.start=.mid}); + try writer.writef(" {{ .fmtid = Guid.initString(\"{s}\"), .pid = {} }};", .{ fmtid, pid }, .{ .start = .mid }); } else { try writer.writef("pub const {s} = @import(\"{s}zig.zig\").typedConst(", .{ name_pool, sdk_file.getWin32DirImportPrefix(), - }, .{.nl=false}); + }, .{ .nl = false }); try generateTypeRef(sdk_file, writer, zig_type_formatter); try writer.writef(", {});", .{ fmtConstValue(value_type, value_node, sdk_file), - }, .{.start=.mid}); + }, .{ .start = .mid }); } } } @@ -1347,7 +1334,7 @@ const CodeWriter = struct { midline: bool, pub fn writeBlock(self: CodeWriter, comptime s: []const u8) !void { - std.debug.assert(s[s.len-1] == '\n'); + std.debug.assert(s[s.len - 1] == '\n'); std.debug.assert(self.depth == 0); std.debug.assert(!self.midline); try self.writer.writeAll(s); @@ -1359,17 +1346,19 @@ const CodeWriter = struct { }; pub fn writef(self: *CodeWriter, comptime fmt: []const u8, args: anytype, comptime opt: LineOpt) !void { std.debug.assert(null == std.mem.indexOf(u8, fmt, "\n")); - const do_indent = blk: { switch (opt.start) { - .line => { - std.debug.assert(!self.midline); - break :blk true; - }, - .any => break :blk !self.midline, - .mid => { - std.debug.assert(self.midline); - break :blk false; - }, - }}; + const do_indent = blk: { + switch (opt.start) { + .line => { + std.debug.assert(!self.midline); + break :blk true; + }, + .any => break :blk !self.midline, + .mid => { + std.debug.assert(self.midline); + break :blk false; + }, + } + }; if (do_indent) { var i: @TypeOf(self.depth) = 0; while (i < self.depth) : (i += 1) { @@ -1401,7 +1390,7 @@ pub fn addArchSpecific(comptime T: type, arch_specific: *ArchSpecificMap(T), poo if (arch_specific.getPtr(pool_name)) |object| { object.add(.{ .arches = arches, .obj = obj }); } else { - var objects = ArchSpecificObjects(T) { }; + var objects = ArchSpecificObjects(T){}; objects.object_array[0] = .{ .arches = arches, .obj = obj }; objects.object_count = 1; try arch_specific.put(pool_name, objects); @@ -1415,22 +1404,22 @@ fn generateType( type_obj: json.ObjectMap, enum_alias_conflicts: *StringPool.HashMap(StringPool.Val), ) !void { - const arches = ArchFlags.initJson((try jsonObjGetRequired(type_obj, "Architectures", sdk_file)).Array.items); + const arches = ArchFlags.initJson((try jsonObjGetRequired(type_obj, "Architectures", sdk_file)).array.items); { const platform_node = try jsonObjGetRequired(type_obj, "Platform", sdk_file); try generatePlatformComment(writer, platform_node); } - const kind = (try jsonObjGetRequired(type_obj, "Kind", sdk_file)).String; - const tmp_name = (try jsonObjGetRequired(type_obj, "Name", sdk_file)).String; + const kind = (try jsonObjGetRequired(type_obj, "Kind", sdk_file)).string; + const tmp_name = (try jsonObjGetRequired(type_obj, "Name", sdk_file)).string; if (std.mem.eql(u8, kind, "ComClassID")) { if (arches.flags != ArchFlags.all.flags) - jsonPanicMsg("not impl", .{}); - try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8 {"Name", "Platform", "Architectures", "Kind", "Guid"}, sdk_file); - const guid = (try jsonObjGetRequired(type_obj, "Guid", sdk_file)).String; + jsonPanicMsg("not impl", .{}); + try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8{ "Name", "Platform", "Architectures", "Kind", "Guid" }, sdk_file); + const guid = (try jsonObjGetRequired(type_obj, "Guid", sdk_file)).string; const clsid_pool = try global_symbol_pool.addFormatted("CLSID_{s}", .{tmp_name}); sdk_file.uses_guid = true; - try writer.linef("const {s}_Value = Guid.initString(\"{s}\");", .{clsid_pool, guid}); + try writer.linef("const {s}_Value = Guid.initString(\"{s}\");", .{ clsid_pool, guid }); try writer.linef("pub const {s} = &{0s}_Value;", .{clsid_pool}); try sdk_file.const_exports.append(clsid_pool); return; @@ -1474,15 +1463,13 @@ fn generateTypeDefinition( def_prefix: []const u8, def_suffix: []const u8, ) !void { - if (std.mem.eql(u8, kind, "NativeTypedef")) { - try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8 {"Name", "Platform", "Architectures", - "AlsoUsableFor", "Kind", "Def", "FreeFunc"}, sdk_file); + try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8{ "Name", "Platform", "Architectures", "AlsoUsableFor", "Kind", "Def", "FreeFunc" }, sdk_file); const also_usable_for_node = try jsonObjGetRequired(type_obj, "AlsoUsableFor", sdk_file); - const def_type = (try jsonObjGetRequired(type_obj, "Def", sdk_file)).Object; - const optional_free_func : ?[]const u8 = switch (try jsonObjGetRequired(type_obj, "FreeFunc", sdk_file)) { - .Null => null, - .String => |s| s, + const def_type = (try jsonObjGetRequired(type_obj, "Def", sdk_file)).object; + const optional_free_func: ?[]const u8 = switch (try jsonObjGetRequired(type_obj, "FreeFunc", sdk_file)) { + .null => null, + .string => |s| s, else => jsonPanic(), }; if (optional_free_func) |free_func| { @@ -1491,7 +1478,7 @@ fn generateTypeDefinition( // HANDLE PSTR and PWSTR specially because win32metadata is not properly declaring them as arrays, only pointers // not sure if this is a real issue with the metadata or intentional - const special : enum { pstr, pwstr, other } = blk: { + const special: enum { pstr, pwstr, other } = blk: { if (std.mem.eql(u8, pool_name.slice, "PSTR")) break :blk .pstr; if (std.mem.eql(u8, pool_name.slice, "PWSTR")) break :blk .pwstr; break :blk .other; @@ -1500,25 +1487,25 @@ fn generateTypeDefinition( // // verify the definition is what we expect, if not, we might be able to remove out workaround // - const def_kind = (try jsonObjGetRequired(def_type, "Kind", sdk_file)).String; - jsonEnforceMsg(std.mem.eql(u8, def_kind, "PointerTo"), "definition of {s} has changed! (Def.Kind != PointerTo, it is {s})", .{pool_name, def_kind}); - try jsonObjEnforceKnownFieldsOnly(def_type, &[_][]const u8 {"Kind", "Child"}, sdk_file); - const child_type = (try jsonObjGetRequired(def_type, "Child", sdk_file)).Object; - const child_kind = (try jsonObjGetRequired(child_type, "Kind", sdk_file)).String; + const def_kind = (try jsonObjGetRequired(def_type, "Kind", sdk_file)).string; + jsonEnforceMsg(std.mem.eql(u8, def_kind, "PointerTo"), "definition of {s} has changed! (Def.Kind != PointerTo, it is {s})", .{ pool_name, def_kind }); + try jsonObjEnforceKnownFieldsOnly(def_type, &[_][]const u8{ "Kind", "Child" }, sdk_file); + const child_type = (try jsonObjGetRequired(def_type, "Child", sdk_file)).object; + const child_kind = (try jsonObjGetRequired(child_type, "Kind", sdk_file)).string; jsonEnforceMsg(std.mem.eql(u8, child_kind, "Native"), "definition of {s} has changed! (Def.Child.Kind != Native", .{pool_name}); - try jsonObjEnforceKnownFieldsOnly(child_type, &[_][]const u8 {"Kind", "Name"}, sdk_file); - const child_native_name = (try jsonObjGetRequired(child_type, "Name", sdk_file)).String; + try jsonObjEnforceKnownFieldsOnly(child_type, &[_][]const u8{ "Kind", "Name" }, sdk_file); + const child_native_name = (try jsonObjGetRequired(child_type, "Name", sdk_file)).string; // TODO: is something is referencing PSTR or PWSTR and is NotNullTerm, then // maybe I'll do something like @import("zig.zig").NotNullTerm(PSTR) const native_type = global_native_type_map.get(child_native_name) orelse jsonPanic(); switch (native_type) { .Byte => { jsonEnforce(special == .pstr); - try writer.linef("{s}[*:0]u8{s}", .{def_prefix, def_suffix}); + try writer.linef("{s}[*:0]u8{s}", .{ def_prefix, def_suffix }); }, .Char => { jsonEnforce(special == .pwstr); - try writer.linef("{s}[*:0]u16{s}", .{def_prefix, def_suffix}); + try writer.linef("{s}[*:0]u16{s}", .{ def_prefix, def_suffix }); }, else => jsonPanic(), } @@ -1526,39 +1513,38 @@ fn generateTypeDefinition( } switch (also_usable_for_node) { - .String => |also_usable_for| { + .string => |also_usable_for| { if (also_usable_type_api_map.get(also_usable_for)) |api| { - try sdk_file.addApiImport(arches, also_usable_for, api, json.Array { .items = &[_]json.Value{}, .capacity = 0, .allocator = allocator }); - try writer.linef("//TODO: type '{s}' is \"AlsoUsableFor\" '{s}' which means this type is implicitly", .{pool_name, also_usable_for}); + try sdk_file.addApiImport(arches, also_usable_for, api, json.Array{ .items = &[_]json.Value{}, .capacity = 0, .allocator = allocator }); + try writer.linef("//TODO: type '{s}' is \"AlsoUsableFor\" '{s}' which means this type is implicitly", .{ pool_name, also_usable_for }); try writer.linef("// convertible to '{s}' but not the other way around. I don't know how to do this", .{also_usable_for}); try writer.line("// in Zig so for now I'm just defining it as an alias"); - try writer.linef("{s}{s}{s}", .{def_prefix, also_usable_for, def_suffix}); + try writer.linef("{s}{s}{s}", .{ def_prefix, also_usable_for, def_suffix }); //try writer.linef("{s}extern struct {{ base: {s} }}{s}", .{def_prefix, also_usable_for, def_suffix}); } else std.debug.panic("AlsoUsableFor type '{s}' is missing from alsoUsableForApiMap", .{also_usable_for}); return; }, - .Null => {}, + .null => {}, else => jsonPanic(), } // NOTE: for now, I'm just hardcoding a few types to redirect to the ones defined in 'std' // this allows apps to use values of these types interchangeably with bindings in std if (@import("handletypes.zig").std_handle_types.get(pool_name.slice)) |std_sym| { - try writer.linef("{s}@import(\"std\").{s}{s}", .{def_prefix, std_sym, def_suffix}); + try writer.linef("{s}@import(\"std\").{s}{s}", .{ def_prefix, std_sym, def_suffix }); return; } // workaround https://github.com/microsoft/win32metadata/issues/395 if (@import("handletypes.zig").handle_types.get(pool_name.slice)) |_| { - try writer.linef("{s}*opaque{{}}{s}", .{def_prefix, def_suffix}); + try writer.linef("{s}*opaque{{}}{s}", .{ def_prefix, def_suffix }); return; } // TODO: set is_const, in and out properly - const zig_type_formatter = try addTypeRefs(sdk_file, arches, def_type, .{ - .reason = .direct_type_access, .is_const = false, .in = false, .out = false, .anon_types = null, .null_modifier = 0 }, null); - try writer.writef("{s}", .{def_prefix}, .{.nl=false}); + const zig_type_formatter = try addTypeRefs(sdk_file, arches, def_type, .{ .reason = .direct_type_access, .is_const = false, .in = false, .out = false, .anon_types = null, .null_modifier = 0 }, null); + try writer.writef("{s}", .{def_prefix}, .{ .nl = false }); try generateTypeRef(sdk_file, writer, zig_type_formatter); - try writer.writef("{s}", .{def_suffix}, .{.start=.mid}); + try writer.writef("{s}", .{def_suffix}, .{ .start = .mid }); } else if (std.mem.eql(u8, kind, "Enum")) { try generateEnum(sdk_file, writer, type_obj, pool_name, enum_alias_conflicts, def_prefix, def_suffix); } else if (std.mem.eql(u8, kind, "Union")) { @@ -1569,9 +1555,9 @@ fn generateTypeDefinition( if (funcPtrHasDependencyLoop(pool_name.slice)) { try writer.line("// TODO: this function pointer causes dependency loop problems, so it's stubbed out"); try writer.linef("{s}switch (@import(\"builtin\").zig_backend) {{ " ++ - ".stage1 => fn() callconv(@import(\"std\").os.windows.WINAPI) void" ++ - ", else => *const fn() callconv(@import(\"std\").os.windows.WINAPI) void" ++ - "}}{s}", .{def_prefix, def_suffix}); + ".stage1 => fn() callconv(@import(\"std\").os.windows.WINAPI) void" ++ + ", else => *const fn() callconv(@import(\"std\").os.windows.WINAPI) void" ++ + "}}{s}", .{ def_prefix, def_suffix }); return; } try generateFunction(sdk_file, writer, type_obj, .{ .ptr = .{ .both = .{ .def_prefix = def_prefix, .def_suffix = def_suffix } } }); @@ -1579,7 +1565,7 @@ fn generateTypeDefinition( } else if (std.mem.eql(u8, kind, "Com")) { try generateCom(sdk_file, writer, type_obj, arches, pool_name, def_prefix); } else { - jsonPanicMsg("{s}: unknown type Kind '{s}'", .{sdk_file.json_basename, kind}); + jsonPanicMsg("{s}: unknown type Kind '{s}'", .{ sdk_file.json_basename, kind }); } } @@ -1625,10 +1611,10 @@ const com_types_to_skip = std.ComptimeStringMap(Nothing, .{ fn generatePlatformComment(writer: *CodeWriter, platform_node: std.json.Value) !void { switch (platform_node) { - .String => |platform| { + .string => |platform| { try writer.linef("// TODO: this type is limited to platform '{s}'", .{platform}); }, - .Null => {}, + .null => {}, else => jsonPanic(), } } @@ -1647,51 +1633,49 @@ const AnonTypes = struct { fn generateStructOrUnion(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: json.ObjectMap, arches: ArchFlags, pool_name: StringPool.Val, def_prefix: []const u8, def_suffix: []const u8, kind: ContainerKind, nested_context: ?*const NestedContext) !void { std.debug.assert(getAnonKind(pool_name.slice) == null); - try writer.writef("{s}", .{def_prefix}, .{.nl=false}); + try writer.writef("{s}", .{def_prefix}, .{ .nl = false }); try generateStructOrUnionDef(sdk_file, writer, type_obj, arches, kind, nested_context); try writer.linef("}}{s}", .{def_suffix}); } fn generateStructOrUnionDef(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: json.ObjectMap, arches: ArchFlags, kind: ContainerKind, nested_context: ?*const NestedContext) anyerror!void { - - try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8 {"Kind", "Name", "Platform", "Architectures", - "Size", "PackingSize", "Fields", "Comment", "NestedTypes"}, sdk_file); - const struct_size = (try jsonObjGetRequired(type_obj, "Size", sdk_file)).Integer; + try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8{ "Kind", "Name", "Platform", "Architectures", "Size", "PackingSize", "Fields", "Comment", "NestedTypes" }, sdk_file); + const struct_size = (try jsonObjGetRequired(type_obj, "Size", sdk_file)).integer; _ = struct_size; // ignored for now - const struct_packing_size = (try jsonObjGetRequired(type_obj, "PackingSize", sdk_file)).Integer; - const struct_fields = (try jsonObjGetRequired(type_obj, "Fields", sdk_file)).Array; - const struct_nested_types = (try jsonObjGetRequired(type_obj, "NestedTypes", sdk_file)).Array; + const struct_packing_size = (try jsonObjGetRequired(type_obj, "PackingSize", sdk_file)).integer; + const struct_fields = (try jsonObjGetRequired(type_obj, "Fields", sdk_file)).array; + const struct_nested_types = (try jsonObjGetRequired(type_obj, "NestedTypes", sdk_file)).array; const zig_type = if (kind == .Struct) "struct" else "union"; - try writer.writef("extern {s} {{", .{zig_type}, .{.start=.any}); + try writer.writef("extern {s} {{", .{zig_type}, .{ .start = .any }); writer.depth += 1; - defer writer.depth -=1; + defer writer.depth -= 1; var anon_types = AnonTypes.init(); defer anon_types.deinit(); - const this_nested_context_data = NestedContext { + const this_nested_context_data = NestedContext{ .nested_types = struct_nested_types, .parent = nested_context, }; const this_nested_context = if (struct_nested_types.items.len > 0) &this_nested_context_data else nested_context; for (struct_nested_types.items) |*nested_type_node_ptr| { - const nested_type_obj = nested_type_node_ptr.Object; - const nested_kind = (try jsonObjGetRequired(nested_type_obj, "Kind", sdk_file)).String; - const nested_tmp_name = (try jsonObjGetRequired(nested_type_obj, "Name", sdk_file)).String; - const architectures = (try jsonObjGetRequired(nested_type_obj, "Architectures", sdk_file)).Array; + const nested_type_obj = nested_type_node_ptr.object; + const nested_kind = (try jsonObjGetRequired(nested_type_obj, "Kind", sdk_file)).string; + const nested_tmp_name = (try jsonObjGetRequired(nested_type_obj, "Name", sdk_file)).string; + const architectures = (try jsonObjGetRequired(nested_type_obj, "Architectures", sdk_file)).array; const pool_name = try global_symbol_pool.add(nested_tmp_name); if (getAnonKind(nested_tmp_name)) |_| { if (architectures.items.len > 0) // we don't handle architectures in this case - jsonPanicMsg("not impl", .{}); + jsonPanicMsg("not impl", .{}); try anon_types.types.put(pool_name, nested_type_obj); } else { // TODO: I don't know why this isn't working!!! //const def_prefix = try std.fmt.allocPrint(allocator, "pub const {s} = ", .{std.zig.fmtId(pool_name)}); //defer allocator.free(def_prefix); - try writer.writef("pub const {s} = ", .{pool_name}, .{.nl=false}); + try writer.writef("pub const {s} = ", .{pool_name}, .{ .nl = false }); if (std.mem.eql(u8, nested_kind, "Union")) { try generateStructOrUnionDef(sdk_file, writer, nested_type_obj, arches, .Union, this_nested_context); } else if (std.mem.eql(u8, nested_kind, "Struct")) { @@ -1705,19 +1689,19 @@ fn generateStructOrUnionDef(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: j try writer.line("placeholder: usize, // TODO: why is this type empty?"); } else { for (struct_fields.items) |*field_node_ptr| { - const field_obj = field_node_ptr.Object; - try jsonObjEnforceKnownFieldsOnly(field_obj, &[_][]const u8 {"Name", "Type", "Attrs"}, sdk_file); - const field_name = (try jsonObjGetRequired(field_obj, "Name", sdk_file)).String; - const field_type = (try jsonObjGetRequired(field_obj, "Type", sdk_file)).Object; - const field_attrs = (try jsonObjGetRequired(field_obj, "Attrs", sdk_file)).Array; + const field_obj = field_node_ptr.object; + try jsonObjEnforceKnownFieldsOnly(field_obj, &[_][]const u8{ "Name", "Type", "Attrs" }, sdk_file); + const field_name = (try jsonObjGetRequired(field_obj, "Name", sdk_file)).string; + const field_type = (try jsonObjGetRequired(field_obj, "Type", sdk_file)).object; + const field_attrs = (try jsonObjGetRequired(field_obj, "Attrs", sdk_file)).array; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // TODO: implement null_modifier // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - var field_options = TypeRefFormatter.Options { .reason = .var_decl, .anon_types = &anon_types, .null_modifier = 0 }; + var field_options = TypeRefFormatter.Options{ .reason = .var_decl, .anon_types = &anon_types, .null_modifier = 0 }; for (field_attrs.items) |*attr_node_ptr| { - const attr_str = attr_node_ptr.String; + const attr_str = attr_node_ptr.string; if (std.mem.eql(u8, attr_str, "Const")) { field_options.is_const = true; } else if (std.mem.eql(u8, attr_str, "NotNullTerminated")) { @@ -1733,12 +1717,12 @@ fn generateStructOrUnionDef(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: j } } const field_type_formatter = try addTypeRefs(sdk_file, arches, field_type, field_options, this_nested_context); - try writer.writef("{}: ", .{std.zig.fmtId(field_name)}, .{.nl=false}); + try writer.writef("{}: ", .{std.zig.fmtId(field_name)}, .{ .nl = false }); try generateTypeRef(sdk_file, writer, field_type_formatter); if (struct_packing_size >= 1) { - try writer.writef(" align({})", .{struct_packing_size}, .{.start=.mid,.nl=false}); + try writer.writef(" align({})", .{struct_packing_size}, .{ .start = .mid, .nl = false }); } - try writer.write(",", .{.start=.mid}); + try writer.write(",", .{ .start = .mid }); } } } @@ -1763,10 +1747,11 @@ fn shortEnumValueName(enum_type_name: []const u8, full_value_name: []const u8) [ const offset = init: { if ((full_value_name.len <= enum_type_name.len + 1) or (full_value_name[enum_type_name.len] != '_') or - !std.mem.startsWith(u8, full_value_name, enum_type_name)) { + !std.mem.startsWith(u8, full_value_name, enum_type_name)) + { break :init 0; } - const first_c = full_value_name[enum_type_name.len+1]; + const first_c = full_value_name[enum_type_name.len + 1]; if (first_c <= '9' and first_c >= '0') { break :init enum_type_name.len; } @@ -1776,7 +1761,7 @@ fn shortEnumValueName(enum_type_name: []const u8, full_value_name: []const u8) [ } // TODO: this is a set of enums whose value symbols conflict with other symbols -const suppress_enum_aliases = std.ComptimeStringMap(Nothing, .{ +const suppress_enum_aliases = ComptimeStringMapQuota(Nothing, .{ // suppress this one because the CFE_UNDERLINE enum value alias conflicts with the name of an enum type .{ "CFE_EFFECTS", .{} }, // these types have values that conflict with their own enum type name @@ -1872,7 +1857,7 @@ const suppress_enum_aliases = std.ComptimeStringMap(Nothing, .{ .{ "SymGetSymbolFile_Type", .{} }, // Multimedia .{ "MIDI_OPEN_TYPE", .{} }, -}); +}, 100000); const EnumValue = struct { pool_name: StringPool.Val, @@ -1882,26 +1867,24 @@ const EnumValue = struct { conflict_index: ?usize, pub fn valueIsZero(self: EnumValue) bool { return switch (self.value) { - .Integer => |i| i == 0, + .integer => |i| i == 0, else => false, }; } }; fn matchLen(a: []const u8, b: []const u8) usize { - var i : usize = 0; - while (i < a.len and i < b.len and a[i] == b[i]) : (i += 1) { } + var i: usize = 0; + while (i < a.len and i < b.len and a[i] == b[i]) : (i += 1) {} return i; } fn setShortNames(values: []EnumValue) void { var at_first = true; - var longest_prefix_match : []const u8 = undefined; + var longest_prefix_match: []const u8 = undefined; for (values) |*val_ref| { - if (( - val_ref.pool_name.eql(global_symbol_none) or - val_ref.pool_name.eql(global_symbol_None) - ) and - val_ref.valueIsZero() - ) { + if ((val_ref.pool_name.eql(global_symbol_none) or + val_ref.pool_name.eql(global_symbol_None)) and + val_ref.valueIsZero()) + { val_ref.short_name = val_ref.pool_name.slice; val_ref.no_alias = true; continue; @@ -1940,23 +1923,23 @@ fn generateEnum( def_prefix: []const u8, def_suffix: []const u8, ) !void { - try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8 {"Name", "Platform", "Architectures", "Kind", "Flags", "Scoped", "Values", "IntegerBase"}, sdk_file); - const flags = (try jsonObjGetRequired(type_obj, "Flags", sdk_file)).Bool; - const scoped = (try jsonObjGetRequired(type_obj, "Scoped", sdk_file)).Bool; - const json_values = (try jsonObjGetRequired(type_obj, "Values", sdk_file)).Array; + try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8{ "Name", "Platform", "Architectures", "Kind", "Flags", "Scoped", "Values", "IntegerBase" }, sdk_file); + const flags = (try jsonObjGetRequired(type_obj, "Flags", sdk_file)).bool; + const scoped = (try jsonObjGetRequired(type_obj, "Scoped", sdk_file)).bool; + const json_values = (try jsonObjGetRequired(type_obj, "Values", sdk_file)).array; const integer_base = switch (try jsonObjGetRequired(type_obj, "IntegerBase", sdk_file)) { - .Null => "i32", - .String => |s| nativeTypeToZigType(global_native_type_map.get(s) orelse - fatal("enum '{}' has an unknown IntegerBase '{s}'", .{pool_name, s})), + .null => "i32", + .string => |s| nativeTypeToZigType(global_native_type_map.get(s) orelse + fatal("enum '{}' has an unknown IntegerBase '{s}'", .{ pool_name, s })), else => jsonPanic(), }; const values = try allocator.alloc(EnumValue, json_values.items.len); var values_initialized_len: usize = 0; defer allocator.free(values); for (json_values.items) |*value_node_ptr| { - const value_obj = value_node_ptr.Object; - try jsonObjEnforceKnownFieldsOnly(value_obj, &[_][]const u8 {"Name", "Value"}, sdk_file); - const value_tmp_name = (try jsonObjGetRequired(value_obj, "Name", sdk_file)).String; + const value_obj = value_node_ptr.object; + try jsonObjEnforceKnownFieldsOnly(value_obj, &[_][]const u8{ "Name", "Value" }, sdk_file); + const value_tmp_name = (try jsonObjGetRequired(value_obj, "Name", sdk_file)).string; values[values_initialized_len] = .{ .pool_name = try global_symbol_pool.add(value_tmp_name), .short_name = "", @@ -1978,17 +1961,16 @@ fn generateEnum( } } - try writer.linef("{s}enum({s}) {{", .{def_prefix, integer_base}); + try writer.linef("{s}enum({s}) {{", .{ def_prefix, integer_base }); if (values.len == 0) { // zig doesn't allow empty enums try writer.line(" _"); } else { for (values) |val| { if (val.conflict_index) |conflict_index| { - try writer.linef(" // {s} = {}, this enum value conflicts with {s}", .{ - std.zig.fmtId(val.short_name), fmtJson(val.value), std.zig.fmtId(values[conflict_index].short_name)}); + try writer.linef(" // {s} = {}, this enum value conflicts with {s}", .{ std.zig.fmtId(val.short_name), fmtJson(val.value), std.zig.fmtId(values[conflict_index].short_name) }); } else { - try writer.linef(" {s} = {},", .{std.zig.fmtId(val.short_name), fmtJson(val.value)}); + try writer.linef(" {s} = {},", .{ std.zig.fmtId(val.short_name), fmtJson(val.value) }); } } if (flags) { @@ -2005,15 +1987,15 @@ fn generateEnum( } } try writer.linef(" }}) {s} {{", .{pool_name}); - try writer.linef(" return @intToEnum({s},", .{pool_name}); + try writer.linef(" return @as({s},@enumFromInt(", .{pool_name}); var prefix: []const u8 = " "; for (values) |val| { if (val.conflict_index == null) { - try writer.linef(" {s} (if (o.{s} == 1) @enumToInt({s}.{1s}) else 0)", .{prefix, std.zig.fmtId(val.short_name), pool_name}); + try writer.linef(" {s} (if (o.{s} == 1) @intFromEnum({s}.{1s}) else 0)", .{ prefix, std.zig.fmtId(val.short_name), pool_name }); prefix = "|"; } } - try writer.line(" );"); + try writer.line(" ));"); try writer.line(" }"); } try writer.linef("}}{s}", .{def_suffix}); @@ -2049,27 +2031,24 @@ fn generateEnum( try enum_alias_conflicts.put(val.pool_name, pool_name); try sdk_file.const_exports.append(val.pool_name); const target_short_name = if (val.conflict_index) |i| values[i].short_name else val.short_name; - try writer.linef("pub const {} = {}.{};", .{val.pool_name, pool_name, std.zig.fmtId(target_short_name)}); + try writer.linef("pub const {} = {}.{};", .{ val.pool_name, pool_name, std.zig.fmtId(target_short_name) }); } } - - - fn generateCom(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: json.ObjectMap, arches: ArchFlags, com_pool_name: StringPool.Val, def_prefix: []const u8) !void { - try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8 {"Kind", "Name", "Platform", "Architectures", "Guid", "Interface", "Methods"}, sdk_file); + try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8{ "Kind", "Name", "Platform", "Architectures", "Guid", "Interface", "Methods" }, sdk_file); - const com_optional_guid : ?[]const u8 = switch (try jsonObjGetRequired(type_obj, "Guid", sdk_file)) { - .Null => null, - .String => |s| s, + const com_optional_guid: ?[]const u8 = switch (try jsonObjGetRequired(type_obj, "Guid", sdk_file)) { + .null => null, + .string => |s| s, else => jsonPanic(), }; - const com_optional_iface : ?json.ObjectMap = switch (try jsonObjGetRequired(type_obj, "Interface", sdk_file)) { - .Null => null, - .Object => |o| o, + const com_optional_iface: ?json.ObjectMap = switch (try jsonObjGetRequired(type_obj, "Interface", sdk_file)) { + .null => null, + .object => |o| o, else => jsonPanic(), }; - const com_methods = (try jsonObjGetRequired(type_obj, "Methods", sdk_file)).Array; + const com_methods = (try jsonObjGetRequired(type_obj, "Methods", sdk_file)).array; const skip = com_types_to_skip.has(com_pool_name.slice); if (skip) { try writer.line("// WARNING: this COM type has been skipped because it causes some sort of error"); @@ -2078,23 +2057,23 @@ fn generateCom(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: json.ObjectMap const iid_pool = try global_symbol_pool.addFormatted("IID_{s}", .{com_pool_name.slice}); if (com_optional_guid) |guid| { sdk_file.uses_guid = true; - try writer.linef("const {s}_Value = Guid.initString(\"{s}\");", .{ iid_pool, guid}); + try writer.linef("const {s}_Value = Guid.initString(\"{s}\");", .{ iid_pool, guid }); try writer.linef("pub const {s} = &{0s}_Value;", .{iid_pool}); try sdk_file.const_exports.append(iid_pool); } try writer.linef("{s}extern struct {{", .{def_prefix}); try writer.line(" pub const VTable = extern struct {"); - var iface_formatter : TypeRefFormatter = undefined; + var iface_formatter: TypeRefFormatter = undefined; if (skip) { try writer.line(" _: *opaque{}, // just a placeholder because this COM type is skipped"); } else { if (com_optional_iface) |iface| { iface_formatter = try addTypeRefs(sdk_file, arches, iface, .{ .reason = .direct_type_access, .anon_types = null, .null_modifier = 0 }, null); - try writer.write(" base: ", .{.nl=false}); + try writer.write(" base: ", .{ .nl = false }); try generateTypeRef(sdk_file, writer, iface_formatter); - try writer.write(".VTable,", .{.start=.mid}); + try writer.write(".VTable,", .{ .start = .mid }); } // some COM objects have methods with the same name and only differ in parameter types @@ -2102,14 +2081,14 @@ fn generateCom(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: json.ObjectMap defer method_conflicts.deinit(); for (com_methods.items) |*method_node_ptr| { - const method_name = (try jsonObjGetRequired(method_node_ptr.Object, "Name", sdk_file)).String; + const method_name = (try jsonObjGetRequired(method_node_ptr.object, "Name", sdk_file)).string; const count = method_conflicts.get(method_name) orelse 0; try method_conflicts.put(method_name, count + 1); writer.depth += 2; - try generateFunction(sdk_file, writer, method_node_ptr.Object, .{ .com = .{ .both = .{ + try generateFunction(sdk_file, writer, method_node_ptr.object, .{ .com = .{ .both = .{ .symbol_suffix = if (count == 0) null else count, .self_type = com_pool_name.slice, - }}}); + } } }); writer.depth -= 2; } } @@ -2126,44 +2105,44 @@ fn generateCom(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: json.ObjectMap if (!skip) { if (com_optional_iface) |_| { // For now we're putting this inside a sub-struct to avoid name conflicts - try writer.write(" pub usingnamespace ", .{.nl=false}); + try writer.write(" pub usingnamespace ", .{ .nl = false }); try generateTypeRef(sdk_file, writer, iface_formatter); - try writer.write(".MethodMixin(T);", .{.start=.mid}); + try writer.write(".MethodMixin(T);", .{ .start = .mid }); } for (com_methods.items) |*method_node_ptr| { - const method_obj = method_node_ptr.Object; - const method_name = (try jsonObjGetRequired(method_obj, "Name", sdk_file)).String; - const return_type = (try jsonObjGetRequired(method_obj, "ReturnType", sdk_file)).Object; - const params = (try jsonObjGetRequired(method_obj, "Params", sdk_file)).Array; + const method_obj = method_node_ptr.object; + const method_name = (try jsonObjGetRequired(method_obj, "Name", sdk_file)).string; + const return_type = (try jsonObjGetRequired(method_obj, "ReturnType", sdk_file)).object; + const params = (try jsonObjGetRequired(method_obj, "Params", sdk_file)).array; const count = method_conflicts.get(method_name) orelse 0; try method_conflicts.put(method_name, count + 1); try writer.line(" // NOTE: method is namespaced with interface name to avoid conflicts for now"); - try writer.writef(" pub fn {s}_{s}", .{com_pool_name, method_name}, .{.nl=false}); + try writer.writef(" pub fn {s}_{s}", .{ com_pool_name, method_name }, .{ .nl = false }); if (count > 0) { - try writer.writef("{}", .{count}, .{.start=.mid,.nl=false}); + try writer.writef("{}", .{count}, .{ .start = .mid, .nl = false }); } - try writer.write("(self: *const T", .{.start=.mid,.nl=false}); + try writer.write("(self: *const T", .{ .start = .mid, .nl = false }); for (params.items) |*param_node_ptr| { - const param_obj = param_node_ptr.Object; - try jsonObjEnforceKnownFieldsOnly(param_obj, &[_][]const u8 {"Name", "Type", "Attrs"}, sdk_file); - const param_name = (try jsonObjGetRequired(param_obj, "Name", sdk_file)).String; - const param_type = (try jsonObjGetRequired(param_obj, "Type", sdk_file)).Object; + const param_obj = param_node_ptr.object; + try jsonObjEnforceKnownFieldsOnly(param_obj, &[_][]const u8{ "Name", "Type", "Attrs" }, sdk_file); + const param_name = (try jsonObjGetRequired(param_obj, "Name", sdk_file)).string; + const param_type = (try jsonObjGetRequired(param_obj, "Type", sdk_file)).object; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // TODO: set null_modifier properly // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! const null_modifier = 0; - const param_options = processParamAttrs((try jsonObjGetRequired(param_obj, "Attrs", sdk_file)).Array, .var_decl, null_modifier, sdk_file); + const param_options = processParamAttrs((try jsonObjGetRequired(param_obj, "Attrs", sdk_file)).array, .var_decl, null_modifier, sdk_file); // NOTE: don't need to call addTypeRefs because it was already called in generateFunction above const param_type_formatter = fmtTypeRef(param_type, arches, param_options, null); if (param_options.optional_bytes_param_index) |bytes_param_index| { _ = bytes_param_index; // NOTE: can't print this because we are currently inline //try writer.linef("// TODO: what to do with BytesParamIndex {}?", .{bytes_param_index}); } - try writer.writef(", {s}: ", .{fmtParamId(param_name, sdk_file.param_names_to_avoid_map_get_fn)}, .{.start=.mid,.nl=false}); + try writer.writef(", {s}: ", .{fmtParamId(param_name, sdk_file.param_names_to_avoid_map_get_fn)}, .{ .start = .mid, .nl = false }); try generateTypeRef(sdk_file, writer, param_type_formatter); } // NOTE: don't need to call addTypeRefs because it was already called in generateFunction above @@ -2173,18 +2152,17 @@ fn generateCom(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: json.ObjectMap // TODO: set null_modifier properly // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - const return_type_formatter = fmtTypeRef(return_type, arches, .{ - .reason = .var_decl, .is_const = false, .in = false, .out = false, .anon_types = null, .null_modifier = 0 }, null); - try writer.write(") callconv(.Inline) ", .{.start=.mid,.nl=false}); + const return_type_formatter = fmtTypeRef(return_type, arches, .{ .reason = .var_decl, .is_const = false, .in = false, .out = false, .anon_types = null, .null_modifier = 0 }, null); + try writer.write(") callconv(.Inline) ", .{ .start = .mid, .nl = false }); try generateTypeRef(sdk_file, writer, return_type_formatter); - try writer.write(" {", .{.start=.mid}); - try writer.writef(" return @ptrCast(*const {s}.VTable, self.vtable).{s}(@ptrCast(*const {0s}, self)", .{com_pool_name, std.zig.fmtId(method_name)}, .{.nl=false}); + try writer.write(" {", .{ .start = .mid }); + try writer.writef(" return @as(*const {s}.VTable,@ptrCast(self.vtable)).{s}(@as(*const {0s},@ptrCast(self))", .{ com_pool_name, std.zig.fmtId(method_name) }, .{ .nl = false }); for (params.items) |*param_node_ptr| { - const param_obj = param_node_ptr.Object; - const param_name = (try jsonObjGetRequired(param_obj, "Name", sdk_file)).String; - try writer.writef(", {s}", .{fmtParamId(param_name, sdk_file.param_names_to_avoid_map_get_fn)}, .{.start=.mid,.nl=false}); + const param_obj = param_node_ptr.object; + const param_name = (try jsonObjGetRequired(param_obj, "Name", sdk_file)).string; + try writer.writef(", {s}", .{fmtParamId(param_name, sdk_file.param_names_to_avoid_map_get_fn)}, .{ .start = .mid, .nl = false }); } - try writer.write(");", .{.start=.any}); + try writer.write(");", .{ .start = .any }); try writer.line(" }"); } } @@ -2194,21 +2172,21 @@ fn generateCom(sdk_file: *SdkFile, writer: *CodeWriter, type_obj: json.ObjectMap } fn processParamAttrs(attrs: json.Array, reason: TypeRefFormatter.Reason, null_modifier: NullModifier, sdk_file: *const SdkFile) TypeRefFormatter.Options { - var opts = TypeRefFormatter.Options { .reason = reason, .anon_types = null, .null_modifier = null_modifier }; + var opts = TypeRefFormatter.Options{ .reason = reason, .anon_types = null, .null_modifier = null_modifier }; for (attrs.items) |*attr_node_ptr| { switch (attr_node_ptr.*) { - .Object => |attr_obj| { - const kind = (try jsonObjGetRequired(attr_obj, "Kind", sdk_file)).String; + .object => |attr_obj| { + const kind = (try jsonObjGetRequired(attr_obj, "Kind", sdk_file)).string; if (std.mem.eql(u8, kind, "MemorySize")) { - try jsonObjEnforceKnownFieldsOnly(attr_obj, &[_][]const u8 {"Kind", "BytesParamIndex"}, sdk_file); - opts.optional_bytes_param_index = @intCast(i16, (try jsonObjGetRequired(attr_obj, "BytesParamIndex", sdk_file)).Integer); + try jsonObjEnforceKnownFieldsOnly(attr_obj, &[_][]const u8{ "Kind", "BytesParamIndex" }, sdk_file); + opts.optional_bytes_param_index = @as(i16, @intCast((try jsonObjGetRequired(attr_obj, "BytesParamIndex", sdk_file)).integer)); } else if (std.mem.eql(u8, kind, "FreeWith")) { - try jsonObjEnforceKnownFieldsOnly(attr_obj, &[_][]const u8 {"Kind", "Func"}, sdk_file); - const func = (try jsonObjGetRequired(attr_obj, "Func", sdk_file)).String; + try jsonObjEnforceKnownFieldsOnly(attr_obj, &[_][]const u8{ "Kind", "Func" }, sdk_file); + const func = (try jsonObjGetRequired(attr_obj, "Func", sdk_file)).string; _ = func; // TODO: what to do with this? } else jsonPanicMsg("unknown param attr Kind '{s}'", .{kind}); }, - .String => |attr_str| { + .string => |attr_str| { if (std.mem.eql(u8, attr_str, "Const")) { opts.is_const = true; } else if (std.mem.eql(u8, attr_str, "In")) { @@ -2242,29 +2220,10 @@ fn processParamAttrs(attrs: json.Array, reason: TypeRefFormatter.Reason, null_mo // Skip these function pointers to workaround: https://github.com/ziglang/zig/issues/4476 fn funcPtrHasDependencyLoop(name: []const u8) bool { if (func_ptr_dependency_loop_problems.get(name)) |_| return true; - if (std.mem.startsWith(u8, name, "PFN_")) return - std.mem.startsWith(u8, name, "PFN_CPD_") - or std.mem.startsWith(u8, name, "PFN_PROVIDER_") - or std.mem.startsWith(u8, name, "PFN_PROVUI_") - ; - if (std.mem.startsWith(u8, name, "PIBIO_")) return - std.mem.startsWith(u8, name, "PIBIO_SENSOR_") - or std.mem.startsWith(u8, name, "PIBIO_ENGINE_") - or std.mem.startsWith(u8, name, "PIBIO_STORAGE_") - or std.mem.startsWith(u8, name, "PIBIO_FRAMEWORK_") - ; - if (std.mem.startsWith(u8, name, "LPDDHAL")) return - std.mem.startsWith(u8, name, "LPDDHAL_") - or std.mem.startsWith(u8, name, "LPDDHALSURFCB_") - or std.mem.startsWith(u8, name, "LPDDHALPALCB_") - or std.mem.startsWith(u8, name, "LPDDHALVPORTCB_") - or std.mem.startsWith(u8, name, "LPDDHALCOLORCB_") - or std.mem.startsWith(u8, name, "LPDDHALMOCOMPCB_") - ; - return - std.mem.startsWith(u8, name, "UText") - or std.mem.startsWith(u8, name, "UCharIterator") - ; + if (std.mem.startsWith(u8, name, "PFN_")) return std.mem.startsWith(u8, name, "PFN_CPD_") or std.mem.startsWith(u8, name, "PFN_PROVIDER_") or std.mem.startsWith(u8, name, "PFN_PROVUI_"); + if (std.mem.startsWith(u8, name, "PIBIO_")) return std.mem.startsWith(u8, name, "PIBIO_SENSOR_") or std.mem.startsWith(u8, name, "PIBIO_ENGINE_") or std.mem.startsWith(u8, name, "PIBIO_STORAGE_") or std.mem.startsWith(u8, name, "PIBIO_FRAMEWORK_"); + if (std.mem.startsWith(u8, name, "LPDDHAL")) return std.mem.startsWith(u8, name, "LPDDHAL_") or std.mem.startsWith(u8, name, "LPDDHALSURFCB_") or std.mem.startsWith(u8, name, "LPDDHALPALCB_") or std.mem.startsWith(u8, name, "LPDDHALVPORTCB_") or std.mem.startsWith(u8, name, "LPDDHALCOLORCB_") or std.mem.startsWith(u8, name, "LPDDHALMOCOMPCB_"); + return std.mem.startsWith(u8, name, "UText") or std.mem.startsWith(u8, name, "UCharIterator"); } const func_ptr_dependency_loop_problems = std.ComptimeStringMap(Nothing, .{ .{ "FREEOBJPROC", .{} }, @@ -2335,10 +2294,7 @@ const FuncPtrKind = union(enum) { ptr: union(enum) { stage1, not_stage1, - both: struct { - def_prefix: []const u8, - def_suffix: []const u8 - }, + both: struct { def_prefix: []const u8, def_suffix: []const u8 }, }, com: union(enum) { stage1: struct { self_type: []const u8 }, @@ -2352,10 +2308,10 @@ const FuncPtrKind = union(enum) { fn generateArchPrefix(writer: *CodeWriter, module_depth: u2, arches: ArchFlags, prefix: []const u8) !void { std.debug.assert(arches.flags != ArchFlags.all.flags); - try writer.linef("{s}usingnamespace switch (@import(\"{s}zig.zig\").arch) {{", .{prefix, import_prefix_table[module_depth]}); + try writer.linef("{s}usingnamespace switch (@import(\"{s}zig.zig\").arch) {{", .{ prefix, import_prefix_table[module_depth] }); var buf: [40]u8 = undefined; - const case_prefix = buf[0 .. try arches.formatCase(&buf)]; + const case_prefix = buf[0..try arches.formatCase(&buf)]; try writer.linef("{s}struct {{", .{case_prefix}); try writer.line(""); } @@ -2367,7 +2323,7 @@ fn generateArchSuffix(writer: *CodeWriter) void { const ParamModifierSet = struct { const max_params = 30; ret: NullModifier = 0, - params: [max_params]NullModifier = [_]NullModifier { 0 } ** max_params, + params: [max_params]NullModifier = [_]NullModifier{0} ** max_params, }; fn generateFunction( @@ -2377,24 +2333,22 @@ fn generateFunction( func_kind: FuncPtrKind, ) !void { switch (func_kind) { - .fixed => try jsonObjEnforceKnownFieldsOnly(function_obj, &[_][]const u8 {"Name", "Platform", "Architectures", - "SetLastError", "DllImport", "ReturnType", "ReturnAttrs", "Attrs", "Params"}, sdk_file), - .ptr, .com => try jsonObjEnforceKnownFieldsOnly(function_obj, &[_][]const u8 {"Kind", "Name", "Platform", "Architectures", - "SetLastError", "ReturnType", "ReturnAttrs", "Attrs", "Params"}, sdk_file), + .fixed => try jsonObjEnforceKnownFieldsOnly(function_obj, &[_][]const u8{ "Name", "Platform", "Architectures", "SetLastError", "DllImport", "ReturnType", "ReturnAttrs", "Attrs", "Params" }, sdk_file), + .ptr, .com => try jsonObjEnforceKnownFieldsOnly(function_obj, &[_][]const u8{ "Kind", "Name", "Platform", "Architectures", "SetLastError", "ReturnType", "ReturnAttrs", "Attrs", "Params" }, sdk_file), } - const func_name_tmp = (try jsonObjGetRequired(function_obj, "Name", sdk_file)).String; + const func_name_tmp = (try jsonObjGetRequired(function_obj, "Name", sdk_file)).string; const platform_node = try jsonObjGetRequired(function_obj, "Platform", sdk_file); - const arches = ArchFlags.initJson((try jsonObjGetRequired(function_obj, "Architectures", sdk_file)).Array.items); - const set_last_error = (try jsonObjGetRequired(function_obj, "SetLastError", sdk_file)).Bool; + const arches = ArchFlags.initJson((try jsonObjGetRequired(function_obj, "Architectures", sdk_file)).array.items); + const set_last_error = (try jsonObjGetRequired(function_obj, "SetLastError", sdk_file)).bool; _ = set_last_error; // ignored for now - const dll_import = if (func_kind == .fixed) (try jsonObjGetRequired(function_obj, "DllImport", sdk_file)).String else ""; - const return_type = (try jsonObjGetRequired(function_obj, "ReturnType", sdk_file)).Object; - const return_attrs = (try jsonObjGetRequired(function_obj, "ReturnAttrs", sdk_file)).Array; - const attrs = (try jsonObjGetRequired(function_obj, "Attrs", sdk_file)).Array; - const params = (try jsonObjGetRequired(function_obj, "Params", sdk_file)).Array; + const dll_import = if (func_kind == .fixed) (try jsonObjGetRequired(function_obj, "DllImport", sdk_file)).string else ""; + const return_type = (try jsonObjGetRequired(function_obj, "ReturnType", sdk_file)).object; + const return_attrs = (try jsonObjGetRequired(function_obj, "ReturnAttrs", sdk_file)).array; + const attrs = (try jsonObjGetRequired(function_obj, "Attrs", sdk_file)).array; + const params = (try jsonObjGetRequired(function_obj, "Params", sdk_file)).array; - var notnull_set = ParamModifierSet { }; + var notnull_set = ParamModifierSet{}; const func_name_pool = try global_symbol_pool.add(func_name_tmp); if (func_kind == .fixed or func_kind == .ptr) { @@ -2403,12 +2357,12 @@ fn generateFunction( } if (sdk_file.not_null_funcs.get(func_name_pool.slice)) |notnull_node| { try sdk_file.not_null_funcs_applied.put(func_name_pool, .{}); - jsonEnforce(notnull_node.Array.items.len > 0); - notnull_set.ret = @intCast(NullModifier, notnull_node.Array.items[0].Integer); - for (notnull_node.Array.items[1..], 0..) |item, i| { + jsonEnforce(notnull_node.array.items.len > 0); + notnull_set.ret = @as(NullModifier, @intCast(notnull_node.array.items[0].integer)); + for (notnull_node.array.items[1..], 0..) |item, i| { jsonEnforce(i < notnull_set.params.len); // if we hit this, increase max param count jsonEnforce(i < params.items.len); - notnull_set.params[i] = @intCast(NullModifier, item.Integer); + notnull_set.params[i] = @as(NullModifier, @intCast(item.integer)); } } } @@ -2423,7 +2377,7 @@ fn generateFunction( for (attrs.items) |attr_node| { switch (attr_node) { - .String => |attr| { + .string => |attr| { if (std.mem.eql(u8, attr, "SpecialName")) { try writer.line("// TODO: this function has a \"SpecialName\", should Zig do anything with this?"); } else jsonPanic(); @@ -2446,8 +2400,7 @@ fn generateFunction( // we modify the dll_import to be lowercase because zig generates // the .lib files using lowercase since that's what mingw uses. // note the casing only matters on case-sensitive filesystems - try writer.linef("pub extern \"{s}\" fn {s}(", .{ - fmtLower(dll_import, 100), std.zig.fmtId(func_name_tmp)}); + try writer.linef("pub extern \"{s}\" fn {s}(", .{ fmtLower(dll_import, 100), std.zig.fmtId(func_name_tmp) }); }, .ptr => |ptr_data_union| switch (ptr_data_union) { .stage1 => try writer.line(".stage1 => fn("), @@ -2475,16 +2428,14 @@ fn generateFunction( }, .both => |com_data| { if (com_data.symbol_suffix) |s| { - try writer.writef("{s}{}", .{func_name_tmp, s}, .{.nl=false}); + try writer.writef("{s}{}", .{ func_name_tmp, s }, .{ .nl = false }); } else { - try writer.writef("{s}", .{std.zig.fmtId(func_name_tmp)}, .{.nl=false}); + try writer.writef("{s}", .{std.zig.fmtId(func_name_tmp)}, .{ .nl = false }); } - try writer.write(": switch (@import(\"builtin\").zig_backend) {", .{.start=.mid}); + try writer.write(": switch (@import(\"builtin\").zig_backend) {", .{ .start = .mid }); writer.depth += 1; - try generateFunction(sdk_file, writer, function_obj, .{ .com = .{ - .stage1 = .{ .self_type = com_data.self_type } } }); - try generateFunction(sdk_file, writer, function_obj, .{ .com = .{ - .not_stage1 = .{ .self_type = com_data.self_type } } }); + try generateFunction(sdk_file, writer, function_obj, .{ .com = .{ .stage1 = .{ .self_type = com_data.self_type } } }); + try generateFunction(sdk_file, writer, function_obj, .{ .com = .{ .not_stage1 = .{ .self_type = com_data.self_type } } }); writer.depth -= 1; try writer.line("},"); return; @@ -2497,9 +2448,9 @@ fn generateFunction( try generateParams(sdk_file, writer, arches, notnull_set, params.items); - try writer.writef(") callconv(@import(\"std\").os.windows.WINAPI) ", .{}, .{.nl=false}); + try writer.writef(") callconv(@import(\"std\").os.windows.WINAPI) ", .{}, .{ .nl = false }); if (noreturn_funcs.get(func_name_tmp)) |_| { - try writer.write("noreturn", .{.start=.mid,.nl=false}); + try writer.write("noreturn", .{ .start = .mid, .nl = false }); } else { // TODO: set is_const, in and out properly const return_opts = processParamAttrs(return_attrs, .var_decl, notnull_set.ret, sdk_file); @@ -2514,7 +2465,7 @@ fn generateFunction( }, .com => ",", }; - try writer.writef("{s}", .{term}, .{.start=.mid}); + try writer.writef("{s}", .{term}, .{ .start = .mid }); } fn generateParams( @@ -2525,42 +2476,42 @@ fn generateParams( params: []const json.Value, ) !void { for (params, 0..) |*param_node_ptr, i| { - const param_obj = param_node_ptr.Object; - try jsonObjEnforceKnownFieldsOnly(param_obj, &[_][]const u8 {"Name", "Type", "Attrs"}, sdk_file); - const param_name = (try jsonObjGetRequired(param_obj, "Name", sdk_file)).String; - const param_type = (try jsonObjGetRequired(param_obj, "Type", sdk_file)).Object; + const param_obj = param_node_ptr.object; + try jsonObjEnforceKnownFieldsOnly(param_obj, &[_][]const u8{ "Name", "Type", "Attrs" }, sdk_file); + const param_name = (try jsonObjGetRequired(param_obj, "Name", sdk_file)).string; + const param_type = (try jsonObjGetRequired(param_obj, "Type", sdk_file)).object; const null_modifier = notnull_set.params[i]; - const param_options = processParamAttrs((try jsonObjGetRequired(param_obj, "Attrs", sdk_file)).Array, .var_decl, null_modifier, sdk_file); + const param_options = processParamAttrs((try jsonObjGetRequired(param_obj, "Attrs", sdk_file)).array, .var_decl, null_modifier, sdk_file); const param_type_formatter = try addTypeRefs(sdk_file, arches, param_type, param_options, null); if (param_options.optional_bytes_param_index) |bytes_param_index| { try writer.linef(" // TODO: what to do with BytesParamIndex {}?", .{bytes_param_index}); } - try writer.writef(" {s}: ", .{std.zig.fmtId(param_name)}, .{.nl=false}); + try writer.writef(" {s}: ", .{std.zig.fmtId(param_name)}, .{ .nl = false }); try generateTypeRef(sdk_file, writer, param_type_formatter); - try writer.write(",", .{.start=.mid}); + try writer.write(",", .{ .start = .mid }); } } fn generateUnicodeAliases(sdk_file: *SdkFile, writer: *CodeWriter, unicode_aliases: []json.Value) !void { - try writer.line ("const thismodule = @This();"); - try writer.linef ("pub usingnamespace switch (@import(\"{s}zig.zig\").unicode_mode) {{", .{sdk_file.getWin32DirImportPrefix()}); - try writer.line (" .ansi => struct {"); + try writer.line("const thismodule = @This();"); + try writer.linef("pub usingnamespace switch (@import(\"{s}zig.zig\").unicode_mode) {{", .{sdk_file.getWin32DirImportPrefix()}); + try writer.line(" .ansi => struct {"); for (unicode_aliases) |*alias_node_ptr| { - try writer.linef(" pub const {s} = thismodule.{0s}A;", .{alias_node_ptr.String}); + try writer.linef(" pub const {s} = thismodule.{0s}A;", .{alias_node_ptr.string}); } try writer.line(" },"); try writer.line(" .wide => struct {"); for (unicode_aliases) |*alias_node_ptr| { - try writer.linef(" pub const {s} = thismodule.{0s}W;", .{alias_node_ptr.String}); + try writer.linef(" pub const {s} = thismodule.{0s}W;", .{alias_node_ptr.string}); } try writer.line(" },"); try writer.line(" .unspecified => if (@import(\"builtin\").is_test) struct {"); for (unicode_aliases) |*alias_node_ptr| { - try writer.linef(" pub const {s} = *opaque{{}};", .{alias_node_ptr.String}); + try writer.linef(" pub const {s} = *opaque{{}};", .{alias_node_ptr.string}); } try writer.line(" } else struct {"); for (unicode_aliases) |*alias_node_ptr| { - try writer.linef(" pub const {s} = @compileError(\"'{0s}' requires that UNICODE be set to true or false in the root module\");", .{alias_node_ptr.String}); + try writer.linef(" pub const {s} = @compileError(\"'{0s}' requires that UNICODE be set to true or false in the root module\");", .{alias_node_ptr.string}); } try writer.line(" },"); try writer.line("};"); @@ -2580,10 +2531,10 @@ pub fn getFlag(arch: Arch) ArchFlags { }; } const ArchFlags = struct { - pub const X86 = ArchFlags { .flags = 0x01 }; - pub const X64 = ArchFlags { .flags = 0x02 }; - pub const Arm64 = ArchFlags { .flags = 0x04 }; - pub const all = ArchFlags { .flags = X86.flags | X64.flags | Arm64.flags }; + pub const X86 = ArchFlags{ .flags = 0x01 }; + pub const X64 = ArchFlags{ .flags = 0x02 }; + pub const Arm64 = ArchFlags{ .flags = 0x04 }; + pub const all = ArchFlags{ .flags = X86.flags | X64.flags | Arm64.flags }; flags: u8, @@ -2591,9 +2542,9 @@ const ArchFlags = struct { if (architectures.len == 0) { return ArchFlags.all; } - var result = ArchFlags { .flags = 0 }; + var result = ArchFlags{ .flags = 0 }; for (architectures) |arch_node| { - const arch = arch_name_map.get(arch_node.String) orelse std.debug.panic("unhandled arch '{s}'", .{arch_node.String}); + const arch = arch_name_map.get(arch_node.string) orelse std.debug.panic("unhandled arch '{s}'", .{arch_node.string}); result.flags |= getFlag(arch).flags; } return result; @@ -2606,7 +2557,7 @@ const ArchFlags = struct { inline for (std.meta.fields(Arch)) |arch_field| { const arch = @field(Arch, arch_field.name); if ((self.flags & getFlag(arch).flags) != 0) { - try arch_writer.print("{s}.{s}", .{case_prefix, @tagName(arch)}); + try arch_writer.print("{s}.{s}", .{ case_prefix, @tagName(arch) }); case_prefix = ", "; } } @@ -2657,7 +2608,7 @@ fn jsonObjGetRequired(map: json.ObjectMap, field: []const u8, file_thing: anytyp fn jsonObjGetRequiredImpl(map: json.ObjectMap, field: []const u8, file_for_error: []const u8) !json.Value { return map.get(field) orelse { // TODO: print file location? - std.debug.print("{s}: json object is missing '{s}' field: {}\n", .{file_for_error, field, fmtJson(map)}); + std.debug.print("{s}: json object is missing '{s}' field: {}\n", .{ file_for_error, field, fmtJson(map) }); jsonPanic(); }; } @@ -2665,12 +2616,12 @@ fn jsonObjGetRequiredImpl(map: json.ObjectMap, field: []const u8, file_for_error // TODO: this should probably be in std.json pub fn jsonEql(a: json.Value, b: json.Value) bool { switch (a) { - .Integer => |a_val| switch (b) { - .Integer => |b_val| return a_val == b_val, + .integer => |a_val| switch (b) { + .integer => |b_val| return a_val == b_val, else => return false, }, - .NumberString => |a_val| switch (b) { - .NumberString => |b_val| return std.mem.eql(u8, a_val, b_val), + .number_string => |a_val| switch (b) { + .number_string => |b_val| return std.mem.eql(u8, a_val, b_val), else => return false, }, else => @panic("not impl"), @@ -2764,29 +2715,29 @@ pub const FmtParamId = struct { } }; pub fn fmtParamId(s: []const u8, avoid_lookup: AvoidLookupFn) FmtParamId { - return FmtParamId { .s = s, .avoid_lookup = avoid_lookup }; + return FmtParamId{ .s = s, .avoid_lookup = avoid_lookup }; } -pub fn FmtLower(comptime buffer_size: comptime_int) type { return struct { - s: []const u8, - pub fn format( - self: @This(), - comptime fmt: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - _ = fmt; - _ = options; - var buffered = std.io.BufferedWriter(buffer_size, @TypeOf(writer)) { - .unbuffered_writer = writer - }; - for (self.s) |c| { - const lower = [_]u8 { std.ascii.toLower(c) }; - try buffered.writer().writeAll(&lower); +pub fn FmtLower(comptime buffer_size: comptime_int) type { + return struct { + s: []const u8, + pub fn format( + self: @This(), + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = fmt; + _ = options; + var buffered = std.io.BufferedWriter(buffer_size, @TypeOf(writer)){ .unbuffered_writer = writer }; + for (self.s) |c| { + const lower = [_]u8{std.ascii.toLower(c)}; + try buffered.writer().writeAll(&lower); + } + try buffered.flush(); } - try buffered.flush(); - } -};} + }; +} pub fn fmtLower(s: []const u8, comptime buffer_size: comptime_int) FmtLower(buffer_size) { return .{ .s = s }; } @@ -2794,10 +2745,10 @@ pub fn fmtLower(s: []const u8, comptime buffer_size: comptime_int) FmtLower(buff fn cleanDir(dir: std.fs.Dir, sub_path: []const u8) !void { try dir.deleteTree(sub_path); const MAX_ATTEMPTS = 30; - var attempt : u32 = 1; + var attempt: u32 = 1; while (true) : (attempt += 1) { if (attempt > MAX_ATTEMPTS) - fatal("failed to delete '{s}' after {} attempts", .{sub_path, MAX_ATTEMPTS}); + fatal("failed to delete '{s}' after {} attempts", .{ sub_path, MAX_ATTEMPTS }); // ERROR: windows.OpenFile is not handling error.Unexpected NTSTATUS=0xc0000056 dir.makeDir(sub_path) catch |e| switch (e) { @@ -2809,7 +2760,6 @@ fn cleanDir(dir: std.fs.Dir, sub_path: []const u8) !void { }; break; } - } fn withoutCrLen(s: []const u8) usize { @@ -2832,3 +2782,82 @@ fn removeCr(comptime s: []const u8) *const [withoutCrLen(s):0]u8 { return &without_cr; } } + +pub fn ComptimeStringMapQuota(comptime V: type, comptime kvs_list: anytype, comptime limit: u32) type { + const precomputed = comptime blk: { + @setEvalBranchQuota(limit); + const KV = struct { + key: []const u8, + value: V, + }; + var sorted_kvs: [kvs_list.len]KV = undefined; + for (kvs_list, 0..) |kv, i| { + if (V != void) { + sorted_kvs[i] = .{ .key = kv.@"0", .value = kv.@"1" }; + } else { + sorted_kvs[i] = .{ .key = kv.@"0", .value = {} }; + } + } + + const SortContext = struct { + kvs: []KV, + + pub fn lessThan(ctx: @This(), a: usize, b: usize) bool { + return ctx.kvs[a].key.len < ctx.kvs[b].key.len; + } + + pub fn swap(ctx: @This(), a: usize, b: usize) void { + return std.mem.swap(KV, &ctx.kvs[a], &ctx.kvs[b]); + } + }; + std.mem.sortUnstableContext(0, sorted_kvs.len, SortContext{ .kvs = &sorted_kvs }); + + const min_len = sorted_kvs[0].key.len; + const max_len = sorted_kvs[sorted_kvs.len - 1].key.len; + var len_indexes: [max_len + 1]usize = undefined; + var len: usize = 0; + var i: usize = 0; + while (len <= max_len) : (len += 1) { + // find the first keyword len == len + while (len > sorted_kvs[i].key.len) { + i += 1; + } + len_indexes[len] = i; + } + break :blk .{ + .min_len = min_len, + .max_len = max_len, + .sorted_kvs = sorted_kvs, + .len_indexes = len_indexes, + }; + }; + + return struct { + /// Array of `struct { key: []const u8, value: V }` where `value` is `void{}` if `V` is `void`. + /// Sorted by `key` length. + pub const kvs = precomputed.sorted_kvs; + + /// Checks if the map has a value for the key. + pub fn has(str: []const u8) bool { + return get(str) != null; + } + + /// Returns the value for the key if any, else null. + pub fn get(str: []const u8) ?V { + if (str.len < precomputed.min_len or str.len > precomputed.max_len) + return null; + + var i = precomputed.len_indexes[str.len]; + while (true) { + const kv = precomputed.sorted_kvs[i]; + if (kv.key.len != str.len) + return null; + if (std.mem.eql(u8, kv.key, str)) + return kv.value; + i += 1; + if (i >= precomputed.sorted_kvs.len) + return null; + } + } + }; +} diff --git a/src/handletypes.zig b/src/handletypes.zig index b25b937..0f30c96 100644 --- a/src/handletypes.zig +++ b/src/handletypes.zig @@ -7,7 +7,7 @@ pub const std_handle_types = std.ComptimeStringMap([]const u8, .{ }); pub const handle_types = list: { @setEvalBranchQuota(3000); - break :list std.ComptimeStringMap(struct{}, .{ + break :list std.ComptimeStringMap(struct {}, .{ .{ "HICON", .{} }, .{ "HCURSOR", .{} }, .{ "HBRUSH", .{} }, diff --git a/src/pass1.zig b/src/pass1.zig index 0c7a53e..e11989e 100644 --- a/src/pass1.zig +++ b/src/pass1.zig @@ -28,11 +28,9 @@ pub fn main() !u8 { var win32json_dir = try std.fs.cwd().openDir(win32json_path, .{}); defer win32json_dir.close(); - { const need_update = blk: { - const dest_mtime = (try common.getModifyTime(std.fs.cwd(), "pass1.json")) - orelse break :blk true; + const dest_mtime = (try common.getModifyTime(std.fs.cwd(), "pass1.json")) orelse break :blk true; break :blk try common.win32jsonIsNewerThan(win32json_dir, dest_mtime); }; if (!need_update) { @@ -41,7 +39,7 @@ pub fn main() !u8 { } } - var api_dir = try win32json_dir.openIterableDir("api", .{}) ; + var api_dir = try win32json_dir.openIterableDir("api", .{}); defer api_dir.close(); var api_list = std.ArrayList([]const u8).init(allocator); @@ -54,11 +52,11 @@ pub fn main() !u8 { try common.readApiList(api_dir, &api_list); // sort so our data is always in the same order - std.sort.sort([]const u8, api_list.items, Nothing {}, common.asciiLessThanIgnoreCase); + std.sort.block([]const u8, api_list.items, Nothing{}, common.asciiLessThanIgnoreCase); const out_file = try std.fs.cwd().createFile("pass1.json.generating", .{}); defer out_file.close(); - var buffered_writer = BufferedWriter{ + var buffered_writer = BufferedWriter{ .unbuffered_writer = out_file.writer(), }; const out = buffered_writer.writer(); @@ -67,8 +65,8 @@ pub fn main() !u8 { var json_obj_prefix: []const u8 = ""; for (api_list.items) |api_json_basename| { - const name = api_json_basename[0..api_json_basename.len-5]; - try out.print(" {s}\"{s}\": {{\n", .{json_obj_prefix, name}); + const name = api_json_basename[0 .. api_json_basename.len - 5]; + try out.print(" {s}\"{s}\": {{\n", .{ json_obj_prefix, name }); var file = try api_dir.dir.openFile(api_json_basename, .{}); defer file.close(); try pass1OnFile(out, api_json_basename, file); @@ -88,29 +86,28 @@ fn pass1OnFile(out: OutWriter, filename: []const u8, file: std.fs.File) !void { const parse_start = std.time.milliTimestamp(); const start = if (std.mem.startsWith(u8, content, "\xEF\xBB\xBF")) 3 else @as(usize, 0); var json_tree = blk: { - var parser = json.Parser.init(allocator, false); // false is copy_strings + var parser = json.Scanner.initCompleteInput(allocator, content[start..]); // false is copy_strings defer parser.deinit(); - break :blk try parser.parse(content[start..]); + break :blk try json.Value.jsonParse(allocator, &parser, .{}); }; - defer json_tree.deinit(); const parse_time = std.time.milliTimestamp() - parse_start; - std.log.info("{} ms: parse time for '{s}'", .{parse_time, filename}); + std.log.info("{} ms: parse time for '{s}'", .{ parse_time, filename }); - try pass1OnJson(out, filename, json_tree.root.Object); + try pass1OnJson(out, filename, json_tree.object); } fn writeType(out: OutWriter, json_obj_prefix: []const u8, name: []const u8, kind: []const u8) !void { - try out.print(" {s}\"{s}\": {{\"Kind\":\"{s}\"}}\n", .{json_obj_prefix, name, kind}); + try out.print(" {s}\"{s}\": {{\"Kind\":\"{s}\"}}\n", .{ json_obj_prefix, name, kind }); } fn pass1OnJson(out: OutWriter, filename: []const u8, root_obj: json.ObjectMap) !void { - const types_array = (try jsonObjGetRequired(root_obj, "Types", filename)).Array; + const types_array = (try jsonObjGetRequired(root_obj, "Types", filename)).array; var json_obj_prefix: []const u8 = ""; for (types_array.items) |*type_node| { - const type_obj = type_node.Object; - const kind = (try jsonObjGetRequired(type_obj, "Kind", filename)).String; - const name = (try jsonObjGetRequired(type_obj, "Name", filename)).String; + const type_obj = type_node.object; + const kind = (try jsonObjGetRequired(type_obj, "Kind", filename)).string; + const name = (try jsonObjGetRequired(type_obj, "Name", filename)).string; //const arches = ArchFlags.initJson((try jsonObjGetRequired(type_obj, "Architectures", filename)).Array.items); if (std.mem.eql(u8, kind, "ComClassID")) { @@ -130,7 +127,7 @@ fn pass1OnJson(out: OutWriter, filename: []const u8, root_obj: json.ObjectMap) ! } else if (std.mem.eql(u8, kind, "Com")) { try writeType(out, json_obj_prefix, name, "Com"); } else { - jsonPanicMsg("{s}: unknown type Kind '{s}'", .{filename, kind}); + jsonPanicMsg("{s}: unknown type Kind '{s}'", .{ filename, kind }); } json_obj_prefix = ","; } @@ -138,9 +135,11 @@ fn pass1OnJson(out: OutWriter, filename: []const u8, root_obj: json.ObjectMap) ! const native_integral_types = std.ComptimeStringMap(Nothing, .{ .{ "Byte", .{} }, - .{ "Int32", .{} }, .{ "UInt32", .{} }, + .{ "Int32", .{} }, + .{ "UInt32", .{} }, .{ "UInt64", .{} }, - .{ "IntPtr", .{} }, .{ "UIntPtr", .{} }, + .{ "IntPtr", .{} }, + .{ "UIntPtr", .{} }, }); fn generateNativeTypedef( @@ -150,15 +149,14 @@ fn generateNativeTypedef( type_obj: std.json.ObjectMap, name: []const u8, ) !void { - try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8 {"Name", "Platform", "Architectures", - "AlsoUsableFor", "Kind", "Def", "FreeFunc"}, filename); + try jsonObjEnforceKnownFieldsOnly(type_obj, &[_][]const u8{ "Name", "Platform", "Architectures", "AlsoUsableFor", "Kind", "Def", "FreeFunc" }, filename); //const platform_node = try jsonObjGetRequired(type_obj, "Platform", sdk_file); //const also_usable_for_node = try jsonObjGetRequired(type_obj, "AlsoUsableFor", sdk_file); - const def_type = (try jsonObjGetRequired(type_obj, "Def", filename)).Object; + const def_type = (try jsonObjGetRequired(type_obj, "Def", filename)).object; // HANDLE PSTR and PWSTR specially because win32metadata is not properly declaring them as arrays, only pointers // not sure if this is a real issue with the metadata or intentional - const special : enum { pstr, pwstr, other } = blk: { + const special: enum { pstr, pwstr, other } = blk: { if (std.mem.eql(u8, name, "PSTR")) break :blk .pstr; if (std.mem.eql(u8, name, "PWSTR")) break :blk .pwstr; break :blk .other; @@ -170,7 +168,7 @@ fn generateNativeTypedef( // we should be able to ignore also_usable_for_node because the def_type should be the same as the type being defined //switch (also_usable_for_node) { - // .String => |also_usable_for| { + // .string => |also_usable_for| { // if (also_usable_type_api_map.get(also_usable_for)) |api| { // try sdk_file.addApiImport(arches, also_usable_for, api, json.Array { .items = &[_]json.Value{}, .capacity = 0, .allocator = allocator }); // try writer.linef("//TODO: type '{s}' is \"AlsoUsableFor\" '{s}' which means this type is implicitly", .{tmp_name, also_usable_for}); @@ -181,7 +179,7 @@ fn generateNativeTypedef( // } else std.debug.panic("AlsoUsableFor type '{s}' is missing from alsoUsableForApiMap", .{also_usable_for}); // return; // }, - // .Null => {}, + // .null => {}, // else => jsonPanic(), //} @@ -197,10 +195,10 @@ fn generateNativeTypedef( return; } - const kind = (try jsonObjGetRequired(def_type, "Kind", filename)).String; + const kind = (try jsonObjGetRequired(def_type, "Kind", filename)).string; if (std.mem.eql(u8, kind, "Native")) { - try jsonObjEnforceKnownFieldsOnly(def_type, &[_][]const u8 {"Kind", "Name"}, filename); - const native_type_name = (try jsonObjGetRequired(def_type, "Name", filename)).String; + try jsonObjEnforceKnownFieldsOnly(def_type, &[_][]const u8{ "Kind", "Name" }, filename); + const native_type_name = (try jsonObjGetRequired(def_type, "Name", filename)).string; if (native_integral_types.get(native_type_name)) |_| { try writeType(out, json_obj_prefix, name, "Integral"); return; @@ -219,7 +217,7 @@ fn generateNativeTypedef( fn jsonObjGetRequired(map: json.ObjectMap, field: []const u8, file_for_error: []const u8) !json.Value { return map.get(field) orelse { // TODO: print file location? - std.log.err("{s}: json object is missing '{s}' field: {}\n", .{file_for_error, field, fmtJson(map)}); + std.log.err("{s}: json object is missing '{s}' field: {}\n", .{ file_for_error, field, fmtJson(map) }); common.jsonPanic(); }; } diff --git a/src/stringpool.zig b/src/stringpool.zig index 3d2f1b7..8efdff0 100644 --- a/src/stringpool.zig +++ b/src/stringpool.zig @@ -25,7 +25,7 @@ pub const StringPool = struct { allocator: std.mem.Allocator, map: StringHashMap(Val), pub fn init(allocator: std.mem.Allocator) @This() { - return @This() { + return @This(){ .allocator = allocator, .map = StringHashMap(Val).init(allocator), }; @@ -49,7 +49,7 @@ pub const StringPool = struct { } var newString = try self.allocator.alloc(u8, s.len); std.mem.copy(u8, newString, s); - const val = Val { .slice = newString }; + const val = Val{ .slice = newString }; _ = try self.map.put(newString, val); return val; } @@ -68,7 +68,7 @@ pub const StringPool = struct { pub const HashContext = struct { pub fn hash(self: HashContext, s: Val) u64 { _ = self; - return std.hash.Wyhash.hash(0, @ptrCast([*]const u8, &s.slice.ptr)[0..@sizeOf(usize)]); + return std.hash.Wyhash.hash(0, @as([*]const u8, @ptrCast(&s.slice.ptr))[0..@sizeOf(usize)]); } pub fn eql(self: HashContext, a: Val, b: Val) bool { _ = self; @@ -78,7 +78,7 @@ pub const StringPool = struct { pub const ArrayHashContext = struct { pub fn hash(self: @This(), s: Val) u32 { _ = self; - return @truncate(u32, std.hash.Wyhash.hash(0, @ptrCast([*]const u8, &s.slice.ptr)[0..@sizeOf(usize)])); + return @as(u32, @truncate(std.hash.Wyhash.hash(0, @as([*]const u8, @ptrCast(&s.slice.ptr))[0..@sizeOf(usize)]))); } pub fn eql(self: @This(), a: Val, b: Val, index: usize) bool { _ = self; @@ -92,13 +92,12 @@ pub const StringPool = struct { } }; -test "stringpool" -{ +test "stringpool" { var pool = StringPool.init(std.testing.allocator); defer pool.deinit(); const s = try pool.add("hello"); { - var buf : [5]u8 = undefined; + var buf: [5]u8 = undefined; std.mem.copy(u8, buf[0..], "hello"); const s2 = try pool.add(buf[0..]); try std.testing.expect(s.slice.ptr == s2.slice.ptr); diff --git a/src/windowlongptr.zig b/src/windowlongptr.zig index 7e8ca2f..e117e95 100644 --- a/src/windowlongptr.zig +++ b/src/windowlongptr.zig @@ -25,11 +25,10 @@ pub usingnamespace switch (@import("zig.zig").unicode_mode) { pub const GetWindowLongPtr = thismodule.GetWindowLongPtrW; }, .unspecified => if (@import("builtin").is_test) struct { - pub const SetWindowLongPtr = *opaque{}; - pub const GetWindowLongPtr = *opaque{}; + pub const SetWindowLongPtr = *opaque {}; + pub const GetWindowLongPtr = *opaque {}; } else struct { pub const SetWindowLongPtr = @compileError("'SetWindowLongPtr' requires that UNICODE be set to true or false in the root module"); pub const GetWindowLongPtr = @compileError("'GetWindowLongPtr' requires that UNICODE be set to true or false in the root module"); }, }; - diff --git a/src/zig.zig b/src/zig.zig index c0075b4..9d11658 100644 --- a/src/zig.zig +++ b/src/zig.zig @@ -15,13 +15,15 @@ pub const L = std.unicode.utf8ToUtf16LeStringLiteral; pub usingnamespace switch (unicode_mode) { .ansi => struct { pub const TCHAR = u8; - pub fn _T(comptime str: []const u8) *const [str.len:0]u8 { return str; } + pub fn _T(comptime str: []const u8) *const [str.len:0]u8 { + return str; + } }, .wide => struct { pub const TCHAR = u16; pub const _T = L; }, - .unspecified => if (builtin.is_test) struct { } else struct { + .unspecified => if (builtin.is_test) struct {} else struct { pub const TCHAR = @compileError("'TCHAR' requires that UNICODE be set to true or false in the root module"); pub const _T = @compileError("'_T' requires that UNICODE be set to true or false in the root module"); }, @@ -45,47 +47,43 @@ pub const Guid = extern union { }, Bytes: [16]u8, - const big_endian_hex_offsets = [16] u6 {0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34}; - const little_endian_hex_offsets = [16] u6 { - 6, 4, 2, 0, - 11, 9, - 16, 14, - 19, 21, 24, 26, 28, 30, 32, 34}; + const big_endian_hex_offsets = [16]u6{ 0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34 }; + const little_endian_hex_offsets = [16]u6{ 6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 24, 26, 28, 30, 32, 34 }; const hex_offsets = switch (builtin.target.cpu.arch.endian()) { .Big => big_endian_hex_offsets, .Little => little_endian_hex_offsets, }; pub fn initString(s: []const u8) Guid { - var guid = Guid { .Bytes = undefined }; + var guid = Guid{ .Bytes = undefined }; for (hex_offsets, 0..) |hex_offset, i| { //guid.Bytes[i] = decodeHexByte(s[offset..offset+2]); - guid.Bytes[i] = decodeHexByte([2]u8 { s[hex_offset], s[hex_offset+1] }); + guid.Bytes[i] = decodeHexByte([2]u8{ s[hex_offset], s[hex_offset + 1] }); } return guid; } }; -comptime { std.debug.assert(@sizeOf(Guid) == 16); } +comptime { + std.debug.assert(@sizeOf(Guid) == 16); +} // TODO: is this in the standard lib somewhere? fn hexVal(c: u8) u4 { - if (c <= '9') return @intCast(u4, c - '0'); - if (c >= 'a') return @intCast(u4, c + 10 - 'a'); - return @intCast(u4, c + 10 - 'A'); + if (c <= '9') return @as(u4, @intCast(c - '0')); + if (c >= 'a') return @as(u4, @intCast(c + 10 - 'a')); + return @as(u4, @intCast(c + 10 - 'A')); } // TODO: is this in the standard lib somewhere? fn decodeHexByte(hex: [2]u8) u8 { - return @intCast(u8, hexVal(hex[0])) << 4 | hexVal(hex[1]); + return @as(u8, @intCast(hexVal(hex[0]))) << 4 | hexVal(hex[1]); } test "Guid" { - try testing.expect(std.mem.eql(u8, - switch (builtin.target.cpu.arch.endian()) { - .Big => "\x01\x23\x45\x67\x89\xAB\xEF\x10\x32\x54\x76\x98\xba\xdc\xfe\x91", - .Little => "\x67\x45\x23\x01\xAB\x89\x10\xEF\x32\x54\x76\x98\xba\xdc\xfe\x91" - }, - &Guid.initString("01234567-89AB-EF10-3254-7698badcfe91").Bytes)); + try testing.expect(std.mem.eql(u8, switch (builtin.target.cpu.arch.endian()) { + .Big => "\x01\x23\x45\x67\x89\xAB\xEF\x10\x32\x54\x76\x98\xba\xdc\xfe\x91", + .Little => "\x67\x45\x23\x01\xAB\x89\x10\xEF\x32\x54\x76\x98\xba\xdc\xfe\x91", + }, &Guid.initString("01234567-89AB-EF10-3254-7698badcfe91").Bytes)); } pub const PropertyKey = extern struct { @@ -108,8 +106,8 @@ pub fn SUCCEEDED(hr: @import("foundation.zig").HRESULT) bool { // These constants were removed from the metadata to allow each projection // to define them however they like (see https://github.com/microsoft/win32metadata/issues/530) -pub const FALSE : @import("foundation.zig").BOOL = 0; -pub const TRUE : @import("foundation.zig").BOOL = 1; +pub const FALSE: @import("foundation.zig").BOOL = 0; +pub const TRUE: @import("foundation.zig").BOOL = 1; /// Converts comptime values to the given type. /// Note that this function is called at compile time rather than converting constant values earlier at code generation time. @@ -128,8 +126,8 @@ pub fn typedConst2(comptime ReturnType: type, comptime SwitchType: type, comptim .Int => |target_type_info| { if (value >= std.math.maxInt(SwitchType)) { if (target_type_info.signedness == .signed) { - const UnsignedT = @Type(std.builtin.Type { .Int = .{ .signedness = .unsigned, .bits = target_type_info.bits }}); - return @bitCast(SwitchType, @as(UnsignedT, value)); + const UnsignedT = @Type(std.builtin.Type{ .Int = .{ .signedness = .unsigned, .bits = target_type_info.bits } }); + return @as(SwitchType, @bitCast(@as(UnsignedT, value))); } } return value; @@ -138,28 +136,28 @@ pub fn typedConst2(comptime ReturnType: type, comptime SwitchType: type, comptim .One, .Many, .C => { switch (@typeInfo(@TypeOf(value))) { .ComptimeInt, .Int => { - const usize_value = if (value >= 0) value else @bitCast(usize, @as(isize, value)); - return @intToPtr(ReturnType, usize_value); + const usize_value = if (value >= 0) value else @as(usize, @bitCast(@as(isize, value))); + return @as(ReturnType, @ptrFromInt(usize_value)); }, else => @compileError(value_type_error), } }, else => target_type_error, }, - .Optional => |target_type_info| switch(@typeInfo(target_type_info.child)) { + .Optional => |target_type_info| switch (@typeInfo(target_type_info.child)) { .Pointer => return typedConst2(ReturnType, target_type_info.child, value), else => target_type_error, }, - .Enum => |_| switch(@typeInfo(@TypeOf(value))) { - .Int => return @intToEnum(ReturnType, value), + .Enum => |_| switch (@typeInfo(@TypeOf(value))) { + .Int => return @as(ReturnType, @enumFromInt(value)), else => target_type_error, }, else => @compileError(target_type_error), } } test "typedConst" { - try testing.expectEqual(@bitCast(usize, @as(isize, -1)), @ptrToInt(typedConst(?*opaque{}, -1))); - try testing.expectEqual(@bitCast(usize, @as(isize, -12)), @ptrToInt(typedConst(?*opaque{}, -12))); + try testing.expectEqual(@as(usize, @bitCast(@as(isize, -1))), @intFromPtr(typedConst(?*opaque {}, -1))); + try testing.expectEqual(@as(usize, @bitCast(@as(isize, -12))), @intFromPtr(typedConst(?*opaque {}, -12))); try testing.expectEqual(@as(u32, 0xffffffff), typedConst(u32, 0xffffffff)); - try testing.expectEqual(@bitCast(i32, @as(u32, 0x80000000)), typedConst(i32, 0x80000000)); + try testing.expectEqual(@as(i32, @bitCast(@as(u32, 0x80000000))), typedConst(i32, 0x80000000)); } From 2844ef8a414427d3ff88f8922514c90ccd4baaf6 Mon Sep 17 00:00:00 2001 From: rimuspp <19101das@gmail.com> Date: Thu, 6 Jul 2023 21:41:34 -0500 Subject: [PATCH 2/2] Updated examples --- examples/basewin.zig | 128 ++++++++++++++------------- examples/build.zig | 2 +- examples/d2dcircle.zig | 157 ++++++++++++++++----------------- examples/helloworld-window.zig | 52 +++++------ examples/helloworld.zig | 6 +- examples/net.zig | 2 +- examples/opendialog.zig | 26 +++--- examples/wasapi.zig | 16 ++-- 8 files changed, 182 insertions(+), 207 deletions(-) diff --git a/examples/basewin.zig b/examples/basewin.zig index 6e22a1d..9dc3718 100644 --- a/examples/basewin.zig +++ b/examples/basewin.zig @@ -18,73 +18,77 @@ const windowlongptr = @import("win32").windowlongptr; // NOTE: should Zig allow symbol conflicts so long as they are not referenced? const mnr = @import("win32").ui.menus_and_resources; -pub fn BaseWindow(comptime DERIVED_TYPE: type) type { return struct { - - fn WindowProc(hwnd: HWND , uMsg: u32, wParam: win32.WPARAM, lParam: win32.LPARAM) callconv(WINAPI) win32.LRESULT - { - var pThis : ?*DERIVED_TYPE = null; - if (uMsg == win32.WM_NCCREATE) - { - const pCreate = @intToPtr(*win32.CREATESTRUCT, @bitCast(usize, lParam)); - pThis = @ptrCast(*DERIVED_TYPE, @alignCast(@alignOf(DERIVED_TYPE), pCreate.lpCreateParams)); - _ = windowlongptr.SetWindowLongPtr(hwnd, win32.GWL_USERDATA, @bitCast(isize, @ptrToInt(pThis))); - pThis.?.base.m_hwnd = hwnd; - } - else - { - pThis = @intToPtr(?*DERIVED_TYPE, @bitCast(usize, windowlongptr.GetWindowLongPtr(hwnd, win32.GWL_USERDATA))); - } - if (pThis) |this| - { - return this.HandleMessage(uMsg, wParam, lParam); +pub fn BaseWindow(comptime DERIVED_TYPE: type) type { + return struct { + fn WindowProc(hwnd: HWND, uMsg: u32, wParam: win32.WPARAM, lParam: win32.LPARAM) callconv(WINAPI) win32.LRESULT { + var pThis: ?*DERIVED_TYPE = null; + if (uMsg == win32.WM_NCCREATE) { + const pCreate = @as(*win32.CREATESTRUCT, @ptrFromInt(@as(usize, @bitCast(lParam)))); + pThis = @as(*DERIVED_TYPE, @ptrCast(@alignCast(pCreate.lpCreateParams))); + _ = windowlongptr.SetWindowLongPtr(hwnd, win32.GWL_USERDATA, @as(isize, @bitCast(@intFromPtr(pThis)))); + pThis.?.base.m_hwnd = hwnd; + } else { + pThis = @as(?*DERIVED_TYPE, @ptrFromInt(@as(usize, @bitCast(windowlongptr.GetWindowLongPtr(hwnd, win32.GWL_USERDATA))))); + } + if (pThis) |this| { + return this.HandleMessage(uMsg, wParam, lParam); + } else { + return win32.DefWindowProc(hwnd, uMsg, wParam, lParam); + } } - else - { - return win32.DefWindowProc(hwnd, uMsg, wParam, lParam); - } - } - pub fn Create(self: *@This(), - lpWindowName: [*:0]const u16, - dwStyle: win32.WINDOW_STYLE, - options: struct { - dwExStyle: win32.WINDOW_EX_STYLE = @intToEnum(win32.WINDOW_EX_STYLE, 0), - x: i32 = win32.CW_USEDEFAULT, - y: i32 = win32.CW_USEDEFAULT, - nWidth: i32 = win32.CW_USEDEFAULT, - nHeight: i32 = win32.CW_USEDEFAULT, - hWndParent: ?HWND = null, - hMenu: ?win32.HMENU = null, - }, - ) win32.BOOL { - const wc = win32.WNDCLASS { - .style = @intToEnum(win32.WNDCLASS_STYLES, 0), - .lpfnWndProc = WindowProc, - .cbClsExtra = 0, - .cbWndExtra = 0, - .hInstance = win32.GetModuleHandle(null), - .hIcon = null, - .hCursor = null, - .hbrBackground = null, - // TODO: autogen bindings don't allow for null, should win32metadata allow Option for fields? Or should all strings allow NULL? - .lpszMenuName = L("Placeholder"), - .lpszClassName = DERIVED_TYPE.ClassName(), - }; + pub fn Create( + self: *@This(), + lpWindowName: [*:0]const u16, + dwStyle: win32.WINDOW_STYLE, + options: struct { + dwExStyle: win32.WINDOW_EX_STYLE = @enumFromInt(0), + x: i32 = win32.CW_USEDEFAULT, + y: i32 = win32.CW_USEDEFAULT, + nWidth: i32 = win32.CW_USEDEFAULT, + nHeight: i32 = win32.CW_USEDEFAULT, + hWndParent: ?HWND = null, + hMenu: ?win32.HMENU = null, + }, + ) win32.BOOL { + const wc = win32.WNDCLASS{ + .style = @as(win32.WNDCLASS_STYLES, @enumFromInt(0)), + .lpfnWndProc = WindowProc, + .cbClsExtra = 0, + .cbWndExtra = 0, + .hInstance = win32.GetModuleHandle(null), + .hIcon = null, + .hCursor = null, + .hbrBackground = null, + // TODO: autogen bindings don't allow for null, should win32metadata allow Option for fields? Or should all strings allow NULL? + .lpszMenuName = L("Placeholder"), + .lpszClassName = DERIVED_TYPE.ClassName(), + }; - _ = win32.RegisterClass(&wc); + _ = win32.RegisterClass(&wc); - self.m_hwnd = win32.CreateWindowEx( - options.dwExStyle, DERIVED_TYPE.ClassName(), lpWindowName, - dwStyle, options.x, options.y, - options.nWidth, options.nHeight, options.hWndParent, options.hMenu, - win32.GetModuleHandle(null), - @ptrCast(*anyopaque, self) + self.m_hwnd = win32.CreateWindowEx( + options.dwExStyle, + DERIVED_TYPE.ClassName(), + lpWindowName, + dwStyle, + options.x, + options.y, + options.nWidth, + options.nHeight, + options.hWndParent, + options.hMenu, + win32.GetModuleHandle(null), + @ptrCast(self), ); - return if (self.m_hwnd != null) win32.TRUE else win32.FALSE; - } + return if (self.m_hwnd != null) win32.TRUE else win32.FALSE; + } - pub fn Window(self: @This()) ?HWND { return self.m_hwnd; } + pub fn Window(self: @This()) ?HWND { + return self.m_hwnd; + } - m_hwnd: ?HWND = null, -};} + m_hwnd: ?HWND = null, + }; +} diff --git a/examples/build.zig b/examples/build.zig index 09d6922..384031c 100644 --- a/examples/build.zig +++ b/examples/build.zig @@ -37,7 +37,7 @@ fn makeExe( ) !void { const exe = b.addExecutable(.{ .name = root, - .root_source_file = .{ .path = try std.mem.concat(b.allocator, u8, &[_][]const u8 {root, ".zig"}) }, + .root_source_file = .{ .path = try std.mem.concat(b.allocator, u8, &[_][]const u8{ root, ".zig" }) }, .target = target, .optimize = optimize, }); diff --git a/examples/d2dcircle.zig b/examples/d2dcircle.zig index 9bc54c4..bc12ac8 100644 --- a/examples/d2dcircle.zig +++ b/examples/d2dcircle.zig @@ -46,13 +46,25 @@ const MainWindow = struct { pBrush: ?*win32.ID2D1SolidColorBrush = null, ellipse: win32.D2D1_ELLIPSE = undefined, - pub fn CalculateLayout(self: *MainWindow) callconv(.Inline) void { MainWindowCalculateLayout(self); } - pub fn CreateGraphicsResources(self: *MainWindow) callconv(.Inline) HRESULT { return MainWindowCreateGraphicsResources(self); } - pub fn DiscardGraphicsResources(self: *MainWindow) callconv(.Inline) void { MainWindowDiscardGraphicsResources(self); } - pub fn OnPaint(self: *MainWindow) callconv(.Inline) void { MainWindowOnPaint(self); } - pub fn Resize(self: *MainWindow) callconv(.Inline) void { MainWindowResize(self); } + pub inline fn CalculateLayout(self: *MainWindow) void { + MainWindowCalculateLayout(self); + } + pub inline fn CreateGraphicsResources(self: *MainWindow) HRESULT { + return MainWindowCreateGraphicsResources(self); + } + pub inline fn DiscardGraphicsResources(self: *MainWindow) void { + MainWindowDiscardGraphicsResources(self); + } + pub inline fn OnPaint(self: *MainWindow) void { + MainWindowOnPaint(self); + } + pub inline fn Resize(self: *MainWindow) void { + MainWindowResize(self); + } - pub fn ClassName() [*:0]const u16 { return L("Circle Window Class"); } + pub fn ClassName() [*:0]const u16 { + return L("Circle Window Class"); + } pub fn HandleMessage(self: *MainWindow, uMsg: u32, wParam: WPARAM, lParam: LPARAM) LRESULT { return MainWindowHandleMessage(self, uMsg, wParam, lParam); @@ -69,38 +81,32 @@ fn MainWindowCalculateLayout(self: *MainWindow) void { // Zig unable to handle a return type of extern struct { x: f32, y: f32 } for WINAPI _ = pRenderTarget; //const size: D2D_SIZE_F = pRenderTarget.ID2D1RenderTarget_GetSize(); - const size = D2D_SIZE_F { .width = 300, .height = 300 }; + const size = D2D_SIZE_F{ .width = 300, .height = 300 }; const x: f32 = size.width / 2; const y: f32 = size.height / 2; - const radius = @import("std").math.min(x, y); + const radius = @min(x, y); self.ellipse = D2D1.Ellipse(D2D1.Point2F(x, y), radius, radius); } } -fn MainWindowCreateGraphicsResources(self: *MainWindow) HRESULT -{ +fn MainWindowCreateGraphicsResources(self: *MainWindow) HRESULT { var hr = win32.S_OK; - if (self.pRenderTarget == null) - { + if (self.pRenderTarget == null) { var rc: RECT = undefined; _ = win32.GetClientRect(self.base.m_hwnd.?, &rc); - const size = D2D_SIZE_U{ .width = @intCast(u32, rc.right), .height = @intCast(u32, rc.bottom) }; + const size = D2D_SIZE_U{ .width = @intCast(rc.right), .height = @intCast(rc.bottom) }; - hr = self.pFactory.?.ID2D1Factory_CreateHwndRenderTarget( - &D2D1.RenderTargetProperties(), - &D2D1.HwndRenderTargetProperties(self.base.m_hwnd.?, size), - // TODO: figure out how to cast a COM object to a base type - @ptrCast(*?*win32.ID2D1HwndRenderTarget, &self.pRenderTarget)); + hr = self.pFactory.?.ID2D1Factory_CreateHwndRenderTarget(&D2D1.RenderTargetProperties(), &D2D1.HwndRenderTargetProperties(self.base.m_hwnd.?, size), + // TODO: figure out how to cast a COM object to a base type + @ptrCast(&self.pRenderTarget)); - if (SUCCEEDED(hr)) - { - const color = D2D1.ColorF(.{ .r = 1, .g = 1, .b = 0}); + if (SUCCEEDED(hr)) { + const color = D2D1.ColorF(.{ .r = 1, .g = 1, .b = 0 }); // TODO: how do I do this ptrCast better by using COM base type? - hr = self.pRenderTarget.?.ID2D1RenderTarget_CreateSolidColorBrush(&color, null, @ptrCast(*?*win32.ID2D1SolidColorBrush, &self.pBrush)); + hr = self.pRenderTarget.?.ID2D1RenderTarget_CreateSolidColorBrush(&color, null, @as(*?*win32.ID2D1SolidColorBrush, @ptrCast(&self.pBrush))); - if (SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { self.CalculateLayout(); } } @@ -108,18 +114,15 @@ fn MainWindowCreateGraphicsResources(self: *MainWindow) HRESULT return hr; } -fn MainWindowDiscardGraphicsResources(self: *MainWindow) void -{ +fn MainWindowDiscardGraphicsResources(self: *MainWindow) void { SafeRelease(&self.pRenderTarget); SafeRelease(&self.pBrush); } -fn MainWindowOnPaint(self: *MainWindow) void -{ +fn MainWindowOnPaint(self: *MainWindow) void { var hr = self.CreateGraphicsResources(); - if (SUCCEEDED(hr)) - { - var ps : win32.PAINTSTRUCT = undefined; + if (SUCCEEDED(hr)) { + var ps: win32.PAINTSTRUCT = undefined; _ = win32.BeginPaint(self.base.m_hwnd.?, &ps); self.pRenderTarget.?.ID2D1RenderTarget_BeginDraw(); @@ -127,25 +130,22 @@ fn MainWindowOnPaint(self: *MainWindow) void self.pRenderTarget.?.ID2D1RenderTarget_Clear(&D2D1.ColorFU32(.{ .rgb = D2D1.SkyBlue })); // TODO: how do I get a COM interface type to convert to a base type without // an explicit cast like this? - self.pRenderTarget.?.ID2D1RenderTarget_FillEllipse(&self.ellipse, @ptrCast(*win32.ID2D1Brush, self.pBrush)); + self.pRenderTarget.?.ID2D1RenderTarget_FillEllipse(&self.ellipse, @as(*win32.ID2D1Brush, @ptrCast(self.pBrush))); hr = self.pRenderTarget.?.ID2D1RenderTarget_EndDraw(null, null); - if (FAILED(hr) or hr == win32.D2DERR_RECREATE_TARGET) - { + if (FAILED(hr) or hr == win32.D2DERR_RECREATE_TARGET) { self.DiscardGraphicsResources(); } _ = win32.EndPaint(self.base.m_hwnd.?, &ps); } } -fn MainWindowResize(self: *MainWindow) void -{ - if (self.pRenderTarget) |renderTarget| - { +fn MainWindowResize(self: *MainWindow) void { + if (self.pRenderTarget) |renderTarget| { var rc: RECT = undefined; _ = win32.GetClientRect(self.base.m_hwnd.?, &rc); - const size = D2D_SIZE_U{ .width = @intCast(u32, rc.right), .height = @intCast(u32, rc.bottom) }; + const size = D2D_SIZE_U{ .width = @as(u32, @intCast(rc.right)), .height = @as(u32, @intCast(rc.bottom)) }; _ = renderTarget.ID2D1HwndRenderTarget_Resize(&size); self.CalculateLayout(); @@ -153,25 +153,22 @@ fn MainWindowResize(self: *MainWindow) void } } -pub export fn wWinMain(_: HINSTANCE, __: ?HINSTANCE, ___: [*:0]u16, nCmdShow: u32) callconv(WINAPI) c_int -{ +pub export fn wWinMain(_: HINSTANCE, __: ?HINSTANCE, ___: [*:0]u16, nCmdShow: u32) callconv(WINAPI) c_int { _ = __; _ = ___; - var win = MainWindow { }; + var win = MainWindow{}; - if (win32.TRUE != win.base.Create(L("Circle"), win32.WS_OVERLAPPEDWINDOW, .{})) - { + if (win32.TRUE != win.base.Create(L("Circle"), win32.WS_OVERLAPPEDWINDOW, .{})) { return 0; } - _ = win32.ShowWindow(win.base.Window(), @intToEnum(win32.SHOW_WINDOW_CMD, nCmdShow)); + _ = win32.ShowWindow(win.base.Window(), @as(win32.SHOW_WINDOW_CMD, @enumFromInt(nCmdShow))); // Run the message loop. - var msg : MSG = undefined; - while (0 != win32.GetMessage(&msg, null, 0, 0)) - { + var msg: MSG = undefined; + while (0 != win32.GetMessage(&msg, null, 0, 0)) { _ = win32.TranslateMessage(&msg); _ = win32.DispatchMessage(&msg); } @@ -179,36 +176,32 @@ pub export fn wWinMain(_: HINSTANCE, __: ?HINSTANCE, ___: [*:0]u16, nCmdShow: u3 return 0; } -fn MainWindowHandleMessage(self: *MainWindow, uMsg: u32, wParam: WPARAM, lParam: LPARAM) LRESULT -{ - switch (uMsg) - { - win32.WM_CREATE => { - // TODO: Should I need to case &self.pFactory to **anyopaque? Maybe - // D2D2CreateFactory probably doesn't have the correct type yet? - if (FAILED(win32.D2D1CreateFactory( - win32.D2D1_FACTORY_TYPE_SINGLE_THREADED, win32.IID_ID2D1Factory, null, @ptrCast(**anyopaque, &self.pFactory)))) - { - return -1; // Fail CreateWindowEx. - } - return 0; - }, - win32.WM_DESTROY => { - self.DiscardGraphicsResources(); - SafeRelease(&self.pFactory); - win32.PostQuitMessage(0); - return 0; - }, - win32.WM_PAINT => { - self.OnPaint(); - return 0; - }, - // Other messages not shown... - win32.WM_SIZE => { - self.Resize(); - return 0; - }, - else => {}, +fn MainWindowHandleMessage(self: *MainWindow, uMsg: u32, wParam: WPARAM, lParam: LPARAM) LRESULT { + switch (uMsg) { + win32.WM_CREATE => { + // TODO: Should I need to case &self.pFactory to **anyopaque? Maybe + // D2D2CreateFactory probably doesn't have the correct type yet? + if (FAILED(win32.D2D1CreateFactory(win32.D2D1_FACTORY_TYPE_SINGLE_THREADED, win32.IID_ID2D1Factory, null, @as(**anyopaque, @ptrCast(&self.pFactory))))) { + return -1; // Fail CreateWindowEx. + } + return 0; + }, + win32.WM_DESTROY => { + self.DiscardGraphicsResources(); + SafeRelease(&self.pFactory); + win32.PostQuitMessage(0); + return 0; + }, + win32.WM_PAINT => { + self.OnPaint(); + return 0; + }, + // Other messages not shown... + win32.WM_SIZE => { + self.Resize(); + return 0; + }, + else => {}, } return win32.DefWindowProc(self.base.m_hwnd.?, uMsg, wParam, lParam); } @@ -226,9 +219,9 @@ const D2D1 = struct { // TODO: this is missing pub fn ColorFU32(o: struct { rgb: u32, a: f32 = 1 }) win32.D2D1_COLOR_F { return .{ - .r = @intToFloat(f32, (o.rgb >> 16) & 0xff) / 255, - .g = @intToFloat(f32, (o.rgb >> 8) & 0xff) / 255, - .b = @intToFloat(f32, (o.rgb >> 0) & 0xff) / 255, + .r = @as(f32, @floatFromInt((o.rgb >> 16) & 0xff)) / 255, + .g = @as(f32, @floatFromInt((o.rgb >> 8) & 0xff)) / 255, + .b = @as(f32, @floatFromInt((o.rgb >> 0) & 0xff)) / 255, .a = o.a, }; } @@ -258,7 +251,7 @@ const D2D1 = struct { } // TODO: this is missing - pub fn PixelFormat() win32.D2D1_PIXEL_FORMAT { + pub fn PixelFormat() win32.D2D1_PIXEL_FORMAT { return .{ .format = win32.DXGI_FORMAT_UNKNOWN, .alphaMode = win32.D2D1_ALPHA_MODE_UNKNOWN, diff --git a/examples/helloworld-window.zig b/examples/helloworld-window.zig index 9b7f62f..a9d29be 100644 --- a/examples/helloworld-window.zig +++ b/examples/helloworld-window.zig @@ -16,15 +16,14 @@ const CW_USEDEFAULT = win32.CW_USEDEFAULT; const MSG = win32.MSG; const HWND = win32.HWND; -pub export fn wWinMain(hInstance: HINSTANCE, _: ?HINSTANCE, pCmdLine: [*:0]u16, nCmdShow: u32) callconv(WINAPI) c_int -{ +pub export fn wWinMain(hInstance: HINSTANCE, _: ?HINSTANCE, pCmdLine: [*:0]u16, nCmdShow: u32) callconv(WINAPI) c_int { _ = pCmdLine; // Register the window class. const CLASS_NAME = L("Sample Window Class"); - const wc = win32.WNDCLASS { - .style = @intToEnum(win32.WNDCLASS_STYLES, 0), + const wc = win32.WNDCLASS{ + .style = @as(win32.WNDCLASS_STYLES, @enumFromInt(0)), .lpfnWndProc = WindowProc, .cbClsExtra = 0, .cbWndExtra = 0, @@ -41,31 +40,26 @@ pub export fn wWinMain(hInstance: HINSTANCE, _: ?HINSTANCE, pCmdLine: [*:0]u16, // Create the window. - const hwnd = win32.CreateWindowEx( - @intToEnum(win32.WINDOW_EX_STYLE, 0), // Optional window styles. - CLASS_NAME, // Window class - L("Learn to Program Windows"), // Window text - win32.WS_OVERLAPPEDWINDOW, // Window style + const hwnd = win32.CreateWindowEx(@as(win32.WINDOW_EX_STYLE, @enumFromInt(0)), // Optional window styles. + CLASS_NAME, // Window class + L("Learn to Program Windows"), // Window text + win32.WS_OVERLAPPEDWINDOW, // Window style - // Size and position - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - - null, // Parent window - null, // Menu - hInstance, // Instance handle - null // Additional application data + // Size and position + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, null, // Parent window + null, // Menu + hInstance, // Instance handle + null // Additional application data ); - if (hwnd == null) - { + if (hwnd == null) { return 0; } - _ = win32.ShowWindow(hwnd, @intToEnum(win32.SHOW_WINDOW_CMD, nCmdShow)); + _ = win32.ShowWindow(hwnd, @as(win32.SHOW_WINDOW_CMD, @enumFromInt(nCmdShow))); // Run the message loop. - var msg : MSG = undefined; - while (win32.GetMessage(&msg, null, 0, 0) != 0) - { + var msg: MSG = undefined; + while (win32.GetMessage(&msg, null, 0, 0) != 0) { _ = win32.TranslateMessage(&msg); _ = win32.DispatchMessage(&msg); } @@ -73,22 +67,18 @@ pub export fn wWinMain(hInstance: HINSTANCE, _: ?HINSTANCE, pCmdLine: [*:0]u16, return 0; } -fn WindowProc(hwnd: HWND , uMsg: u32, wParam: win32.WPARAM, lParam: win32.LPARAM) callconv(WINAPI) win32.LRESULT -{ - switch (uMsg) - { - win32.WM_DESTROY => - { +fn WindowProc(hwnd: HWND, uMsg: u32, wParam: win32.WPARAM, lParam: win32.LPARAM) callconv(WINAPI) win32.LRESULT { + switch (uMsg) { + win32.WM_DESTROY => { win32.PostQuitMessage(0); return 0; }, - win32.WM_PAINT => - { + win32.WM_PAINT => { var ps: win32.PAINTSTRUCT = undefined; const hdc = win32.BeginPaint(hwnd, &ps); // All painting occurs here, between BeginPaint and EndPaint. - _ = win32.FillRect(hdc, &ps.rcPaint, @intToPtr(win32.HBRUSH, @as(usize, @enumToInt(win32.COLOR_WINDOW)+1))); + _ = win32.FillRect(hdc, &ps.rcPaint, @as(win32.HBRUSH, @ptrFromInt(@as(usize, @intFromEnum(win32.COLOR_WINDOW) + 1)))); _ = win32.EndPaint(hwnd, &ps); return 0; }, diff --git a/examples/helloworld.zig b/examples/helloworld.zig index b1a8170..c535465 100644 --- a/examples/helloworld.zig +++ b/examples/helloworld.zig @@ -11,10 +11,10 @@ pub export fn WinMainCRTStartup() callconv(@import("std").os.windows.WINAPI) nor } fn writeAll(hFile: win32.HANDLE, buffer: []const u8) !void { - var written : usize = 0; + var written: usize = 0; while (written < buffer.len) { - const next_write = @intCast(u32, 0xFFFFFFFF & (buffer.len - written)); - var last_written : u32 = undefined; + const next_write = @as(u32, @intCast(0xFFFFFFFF & (buffer.len - written))); + var last_written: u32 = undefined; if (1 != win32.WriteFile(hFile, buffer.ptr + written, next_write, &last_written, null)) { // TODO: return from GetLastError return error.WriteFileFailed; diff --git a/examples/net.zig b/examples/net.zig index 22b6449..db9c440 100644 --- a/examples/net.zig +++ b/examples/net.zig @@ -8,7 +8,7 @@ const win32 = struct { }; pub fn main() void { - const s = win32.socket(@enumToInt(win32.AF_INET), win32.SOCK_STREAM, @enumToInt(win32.IPPROTO_TCP)); + const s = win32.socket(@intFromEnum(win32.AF_INET), win32.SOCK_STREAM, @intFromEnum(win32.IPPROTO_TCP)); if (s == win32.INVALID_SOCKET) { std.log.err("socket failed with {}", .{win32.GetLastError()}); } diff --git a/examples/opendialog.zig b/examples/opendialog.zig index b5820ed..20796a3 100644 --- a/examples/opendialog.zig +++ b/examples/opendialog.zig @@ -14,36 +14,30 @@ const win32 = struct { usingnamespace @import("win32").ui.shell; }; -pub export fn wWinMain(__: win32.HINSTANCE, _: ?win32.HINSTANCE, ___: [*:0]u16, ____: u32) callconv(WINAPI) c_int -{ +pub export fn wWinMain(__: win32.HINSTANCE, _: ?win32.HINSTANCE, ___: [*:0]u16, ____: u32) callconv(WINAPI) c_int { _ = __; _ = ___; _ = ____; - var hr = win32.CoInitializeEx(null, win32.COINIT.initFlags(.{.APARTMENTTHREADED = 1, .DISABLE_OLE1DDE = 1})); - if (win32.SUCCEEDED(hr)) - { - var pFileOpen : ?*win32.IFileOpenDialog = undefined; + var hr = win32.CoInitializeEx(null, win32.COINIT.initFlags(.{ .APARTMENTTHREADED = 1, .DISABLE_OLE1DDE = 1 })); + if (win32.SUCCEEDED(hr)) { + var pFileOpen: ?*win32.IFileOpenDialog = undefined; // Create the FileOpenDialog object. - hr = win32.CoCreateInstance(win32.CLSID_FileOpenDialog, null, .ALL, win32.IID_IFileOpenDialog, @ptrCast(*?*anyopaque, &pFileOpen)); - if (win32.SUCCEEDED(hr)) - { + hr = win32.CoCreateInstance(win32.CLSID_FileOpenDialog, null, .ALL, win32.IID_IFileOpenDialog, @as(*?*anyopaque, @ptrCast(&pFileOpen))); + if (win32.SUCCEEDED(hr)) { // Show the Open dialog box. hr = pFileOpen.?.IModalWindow_Show(null); // Get the file name from the dialog box. - if (win32.SUCCEEDED(hr)) - { + if (win32.SUCCEEDED(hr)) { var pItem: ?*win32.IShellItem = undefined; hr = pFileOpen.?.IFileDialog_GetResult(&pItem); - if (win32.SUCCEEDED(hr)) - { - var pszFilePath : ?[*:0]u16 = undefined; + if (win32.SUCCEEDED(hr)) { + var pszFilePath: ?[*:0]u16 = undefined; hr = pItem.?.IShellItem_GetDisplayName(win32.SIGDN_FILESYSPATH, &pszFilePath); // Display the file name to the user. - if (win32.SUCCEEDED(hr)) - { + if (win32.SUCCEEDED(hr)) { _ = win32.MessageBoxW(null, pszFilePath.?, win32.L("File Path"), win32.MB_OK); win32.CoTaskMemFree(pszFilePath.?); } diff --git a/examples/wasapi.zig b/examples/wasapi.zig index 0aa9ed0..3b01736 100644 --- a/examples/wasapi.zig +++ b/examples/wasapi.zig @@ -17,13 +17,7 @@ pub fn getDefaultDevice() !void { var enumerator: ?*win32.IMMDeviceEnumerator = undefined; { - const status = win32.CoCreateInstance( - win32.CLSID_MMDeviceEnumerator, - null, - win32.CLSCTX_ALL, - win32.IID_IMMDeviceEnumerator, - @ptrCast(*?*anyopaque, &enumerator) - ); + const status = win32.CoCreateInstance(win32.CLSID_MMDeviceEnumerator, null, win32.CLSCTX_ALL, win32.IID_IMMDeviceEnumerator, @as(*?*anyopaque, @ptrCast(&enumerator))); if (win32.FAILED(status)) { log("CoCreateInstance FAILED: {d}", .{status}); return error.Fail; @@ -42,7 +36,7 @@ pub fn getDefaultDevice() !void { } } defer _ = device.?.IUnknown_Release(); // No such method - + var properties: ?*win32.IPropertyStore = undefined; { const status = device.?.IMMDevice_OpenPropertyStore(win32.STGM_READ, &properties); @@ -51,7 +45,7 @@ pub fn getDefaultDevice() !void { return error.Fail; } } - + var count: u32 = 0; { const status = properties.?.IPropertyStore_GetCount(&count); @@ -60,7 +54,7 @@ pub fn getDefaultDevice() !void { return error.Fail; } } - + var index: u32 = 0; while (index < count - 1) : (index += 1) { var propKey: win32.PROPERTYKEY = undefined; @@ -85,7 +79,7 @@ pub fn getDefaultDevice() !void { } pub fn main() !u8 { - const config_value = win32.COINIT.initFlags(.{.APARTMENTTHREADED = 1, .DISABLE_OLE1DDE = 1}); + const config_value = win32.COINIT.initFlags(.{ .APARTMENTTHREADED = 1, .DISABLE_OLE1DDE = 1 }); { _ = config_value; const status = win32.CoInitialize(null); // CoInitializeEx(null, @intToEnum(COINIT, config_value));