Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/genzig.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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.initString({});", .{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)});
}
Expand All @@ -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});
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
73 changes: 10 additions & 63 deletions src/zig.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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");
},
Expand All @@ -35,65 +35,12 @@ 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); }

// 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');
}

// TODO: is this in the standard lib somewhere?
fn decodeHexByte(hex: [2]u8) u8 {
return @intCast(u8, 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));
}

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.initString(fmtid),
.fmtid = std.os.windows.GUID.parse(fmtid),
.pid = pid,
};
}
Expand All @@ -108,8 +55,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.
Expand All @@ -128,7 +75,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));
}
}
Expand All @@ -146,20 +93,20 @@ 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,
},
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(@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));
}