authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-05-26 07:07:44-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-27 20:56:48-07:00
logd77f5e7aaa94b66db4e3604f21c41b315743fb81
tree809d2b9a253d0365861495e7a367ce6302a65bae
parentd403d8cb7a147856232430afe9af8562d59de38b

Progress: fix compile errors on windows

Works for `zig build-exe`, IPC still not implemented yet.

5 files changed, 96 insertions(+), 51 deletions(-)

lib/std/Progress.zig+58-21
...@@ -86,12 +86,20 @@ pub const Node = struct {...@@ -86,12 +86,20 @@ pub const Node = struct {
86 name: [max_name_len]u8,86 name: [max_name_len]u8,
8787
88 fn getIpcFd(s: Storage) ?posix.fd_t {88 fn getIpcFd(s: Storage) ?posix.fd_t {
89 return if (s.estimated_total_count != std.math.maxInt(u32)) null else @bitCast(s.completed_count);89 return if (s.estimated_total_count == std.math.maxInt(u32)) switch (@typeInfo(posix.fd_t)) {
90 .Int => @bitCast(s.completed_count),
91 .Pointer => @ptrFromInt(s.completed_count),
92 else => @compileError("unsupported fd_t of " ++ @typeName(posix.fd_t)),
93 } else null;
90 }94 }
9195
92 fn setIpcFd(s: *Storage, fd: posix.fd_t) void {96 fn setIpcFd(s: *Storage, fd: posix.fd_t) void {
93 s.estimated_total_count = std.math.maxInt(u32);97 s.estimated_total_count = std.math.maxInt(u32);
94 s.completed_count = @bitCast(fd);98 s.completed_count = switch (@typeInfo(posix.fd_t)) {
99 .Int => @bitCast(fd),
100 .Pointer => @intFromPtr(fd),
101 else => @compileError("unsupported fd_t of " ++ @typeName(posix.fd_t)),
102 };
95 }103 }
96104
97 comptime {105 comptime {
...@@ -316,12 +324,16 @@ pub fn start(options: Options) Node {...@@ -316,12 +324,16 @@ pub fn start(options: Options) Node {
316 global_progress.initial_delay_ns = options.initial_delay_ns;324 global_progress.initial_delay_ns = options.initial_delay_ns;
317325
318 if (std.process.parseEnvVarInt("ZIG_PROGRESS", u31, 10)) |ipc_fd| {326 if (std.process.parseEnvVarInt("ZIG_PROGRESS", u31, 10)) |ipc_fd| {
319 if (std.Thread.spawn(.{}, ipcThreadRun, .{ipc_fd})) |thread| {327 global_progress.update_thread = std.Thread.spawn(.{}, ipcThreadRun, .{
320 global_progress.update_thread = thread;328 @as(posix.fd_t, switch (@typeInfo(posix.fd_t)) {
321 } else |err| {329 .Int => ipc_fd,
330 .Pointer => @ptrFromInt(ipc_fd),
331 else => @compileError("unsupported fd_t of " ++ @typeName(posix.fd_t)),
332 }),
333 }) catch |err| {
322 std.log.warn("failed to spawn IPC thread for communicating progress to parent: {s}", .{@errorName(err)});334 std.log.warn("failed to spawn IPC thread for communicating progress to parent: {s}", .{@errorName(err)});
323 return .{ .index = .none };335 return .{ .index = .none };
324 }336 };
325 } else |env_err| switch (env_err) {337 } else |env_err| switch (env_err) {
326 error.EnvironmentVariableNotFound => {338 error.EnvironmentVariableNotFound => {
327 if (options.disable_printing) {339 if (options.disable_printing) {
...@@ -572,6 +584,20 @@ const SavedMetadata = struct {...@@ -572,6 +584,20 @@ const SavedMetadata = struct {
572 main_index: u16,584 main_index: u16,
573 start_index: u16,585 start_index: u16,
574 nodes_len: u16,586 nodes_len: u16,
587
588 fn getIpcFd(metadata: SavedMetadata) posix.fd_t {
589 return if (builtin.os.tag == .windows)
590 @ptrFromInt(@as(usize, metadata.ipc_fd) << 2)
591 else
592 metadata.ipc_fd;
593 }
594
595 fn setIpcFd(fd: posix.fd_t) u16 {
596 return @intCast(if (builtin.os.tag == .windows)
597 @shrExact(@intFromPtr(fd), 2)
598 else
599 fd);
600 }
575};601};
576602
577fn serializeIpc(start_serialized_len: usize) usize {603fn serializeIpc(start_serialized_len: usize) usize {
...@@ -638,7 +664,7 @@ fn serializeIpc(start_serialized_len: usize) usize {...@@ -638,7 +664,7 @@ fn serializeIpc(start_serialized_len: usize) usize {
638664
639 // Remember in case the pipe is empty on next update.665 // Remember in case the pipe is empty on next update.
640 ipc_metadata[ipc_metadata_len] = .{666 ipc_metadata[ipc_metadata_len] = .{
641 .ipc_fd = @intCast(fd),667 .ipc_fd = SavedMetadata.setIpcFd(fd),
642 .start_index = @intCast(serialized_len),668 .start_index = @intCast(serialized_len),
643 .nodes_len = @intCast(parents.len),669 .nodes_len = @intCast(parents.len),
644 .main_index = @intCast(main_index),670 .main_index = @intCast(main_index),
...@@ -687,7 +713,7 @@ fn copyRoot(dest: *Node.Storage, src: *align(2) Node.Storage) void {...@@ -687,7 +713,7 @@ fn copyRoot(dest: *Node.Storage, src: *align(2) Node.Storage) void {
687713
688fn findOld(ipc_fd: posix.fd_t, old_metadata: []const SavedMetadata) ?*const SavedMetadata {714fn findOld(ipc_fd: posix.fd_t, old_metadata: []const SavedMetadata) ?*const SavedMetadata {
689 for (old_metadata) |*m| {715 for (old_metadata) |*m| {
690 if (m.ipc_fd == ipc_fd)716 if (m.getIpcFd() == ipc_fd)
691 return m;717 return m;
692 }718 }
693 return null;719 return null;
...@@ -711,7 +737,7 @@ fn useSavedIpcData(...@@ -711,7 +737,7 @@ fn useSavedIpcData(
711 const old_main_index = saved_metadata.main_index;737 const old_main_index = saved_metadata.main_index;
712738
713 ipc_metadata[ipc_metadata_len] = .{739 ipc_metadata[ipc_metadata_len] = .{
714 .ipc_fd = @intCast(ipc_fd),740 .ipc_fd = SavedMetadata.setIpcFd(ipc_fd),
715 .start_index = @intCast(start_serialized_len),741 .start_index = @intCast(start_serialized_len),
716 .nodes_len = nodes_len,742 .nodes_len = nodes_len,
717 .main_index = @intCast(main_index),743 .main_index = @intCast(main_index),
...@@ -911,21 +937,32 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void {...@@ -911,21 +937,32 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void {
911fn maybeUpdateSize(resize_flag: bool) void {937fn maybeUpdateSize(resize_flag: bool) void {
912 if (!resize_flag) return;938 if (!resize_flag) return;
913939
914 var winsize: posix.winsize = .{
915 .ws_row = 0,
916 .ws_col = 0,
917 .ws_xpixel = 0,
918 .ws_ypixel = 0,
919 };
920
921 const fd = (global_progress.terminal orelse return).handle;940 const fd = (global_progress.terminal orelse return).handle;
922941
923 const err = posix.system.ioctl(fd, posix.T.IOCGWINSZ, @intFromPtr(&winsize));942 if (builtin.os.tag == .windows) {
924 if (posix.errno(err) == .SUCCESS) {943 var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
925 global_progress.rows = winsize.ws_row;944
926 global_progress.cols = winsize.ws_col;945 if (windows.kernel32.GetConsoleScreenBufferInfo(fd, &info) == windows.FALSE) {
946 @panic("TODO: handle this failure");
947 }
948
949 global_progress.rows = @intCast(info.dwSize.Y);
950 global_progress.cols = @intCast(info.dwSize.X);
927 } else {951 } else {
928 @panic("TODO: handle this failure");952 var winsize: posix.winsize = .{
953 .ws_row = 0,
954 .ws_col = 0,
955 .ws_xpixel = 0,
956 .ws_ypixel = 0,
957 };
958
959 const err = posix.system.ioctl(fd, posix.T.IOCGWINSZ, @intFromPtr(&winsize));
960 if (posix.errno(err) == .SUCCESS) {
961 global_progress.rows = winsize.ws_row;
962 global_progress.cols = winsize.ws_col;
963 } else {
964 @panic("TODO: handle this failure");
965 }
929 }966 }
930}967}
931968
lib/std/fmt.zig+35-24
...@@ -9,7 +9,7 @@ const assert = std.debug.assert;...@@ -9,7 +9,7 @@ const assert = std.debug.assert;
9const mem = std.mem;9const mem = std.mem;
10const unicode = std.unicode;10const unicode = std.unicode;
11const meta = std.meta;11const meta = std.meta;
12const lossyCast = std.math.lossyCast;12const lossyCast = math.lossyCast;
13const expectFmt = std.testing.expectFmt;13const expectFmt = std.testing.expectFmt;
1414
15pub const default_max_depth = 3;15pub const default_max_depth = 3;
...@@ -1494,10 +1494,20 @@ pub fn Formatter(comptime format_fn: anytype) type {...@@ -1494,10 +1494,20 @@ pub fn Formatter(comptime format_fn: anytype) type {
1494/// Ignores '_' character in `buf`.1494/// Ignores '_' character in `buf`.
1495/// See also `parseUnsigned`.1495/// See also `parseUnsigned`.
1496pub fn parseInt(comptime T: type, buf: []const u8, base: u8) ParseIntError!T {1496pub fn parseInt(comptime T: type, buf: []const u8, base: u8) ParseIntError!T {
1497 return parseIntWithGenericCharacter(T, u8, buf, base);
1498}
1499
1500/// Like `parseInt`, but with a generic `Character` type.
1501pub fn parseIntWithGenericCharacter(
1502 comptime Result: type,
1503 comptime Character: type,
1504 buf: []const Character,
1505 base: u8,
1506) ParseIntError!Result {
1497 if (buf.len == 0) return error.InvalidCharacter;1507 if (buf.len == 0) return error.InvalidCharacter;
1498 if (buf[0] == '+') return parseWithSign(T, buf[1..], base, .pos);1508 if (buf[0] == '+') return parseIntWithSign(Result, Character, buf[1..], base, .pos);
1499 if (buf[0] == '-') return parseWithSign(T, buf[1..], base, .neg);1509 if (buf[0] == '-') return parseIntWithSign(Result, Character, buf[1..], base, .neg);
1500 return parseWithSign(T, buf, base, .pos);1510 return parseIntWithSign(Result, Character, buf, base, .pos);
1501}1511}
15021512
1503test parseInt {1513test parseInt {
...@@ -1560,12 +1570,13 @@ test parseInt {...@@ -1560,12 +1570,13 @@ test parseInt {
1560 try std.testing.expectEqual(@as(i5, -16), try std.fmt.parseInt(i5, "-10", 16));1570 try std.testing.expectEqual(@as(i5, -16), try std.fmt.parseInt(i5, "-10", 16));
1561}1571}
15621572
1563fn parseWithSign(1573fn parseIntWithSign(
1564 comptime T: type,1574 comptime Result: type,
1565 buf: []const u8,1575 comptime Character: type,
1576 buf: []const Character,
1566 base: u8,1577 base: u8,
1567 comptime sign: enum { pos, neg },1578 comptime sign: enum { pos, neg },
1568) ParseIntError!T {1579) ParseIntError!Result {
1569 if (buf.len == 0) return error.InvalidCharacter;1580 if (buf.len == 0) return error.InvalidCharacter;
15701581
1571 var buf_base = base;1582 var buf_base = base;
...@@ -1575,7 +1586,7 @@ fn parseWithSign(...@@ -1575,7 +1586,7 @@ fn parseWithSign(
1575 buf_base = 10;1586 buf_base = 10;
1576 // Detect the base by looking at buf prefix.1587 // Detect the base by looking at buf prefix.
1577 if (buf.len > 2 and buf[0] == '0') {1588 if (buf.len > 2 and buf[0] == '0') {
1578 switch (std.ascii.toLower(buf[1])) {1589 if (math.cast(u8, buf[1])) |c| switch (std.ascii.toLower(c)) {
1579 'b' => {1590 'b' => {
1580 buf_base = 2;1591 buf_base = 2;
1581 buf_start = buf[2..];1592 buf_start = buf[2..];
...@@ -1589,7 +1600,7 @@ fn parseWithSign(...@@ -1589,7 +1600,7 @@ fn parseWithSign(
1589 buf_start = buf[2..];1600 buf_start = buf[2..];
1590 },1601 },
1591 else => {},1602 else => {},
1592 }1603 };
1593 }1604 }
1594 }1605 }
15951606
...@@ -1598,33 +1609,33 @@ fn parseWithSign(...@@ -1598,33 +1609,33 @@ fn parseWithSign(
1598 .neg => math.sub,1609 .neg => math.sub,
1599 };1610 };
16001611
1601 // accumulate into U which is always 8 bits or larger. this prevents1612 // accumulate into Accumulate which is always 8 bits or larger. this prevents
1602 // `buf_base` from overflowing T.1613 // `buf_base` from overflowing Result.
1603 const info = @typeInfo(T);1614 const info = @typeInfo(Result);
1604 const U = std.meta.Int(info.Int.signedness, @max(8, info.Int.bits));1615 const Accumulate = std.meta.Int(info.Int.signedness, @max(8, info.Int.bits));
1605 var x: U = 0;1616 var accumulate: Accumulate = 0;
16061617
1607 if (buf_start[0] == '_' or buf_start[buf_start.len - 1] == '_') return error.InvalidCharacter;1618 if (buf_start[0] == '_' or buf_start[buf_start.len - 1] == '_') return error.InvalidCharacter;
16081619
1609 for (buf_start) |c| {1620 for (buf_start) |c| {
1610 if (c == '_') continue;1621 if (c == '_') continue;
1611 const digit = try charToDigit(c, buf_base);1622 const digit = try charToDigit(math.cast(u8, c) orelse return error.InvalidCharacter, buf_base);
1612 if (x != 0) {1623 if (accumulate != 0) {
1613 x = try math.mul(U, x, math.cast(U, buf_base) orelse return error.Overflow);1624 accumulate = try math.mul(Accumulate, accumulate, math.cast(Accumulate, buf_base) orelse return error.Overflow);
1614 } else if (sign == .neg) {1625 } else if (sign == .neg) {
1615 // The first digit of a negative number.1626 // The first digit of a negative number.
1616 // Consider parsing "-4" as an i3.1627 // Consider parsing "-4" as an i3.
1617 // This should work, but positive 4 overflows i3, so we can't cast the digit to T and subtract.1628 // This should work, but positive 4 overflows i3, so we can't cast the digit to T and subtract.
1618 x = math.cast(U, -@as(i8, @intCast(digit))) orelse return error.Overflow;1629 accumulate = math.cast(Accumulate, -@as(i8, @intCast(digit))) orelse return error.Overflow;
1619 continue;1630 continue;
1620 }1631 }
1621 x = try add(U, x, math.cast(U, digit) orelse return error.Overflow);1632 accumulate = try add(Accumulate, accumulate, math.cast(Accumulate, digit) orelse return error.Overflow);
1622 }1633 }
16231634
1624 return if (T == U)1635 return if (Result == Accumulate)
1625 x1636 accumulate
1626 else1637 else
1627 math.cast(T, x) orelse return error.Overflow;1638 math.cast(Result, accumulate) orelse return error.Overflow;
1628}1639}
16291640
1630/// Parses the string `buf` as unsigned representation in the specified base1641/// Parses the string `buf` as unsigned representation in the specified base
...@@ -1639,7 +1650,7 @@ fn parseWithSign(...@@ -1639,7 +1650,7 @@ fn parseWithSign(
1639/// Ignores '_' character in `buf`.1650/// Ignores '_' character in `buf`.
1640/// See also `parseInt`.1651/// See also `parseInt`.
1641pub fn parseUnsigned(comptime T: type, buf: []const u8, base: u8) ParseIntError!T {1652pub fn parseUnsigned(comptime T: type, buf: []const u8, base: u8) ParseIntError!T {
1642 return parseWithSign(T, buf, base, .pos);1653 return parseIntWithSign(T, u8, buf, base, .pos);
1643}1654}
16441655
1645test parseUnsigned {1656test parseUnsigned {
lib/std/io/tty.zig+1-1
...@@ -24,7 +24,7 @@ pub fn detectConfig(file: File) Config {...@@ -24,7 +24,7 @@ pub fn detectConfig(file: File) Config {
2424
25 if (native_os == .windows and file.isTty()) {25 if (native_os == .windows and file.isTty()) {
26 var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;26 var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
27 if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) {27 if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) == windows.FALSE) {
28 return if (force_color == true) .escape_codes else .no_color;28 return if (force_color == true) .escape_codes else .no_color;
29 }29 }
30 return .{ .windows_api = .{30 return .{ .windows_api = .{
lib/std/process.zig+1-4
...@@ -442,10 +442,7 @@ pub fn parseEnvVarInt(comptime key: []const u8, comptime I: type, base: u8) Pars...@@ -442,10 +442,7 @@ pub fn parseEnvVarInt(comptime key: []const u8, comptime I: type, base: u8) Pars
442 if (native_os == .windows) {442 if (native_os == .windows) {
443 const key_w = comptime std.unicode.utf8ToUtf16LeStringLiteral(key);443 const key_w = comptime std.unicode.utf8ToUtf16LeStringLiteral(key);
444 const text = getenvW(key_w) orelse return error.EnvironmentVariableNotFound;444 const text = getenvW(key_w) orelse return error.EnvironmentVariableNotFound;
445 // For this implementation perhaps std.fmt.parseInt can be expanded to be generic across445 return std.fmt.parseIntWithGenericCharacter(I, u16, text, base);
446 // []u8 and []u16 like how many std.mem functions work.
447 _ = text;
448 @compileError("TODO implement this");
449 } else if (native_os == .wasi and !builtin.link_libc) {446 } else if (native_os == .wasi and !builtin.link_libc) {
450 @compileError("parseEnvVarInt is not supported for WASI without libc");447 @compileError("parseEnvVarInt is not supported for WASI without libc");
451 } else {448 } else {
src/Module.zig+1-1
...@@ -4504,7 +4504,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato...@@ -4504,7 +4504,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
4504 log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(mod) catch break :blk).fmt(ip)});4504 log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(mod) catch break :blk).fmt(ip)});
4505 }4505 }
45064506
4507 const decl_prog_node = mod.sema_prog_ndoe.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);4507 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(mod)).toSlice(ip), 0);
4508 defer decl_prog_node.end();4508 defer decl_prog_node.end();
45094509
4510 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index }));4510 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index }));