mirror of
https://github.com/ziglang/zig.git
synced 2026-01-06 13:33:21 +00:00
link: port to std.io.BufferedReader API changes
This commit is contained in:
parent
6a0f2227e8
commit
d62f22cc4d
@ -484,11 +484,13 @@ fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) Delimiter
|
||||
/// found. Does not write the delimiter itself.
|
||||
///
|
||||
/// Returns number of bytes streamed.
|
||||
pub fn streamReadDelimiter(br: *BufferedReader, bw: *BufferedWriter, delimiter: u8) Reader.Error!usize {
|
||||
_ = br;
|
||||
_ = bw;
|
||||
_ = delimiter;
|
||||
@panic("TODO");
|
||||
pub fn streamToDelimiter(br: *BufferedReader, bw: *BufferedWriter, delimiter: u8) Reader.RwError!usize {
|
||||
const amount, const to = try br.streamToAny(bw, delimiter, .unlimited);
|
||||
return switch (to) {
|
||||
.delimiter => amount,
|
||||
.limit => unreachable,
|
||||
.end => error.EndOfStream,
|
||||
};
|
||||
}
|
||||
|
||||
/// 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:
|
||||
/// Succeeds if stream ends before delimiter found.
|
||||
///
|
||||
/// Returns number of bytes streamed. The end is not signaled to the writer.
|
||||
pub fn streamReadDelimiterExclusive(
|
||||
pub fn streamToDelimiterOrEnd(
|
||||
br: *BufferedReader,
|
||||
bw: *BufferedWriter,
|
||||
delimiter: u8,
|
||||
) Reader.ShortError!usize {
|
||||
_ = br;
|
||||
_ = bw;
|
||||
_ = delimiter;
|
||||
@panic("TODO");
|
||||
) Reader.RwAllError!usize {
|
||||
const amount, const to = try br.streamToAny(bw, delimiter, .unlimited);
|
||||
return switch (to) {
|
||||
.delimiter, .end => amount,
|
||||
.limit => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub const StreamDelimiterLimitedError = Reader.ShortError || error{
|
||||
pub const StreamDelimiterLimitedError = Reader.RwAllError || error{
|
||||
/// Stream ended before the delimiter was found.
|
||||
EndOfStream,
|
||||
/// The delimiter was not found within the limit.
|
||||
@ -517,19 +520,46 @@ pub const StreamDelimiterLimitedError = Reader.ShortError || error{
|
||||
|
||||
/// Appends to `bw` contents by reading from the stream until `delimiter` is found.
|
||||
/// Does not write the delimiter itself.
|
||||
//
|
||||
///
|
||||
/// Returns number of bytes streamed.
|
||||
pub fn streamReadDelimiterLimited(
|
||||
pub fn streamToDelimiterOrLimit(
|
||||
br: *BufferedReader,
|
||||
bw: *BufferedWriter,
|
||||
delimiter: u8,
|
||||
limit: Reader.Limit,
|
||||
) StreamDelimiterLimitedError!usize {
|
||||
_ = br;
|
||||
_ = bw;
|
||||
_ = delimiter;
|
||||
_ = limit;
|
||||
@panic("TODO");
|
||||
const amount, const to = try br.streamToAny(bw, delimiter, limit);
|
||||
return switch (to) {
|
||||
.delimiter => amount,
|
||||
.limit => error.StreamTooLong,
|
||||
.end => error.EndOfStream,
|
||||
};
|
||||
}
|
||||
|
||||
fn streamToAny(
|
||||
br: *BufferedReader,
|
||||
bw: *BufferedWriter,
|
||||
delimiter: ?u8,
|
||||
limit: Reader.Limit,
|
||||
) Reader.RwAllError!struct { usize, enum { delimiter, limit, end } } {
|
||||
var amount: usize = 0;
|
||||
var remaining = limit;
|
||||
while (remaining.nonzero()) {
|
||||
const available = remaining.slice(br.peekGreedy(1) catch |err| switch (err) {
|
||||
error.ReadFailed => |e| return e,
|
||||
error.EndOfStream => return .{ amount, .end },
|
||||
});
|
||||
if (delimiter) |d| if (std.mem.indexOfScalar(u8, available, d)) |delimiter_index| {
|
||||
try bw.writeAll(available[0..delimiter_index]);
|
||||
br.toss(delimiter_index + 1);
|
||||
return .{ amount + delimiter_index, .delimiter };
|
||||
};
|
||||
try bw.writeAll(available);
|
||||
br.toss(available.len);
|
||||
amount += available.len;
|
||||
remaining = remaining.subtract(available.len).?;
|
||||
}
|
||||
return .{ amount, .limit };
|
||||
}
|
||||
|
||||
/// Reads from the stream until specified byte is found, discarding all data,
|
||||
@ -824,15 +854,15 @@ test peekDelimiterExclusive {
|
||||
return error.Unimplemented;
|
||||
}
|
||||
|
||||
test streamReadDelimiter {
|
||||
test streamToDelimiter {
|
||||
return error.Unimplemented;
|
||||
}
|
||||
|
||||
test streamReadDelimiterExclusive {
|
||||
test streamToDelimiterOrEnd {
|
||||
return error.Unimplemented;
|
||||
}
|
||||
|
||||
test streamReadDelimiterLimited {
|
||||
test streamToDelimiterOrLimit {
|
||||
return error.Unimplemented;
|
||||
}
|
||||
|
||||
|
||||
@ -1000,11 +1000,14 @@ pub const CObject = struct {
|
||||
defer file.close();
|
||||
file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0;
|
||||
|
||||
var line = std.ArrayList(u8).init(eb.gpa);
|
||||
defer line.deinit();
|
||||
file.reader().readUntilDelimiterArrayList(&line, '\n', 1 << 10) catch break :source_line 0;
|
||||
|
||||
break :source_line try eb.addString(line.items);
|
||||
var buffer: [1 << 10]u8 = undefined;
|
||||
var fr = file.reader();
|
||||
var br = fr.interface().buffered(&buffer);
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buffer);
|
||||
break :source_line try eb.addString(
|
||||
buffer[0 .. br.streamToDelimiterOrEnd(&bw, '\n') catch break :source_line 0],
|
||||
);
|
||||
};
|
||||
|
||||
return .{
|
||||
@ -3781,7 +3784,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
||||
if (!refs.contains(anal_unit)) continue;
|
||||
}
|
||||
|
||||
std.log.scoped(.zcu).debug("analysis error '{s}' reported from unit '{}'", .{
|
||||
std.log.scoped(.zcu).debug("analysis error '{s}' reported from unit '{f}'", .{
|
||||
error_msg.msg,
|
||||
zcu.fmtAnalUnit(anal_unit),
|
||||
});
|
||||
@ -3941,12 +3944,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
|
||||
// This AU is referenced and has a transitive compile error, meaning it referenced something with a compile error.
|
||||
// However, we haven't reported any such error.
|
||||
// This is a compiler bug.
|
||||
var stderr = std.debug.lockStdErr2(&.{});
|
||||
defer std.debug.unlockStdErr();
|
||||
try stderr.writeAll("referenced transitive analysis errors, but none actually emitted\n");
|
||||
try stderr.print("{} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)});
|
||||
var stderr_bw = std.debug.lockStderrWriter(&.{});
|
||||
defer std.debug.unlockStderrWriter();
|
||||
try stderr_bw.writeAll("referenced transitive analysis errors, but none actually emitted\n");
|
||||
try stderr_bw.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)});
|
||||
while (ref) |r| {
|
||||
try stderr.print("referenced by: {}{s}\n", .{
|
||||
try stderr_bw.print("referenced by: {f}{s}\n", .{
|
||||
zcu.fmtAnalUnit(r.referencer),
|
||||
if (zcu.transitive_failed_analysis.contains(r.referencer)) " [transitive failure]" else "",
|
||||
});
|
||||
|
||||
@ -268,7 +268,7 @@ pub fn updateFile(
|
||||
file.zir = try AstGen.generate(gpa, file.tree.?);
|
||||
Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) {
|
||||
error.OutOfMemory => |e| return e,
|
||||
else => log.warn("unable to write cached ZIR code for {} to {}{s}: {s}", .{
|
||||
else => log.warn("unable to write cached ZIR code for {f} to {f}{s}: {s}", .{
|
||||
file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err),
|
||||
}),
|
||||
};
|
||||
@ -276,7 +276,7 @@ pub fn updateFile(
|
||||
.zon => {
|
||||
file.zoir = try ZonGen.generate(gpa, file.tree.?, .{});
|
||||
Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| {
|
||||
log.warn("unable to write cached ZOIR code for {} to {}{s}: {s}", .{
|
||||
log.warn("unable to write cached ZOIR code for {f} to {f}{s}: {s}", .{
|
||||
file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err),
|
||||
});
|
||||
};
|
||||
|
||||
48
src/link.zig
48
src/link.zig
@ -1023,15 +1023,24 @@ pub const File = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn loadGnuLdScript(base: *File, path: Path, parent_query: UnresolvedInput.Query, file: fs.File) anyerror!void {
|
||||
fn loadGnuLdScript(
|
||||
base: *File,
|
||||
path: Path,
|
||||
parent_query: UnresolvedInput.Query,
|
||||
file: fs.File,
|
||||
) anyerror!void {
|
||||
const diags = &base.comp.link_diags;
|
||||
const gpa = base.comp.gpa;
|
||||
const stat = try file.stat();
|
||||
const size = std.math.cast(u32, stat.size) orelse return error.FileTooBig;
|
||||
const buf = try gpa.alloc(u8, size);
|
||||
defer gpa.free(buf);
|
||||
const n = try file.preadAll(buf, 0);
|
||||
if (buf.len != n) return error.UnexpectedEndOfFile;
|
||||
var fr = file.reader();
|
||||
var br = fr.interface().unbuffered();
|
||||
br.readSlice(buf) catch |err| switch (err) {
|
||||
error.ReadFailed => if (fr.err) |_| unreachable else |e| return e,
|
||||
error.EndOfStream => return error.UnexpectedEndOfFile,
|
||||
};
|
||||
var ld_script = try LdScript.parse(gpa, diags, path, buf);
|
||||
defer ld_script.deinit(gpa);
|
||||
for (ld_script.args) |arg| {
|
||||
@ -2092,24 +2101,33 @@ fn resolvePathInputLib(
|
||||
};
|
||||
errdefer file.close();
|
||||
try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len));
|
||||
const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f'}': {s}", .{
|
||||
test_path, @errorName(err),
|
||||
});
|
||||
const buf = ld_script_bytes.items[0..n];
|
||||
if (mem.startsWith(u8, buf, std.elf.MAGIC) or mem.startsWith(u8, buf, std.elf.ARMAG)) {
|
||||
// Appears to be an ELF or archive file.
|
||||
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
|
||||
var fr = file.reader();
|
||||
var br = fr.interface().unbuffered();
|
||||
ok: {
|
||||
br.readSlice(ld_script_bytes.items) catch |err| switch (err) {
|
||||
error.ReadFailed => fatal("failed to read '{f'}': {s}", .{
|
||||
test_path,
|
||||
@errorName(if (fr.err) |_| unreachable else |e| e),
|
||||
}),
|
||||
error.EndOfStream => break :ok,
|
||||
};
|
||||
if (mem.startsWith(u8, ld_script_bytes.items, std.elf.MAGIC) or
|
||||
mem.startsWith(u8, ld_script_bytes.items, std.elf.ARMAG))
|
||||
{
|
||||
// Appears to be an ELF or archive file.
|
||||
return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query);
|
||||
}
|
||||
}
|
||||
const stat = file.stat() catch |err|
|
||||
fatal("failed to stat {f}: {s}", .{ test_path, @errorName(err) });
|
||||
const size = std.math.cast(u32, stat.size) orelse
|
||||
fatal("{f}: linker script too big", .{test_path});
|
||||
try ld_script_bytes.resize(gpa, size);
|
||||
const buf2 = ld_script_bytes.items[n..];
|
||||
const n2 = file.preadAll(buf2, n) catch |err|
|
||||
fatal("failed to read {f}: {s}", .{ test_path, @errorName(err) });
|
||||
if (n2 != buf2.len) fatal("failed to read {f}: unexpected end of file", .{test_path});
|
||||
var diags = Diags.init(gpa);
|
||||
br.readSlice(ld_script_bytes.items[@intCast(fr.pos)..]) catch |err| switch (err) {
|
||||
error.ReadFailed => if (fr.err) |_| unreachable else |e| fatal("failed to read {f}: {s}", .{ test_path, @errorName(e) }),
|
||||
error.EndOfStream => fatal("failed to read {f}: unexpected end of file", .{test_path}),
|
||||
};
|
||||
var diags: Diags = .init(gpa);
|
||||
defer diags.deinit();
|
||||
const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items);
|
||||
if (diags.hasErrors()) {
|
||||
|
||||
@ -3511,7 +3511,7 @@ fn buildOutputType(
|
||||
if (t.arch == target.cpu.arch and t.os == target.os.tag) {
|
||||
// If there's a `glibc_min`, there's also an `os_ver`.
|
||||
if (t.glibc_min) |glibc_min| {
|
||||
std.log.info("zig can provide libc for related target {s}-{s}.{}-{s}.{d}.{d}", .{
|
||||
std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}.{d}.{d}", .{
|
||||
@tagName(t.arch),
|
||||
@tagName(t.os),
|
||||
t.os_ver.?,
|
||||
@ -3520,7 +3520,7 @@ fn buildOutputType(
|
||||
glibc_min.minor,
|
||||
});
|
||||
} else if (t.os_ver) |os_ver| {
|
||||
std.log.info("zig can provide libc for related target {s}-{s}.{}-{s}", .{
|
||||
std.log.info("zig can provide libc for related target {s}-{s}.{f}-{s}", .{
|
||||
@tagName(t.arch),
|
||||
@tagName(t.os),
|
||||
os_ver,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user