| author | |
| committer | |
| log | d62f22cc4d2f17db0877cd9316bf8be9470d04a5 |
| tree | bc97e5ae7485bf5f50350a1068019aae4db9b0db |
| parent | 6a0f2227e8b40e3456d3c85c72f68f483b239af3 |
5 files changed, 103 insertions(+), 52 deletions(-)
lib/std/io/BufferedReader.zig+52-22| ... | ... | @@ -484,11 +484,13 @@ fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) Delimiter |
| 484 | 484 | /// found. Does not write the delimiter itself. |
| 485 | 485 | /// |
| 486 | 486 | /// Returns number of bytes streamed. |
| 487 | pub fn streamReadDelimiter(br: *BufferedReader, bw: *BufferedWriter, delimiter: u8) Reader.Error!usize { | |
| 488 | _ = br; | |
| 489 | _ = bw; | |
| 490 | _ = delimiter; | |
| 491 | @panic("TODO"); | |
| 487 | pub fn streamToDelimiter(br: *BufferedReader, bw: *BufferedWriter, delimiter: u8) Reader.RwError!usize { | |
| 488 | const amount, const to = try br.streamToAny(bw, delimiter, .unlimited); | |
| 489 | return switch (to) { | |
| 490 | .delimiter => amount, | |
| 491 | .limit => unreachable, | |
| 492 | .end => error.EndOfStream, | |
| 493 | }; | |
| 492 | 494 | } |
| 493 | 495 | |
| 494 | 496 | /// Appends to `bw` contents by reading from the stream until `delimiter` is found. |
| ... | ... | @@ -497,18 +499,19 @@ pub fn streamReadDelimiter(br: *BufferedReader, bw: *BufferedWriter, delimiter: |
| 497 | 499 | /// Succeeds if stream ends before delimiter found. |
| 498 | 500 | /// |
| 499 | 501 | /// Returns number of bytes streamed. The end is not signaled to the writer. |
| 500 | pub fn streamReadDelimiterExclusive( | |
| 502 | pub fn streamToDelimiterOrEnd( | |
| 501 | 503 | br: *BufferedReader, |
| 502 | 504 | bw: *BufferedWriter, |
| 503 | 505 | delimiter: u8, |
| 504 | ) Reader.ShortError!usize { | |
| 505 | _ = br; | |
| 506 | _ = bw; | |
| 507 | _ = delimiter; | |
| 508 | @panic("TODO"); | |
| 506 | ) Reader.RwAllError!usize { | |
| 507 | const amount, const to = try br.streamToAny(bw, delimiter, .unlimited); | |
| 508 | return switch (to) { | |
| 509 | .delimiter, .end => amount, | |
| 510 | .limit => unreachable, | |
| 511 | }; | |
| 509 | 512 | } |
| 510 | 513 | |
| 511 | pub const StreamDelimiterLimitedError = Reader.ShortError || error{ | |
| 514 | pub const StreamDelimiterLimitedError = Reader.RwAllError || error{ | |
| 512 | 515 | /// Stream ended before the delimiter was found. |
| 513 | 516 | EndOfStream, |
| 514 | 517 | /// The delimiter was not found within the limit. |
| ... | ... | @@ -517,19 +520,46 @@ pub const StreamDelimiterLimitedError = Reader.ShortError || error{ |
| 517 | 520 | |
| 518 | 521 | /// Appends to `bw` contents by reading from the stream until `delimiter` is found. |
| 519 | 522 | /// Does not write the delimiter itself. |
| 520 | // | |
| 523 | /// | |
| 521 | 524 | /// Returns number of bytes streamed. |
| 522 | pub fn streamReadDelimiterLimited( | |
| 525 | pub fn streamToDelimiterOrLimit( | |
| 523 | 526 | br: *BufferedReader, |
| 524 | 527 | bw: *BufferedWriter, |
| 525 | 528 | delimiter: u8, |
| 526 | 529 | limit: Reader.Limit, |
| 527 | 530 | ) StreamDelimiterLimitedError!usize { |
| 528 | _ = br; | |
| 529 | _ = bw; | |
| 530 | _ = delimiter; | |
| 531 | _ = limit; | |
| 532 | @panic("TODO"); | |
| 531 | const amount, const to = try br.streamToAny(bw, delimiter, limit); | |
| 532 | return switch (to) { | |
| 533 | .delimiter => amount, | |
| 534 | .limit => error.StreamTooLong, | |
| 535 | .end => error.EndOfStream, | |
| 536 | }; | |
| 537 | } | |
| 538 | ||
| 539 | fn streamToAny( | |
| 540 | br: *BufferedReader, | |
| 541 | bw: *BufferedWriter, | |
| 542 | delimiter: ?u8, | |
| 543 | limit: Reader.Limit, | |
| 544 | ) Reader.RwAllError!struct { usize, enum { delimiter, limit, end } } { | |
| 545 | var amount: usize = 0; | |
| 546 | var remaining = limit; | |
| 547 | while (remaining.nonzero()) { | |
| 548 | const available = remaining.slice(br.peekGreedy(1) catch |err| switch (err) { | |
| 549 | error.ReadFailed => |e| return e, | |
| 550 | error.EndOfStream => return .{ amount, .end }, | |
| 551 | }); | |
| 552 | if (delimiter) |d| if (std.mem.indexOfScalar(u8, available, d)) |delimiter_index| { | |
| 553 | try bw.writeAll(available[0..delimiter_index]); | |
| 554 | br.toss(delimiter_index + 1); | |
| 555 | return .{ amount + delimiter_index, .delimiter }; | |
| 556 | }; | |
| 557 | try bw.writeAll(available); | |
| 558 | br.toss(available.len); | |
| 559 | amount += available.len; | |
| 560 | remaining = remaining.subtract(available.len).?; | |
| 561 | } | |
| 562 | return .{ amount, .limit }; | |
| 533 | 563 | } |
| 534 | 564 | |
| 535 | 565 | /// Reads from the stream until specified byte is found, discarding all data, |
| ... | ... | @@ -824,15 +854,15 @@ test peekDelimiterExclusive { |
| 824 | 854 | return error.Unimplemented; |
| 825 | 855 | } |
| 826 | 856 | |
| 827 | test streamReadDelimiter { | |
| 857 | test streamToDelimiter { | |
| 828 | 858 | return error.Unimplemented; |
| 829 | 859 | } |
| 830 | 860 | |
| 831 | test streamReadDelimiterExclusive { | |
| 861 | test streamToDelimiterOrEnd { | |
| 832 | 862 | return error.Unimplemented; |
| 833 | 863 | } |
| 834 | 864 | |
| 835 | test streamReadDelimiterLimited { | |
| 865 | test streamToDelimiterOrLimit { | |
| 836 | 866 | return error.Unimplemented; |
| 837 | 867 | } |
| 838 | 868 |
src/Compilation.zig+14-11| ... | ... | @@ -1000,11 +1000,14 @@ pub const CObject = struct { |
| 1000 | 1000 | defer file.close(); |
| 1001 | 1001 | file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; |
| 1002 | 1002 | |
| 1003 | var line = std.ArrayList(u8).init(eb.gpa); | |
| 1004 | defer line.deinit(); | |
| 1005 | file.reader().readUntilDelimiterArrayList(&line, '\n', 1 << 10) catch break :source_line 0; | |
| 1006 | ||
| 1007 | break :source_line try eb.addString(line.items); | |
| 1003 | var buffer: [1 << 10]u8 = undefined; | |
| 1004 | var fr = file.reader(); | |
| 1005 | var br = fr.interface().buffered(&buffer); | |
| 1006 | var bw: std.io.BufferedWriter = undefined; | |
| 1007 | bw.initFixed(&buffer); | |
| 1008 | break :source_line try eb.addString( | |
| 1009 | buffer[0 .. br.streamToDelimiterOrEnd(&bw, '\n') catch break :source_line 0], | |
| 1010 | ); | |
| 1008 | 1011 | }; |
| 1009 | 1012 | |
| 1010 | 1013 | return .{ |
| ... | ... | @@ -3781,7 +3784,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3781 | 3784 | if (!refs.contains(anal_unit)) continue; |
| 3782 | 3785 | } |
| 3783 | 3786 | |
| 3784 | std.log.scoped(.zcu).debug("analysis error '{s}' reported from unit '{}'", .{ | |
| 3787 | std.log.scoped(.zcu).debug("analysis error '{s}' reported from unit '{f}'", .{ | |
| 3785 | 3788 | error_msg.msg, |
| 3786 | 3789 | zcu.fmtAnalUnit(anal_unit), |
| 3787 | 3790 | }); |
| ... | ... | @@ -3941,12 +3944,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3941 | 3944 | // This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error. |
| 3942 | 3945 | // However, we haven't reported any such error. |
| 3943 | 3946 | // This is a compiler bug. |
| 3944 | var stderr = std.debug.lockStdErr2(&.{}); | |
| 3945 | defer std.debug.unlockStdErr(); | |
| 3946 | try stderr.writeAll("referenced transitive analysis errors, but none actually emitted\n"); | |
| 3947 | try stderr.print("{} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}); | |
| 3947 | var stderr_bw = std.debug.lockStderrWriter(&.{}); | |
| 3948 | defer std.debug.unlockStderrWriter(); | |
| 3949 | try stderr_bw.writeAll("referenced transitive analysis errors, but none actually emitted\n"); | |
| 3950 | try stderr_bw.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}); | |
| 3948 | 3951 | while (ref) |r| { |
| 3949 | try stderr.print("referenced by: {}{s}\n", .{ | |
| 3952 | try stderr_bw.print("referenced by: {f}{s}\n", .{ | |
| 3950 | 3953 | zcu.fmtAnalUnit(r.referencer), |
| 3951 | 3954 | if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "", |
| 3952 | 3955 | }); |
src/Zcu/PerThread.zig+2-2| ... | ... | @@ -268,7 +268,7 @@ pub fn updateFile( |
| 268 | 268 | file.zir = try AstGen.generate(gpa, file.tree.?); |
| 269 | 269 | Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) { |
| 270 | 270 | error.OutOfMemory => |e| return e, |
| 271 | else => log.warn("unable to write cached ZIR code for {} to {}{s}: {s}", .{ | |
| 271 | else => log.warn("unable to write cached ZIR code for {f} to {f}{s}: {s}", .{ | |
| 272 | 272 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), |
| 273 | 273 | }), |
| 274 | 274 | }; |
| ... | ... | @@ -276,7 +276,7 @@ pub fn updateFile( |
| 276 | 276 | .zon => { |
| 277 | 277 | file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); |
| 278 | 278 | Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| { |
| 279 | log.warn("unable to write cached ZOIR code for {} to {}{s}: {s}", .{ | |
| 279 | log.warn("unable to write cached ZOIR code for {f} to {f}{s}: {s}", .{ | |
| 280 | 280 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), |
| 281 | 281 | }); |
| 282 | 282 | }; |
src/link.zig+33-15| ... | ... | @@ -1023,15 +1023,24 @@ pub const File = struct { |
| 1023 | 1023 | }; |
| 1024 | 1024 | } |
| 1025 | 1025 | |
| 1026 | fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: fs.File) anyerror!void { | |
| 1026 | fn loadGnuLdScript( | |
| 1027 | base: *File, | |
| 1028 | path: Path, | |
| 1029 | parent_query: UnresolvedInput.Query, | |
| 1030 | file: fs.File, | |
| 1031 | ) anyerror!void { | |
| 1027 | 1032 | const diags = &base.comp.link_diags; |
| 1028 | 1033 | const gpa = base.comp.gpa; |
| 1029 | 1034 | const stat = try file.stat(); |
| 1030 | 1035 | const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig; |
| 1031 | 1036 | const buf = try gpa.alloc(u8, size); |
| 1032 | 1037 | defer gpa.free(buf); |
| 1033 | const n = try file.preadAll(buf, 0); | |
| 1034 | if (buf.len != n) return error.UnexpectedEndOfFile; | |
| 1038 | var fr = file.reader(); | |
| 1039 | var br = fr.interface().unbuffered(); | |
| 1040 | br.readSlice(buf) catch |err| switch (err) { | |
| 1041 | error.ReadFailed => if (fr.err) |_| unreachable else |e| return e, | |
| 1042 | error.EndOfStream => return error.UnexpectedEndOfFile, | |
| 1043 | }; | |
| 1035 | 1044 | var ld_script = try LdScript.parse(gpa, diags, path, buf); |
| 1036 | 1045 | defer ld_script.deinit(gpa); |
| 1037 | 1046 | for (ld_script.args) |arg| { |
| ... | ... | @@ -2092,24 +2101,33 @@ fn resolvePathInputLib( |
| 2092 | 2101 | }; |
| 2093 | 2102 | errdefer file.close(); |
| 2094 | 2103 | try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len)); |
| 2095 | const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f'}': {s}", .{ | |
| 2096 | test_path, @errorName(err), | |
| 2097 | }); | |
| 2098 | const buf = ld_script_bytes.items[0..n]; | |
| 2099 | if (mem.startsWith(u8, buf, std.elf.MAGIC) or mem.startsWith(u8, buf, std.elf.ARMAG)) { | |
| 2100 | // Appears to be an ELF or archive file. | |
| 2101 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); | |
| 2104 | var fr = file.reader(); | |
| 2105 | var br = fr.interface().unbuffered(); | |
| 2106 | ok: { | |
| 2107 | br.readSlice(ld_script_bytes.items) catch |err| switch (err) { | |
| 2108 | error.ReadFailed => fatal("failed to read '{f'}': {s}", .{ | |
| 2109 | test_path, | |
| 2110 | @errorName(if (fr.err) |_| unreachable else |e| e), | |
| 2111 | }), | |
| 2112 | error.EndOfStream => break :ok, | |
| 2113 | }; | |
| 2114 | if (mem.startsWith(u8, ld_script_bytes.items, std.elf.MAGIC) or | |
| 2115 | mem.startsWith(u8, ld_script_bytes.items, std.elf.ARMAG)) | |
| 2116 | { | |
| 2117 | // Appears to be an ELF or archive file. | |
| 2118 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); | |
| 2119 | } | |
| 2102 | 2120 | } |
| 2103 | 2121 | const stat = file.stat() catch |err| |
| 2104 | 2122 | fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) }); |
| 2105 | 2123 | const size = std.math.cast(u32, stat.size) orelse |
| 2106 | 2124 | fatal("{f}: linker script too big", .{test_path}); |
| 2107 | 2125 | try ld_script_bytes.resize(gpa, size); |
| 2108 | const buf2 = ld_script_bytes.items[n..]; | |
| 2109 | const n2 = file.preadAll(buf2, n) catch |err| | |
| 2110 | fatal("failed to read {f}: {s}", .{ test_path, @errorName(err) }); | |
| 2111 | if (n2 != buf2.len) fatal("failed to read {f}: unexpected end of file", .{test_path}); | |
| 2112 | var diags = Diags.init(gpa); | |
| 2126 | br.readSlice(ld_script_bytes.items[@intCast(fr.pos)..]) catch |err| switch (err) { | |
| 2127 | error.ReadFailed => if (fr.err) |_| unreachable else |e| fatal("failed to read {f}: {s}", .{ test_path, @errorName(e) }), | |
| 2128 | error.EndOfStream => fatal("failed to read {f}: unexpected end of file", .{test_path}), | |
| 2129 | }; | |
| 2130 | var diags: Diags = .init(gpa); | |
| 2113 | 2131 | defer diags.deinit(); |
| 2114 | 2132 | const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items); |
| 2115 | 2133 | if (diags.hasErrors()) { |
src/main.zig+2-2| ... | ... | @@ -3511,7 +3511,7 @@ fn buildOutputType( |
| 3511 | 3511 | if (t.arch == target.cpu.arch and t.os == target.os.tag) { |
| 3512 | 3512 | // If there's a `glibc_min`, there's also an `os_ver`. |
| 3513 | 3513 | if (t.glibc_min) |glibc_min| { |
| 3514 | std.log.info("zig can provide libc for related target {s}-{s}.{}-{s}.{d}.{d}", .{ | |
| 3514 | std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}.{d}.{d}", .{ | |
| 3515 | 3515 | @tagName(t.arch), |
| 3516 | 3516 | @tagName(t.os), |
| 3517 | 3517 | t.os_ver.?, |
| ... | ... | @@ -3520,7 +3520,7 @@ fn buildOutputType( |
| 3520 | 3520 | glibc_min.minor, |
| 3521 | 3521 | }); |
| 3522 | 3522 | } else if (t.os_ver) |os_ver| { |
| 3523 | std.log.info("zig can provide libc for related target {s}-{s}.{}-{s}", .{ | |
| 3523 | std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}", .{ | |
| 3524 | 3524 | @tagName(t.arch), |
| 3525 | 3525 | @tagName(t.os), |
| 3526 | 3526 | os_ver, |