| 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 | 86 | name: [max_name_len]u8, |
| 87 | 87 | |
| 88 | 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 | 96 | fn setIpcFd(s: *Storage, fd: posix.fd_t) void { |
| 93 | 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 | 105 | comptime { |
| ... | ... | @@ -316,12 +324,16 @@ pub fn start(options: Options) Node { |
| 316 | 324 | global_progress.initial_delay_ns = options.initial_delay_ns; |
| 317 | 325 | |
| 318 | 326 | if (std.process.parseEnvVarInt("ZIG_PROGRESS", u31, 10)) |ipc_fd| { |
| 319 | if (std.Thread.spawn(.{}, ipcThreadRun, .{ipc_fd})) |thread| { | |
| 320 | global_progress.update_thread = thread; | |
| 321 | } else |err| { | |
| 327 | global_progress.update_thread = std.Thread.spawn(.{}, ipcThreadRun, .{ | |
| 328 | @as(posix.fd_t, switch (@typeInfo(posix.fd_t)) { | |
| 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 | 334 | std.log.warn("failed to spawn IPC thread for communicating progress to parent: {s}", .{@errorName(err)}); |
| 323 | 335 | return .{ .index = .none }; |
| 324 | } | |
| 336 | }; | |
| 325 | 337 | } else |env_err| switch (env_err) { |
| 326 | 338 | error.EnvironmentVariableNotFound => { |
| 327 | 339 | if (options.disable_printing) { |
| ... | ... | @@ -572,6 +584,20 @@ const SavedMetadata = struct { |
| 572 | 584 | main_index: u16, |
| 573 | 585 | start_index: u16, |
| 574 | 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 | 603 | fn serializeIpc(start_serialized_len: usize) usize { |
| ... | ... | @@ -638,7 +664,7 @@ fn serializeIpc(start_serialized_len: usize) usize { |
| 638 | 664 | |
| 639 | 665 | // Remember in case the pipe is empty on next update. |
| 640 | 666 | ipc_metadata[ipc_metadata_len] = .{ |
| 641 | .ipc_fd = @intCast(fd), | |
| 667 | .ipc_fd = SavedMetadata.setIpcFd(fd), | |
| 642 | 668 | .start_index = @intCast(serialized_len), |
| 643 | 669 | .nodes_len = @intCast(parents.len), |
| 644 | 670 | .main_index = @intCast(main_index), |
| ... | ... | @@ -687,7 +713,7 @@ fn copyRoot(dest: *Node.Storage, src: *align(2) Node.Storage) void { |
| 687 | 713 | |
| 688 | 714 | fn findOld(ipc_fd: posix.fd_t, old_metadata: []const SavedMetadata) ?*const SavedMetadata { |
| 689 | 715 | for (old_metadata) |*m| { |
| 690 | if (m.ipc_fd == ipc_fd) | |
| 716 | if (m.getIpcFd() == ipc_fd) | |
| 691 | 717 | return m; |
| 692 | 718 | } |
| 693 | 719 | return null; |
| ... | ... | @@ -711,7 +737,7 @@ fn useSavedIpcData( |
| 711 | 737 | const old_main_index = saved_metadata.main_index; |
| 712 | 738 | |
| 713 | 739 | ipc_metadata[ipc_metadata_len] = .{ |
| 714 | .ipc_fd = @intCast(ipc_fd), | |
| 740 | .ipc_fd = SavedMetadata.setIpcFd(ipc_fd), | |
| 715 | 741 | .start_index = @intCast(start_serialized_len), |
| 716 | 742 | .nodes_len = nodes_len, |
| 717 | 743 | .main_index = @intCast(main_index), |
| ... | ... | @@ -911,21 +937,32 @@ fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { |
| 911 | 937 | fn maybeUpdateSize(resize_flag: bool) void { |
| 912 | 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 | 940 | const fd = (global_progress.terminal orelse return).handle; |
| 922 | 941 | |
| 923 | const err = posix.system.ioctl(fd, posix.T.IOCGWINSZ, @intFromPtr(&winsize)); | |
| 924 | if (posix.errno(err) == .SUCCESS) { | |
| 925 | global_progress.rows = winsize.ws_row; | |
| 926 | global_progress.cols = winsize.ws_col; | |
| 942 | if (builtin.os.tag == .windows) { | |
| 943 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; | |
| 944 | ||
| 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 | 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 | 9 | const mem = std.mem; |
| 10 | 10 | const unicode = std.unicode; |
| 11 | 11 | const meta = std.meta; |
| 12 | const lossyCast = std.math.lossyCast; | |
| 12 | const lossyCast = math.lossyCast; | |
| 13 | 13 | const expectFmt = std.testing.expectFmt; |
| 14 | 14 | |
| 15 | 15 | pub const default_max_depth = 3; |
| ... | ... | @@ -1494,10 +1494,20 @@ pub fn Formatter(comptime format_fn: anytype) type { |
| 1494 | 1494 | /// Ignores '_' character in `buf`. |
| 1495 | 1495 | /// See also `parseUnsigned`. |
| 1496 | 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 | 1507 | if (buf.len == 0) return error.InvalidCharacter; |
| 1498 | if (buf[0] == '+') return parseWithSign(T, buf[1..], base, .pos); | |
| 1499 | if (buf[0] == '-') return parseWithSign(T, buf[1..], base, .neg); | |
| 1500 | return parseWithSign(T, buf, base, .pos); | |
| 1508 | if (buf[0] == '+') return parseIntWithSign(Result, Character, buf[1..], base, .pos); | |
| 1509 | if (buf[0] == '-') return parseIntWithSign(Result, Character, buf[1..], base, .neg); | |
| 1510 | return parseIntWithSign(Result, Character, buf, base, .pos); | |
| 1501 | 1511 | } |
| 1502 | 1512 | |
| 1503 | 1513 | test parseInt { |
| ... | ... | @@ -1560,12 +1570,13 @@ test parseInt { |
| 1560 | 1570 | try std.testing.expectEqual(@as(i5, -16), try std.fmt.parseInt(i5, "-10", 16)); |
| 1561 | 1571 | } |
| 1562 | 1572 | |
| 1563 | fn parseWithSign( | |
| 1564 | comptime T: type, | |
| 1565 | buf: []const u8, | |
| 1573 | fn parseIntWithSign( | |
| 1574 | comptime Result: type, | |
| 1575 | comptime Character: type, | |
| 1576 | buf: []const Character, | |
| 1566 | 1577 | base: u8, |
| 1567 | 1578 | comptime sign: enum { pos, neg }, |
| 1568 | ) ParseIntError!T { | |
| 1579 | ) ParseIntError!Result { | |
| 1569 | 1580 | if (buf.len == 0) return error.InvalidCharacter; |
| 1570 | 1581 | |
| 1571 | 1582 | var buf_base = base; |
| ... | ... | @@ -1575,7 +1586,7 @@ fn parseWithSign( |
| 1575 | 1586 | buf_base = 10; |
| 1576 | 1587 | // Detect the base by looking at buf prefix. |
| 1577 | 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 | 1590 | 'b' => { |
| 1580 | 1591 | buf_base = 2; |
| 1581 | 1592 | buf_start = buf[2..]; |
| ... | ... | @@ -1589,7 +1600,7 @@ fn parseWithSign( |
| 1589 | 1600 | buf_start = buf[2..]; |
| 1590 | 1601 | }, |
| 1591 | 1602 | else => {}, |
| 1592 | } | |
| 1603 | }; | |
| 1593 | 1604 | } |
| 1594 | 1605 | } |
| 1595 | 1606 | |
| ... | ... | @@ -1598,33 +1609,33 @@ fn parseWithSign( |
| 1598 | 1609 | .neg => math.sub, |
| 1599 | 1610 | }; |
| 1600 | 1611 | |
| 1601 | // accumulate into U which is always 8 bits or larger. this prevents | |
| 1602 | // `buf_base` from overflowing T. | |
| 1603 | const info = @typeInfo(T); | |
| 1604 | const U = std.meta.Int(info.Int.signedness, @max(8, info.Int.bits)); | |
| 1605 | var x: U = 0; | |
| 1612 | // accumulate into Accumulate which is always 8 bits or larger. this prevents | |
| 1613 | // `buf_base` from overflowing Result. | |
| 1614 | const info = @typeInfo(Result); | |
| 1615 | const Accumulate = std.meta.Int(info.Int.signedness, @max(8, info.Int.bits)); | |
| 1616 | var accumulate: Accumulate = 0; | |
| 1606 | 1617 | |
| 1607 | 1618 | if (buf_start[0] == '_' or buf_start[buf_start.len - 1] == '_') return error.InvalidCharacter; |
| 1608 | 1619 | |
| 1609 | 1620 | for (buf_start) |c| { |
| 1610 | 1621 | if (c == '_') continue; |
| 1611 | const digit = try charToDigit(c, buf_base); | |
| 1612 | if (x != 0) { | |
| 1613 | x = try math.mul(U, x, math.cast(U, buf_base) orelse return error.Overflow); | |
| 1622 | const digit = try charToDigit(math.cast(u8, c) orelse return error.InvalidCharacter, buf_base); | |
| 1623 | if (accumulate != 0) { | |
| 1624 | accumulate = try math.mul(Accumulate, accumulate, math.cast(Accumulate, buf_base) orelse return error.Overflow); | |
| 1614 | 1625 | } else if (sign == .neg) { |
| 1615 | 1626 | // The first digit of a negative number. |
| 1616 | 1627 | // Consider parsing "-4" as an i3. |
| 1617 | 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 | 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) | |
| 1625 | x | |
| 1635 | return if (Result == Accumulate) | |
| 1636 | accumulate | |
| 1626 | 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 | 1641 | /// Parses the string `buf` as unsigned representation in the specified base |
| ... | ... | @@ -1639,7 +1650,7 @@ fn parseWithSign( |
| 1639 | 1650 | /// Ignores '_' character in `buf`. |
| 1640 | 1651 | /// See also `parseInt`. |
| 1641 | 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 | 1656 | test parseUnsigned { |
lib/std/io/tty.zig+1-1| ... | ... | @@ -24,7 +24,7 @@ pub fn detectConfig(file: File) Config { |
| 24 | 24 | |
| 25 | 25 | if (native_os == .windows and file.isTty()) { |
| 26 | 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 | 28 | return if (force_color == true) .escape_codes else .no_color; |
| 29 | 29 | } |
| 30 | 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 | 442 | if (native_os == .windows) { |
| 443 | 443 | const key_w = comptime std.unicode.utf8ToUtf16LeStringLiteral(key); |
| 444 | 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 | |
| 446 | // []u8 and []u16 like how many std.mem functions work. | |
| 447 | _ = text; | |
| 448 | @compileError("TODO implement this"); | |
| 445 | return std.fmt.parseIntWithGenericCharacter(I, u16, text, base); | |
| 449 | 446 | } else if (native_os == .wasi and !builtin.link_libc) { |
| 450 | 447 | @compileError("parseEnvVarInt is not supported for WASI without libc"); |
| 451 | 448 | } else { |
src/Module.zig+1-1| ... | ... | @@ -4504,7 +4504,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato |
| 4504 | 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 | 4508 | defer decl_prog_node.end(); |
| 4509 | 4509 | |
| 4510 | 4510 | mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index })); |