| author | |
| committer | |
| log | d77f5e7aaa94b66db4e3604f21c41b315743fb81 |
| tree | 809d2b9a253d0365861495e7a367ce6302a65bae |
| parent | d403d8cb7a147856232430afe9af8562d59de38b |
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, |
| 87 | 87 | ||
| 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 | } |
| 91 | 95 | ||
| 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 | } |
| 96 | 104 | ||
| 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; |
| 317 | 325 | ||
| 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 | }; |
| 576 | 602 | ||
| 577 | fn serializeIpc(start_serialized_len: usize) usize { | 603 | fn 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 { |
| 638 | 664 | ||
| 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 { |
| 687 | 713 | ||
| 688 | fn findOld(ipc_fd: posix.fd_t, old_metadata: []const SavedMetadata) ?*const SavedMetadata { | 714 | fn 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; |
| 712 | 738 | ||
| 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 { |
| 911 | fn maybeUpdateSize(resize_flag: bool) void { | 937 | fn maybeUpdateSize(resize_flag: bool) void { |
| 912 | if (!resize_flag) return; | 938 | if (!resize_flag) return; |
| 913 | 939 | ||
| 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; |
| 922 | 941 | ||
| 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 | } |
| 931 | 968 |
lib/std/fmt.zig+35-24| ... | @@ -9,7 +9,7 @@ const assert = std.debug.assert; | ... | @@ -9,7 +9,7 @@ const assert = std.debug.assert; |
| 9 | const mem = std.mem; | 9 | const mem = std.mem; |
| 10 | const unicode = std.unicode; | 10 | const unicode = std.unicode; |
| 11 | const meta = std.meta; | 11 | const meta = std.meta; |
| 12 | const lossyCast = std.math.lossyCast; | 12 | const lossyCast = math.lossyCast; |
| 13 | const expectFmt = std.testing.expectFmt; | 13 | const expectFmt = std.testing.expectFmt; |
| 14 | 14 | ||
| 15 | pub const default_max_depth = 3; | 15 | pub 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`. |
| 1496 | pub fn parseInt(comptime T: type, buf: []const u8, base: u8) ParseIntError!T { | 1496 | pub 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. | ||
| 1501 | pub 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 | } |
| 1502 | 1512 | ||
| 1503 | test parseInt { | 1513 | test 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 | } |
| 1562 | 1572 | ||
| 1563 | fn parseWithSign( | 1573 | fn 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; |
| 1570 | 1581 | ||
| 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 | } |
| 1595 | 1606 | ||
| ... | @@ -1598,33 +1609,33 @@ fn parseWithSign( | ... | @@ -1598,33 +1609,33 @@ fn parseWithSign( |
| 1598 | .neg => math.sub, | 1609 | .neg => math.sub, |
| 1599 | }; | 1610 | }; |
| 1600 | 1611 | ||
| 1601 | // accumulate into U which is always 8 bits or larger. this prevents | 1612 | // 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; |
| 1606 | 1617 | ||
| 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; |
| 1608 | 1619 | ||
| 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 | } |
| 1623 | 1634 | ||
| 1624 | return if (T == U) | 1635 | return if (Result == Accumulate) |
| 1625 | x | 1636 | accumulate |
| 1626 | else | 1637 | else |
| 1627 | math.cast(T, x) orelse return error.Overflow; | 1638 | math.cast(Result, accumulate) orelse return error.Overflow; |
| 1628 | } | 1639 | } |
| 1629 | 1640 | ||
| 1630 | /// Parses the string `buf` as unsigned representation in the specified base | 1641 | /// 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`. |
| 1641 | pub fn parseUnsigned(comptime T: type, buf: []const u8, base: u8) ParseIntError!T { | 1652 | pub 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 | } |
| 1644 | 1655 | ||
| 1645 | test parseUnsigned { | 1656 | test 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 { |
| 24 | 24 | ||
| 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 across | 445 | 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 | } |
| 4506 | 4506 | ||
| 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(); |
| 4509 | 4509 | ||
| 4510 | mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index })); | 4510 | mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index })); |