From 7ddaf429b92666c951db2814e3b6f77ecf760b25 Mon Sep 17 00:00:00 2001 From: Andreas Reischuck Date: Sun, 23 Jan 2022 17:06:42 +0100 Subject: [PATCH 1/3] use std.os.windows.GUID instead of custom implementation * custom parsing because Guid.parse expects curly braces. --- src/genzig.zig | 2 +- src/zig.zig | 105 ++++++++++++++++++++++--------------------------- 2 files changed, 49 insertions(+), 58 deletions(-) diff --git a/src/genzig.zig b/src/genzig.zig index 56d3a4f..73b445a 100644 --- a/src/genzig.zig +++ b/src/genzig.zig @@ -1283,7 +1283,7 @@ fn generateConstant(sdk_file: *SdkFile, writer: *CodeWriter, constant_obj: json. 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} = @import(\"{s}zig.zig\").guidParseWithoutCurly({});", .{name_pool, sdk_file.getWin32DirImportPrefix(), fmtConstValue(value_type, value_node, sdk_file)}); } else { try writer.linef("pub const {s} = {};", .{name_pool, fmtConstValue(value_type, value_node, sdk_file)}); } diff --git a/src/zig.zig b/src/zig.zig index cb1db02..8e107b7 100644 --- a/src/zig.zig +++ b/src/zig.zig @@ -21,7 +21,7 @@ pub usingnamespace switch (unicode_mode) { 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"); }, @@ -35,57 +35,48 @@ pub const arch: Arch = switch (builtin.target.cpu.arch) { else => @compileError("unable to determine win32 arch"), }; -// TODO: this should probably be in the standard lib somewhere? -pub const Guid = extern union { - Ints: extern struct { - a: u32, - b: u16, - c: u16, - d: [8]u8, - }, - 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 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 }; - for (hex_offsets) |hex_offset, i| { - //guid.Bytes[i] = decodeHexByte(s[offset..offset+2]); - guid.Bytes[i] = decodeHexByte([2]u8 { s[hex_offset], s[hex_offset+1] }); - } - return guid; - } -}; -comptime { std.debug.assert(@sizeOf(Guid) == 16); } +pub const Guid = std.os.windows.GUID; +// note: implementation copied from std.os.windows.GUID.parse +// * remoted curly braces asserts +pub fn guidParseWithoutCurly(str: []const u8) Guid { + var guid: Guid = undefined; + var index: usize = 0; -// 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'); -} + const assert = std.debug.assert; -// TODO: is this in the standard lib somewhere? -fn decodeHexByte(hex: [2]u8) u8 { - return @intCast(u8, hexVal(hex[0])) << 4 | hexVal(hex[1]); -} + guid.Data1 = std.fmt.parseUnsigned(c_ulong, str[index .. index + 8], 16) catch unreachable; + index += 8; -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)); + assert(str[index] == '-'); + index += 1; + + guid.Data2 = std.fmt.parseUnsigned(c_ushort, str[index .. index + 4], 16) catch unreachable; + index += 4; + + assert(str[index] == '-'); + index += 1; + + guid.Data3 = std.fmt.parseUnsigned(c_ushort, str[index .. index + 4], 16) catch unreachable; + index += 4; + + assert(str[index] == '-'); + index += 1; + + guid.Data4[0] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable; + index += 2; + guid.Data4[1] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable; + index += 2; + + assert(str[index] == '-'); + index += 1; + + var i: usize = 2; + while (i < guid.Data4.len) : (i += 1) { + guid.Data4[i] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable; + index += 2; + } + + return guid; } pub const PropertyKey = extern struct { @@ -93,7 +84,7 @@ pub const PropertyKey = extern struct { pid: u32, pub fn init(fmtid: []const u8, pid: u32) PropertyKey { return .{ - .fmtid = Guid.initString(fmtid), + .fmtid = guidParseWithoutCurly(fmtid), .pid = pid, }; } @@ -108,8 +99,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,7 +119,7 @@ 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.TypeInfo { .Int = .{ .signedness = .unsigned, .bits = target_type_info.bits }}); + const UnsignedT = @Type(std.builtin.TypeInfo{ .Int = .{ .signedness = .unsigned, .bits = target_type_info.bits } }); return @bitCast(SwitchType, @as(UnsignedT, value)); } } @@ -146,11 +137,11 @@ pub fn typedConst2(comptime ReturnType: type, comptime SwitchType: type, comptim }, 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))) { + .Enum => |_| switch (@typeInfo(@TypeOf(value))) { .Int => return @intToEnum(ReturnType, value), else => target_type_error, }, @@ -158,8 +149,8 @@ pub fn typedConst2(comptime ReturnType: type, comptime SwitchType: type, comptim } } 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(@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(u32, 0xffffffff), typedConst(u32, 0xffffffff)); try testing.expectEqual(@bitCast(i32, @as(u32, 0x80000000)), typedConst(i32, 0x80000000)); } From c4745760b0bfd6a167832d37a6e546bcff9afc33 Mon Sep 17 00:00:00 2001 From: Andreas Reischuck Date: Sun, 23 Jan 2022 17:13:29 +0100 Subject: [PATCH 2/3] use Guid.parse * requires win32jsongen feature guid-with-curly-braces --- src/genzig.zig | 2 +- src/zig.zig | 44 +------------------------------------------- 2 files changed, 2 insertions(+), 44 deletions(-) diff --git a/src/genzig.zig b/src/genzig.zig index 73b445a..9faf14b 100644 --- a/src/genzig.zig +++ b/src/genzig.zig @@ -1283,7 +1283,7 @@ fn generateConstant(sdk_file: *SdkFile, writer: *CodeWriter, constant_obj: json. 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} = @import(\"{s}zig.zig\").guidParseWithoutCurly({});", .{name_pool, sdk_file.getWin32DirImportPrefix(), fmtConstValue(value_type, value_node, sdk_file)}); + try writer.linef("pub const {s} = Guid.parse({});", .{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)}); } diff --git a/src/zig.zig b/src/zig.zig index 8e107b7..eb2bb53 100644 --- a/src/zig.zig +++ b/src/zig.zig @@ -36,55 +36,13 @@ pub const arch: Arch = switch (builtin.target.cpu.arch) { }; pub const Guid = std.os.windows.GUID; -// note: implementation copied from std.os.windows.GUID.parse -// * remoted curly braces asserts -pub fn guidParseWithoutCurly(str: []const u8) Guid { - var guid: Guid = undefined; - var index: usize = 0; - - const assert = std.debug.assert; - - guid.Data1 = std.fmt.parseUnsigned(c_ulong, str[index .. index + 8], 16) catch unreachable; - index += 8; - - assert(str[index] == '-'); - index += 1; - - guid.Data2 = std.fmt.parseUnsigned(c_ushort, str[index .. index + 4], 16) catch unreachable; - index += 4; - - assert(str[index] == '-'); - index += 1; - - guid.Data3 = std.fmt.parseUnsigned(c_ushort, str[index .. index + 4], 16) catch unreachable; - index += 4; - - assert(str[index] == '-'); - index += 1; - - guid.Data4[0] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable; - index += 2; - guid.Data4[1] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable; - index += 2; - - assert(str[index] == '-'); - index += 1; - - var i: usize = 2; - while (i < guid.Data4.len) : (i += 1) { - guid.Data4[i] = std.fmt.parseUnsigned(u8, str[index .. index + 2], 16) catch unreachable; - index += 2; - } - - return guid; -} pub const PropertyKey = extern struct { fmtid: Guid, pid: u32, pub fn init(fmtid: []const u8, pid: u32) PropertyKey { return .{ - .fmtid = guidParseWithoutCurly(fmtid), + .fmtid = Guid.parse(fmtid), .pid = pid, }; } From 6ab2afb336250c497f790f468caa2e08504d95b2 Mon Sep 17 00:00:00 2001 From: Jonathan Marler Date: Mon, 24 Jan 2022 01:05:52 -0700 Subject: [PATCH 3/3] remove Guid from zig.zig, add curly to guid strings for GUID.parse --- src/genzig.zig | 11 ++++++----- src/zig.zig | 6 ++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/genzig.zig b/src/genzig.zig index 9faf14b..f2d9357 100644 --- a/src/genzig.zig +++ b/src/genzig.zig @@ -715,7 +715,7 @@ fn generateFile(module_dir: std.fs.Dir, module: *Module, tree: json.ValueTree) ! try writer.linef("// Section: Imports ({})", .{import_total}); try writer.line("//--------------------------------------------------------------------------------"); if (sdk_file.uses_guid) { - try writer.linef("const Guid = @import(\"{s}zig.zig\").Guid;", .{sdk_file.getWin32DirImportPrefix()}); + try writer.linef("const Guid = @import(\"std\").os.windows.GUID;", .{}); } { var arch_specific_imports = ArchSpecificMap(StringPool.Val).init(allocator); @@ -1283,7 +1283,8 @@ fn generateConstant(sdk_file: *SdkFile, writer: *CodeWriter, constant_obj: json. 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.parse({});", .{name_pool, fmtConstValue(value_type, value_node, sdk_file)}); + jsonEnforce(value_type == .String); + try writer.linef("pub const {s} = Guid.parse(\"{{{s}}}\");", .{name_pool, value_node.String}); } else { try writer.linef("pub const {s} = {};", .{name_pool, fmtConstValue(value_type, value_node, sdk_file)}); } @@ -1299,7 +1300,7 @@ fn generateConstant(sdk_file: *SdkFile, writer: *CodeWriter, constant_obj: json. 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 = {} }};", .{ + try writer.writef(" {{ .fmtid = Guid.parse(\"{{{s}}}\"), .pid = {} }};", .{ fmtid, pid }, .{.start=.mid}); @@ -1417,7 +1418,7 @@ fn generateType( 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.parse(\"{{{s}}}\");", .{clsid_pool, guid}); try writer.linef("pub const {s} = &{0s}_Value;", .{clsid_pool}); try sdk_file.const_exports.append(clsid_pool); return; @@ -2070,7 +2071,7 @@ 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.parse(\"{{{s}}}\");", .{ iid_pool, guid}); try writer.linef("pub const {s} = &{0s}_Value;", .{iid_pool}); try sdk_file.const_exports.append(iid_pool); } diff --git a/src/zig.zig b/src/zig.zig index eb2bb53..d285d75 100644 --- a/src/zig.zig +++ b/src/zig.zig @@ -35,14 +35,12 @@ pub const arch: Arch = switch (builtin.target.cpu.arch) { else => @compileError("unable to determine win32 arch"), }; -pub const Guid = std.os.windows.GUID; - pub const PropertyKey = extern struct { - fmtid: Guid, + fmtid: std.os.windows.GUID, pid: u32, pub fn init(fmtid: []const u8, pid: u32) PropertyKey { return .{ - .fmtid = Guid.parse(fmtid), + .fmtid = std.os.windows.GUID.parse(fmtid), .pid = pid, }; }