| 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,11 +484,13 @@ fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) Delimiter |
| 484 | /// found. Does not write the delimiter itself. | 484 | /// found. Does not write the delimiter itself. |
| 485 | /// | 485 | /// |
| 486 | /// Returns number of bytes streamed. | 486 | /// Returns number of bytes streamed. |
| 487 | pub fn streamReadDelimiter(br: *BufferedReader, bw: *BufferedWriter, delimiter: u8) Reader.Error!usize { | 487 | pub fn streamToDelimiter(br: *BufferedReader, bw: *BufferedWriter, delimiter: u8) Reader.RwError!usize { |
| 488 | _ = br; | 488 | const amount, const to = try br.streamToAny(bw, delimiter, .unlimited); |
| 489 | _ = bw; | 489 | return switch (to) { |
| 490 | _ = delimiter; | 490 | .delimiter => amount, |
| 491 | @panic("TODO"); | 491 | .limit => unreachable, |
| 492 | .end => error.EndOfStream, | ||
| 493 | }; | ||
| 492 | } | 494 | } |
| 493 | 495 | ||
| 494 | /// Appends to `bw` contents by reading from the stream until `delimiter` is found. | 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,18 +499,19 @@ pub fn streamReadDelimiter(br: *BufferedReader, bw: *BufferedWriter, delimiter: |
| 497 | /// Succeeds if stream ends before delimiter found. | 499 | /// Succeeds if stream ends before delimiter found. |
| 498 | /// | 500 | /// |
| 499 | /// Returns number of bytes streamed. The end is not signaled to the writer. | 501 | /// Returns number of bytes streamed. The end is not signaled to the writer. |
| 500 | pub fn streamReadDelimiterExclusive( | 502 | pub fn streamToDelimiterOrEnd( |
| 501 | br: *BufferedReader, | 503 | br: *BufferedReader, |
| 502 | bw: *BufferedWriter, | 504 | bw: *BufferedWriter, |
| 503 | delimiter: u8, | 505 | delimiter: u8, |
| 504 | ) Reader.ShortError!usize { | 506 | ) Reader.RwAllError!usize { |
| 505 | _ = br; | 507 | const amount, const to = try br.streamToAny(bw, delimiter, .unlimited); |
| 506 | _ = bw; | 508 | return switch (to) { |
| 507 | _ = delimiter; | 509 | .delimiter, .end => amount, |
| 508 | @panic("TODO"); | 510 | .limit => unreachable, |
| 511 | }; | ||
| 509 | } | 512 | } |
| 510 | 513 | ||
| 511 | pub const StreamDelimiterLimitedError = Reader.ShortError || error{ | 514 | pub const StreamDelimiterLimitedError = Reader.RwAllError || error{ |
| 512 | /// Stream ended before the delimiter was found. | 515 | /// Stream ended before the delimiter was found. |
| 513 | EndOfStream, | 516 | EndOfStream, |
| 514 | /// The delimiter was not found within the limit. | 517 | /// The delimiter was not found within the limit. |
| ... | @@ -517,19 +520,46 @@ pub const StreamDelimiterLimitedError = Reader.ShortError || error{ | ... | @@ -517,19 +520,46 @@ pub const StreamDelimiterLimitedError = Reader.ShortError || error{ |
| 517 | 520 | ||
| 518 | /// Appends to `bw` contents by reading from the stream until `delimiter` is found. | 521 | /// Appends to `bw` contents by reading from the stream until `delimiter` is found. |
| 519 | /// Does not write the delimiter itself. | 522 | /// Does not write the delimiter itself. |
| 520 | // | 523 | /// |
| 521 | /// Returns number of bytes streamed. | 524 | /// Returns number of bytes streamed. |
| 522 | pub fn streamReadDelimiterLimited( | 525 | pub fn streamToDelimiterOrLimit( |
| 523 | br: *BufferedReader, | 526 | br: *BufferedReader, |
| 524 | bw: *BufferedWriter, | 527 | bw: *BufferedWriter, |
| 525 | delimiter: u8, | 528 | delimiter: u8, |
| 526 | limit: Reader.Limit, | 529 | limit: Reader.Limit, |
| 527 | ) StreamDelimiterLimitedError!usize { | 530 | ) StreamDelimiterLimitedError!usize { |
| 528 | _ = br; | 531 | const amount, const to = try br.streamToAny(bw, delimiter, limit); |
| 529 | _ = bw; | 532 | return switch (to) { |
| 530 | _ = delimiter; | 533 | .delimiter => amount, |
| 531 | _ = limit; | 534 | .limit => error.StreamTooLong, |
| 532 | @panic("TODO"); | 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 | /// Reads from the stream until specified byte is found, discarding all data, | 565 | /// Reads from the stream until specified byte is found, discarding all data, |
| ... | @@ -824,15 +854,15 @@ test peekDelimiterExclusive { | ... | @@ -824,15 +854,15 @@ test peekDelimiterExclusive { |
| 824 | return error.Unimplemented; | 854 | return error.Unimplemented; |
| 825 | } | 855 | } |
| 826 | 856 | ||
| 827 | test streamReadDelimiter { | 857 | test streamToDelimiter { |
| 828 | return error.Unimplemented; | 858 | return error.Unimplemented; |
| 829 | } | 859 | } |
| 830 | 860 | ||
| 831 | test streamReadDelimiterExclusive { | 861 | test streamToDelimiterOrEnd { |
| 832 | return error.Unimplemented; | 862 | return error.Unimplemented; |
| 833 | } | 863 | } |
| 834 | 864 | ||
| 835 | test streamReadDelimiterLimited { | 865 | test streamToDelimiterOrLimit { |
| 836 | return error.Unimplemented; | 866 | return error.Unimplemented; |
| 837 | } | 867 | } |
| 838 | 868 |
src/Compilation.zig+14-11| ... | @@ -1000,11 +1000,14 @@ pub const CObject = struct { | ... | @@ -1000,11 +1000,14 @@ pub const CObject = struct { |
| 1000 | defer file.close(); | 1000 | defer file.close(); |
| 1001 | file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0; | 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); | 1003 | var buffer: [1 << 10]u8 = undefined; |
| 1004 | defer line.deinit(); | 1004 | var fr = file.reader(); |
| 1005 | file.reader().readUntilDelimiterArrayList(&line, '\n', 1 << 10) catch break :source_line 0; | 1005 | var br = fr.interface().buffered(&buffer); |
| 1006 | 1006 | var bw: std.io.BufferedWriter = undefined; | |
| 1007 | break :source_line try eb.addString(line.items); | 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 | return .{ | 1013 | return .{ |
| ... | @@ -3781,7 +3784,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { | ... | @@ -3781,7 +3784,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3781 | if (!refs.contains(anal_unit)) continue; | 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 | error_msg.msg, | 3788 | error_msg.msg, |
| 3786 | zcu.fmtAnalUnit(anal_unit), | 3789 | zcu.fmtAnalUnit(anal_unit), |
| 3787 | }); | 3790 | }); |
| ... | @@ -3941,12 +3944,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { | ... | @@ -3941,12 +3944,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3941 | // This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error. | 3944 | // This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error. |
| 3942 | // However, we haven't reported any such error. | 3945 | // However, we haven't reported any such error. |
| 3943 | // This is a compiler bug. | 3946 | // This is a compiler bug. |
| 3944 | var stderr = std.debug.lockStdErr2(&.{}); | 3947 | var stderr_bw = std.debug.lockStderrWriter(&.{}); |
| 3945 | defer std.debug.unlockStdErr(); | 3948 | defer std.debug.unlockStderrWriter(); |
| 3946 | try stderr.writeAll("referenced transitive analysis errors, but none actually emitted\n"); | 3949 | try stderr_bw.writeAll("referenced transitive analysis errors, but none actually emitted\n"); |
| 3947 | try stderr.print("{} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}); | 3950 | try stderr_bw.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}); |
| 3948 | while (ref) |r| { | 3951 | while (ref) |r| { |
| 3949 | try stderr.print("referenced by: {}{s}\n", .{ | 3952 | try stderr_bw.print("referenced by: {f}{s}\n", .{ |
| 3950 | zcu.fmtAnalUnit(r.referencer), | 3953 | zcu.fmtAnalUnit(r.referencer), |
| 3951 | if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "", | 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,7 +268,7 @@ pub fn updateFile( |
| 268 | file.zir = try AstGen.generate(gpa, file.tree.?); | 268 | file.zir = try AstGen.generate(gpa, file.tree.?); |
| 269 | Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) { | 269 | Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) { |
| 270 | error.OutOfMemory => |e| return e, | 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 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), | 272 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), |
| 273 | }), | 273 | }), |
| 274 | }; | 274 | }; |
| ... | @@ -276,7 +276,7 @@ pub fn updateFile( | ... | @@ -276,7 +276,7 @@ pub fn updateFile( |
| 276 | .zon => { | 276 | .zon => { |
| 277 | file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); | 277 | file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); |
| 278 | Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| { | 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 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), | 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,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 | const diags = &base.comp.link_diags; | 1032 | const diags = &base.comp.link_diags; |
| 1028 | const gpa = base.comp.gpa; | 1033 | const gpa = base.comp.gpa; |
| 1029 | const stat = try file.stat(); | 1034 | const stat = try file.stat(); |
| 1030 | const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig; | 1035 | const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig; |
| 1031 | const buf = try gpa.alloc(u8, size); | 1036 | const buf = try gpa.alloc(u8, size); |
| 1032 | defer gpa.free(buf); | 1037 | defer gpa.free(buf); |
| 1033 | const n = try file.preadAll(buf, 0); | 1038 | var fr = file.reader(); |
| 1034 | if (buf.len != n) return error.UnexpectedEndOfFile; | 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 | var ld_script = try LdScript.parse(gpa, diags, path, buf); | 1044 | var ld_script = try LdScript.parse(gpa, diags, path, buf); |
| 1036 | defer ld_script.deinit(gpa); | 1045 | defer ld_script.deinit(gpa); |
| 1037 | for (ld_script.args) |arg| { | 1046 | for (ld_script.args) |arg| { |
| ... | @@ -2092,24 +2101,33 @@ fn resolvePathInputLib( | ... | @@ -2092,24 +2101,33 @@ fn resolvePathInputLib( |
| 2092 | }; | 2101 | }; |
| 2093 | errdefer file.close(); | 2102 | errdefer file.close(); |
| 2094 | try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len)); | 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}", .{ | 2104 | var fr = file.reader(); |
| 2096 | test_path, @errorName(err), | 2105 | var br = fr.interface().unbuffered(); |
| 2097 | }); | 2106 | ok: { |
| 2098 | const buf = ld_script_bytes.items[0..n]; | 2107 | br.readSlice(ld_script_bytes.items) catch |err| switch (err) { |
| 2099 | if (mem.startsWith(u8, buf, std.elf.MAGIC) or mem.startsWith(u8, buf, std.elf.ARMAG)) { | 2108 | error.ReadFailed => fatal("failed to read '{f'}': {s}", .{ |
| 2100 | // Appears to be an ELF or archive file. | 2109 | test_path, |
| 2101 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); | 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 | const stat = file.stat() catch |err| | 2121 | const stat = file.stat() catch |err| |
| 2104 | fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) }); | 2122 | fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) }); |
| 2105 | const size = std.math.cast(u32, stat.size) orelse | 2123 | const size = std.math.cast(u32, stat.size) orelse |
| 2106 | fatal("{f}: linker script too big", .{test_path}); | 2124 | fatal("{f}: linker script too big", .{test_path}); |
| 2107 | try ld_script_bytes.resize(gpa, size); | 2125 | try ld_script_bytes.resize(gpa, size); |
| 2108 | const buf2 = ld_script_bytes.items[n..]; | 2126 | br.readSlice(ld_script_bytes.items[@intCast(fr.pos)..]) catch |err| switch (err) { |
| 2109 | const n2 = file.preadAll(buf2, n) catch |err| | 2127 | error.ReadFailed => if (fr.err) |_| unreachable else |e| fatal("failed to read {f}: {s}", .{ test_path, @errorName(e) }), |
| 2110 | fatal("failed to read {f}: {s}", .{ test_path, @errorName(err) }); | 2128 | error.EndOfStream => fatal("failed to read {f}: unexpected end of file", .{test_path}), |
| 2111 | if (n2 != buf2.len) fatal("failed to read {f}: unexpected end of file", .{test_path}); | 2129 | }; |
| 2112 | var diags = Diags.init(gpa); | 2130 | var diags: Diags = .init(gpa); |
| 2113 | defer diags.deinit(); | 2131 | defer diags.deinit(); |
| 2114 | const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items); | 2132 | const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items); |
| 2115 | if (diags.hasErrors()) { | 2133 | if (diags.hasErrors()) { |
src/main.zig+2-2| ... | @@ -3511,7 +3511,7 @@ fn buildOutputType( | ... | @@ -3511,7 +3511,7 @@ fn buildOutputType( |
| 3511 | if (t.arch == target.cpu.arch and t.os == target.os.tag) { | 3511 | if (t.arch == target.cpu.arch and t.os == target.os.tag) { |
| 3512 | // If there's a `glibc_min`, there's also an `os_ver`. | 3512 | // If there's a `glibc_min`, there's also an `os_ver`. |
| 3513 | if (t.glibc_min) |glibc_min| { | 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 | @tagName(t.arch), | 3515 | @tagName(t.arch), |
| 3516 | @tagName(t.os), | 3516 | @tagName(t.os), |
| 3517 | t.os_ver.?, | 3517 | t.os_ver.?, |
| ... | @@ -3520,7 +3520,7 @@ fn buildOutputType( | ... | @@ -3520,7 +3520,7 @@ fn buildOutputType( |
| 3520 | glibc_min.minor, | 3520 | glibc_min.minor, |
| 3521 | }); | 3521 | }); |
| 3522 | } else if (t.os_ver) |os_ver| { | 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 | @tagName(t.arch), | 3524 | @tagName(t.arch), |
| 3525 | @tagName(t.os), | 3525 | @tagName(t.os), |
| 3526 | os_ver, | 3526 | os_ver, |