mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
std: combine BufferedWriter into Writer
This commit is contained in:
parent
3c98e2c826
commit
1e2aab2f97
6
lib/compiler/aro/aro/Diagnostics.zig
vendored
6
lib/compiler/aro/aro/Diagnostics.zig
vendored
@ -535,13 +535,13 @@ fn tagKind(d: *Diagnostics, tag: Tag, langopts: LangOpts) Kind {
|
||||
}
|
||||
|
||||
const MsgWriter = struct {
|
||||
w: std.io.BufferedWriter(4096, std.fs.File.Writer),
|
||||
w: *std.fs.File.Writer,
|
||||
config: std.io.tty.Config,
|
||||
|
||||
fn init(config: std.io.tty.Config) MsgWriter {
|
||||
fn init(config: std.io.tty.Config, buffer: []u8) MsgWriter {
|
||||
std.debug.lockStdErr();
|
||||
return .{
|
||||
.w = std.io.bufferedWriter(std.io.getStdErr().writer()),
|
||||
.w = std.fs.stderr().writer(buffer),
|
||||
.config = config,
|
||||
};
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ const Watch = std.Build.Watch;
|
||||
const Fuzz = std.Build.Fuzz;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const fatal = std.process.fatal;
|
||||
const Writer = std.io.Writer;
|
||||
const runner = @This();
|
||||
|
||||
pub const root = @import("@build");
|
||||
@ -773,7 +774,7 @@ const PrintNode = struct {
|
||||
last: bool = false,
|
||||
};
|
||||
|
||||
fn printPrefix(node: *PrintNode, stderr: *std.io.BufferedWriter, ttyconf: std.io.tty.Config) !void {
|
||||
fn printPrefix(node: *PrintNode, stderr: *Writer, ttyconf: std.io.tty.Config) !void {
|
||||
const parent = node.parent orelse return;
|
||||
if (parent.parent == null) return;
|
||||
try printPrefix(parent, stderr, ttyconf);
|
||||
@ -787,7 +788,7 @@ fn printPrefix(node: *PrintNode, stderr: *std.io.BufferedWriter, ttyconf: std.io
|
||||
}
|
||||
}
|
||||
|
||||
fn printChildNodePrefix(stderr: *std.io.BufferedWriter, ttyconf: std.io.tty.Config) !void {
|
||||
fn printChildNodePrefix(stderr: *Writer, ttyconf: std.io.tty.Config) !void {
|
||||
try stderr.writeAll(switch (ttyconf) {
|
||||
.no_color, .windows_api => "+- ",
|
||||
.escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─
|
||||
@ -796,7 +797,7 @@ fn printChildNodePrefix(stderr: *std.io.BufferedWriter, ttyconf: std.io.tty.Conf
|
||||
|
||||
fn printStepStatus(
|
||||
s: *Step,
|
||||
stderr: *std.io.BufferedWriter,
|
||||
stderr: *Writer,
|
||||
ttyconf: std.io.tty.Config,
|
||||
run: *const Run,
|
||||
) !void {
|
||||
@ -876,7 +877,7 @@ fn printStepStatus(
|
||||
|
||||
fn printStepFailure(
|
||||
s: *Step,
|
||||
stderr: *std.io.BufferedWriter,
|
||||
stderr: *Writer,
|
||||
ttyconf: std.io.tty.Config,
|
||||
) !void {
|
||||
if (s.result_error_bundle.errorMessageCount() > 0) {
|
||||
@ -930,7 +931,7 @@ fn printTreeStep(
|
||||
b: *std.Build,
|
||||
s: *Step,
|
||||
run: *const Run,
|
||||
stderr: *std.io.BufferedWriter,
|
||||
stderr: *Writer,
|
||||
ttyconf: std.io.tty.Config,
|
||||
parent_node: *PrintNode,
|
||||
step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void),
|
||||
@ -1188,7 +1189,7 @@ pub fn printErrorMessages(
|
||||
gpa: Allocator,
|
||||
failing_step: *Step,
|
||||
options: std.zig.ErrorBundle.RenderOptions,
|
||||
stderr: *std.io.BufferedWriter,
|
||||
stderr: *Writer,
|
||||
prominent_compile_errors: bool,
|
||||
) !void {
|
||||
// Provide context for where these error messages are coming from by
|
||||
@ -1241,7 +1242,7 @@ pub fn printErrorMessages(
|
||||
}
|
||||
}
|
||||
|
||||
fn steps(builder: *std.Build, bw: *std.io.BufferedWriter) !void {
|
||||
fn steps(builder: *std.Build, bw: *Writer) !void {
|
||||
const allocator = builder.allocator;
|
||||
for (builder.top_level_steps.values()) |top_level_step| {
|
||||
const name = if (&top_level_step.step == builder.default_step)
|
||||
@ -1254,7 +1255,7 @@ fn steps(builder: *std.Build, bw: *std.io.BufferedWriter) !void {
|
||||
|
||||
var stdio_buffer: [256]u8 = undefined;
|
||||
|
||||
fn usage(b: *std.Build, bw: *std.io.BufferedWriter) !void {
|
||||
fn usage(b: *std.Build, bw: *Writer) !void {
|
||||
try bw.print(
|
||||
\\Usage: {s} build [steps] [options]
|
||||
\\
|
||||
|
||||
@ -5,6 +5,7 @@ const Ast = std.zig.Ast;
|
||||
const Walk = @import("Walk");
|
||||
const markdown = @import("markdown.zig");
|
||||
const Decl = Walk.Decl;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const fileSourceHtml = @import("html_render.zig").fileSourceHtml;
|
||||
const appendEscaped = @import("html_render.zig").appendEscaped;
|
||||
@ -702,7 +703,7 @@ fn render_docs(
|
||||
r: markdown.Render,
|
||||
doc: markdown.Document,
|
||||
node: markdown.Document.Node.Index,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
) !void {
|
||||
const decl_index_ptr: *const Decl.Index = @alignCast(@ptrCast(r.context));
|
||||
const data = doc.nodes.items(.data)[@intFromEnum(node)];
|
||||
|
||||
@ -5,6 +5,7 @@ const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Render = @import("Render.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
nodes: Node.List.Slice,
|
||||
extra: []u32,
|
||||
@ -160,7 +161,7 @@ pub fn deinit(doc: *Document, allocator: Allocator) void {
|
||||
}
|
||||
|
||||
/// Renders a document directly to a writer using the default renderer.
|
||||
pub fn render(doc: Document, writer: *std.io.BufferedWriter) @TypeOf(writer).Error!void {
|
||||
pub fn render(doc: Document, writer: *Writer) Writer.Error!void {
|
||||
const renderer: Render(@TypeOf(writer), void) = .{ .context = {} };
|
||||
try renderer.render(doc, writer);
|
||||
}
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
//! for node types for which they require no special rendering.
|
||||
|
||||
const std = @import("std");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Document = @import("Document.zig");
|
||||
const Node = Document.Node;
|
||||
const Render = @This();
|
||||
@ -14,10 +16,10 @@ renderFn: *const fn (
|
||||
r: Render,
|
||||
doc: Document,
|
||||
node: Node.Index,
|
||||
writer: *std.io.BufferedWriter,
|
||||
) std.io.Writer.Error!void = renderDefault,
|
||||
writer: *Writer,
|
||||
) Writer.Error!void = renderDefault,
|
||||
|
||||
pub fn render(r: Render, doc: Document, writer: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn render(r: Render, doc: Document, writer: *Writer) Writer.Error!void {
|
||||
try r.renderFn(r, doc, .root, writer);
|
||||
}
|
||||
|
||||
@ -25,8 +27,8 @@ pub fn renderDefault(
|
||||
r: Render,
|
||||
doc: Document,
|
||||
node: Node.Index,
|
||||
writer: *std.io.BufferedWriter,
|
||||
) std.io.Writer.Error!void {
|
||||
writer: *Writer,
|
||||
) Writer.Error!void {
|
||||
const data = doc.nodes.items(.data)[@intFromEnum(node)];
|
||||
switch (doc.nodes.items(.tag)[@intFromEnum(node)]) {
|
||||
.root => {
|
||||
@ -183,8 +185,8 @@ pub fn renderDefault(
|
||||
pub fn renderInlineNodeText(
|
||||
doc: Document,
|
||||
node: Node.Index,
|
||||
writer: *std.io.BufferedWriter,
|
||||
) std.io.Writer.Error!void {
|
||||
writer: *Writer,
|
||||
) Writer.Error!void {
|
||||
const data = doc.nodes.items(.data)[@intFromEnum(node)];
|
||||
switch (doc.nodes.items(.tag)[@intFromEnum(node)]) {
|
||||
.root,
|
||||
@ -229,7 +231,7 @@ pub fn fmtHtml(bytes: []const u8) std.fmt.Formatter(formatHtml) {
|
||||
return .{ .data = bytes };
|
||||
}
|
||||
|
||||
fn formatHtml(bytes: []const u8, writer: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
fn formatHtml(bytes: []const u8, writer: *Writer, comptime fmt: []const u8) !void {
|
||||
_ = fmt;
|
||||
for (bytes) |b| {
|
||||
switch (b) {
|
||||
|
||||
@ -286,9 +286,8 @@ pub const HashHelper = struct {
|
||||
|
||||
pub fn binToHex(bin_digest: BinDigest) HexDigest {
|
||||
var out_digest: HexDigest = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&out_digest);
|
||||
bw.printHex(&bin_digest, .lower) catch unreachable;
|
||||
var w: std.io.Writer = .fixed(&out_digest);
|
||||
w.printHex(&bin_digest, .lower) catch unreachable;
|
||||
return out_digest;
|
||||
}
|
||||
|
||||
|
||||
@ -55,15 +55,11 @@ pub fn closeAndFree(self: *Directory, gpa: Allocator) void {
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
self: Directory,
|
||||
bw: *std.io.BufferedWriter,
|
||||
comptime fmt_string: []const u8,
|
||||
) !void {
|
||||
pub fn format(self: Directory, w: *std.io.Writer, comptime fmt_string: []const u8) !void {
|
||||
if (fmt_string.len != 0) fmt.invalidFmtError(fmt_string, self);
|
||||
if (self.path) |p| {
|
||||
try bw.writeAll(p);
|
||||
try bw.writeAll(fs.path.sep_str);
|
||||
try w.writeAll(p);
|
||||
try w.writeAll(fs.path.sep_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -140,11 +140,7 @@ pub fn toStringZ(p: Path, allocator: Allocator) Allocator.Error![:0]u8 {
|
||||
return std.fmt.allocPrintZ(allocator, "{f}", .{p});
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
self: Path,
|
||||
bw: *std.io.BufferedWriter,
|
||||
comptime fmt_string: []const u8,
|
||||
) !void {
|
||||
pub fn format(self: Path, w: *std.io.Writer, comptime fmt_string: []const u8) !void {
|
||||
if (fmt_string.len == 1) {
|
||||
// Quote-escape the string.
|
||||
const stringEscape = std.zig.stringEscape;
|
||||
@ -154,33 +150,33 @@ pub fn format(
|
||||
else => @compileError("unsupported format string: " ++ fmt_string),
|
||||
};
|
||||
if (self.root_dir.path) |p| {
|
||||
try stringEscape(p, bw, f);
|
||||
if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, bw, f);
|
||||
try stringEscape(p, w, f);
|
||||
if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, w, f);
|
||||
}
|
||||
if (self.sub_path.len > 0) {
|
||||
try stringEscape(self.sub_path, bw, f);
|
||||
try stringEscape(self.sub_path, w, f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (fmt_string.len > 0)
|
||||
std.fmt.invalidFmtError(fmt_string, self);
|
||||
if (std.fs.path.isAbsolute(self.sub_path)) {
|
||||
try bw.writeAll(self.sub_path);
|
||||
try w.writeAll(self.sub_path);
|
||||
return;
|
||||
}
|
||||
if (self.root_dir.path) |p| {
|
||||
try bw.writeAll(p);
|
||||
try w.writeAll(p);
|
||||
if (self.sub_path.len > 0) {
|
||||
try bw.writeAll(fs.path.sep_str);
|
||||
try bw.writeAll(self.sub_path);
|
||||
try w.writeAll(fs.path.sep_str);
|
||||
try w.writeAll(self.sub_path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (self.sub_path.len > 0) {
|
||||
try bw.writeAll(self.sub_path);
|
||||
try w.writeAll(self.sub_path);
|
||||
return;
|
||||
}
|
||||
try bw.writeByte('.');
|
||||
try w.writeByte('.');
|
||||
}
|
||||
|
||||
pub fn eql(self: Path, other: Path) bool {
|
||||
|
||||
@ -6,6 +6,7 @@ const macho = std.macho;
|
||||
const math = std.math;
|
||||
const mem = std.mem;
|
||||
const testing = std.testing;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const CheckObject = @This();
|
||||
|
||||
@ -231,7 +232,7 @@ const ComputeCompareExpected = struct {
|
||||
|
||||
pub fn format(
|
||||
value: ComputeCompareExpected,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime fmt: []const u8,
|
||||
) !void {
|
||||
if (fmt.len != 0) std.fmt.invalidFmtError(fmt, value);
|
||||
@ -619,7 +620,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void {
|
||||
|
||||
fn formatMessageString(
|
||||
ctx: Ctx,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime unused_fmt_string: []const u8,
|
||||
) !void {
|
||||
_ = unused_fmt_string;
|
||||
@ -813,7 +814,7 @@ const MachODumper = struct {
|
||||
return null;
|
||||
}
|
||||
|
||||
fn dumpHeader(hdr: macho.mach_header_64, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpHeader(hdr: macho.mach_header_64, bw: *Writer) !void {
|
||||
const cputype = switch (hdr.cputype) {
|
||||
macho.CPU_TYPE_ARM64 => "ARM64",
|
||||
macho.CPU_TYPE_X86_64 => "X86_64",
|
||||
@ -881,7 +882,7 @@ const MachODumper = struct {
|
||||
try bw.writeByte('\n');
|
||||
}
|
||||
|
||||
fn dumpLoadCommand(lc: macho.LoadCommandIterator.LoadCommand, index: usize, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpLoadCommand(lc: macho.LoadCommandIterator.LoadCommand, index: usize, bw: *Writer) !void {
|
||||
// print header first
|
||||
try bw.print(
|
||||
\\LC {d}
|
||||
@ -1107,7 +1108,7 @@ const MachODumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpSymtab(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpSymtab(ctx: ObjectContext, bw: *Writer) !void {
|
||||
try bw.writeAll(symtab_label ++ "\n");
|
||||
|
||||
for (ctx.symtab.items) |sym| {
|
||||
@ -1178,7 +1179,7 @@ const MachODumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpIndirectSymtab(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpIndirectSymtab(ctx: ObjectContext, bw: *Writer) !void {
|
||||
try bw.writeAll(indirect_symtab_label ++ "\n");
|
||||
|
||||
var sects_buffer: [3]macho.section_64 = undefined;
|
||||
@ -1227,7 +1228,7 @@ const MachODumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, bw: *Writer) !void {
|
||||
var rebases: std.ArrayList(u64) = .init(ctx.gpa);
|
||||
defer rebases.deinit();
|
||||
try ctx.parseRebaseInfo(data, &rebases);
|
||||
@ -1324,7 +1325,7 @@ const MachODumper = struct {
|
||||
};
|
||||
};
|
||||
|
||||
fn dumpBindInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpBindInfo(ctx: ObjectContext, data: []const u8, bw: *Writer) !void {
|
||||
var bindings: std.ArrayList(Binding) = .init(ctx.gpa);
|
||||
defer {
|
||||
for (bindings.items) |*b| {
|
||||
@ -1348,8 +1349,7 @@ const MachODumper = struct {
|
||||
}
|
||||
|
||||
fn parseBindInfo(ctx: ObjectContext, data: []const u8, bindings: *std.ArrayList(Binding)) !void {
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(@constCast(data));
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
|
||||
var seg_id: ?u8 = null;
|
||||
var tag: Binding.Tag = .self;
|
||||
@ -1439,15 +1439,14 @@ const MachODumper = struct {
|
||||
} else |_| {}
|
||||
}
|
||||
|
||||
fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, bw: *Writer) !void {
|
||||
const seg = ctx.getSegmentByName("__TEXT") orelse return;
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(ctx.gpa);
|
||||
defer arena.deinit();
|
||||
|
||||
var exports: std.ArrayList(Export) = .init(arena.allocator());
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(@constCast(data));
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
try parseTrieNode(arena.allocator(), &br, "", &exports);
|
||||
|
||||
mem.sort(Export, exports.items, {}, Export.lessThan);
|
||||
@ -1577,7 +1576,7 @@ const MachODumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpSection(ctx: ObjectContext, sect: macho.section_64, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpSection(ctx: ObjectContext, sect: macho.section_64, bw: *Writer) !void {
|
||||
const data = ctx.data[sect.offset..][0..sect.size];
|
||||
try bw.print("{s}", .{data});
|
||||
}
|
||||
@ -1704,8 +1703,7 @@ const ElfDumper = struct {
|
||||
|
||||
fn parseAndDumpArchive(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
|
||||
const gpa = step.owner.allocator;
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(@constCast(bytes));
|
||||
var br: std.io.Reader = .fixed(bytes);
|
||||
|
||||
if (!mem.eql(u8, try br.takeArray(elf.ARMAG.len), elf.ARMAG)) return error.InvalidArchiveMagicNumber;
|
||||
|
||||
@ -1779,8 +1777,7 @@ const ElfDumper = struct {
|
||||
}
|
||||
|
||||
fn parseSymtab(ctx: *ArchiveContext, data: []const u8, ptr_width: enum { p32, p64 }) !void {
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(@constCast(data));
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
const num = switch (ptr_width) {
|
||||
.p32 => try br.takeInt(u32, .big),
|
||||
.p64 => try br.takeInt(u64, .big),
|
||||
@ -1807,7 +1804,7 @@ const ElfDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpSymtab(ctx: ArchiveContext, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpSymtab(ctx: ArchiveContext, bw: *Writer) !void {
|
||||
var symbols: std.AutoArrayHashMap(usize, std.ArrayList([]const u8)) = .init(ctx.gpa);
|
||||
defer {
|
||||
for (symbols.values()) |*value| value.deinit();
|
||||
@ -1827,7 +1824,7 @@ const ElfDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpObjects(ctx: ArchiveContext, step: *Step, check: Check, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpObjects(ctx: ArchiveContext, step: *Step, check: Check, bw: *Writer) !void {
|
||||
for (ctx.objects.values()) |object| {
|
||||
try bw.print("object {s}\n", .{object.name});
|
||||
const output = try parseAndDumpObject(step, check, object.data);
|
||||
@ -1850,8 +1847,7 @@ const ElfDumper = struct {
|
||||
|
||||
fn parseAndDumpObject(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
|
||||
const gpa = step.owner.allocator;
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(@constCast(bytes));
|
||||
var br: std.io.Reader = .fixed(bytes);
|
||||
|
||||
const hdr = try br.takeStruct(elf.Elf64_Ehdr);
|
||||
if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidMagicNumber;
|
||||
@ -1944,13 +1940,13 @@ const ElfDumper = struct {
|
||||
symtab: Symtab,
|
||||
dysymtab: Symtab,
|
||||
|
||||
fn dumpHeader(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpHeader(ctx: ObjectContext, bw: *Writer) !void {
|
||||
try bw.writeAll("header\n");
|
||||
try bw.print("type {s}\n", .{@tagName(ctx.hdr.e_type)});
|
||||
try bw.print("entry {x}\n", .{ctx.hdr.e_entry});
|
||||
}
|
||||
|
||||
fn dumpPhdrs(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpPhdrs(ctx: ObjectContext, bw: *Writer) !void {
|
||||
if (ctx.phdrs.len == 0) return;
|
||||
|
||||
try bw.writeAll("program headers\n");
|
||||
@ -1989,7 +1985,7 @@ const ElfDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpShdrs(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpShdrs(ctx: ObjectContext, bw: *Writer) !void {
|
||||
if (ctx.shdrs.len == 0) return;
|
||||
|
||||
try bw.writeAll("section headers\n");
|
||||
@ -2006,7 +2002,7 @@ const ElfDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, bw: *Writer) !void {
|
||||
const shdr = ctx.shdrs[shndx];
|
||||
const strtab = ctx.getSectionContents(shdr.sh_link);
|
||||
const data = ctx.getSectionContents(shndx);
|
||||
@ -2144,7 +2140,7 @@ const ElfDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpSymtab(ctx: ObjectContext, comptime @"type": enum { symtab, dysymtab }, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpSymtab(ctx: ObjectContext, comptime @"type": enum { symtab, dysymtab }, bw: *Writer) !void {
|
||||
const symtab = switch (@"type") {
|
||||
.symtab => ctx.symtab,
|
||||
.dysymtab => ctx.dysymtab,
|
||||
@ -2226,7 +2222,7 @@ const ElfDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn dumpSection(ctx: ObjectContext, shndx: usize, bw: *std.io.BufferedWriter) !void {
|
||||
fn dumpSection(ctx: ObjectContext, shndx: usize, bw: *Writer) !void {
|
||||
const data = ctx.getSectionContents(shndx);
|
||||
try bw.print("{s}", .{data});
|
||||
}
|
||||
@ -2276,7 +2272,7 @@ const ElfDumper = struct {
|
||||
|
||||
fn formatShType(
|
||||
sh_type: u32,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime unused_fmt_string: []const u8,
|
||||
) !void {
|
||||
_ = unused_fmt_string;
|
||||
@ -2321,7 +2317,7 @@ const ElfDumper = struct {
|
||||
|
||||
fn formatPhType(
|
||||
ph_type: u32,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime unused_fmt_string: []const u8,
|
||||
) !void {
|
||||
_ = unused_fmt_string;
|
||||
@ -2353,8 +2349,7 @@ const WasmDumper = struct {
|
||||
|
||||
fn parseAndDump(step: *Step, check: Check, bytes: []const u8) ![]const u8 {
|
||||
const gpa = step.owner.allocator;
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(@constCast(bytes));
|
||||
var br: std.io.Reader = .fixed(bytes);
|
||||
|
||||
const buf = try br.takeArray(8);
|
||||
if (!mem.eql(u8, buf[0..4], &std.wasm.magic)) return error.InvalidMagicByte;
|
||||
@ -2376,12 +2371,12 @@ const WasmDumper = struct {
|
||||
step: *Step,
|
||||
check: Check,
|
||||
br: *std.io.Reader,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
) !void {
|
||||
var section_br: std.io.Reader = undefined;
|
||||
switch (check.kind) {
|
||||
.headers => while (br.takeEnum(std.wasm.Section, .little)) |section| {
|
||||
section_br.initFixed(try br.take(try br.takeLeb128(u32)));
|
||||
section_br = .fixed(try br.take(try br.takeLeb128(u32)));
|
||||
try parseAndDumpSection(step, section, §ion_br, bw);
|
||||
} else |err| switch (err) {
|
||||
error.InvalidEnumTag => return step.fail("invalid section id", .{}),
|
||||
@ -2396,7 +2391,7 @@ const WasmDumper = struct {
|
||||
step: *Step,
|
||||
section: std.wasm.Section,
|
||||
br: *std.io.Reader,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
) !void {
|
||||
try bw.print(
|
||||
\\Section {s}
|
||||
@ -2444,7 +2439,7 @@ const WasmDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn parseSection(step: *Step, section: std.wasm.Section, br: *std.io.Reader, entries: u32, bw: *std.io.BufferedWriter) !void {
|
||||
fn parseSection(step: *Step, section: std.wasm.Section, br: *std.io.Reader, entries: u32, bw: *Writer) !void {
|
||||
switch (section) {
|
||||
.type => {
|
||||
var i: u32 = 0;
|
||||
@ -2575,7 +2570,7 @@ const WasmDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn parseDumpType(step: *Step, comptime E: type, br: *std.io.Reader, bw: *std.io.BufferedWriter) !E {
|
||||
fn parseDumpType(step: *Step, comptime E: type, br: *std.io.Reader, bw: *Writer) !E {
|
||||
const tag = br.takeEnum(E, .little) catch |err| switch (err) {
|
||||
error.InvalidEnumTag => return step.fail("invalid wasm type value", .{}),
|
||||
else => |e| return e,
|
||||
@ -2584,7 +2579,7 @@ const WasmDumper = struct {
|
||||
return tag;
|
||||
}
|
||||
|
||||
fn parseDumpLimits(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void {
|
||||
fn parseDumpLimits(br: *std.io.Reader, bw: *Writer) !void {
|
||||
const flags = try br.takeLeb128(u8);
|
||||
const min = try br.takeLeb128(u32);
|
||||
|
||||
@ -2592,7 +2587,7 @@ const WasmDumper = struct {
|
||||
if (flags != 0) try bw.print("max {x}\n", .{try br.takeLeb128(u32)});
|
||||
}
|
||||
|
||||
fn parseDumpInit(step: *Step, br: *std.io.Reader, bw: *std.io.BufferedWriter) !void {
|
||||
fn parseDumpInit(step: *Step, br: *std.io.Reader, bw: *Writer) !void {
|
||||
const opcode = br.takeEnum(std.wasm.Opcode, .little) catch |err| switch (err) {
|
||||
error.InvalidEnumTag => return step.fail("invalid wasm opcode", .{}),
|
||||
else => |e| return e,
|
||||
@ -2612,14 +2607,14 @@ const WasmDumper = struct {
|
||||
}
|
||||
|
||||
/// https://webassembly.github.io/spec/core/appendix/custom.html
|
||||
fn parseDumpNames(step: *Step, br: *std.io.Reader, bw: *std.io.BufferedWriter) !void {
|
||||
fn parseDumpNames(step: *Step, br: *std.io.Reader, bw: *Writer) !void {
|
||||
var subsection_br: std.io.Reader = undefined;
|
||||
while (br.seek < br.buffer.len) {
|
||||
switch (try parseDumpType(step, std.wasm.NameSubsection, br, bw)) {
|
||||
// The module name subsection ... consists of a single name
|
||||
// that is assigned to the module itself.
|
||||
.module => {
|
||||
subsection_br.initFixed(try br.take(try br.takeLeb128(u32)));
|
||||
subsection_br = .fixed(try br.take(try br.takeLeb128(u32)));
|
||||
const name = try subsection_br.take(try subsection_br.takeLeb128(u32));
|
||||
try bw.print(
|
||||
\\name {s}
|
||||
@ -2631,7 +2626,7 @@ const WasmDumper = struct {
|
||||
// The function name subsection ... consists of a name map
|
||||
// assigning function names to function indices.
|
||||
.function, .global, .data_segment => {
|
||||
subsection_br.initFixed(try br.take(try br.takeLeb128(u32)));
|
||||
subsection_br = .fixed(try br.take(try br.takeLeb128(u32)));
|
||||
const entries = try br.takeLeb128(u32);
|
||||
try bw.print(
|
||||
\\names {d}
|
||||
@ -2661,7 +2656,7 @@ const WasmDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn parseDumpProducers(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void {
|
||||
fn parseDumpProducers(br: *std.io.Reader, bw: *Writer) !void {
|
||||
const field_count = try br.takeLeb128(u32);
|
||||
try bw.print(
|
||||
\\fields {d}
|
||||
@ -2689,7 +2684,7 @@ const WasmDumper = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn parseDumpFeatures(br: *std.io.Reader, bw: *std.io.BufferedWriter) !void {
|
||||
fn parseDumpFeatures(br: *std.io.Reader, bw: *Writer) !void {
|
||||
const feature_count = try br.takeLeb128(u32);
|
||||
try bw.print(
|
||||
\\features {d}
|
||||
|
||||
@ -2,6 +2,7 @@ const std = @import("std");
|
||||
const ConfigHeader = @This();
|
||||
const Step = std.Build.Step;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const Style = union(enum) {
|
||||
/// A configure format supported by autotools that uses `#undef foo` to
|
||||
@ -277,7 +278,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
|
||||
fn render_autoconf_undef(
|
||||
step: *Step,
|
||||
contents: []const u8,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
values: std.StringArrayHashMap(Value),
|
||||
src_path: []const u8,
|
||||
) !void {
|
||||
@ -382,7 +383,7 @@ fn render_autoconf_at(
|
||||
fn render_cmake(
|
||||
step: *Step,
|
||||
contents: []const u8,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
values: std.StringArrayHashMap(Value),
|
||||
src_path: []const u8,
|
||||
) !void {
|
||||
@ -508,7 +509,7 @@ fn render_cmake(
|
||||
|
||||
fn render_blank(
|
||||
gpa: std.mem.Allocator,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
defines: std.StringArrayHashMap(Value),
|
||||
include_path: []const u8,
|
||||
include_guard_override: ?[]const u8,
|
||||
@ -541,11 +542,11 @@ fn render_blank(
|
||||
, .{include_guard_name});
|
||||
}
|
||||
|
||||
fn render_nasm(bw: *std.io.BufferedWriter, defines: std.StringArrayHashMap(Value)) !void {
|
||||
fn render_nasm(bw: *Writer, defines: std.StringArrayHashMap(Value)) !void {
|
||||
for (defines.keys(), defines.values()) |name, value| try renderValueNasm(bw, name, value);
|
||||
}
|
||||
|
||||
fn renderValueC(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !void {
|
||||
fn renderValueC(bw: *Writer, name: []const u8, value: Value) !void {
|
||||
switch (value) {
|
||||
.undef => try bw.print("/* #undef {s} */\n", .{name}),
|
||||
.defined => try bw.print("#define {s}\n", .{name}),
|
||||
@ -557,7 +558,7 @@ fn renderValueC(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !voi
|
||||
}
|
||||
}
|
||||
|
||||
fn renderValueNasm(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !void {
|
||||
fn renderValueNasm(bw: *Writer, name: []const u8, value: Value) !void {
|
||||
switch (value) {
|
||||
.undef => try bw.print("; %undef {s}\n", .{name}),
|
||||
.defined => try bw.print("%define {s}\n", .{name}),
|
||||
@ -570,7 +571,7 @@ fn renderValueNasm(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !
|
||||
}
|
||||
|
||||
fn expand_variables_autoconf_at(
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
contents: []const u8,
|
||||
values: std.StringArrayHashMap(Value),
|
||||
used: []bool,
|
||||
|
||||
@ -1015,18 +1015,14 @@ fn populateGeneratedPaths(
|
||||
}
|
||||
}
|
||||
|
||||
fn formatTerm(
|
||||
term: ?std.process.Child.Term,
|
||||
bw: *std.io.BufferedWriter,
|
||||
comptime fmt: []const u8,
|
||||
) !void {
|
||||
_ = fmt;
|
||||
fn formatTerm(term: ?std.process.Child.Term, w: *std.io.Writer, comptime fmt: []const u8) !void {
|
||||
comptime assert(fmt.len == 0);
|
||||
if (term) |t| switch (t) {
|
||||
.Exited => |code| try bw.print("exited with code {}", .{code}),
|
||||
.Signal => |sig| try bw.print("terminated with signal {}", .{sig}),
|
||||
.Stopped => |sig| try bw.print("stopped with signal {}", .{sig}),
|
||||
.Unknown => |code| try bw.print("terminated for unknown reason with code {}", .{code}),
|
||||
} else try bw.writeAll("exited with any code");
|
||||
.Exited => |code| try w.print("exited with code {}", .{code}),
|
||||
.Signal => |sig| try w.print("terminated with signal {}", .{sig}),
|
||||
.Stopped => |sig| try w.print("stopped with signal {}", .{sig}),
|
||||
.Unknown => |code| try w.print("terminated for unknown reason with code {}", .{code}),
|
||||
} else try w.writeAll("exited with any code");
|
||||
}
|
||||
fn fmtTerm(term: ?std.process.Child.Term) std.fmt.Formatter(formatTerm) {
|
||||
return .{ .data = term };
|
||||
|
||||
@ -9,6 +9,7 @@ const Progress = @This();
|
||||
const posix = std.posix;
|
||||
const is_big_endian = builtin.cpu.arch.endian() == .big;
|
||||
const is_windows = builtin.os.tag == .windows;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
/// `null` if the current node (and its children) should
|
||||
/// not print on update()
|
||||
@ -607,7 +608,7 @@ pub fn unlockStdErr() void {
|
||||
}
|
||||
|
||||
/// Protected by `stderr_mutex`.
|
||||
var stderr_buffered_writer: std.io.BufferedWriter = .{
|
||||
var stderr_buffered_writer: Writer = .{
|
||||
.unbuffered_writer = stderr_file_writer.interface(),
|
||||
.buffer = &.{},
|
||||
};
|
||||
@ -617,13 +618,13 @@ var stderr_file_writer: std.fs.File.Writer = .{
|
||||
.mode = .streaming,
|
||||
};
|
||||
|
||||
/// Allows the caller to freely write to the returned `std.io.BufferedWriter`,
|
||||
/// Allows the caller to freely write to the returned `Writer`,
|
||||
/// initialized with `buffer`, until `unlockStderrWriter` is called.
|
||||
///
|
||||
/// During the lock, any `std.Progress` information is cleared from the terminal.
|
||||
///
|
||||
/// The lock is recursive; the same thread may hold the lock multiple times.
|
||||
pub fn lockStderrWriter(buffer: []u8) *std.io.BufferedWriter {
|
||||
pub fn lockStderrWriter(buffer: []u8) *Writer {
|
||||
stderr_mutex.lock();
|
||||
clearWrittenWithEscapeCodes() catch {};
|
||||
if (is_windows) stderr_file_writer.file = .stderr();
|
||||
|
||||
@ -152,7 +152,7 @@ fn parseNum(text: []const u8) error{ InvalidVersion, Overflow }!usize {
|
||||
|
||||
pub fn format(
|
||||
self: Version,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *std.io.Writer,
|
||||
comptime fmt: []const u8,
|
||||
) !void {
|
||||
if (fmt.len != 0) std.fmt.invalidFmtError(fmt, self);
|
||||
|
||||
@ -301,7 +301,7 @@ pub const Os = struct {
|
||||
|
||||
/// This function is defined to serialize a Zig source code representation of this
|
||||
/// type, that, when parsed, will deserialize into the same data.
|
||||
pub fn format(ver: WindowsVersion, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(ver: WindowsVersion, bw: *std.io.Writer, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
const maybe_name = std.enums.tagName(WindowsVersion, ver);
|
||||
if (comptime std.mem.eql(u8, fmt_str, "s")) {
|
||||
if (maybe_name) |name|
|
||||
|
||||
@ -5,6 +5,7 @@ const std = @import("std.zig");
|
||||
const testing = std.testing;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Uri = @This();
|
||||
|
||||
@ -84,7 +85,7 @@ pub const Component = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn format(component: Component, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(component: Component, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
if (fmt.len == 0) {
|
||||
try bw.print("std.Uri.Component{{ .{s} = \"{}\" }}", .{
|
||||
@tagName(component),
|
||||
@ -136,10 +137,10 @@ pub const Component = union(enum) {
|
||||
}
|
||||
|
||||
pub fn percentEncode(
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
raw: []const u8,
|
||||
comptime isValidChar: fn (u8) bool,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
var start: usize = 0;
|
||||
for (raw, 0..) |char, index| {
|
||||
if (isValidChar(char)) continue;
|
||||
@ -280,7 +281,7 @@ pub const WriteToStreamOptions = struct {
|
||||
port: bool = true,
|
||||
};
|
||||
|
||||
pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *Writer) Writer.Error!void {
|
||||
if (options.scheme) {
|
||||
try bw.print("{s}:", .{uri.scheme});
|
||||
if (options.authority and uri.host != null) {
|
||||
@ -317,7 +318,7 @@ pub fn writeToStream(uri: Uri, options: WriteToStreamOptions, bw: *std.io.Buffer
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format(uri: Uri, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(uri: Uri, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
const scheme = comptime std.mem.indexOfScalar(u8, fmt, ';') != null or fmt.len == 0;
|
||||
const authentication = comptime std.mem.indexOfScalar(u8, fmt, '@') != null or fmt.len == 0;
|
||||
const authority = comptime std.mem.indexOfScalar(u8, fmt, '+') != null or fmt.len == 0;
|
||||
@ -461,8 +462,7 @@ test remove_dot_segments {
|
||||
|
||||
/// 5.2.3. Merge Paths
|
||||
fn merge_paths(base: Component, new: []u8, aux_buf: *[]u8) error{NoSpaceLeft}!Component {
|
||||
var aux: std.io.BufferedWriter = undefined;
|
||||
aux.initFixed(aux_buf.*);
|
||||
var aux: Writer = .fixed(aux_buf.*);
|
||||
if (!base.isEmpty()) {
|
||||
aux.print("{fpath}", .{base}) catch return error.NoSpaceLeft;
|
||||
aux.end = std.mem.lastIndexOfScalar(u8, aux.getWritten(), '/') orelse
|
||||
|
||||
@ -905,20 +905,18 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?mem.Alig
|
||||
pub fn print(self: *Self, gpa: Allocator, comptime fmt: []const u8, args: anytype) error{OutOfMemory}!void {
|
||||
comptime assert(T == u8);
|
||||
try self.ensureUnusedCapacity(gpa, fmt.len);
|
||||
var aw: std.io.AllocatingWriter = undefined;
|
||||
const bw = aw.fromArrayList(gpa, self);
|
||||
var aw: std.io.AllocatingWriter = .fromArrayList(gpa, self);
|
||||
defer self.* = aw.toArrayList();
|
||||
return bw.print(fmt, args) catch |err| switch (err) {
|
||||
return aw.interface.print(fmt, args) catch |err| switch (err) {
|
||||
error.WriteFailed => return error.OutOfMemory,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn printAssumeCapacity(self: *Self, comptime fmt: []const u8, args: anytype) void {
|
||||
comptime assert(T == u8);
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(self.unusedCapacitySlice());
|
||||
bw.print(fmt, args) catch unreachable;
|
||||
self.items.len += bw.end;
|
||||
var w: std.io.Writer = .fixed(self.unusedCapacitySlice());
|
||||
w.print(fmt, args) catch unreachable;
|
||||
self.items.len += w.end;
|
||||
}
|
||||
|
||||
/// Append a value to the list `n` times.
|
||||
|
||||
@ -34,7 +34,7 @@ pub const StackTrace = struct {
|
||||
index: usize,
|
||||
instruction_addresses: []usize,
|
||||
|
||||
pub fn format(st: StackTrace, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
pub fn format(st: StackTrace, bw: *std.io.Writer, comptime fmt: []const u8) !void {
|
||||
comptime if (fmt.len != 0) unreachable;
|
||||
|
||||
// TODO: re-evaluate whether to use format() methods at all.
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("../std.zig");
|
||||
const testing = std.testing;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
/// Container of the deflate bit stream body. Container adds header before
|
||||
/// deflate bit stream and footer after. It can bi gzip, zlib or raw (no header,
|
||||
@ -106,7 +107,7 @@ pub const Container = enum {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeFooter(hasher: *Hasher, writer: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn writeFooter(hasher: *Hasher, writer: *Writer) Writer.Error!void {
|
||||
var bits: [4]u8 = undefined;
|
||||
switch (hasher.*) {
|
||||
.gzip => |*gzip| {
|
||||
@ -230,8 +231,7 @@ test "compress/decompress" {
|
||||
// compress original stream to compressed stream
|
||||
{
|
||||
var original: std.io.Reader = .fixed(data);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&cmp_buf);
|
||||
var compressed: Writer = .fixed(&cmp_buf);
|
||||
var compress: Compress = .init(&original, .raw);
|
||||
var compress_br = compress.readable(&.{});
|
||||
const n = try compress_br.readRemaining(&compressed, .{ .level = level });
|
||||
@ -246,16 +246,14 @@ test "compress/decompress" {
|
||||
// decompress compressed stream to decompressed stream
|
||||
{
|
||||
var compressed: std.io.Reader = .fixed(cmp_buf[0..compressed_size]);
|
||||
var decompressed: std.io.BufferedWriter = undefined;
|
||||
decompressed.initFixed(&dcm_buf);
|
||||
var decompressed: Writer = .fixed(&dcm_buf);
|
||||
try Decompress.pump(container, &compressed, &decompressed);
|
||||
try testing.expectEqualSlices(u8, data, decompressed.getWritten());
|
||||
}
|
||||
|
||||
// compressor writer interface
|
||||
{
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&cmp_buf);
|
||||
var compressed: Writer = .fixed(&cmp_buf);
|
||||
var cmp = try Compress.init(container, &compressed, .{ .level = level });
|
||||
var cmp_wrt = cmp.writer();
|
||||
try cmp_wrt.writeAll(data);
|
||||
@ -285,8 +283,7 @@ test "compress/decompress" {
|
||||
// compress original stream to compressed stream
|
||||
{
|
||||
var original: std.io.Reader = .fixed(data);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&cmp_buf);
|
||||
var compressed: Writer = .fixed(&cmp_buf);
|
||||
var cmp = try Compress.Huffman.init(container, &compressed);
|
||||
try cmp.compress(original.reader());
|
||||
try cmp.finish();
|
||||
@ -300,8 +297,7 @@ test "compress/decompress" {
|
||||
// decompress compressed stream to decompressed stream
|
||||
{
|
||||
var compressed: std.io.Reader = .fixed(cmp_buf[0..compressed_size]);
|
||||
var decompressed: std.io.BufferedWriter = undefined;
|
||||
decompressed.initFixed(&dcm_buf);
|
||||
var decompressed: Writer = .fixed(&dcm_buf);
|
||||
try Decompress.pump(container, &compressed, &decompressed);
|
||||
try testing.expectEqualSlices(u8, data, decompressed.getWritten());
|
||||
}
|
||||
@ -319,8 +315,7 @@ test "compress/decompress" {
|
||||
// compress original stream to compressed stream
|
||||
{
|
||||
var original: std.io.Reader = .fixed(data);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&cmp_buf);
|
||||
var compressed: Writer = .fixed(&cmp_buf);
|
||||
var cmp = try Compress.SimpleCompressor(.store, container).init(&compressed);
|
||||
try cmp.compress(original.reader());
|
||||
try cmp.finish();
|
||||
@ -335,8 +330,7 @@ test "compress/decompress" {
|
||||
// decompress compressed stream to decompressed stream
|
||||
{
|
||||
var compressed: std.io.Reader = .fixed(cmp_buf[0..compressed_size]);
|
||||
var decompressed: std.io.BufferedWriter = undefined;
|
||||
decompressed.initFixed(&dcm_buf);
|
||||
var decompressed: Writer = .fixed(&dcm_buf);
|
||||
try Decompress.pump(container, &compressed, &decompressed);
|
||||
try testing.expectEqualSlices(u8, data, decompressed.getWritten());
|
||||
}
|
||||
@ -491,8 +485,7 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
|
||||
|
||||
// decompress
|
||||
{
|
||||
var plain: std.io.BufferedWriter = undefined;
|
||||
plain.initFixed(&buffer2);
|
||||
var plain: Writer = .fixed(&buffer2);
|
||||
|
||||
var in: std.io.Reader = .fixed(gzip_data);
|
||||
try pkg.decompress(&in, &plain);
|
||||
@ -501,10 +494,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
|
||||
|
||||
// compress/decompress
|
||||
{
|
||||
var plain: std.io.BufferedWriter = undefined;
|
||||
plain.initFixed(&buffer2);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&buffer1);
|
||||
var plain: Writer = .fixed(&buffer2);
|
||||
var compressed: Writer = .fixed(&buffer1);
|
||||
|
||||
var in: std.io.Reader = .fixed(plain_data);
|
||||
try pkg.compress(&in, &compressed, .{});
|
||||
@ -516,10 +507,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
|
||||
|
||||
// compressor/decompressor
|
||||
{
|
||||
var plain: std.io.BufferedWriter = undefined;
|
||||
plain.initFixed(&buffer2);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&buffer1);
|
||||
var plain: Writer = .fixed(&buffer2);
|
||||
var compressed: Writer = .fixed(&buffer1);
|
||||
|
||||
var in: std.io.Reader = .fixed(plain_data);
|
||||
var cmp = try pkg.compressor(&compressed, .{});
|
||||
@ -536,10 +525,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
|
||||
{
|
||||
// huffman compress/decompress
|
||||
{
|
||||
var plain: std.io.BufferedWriter = undefined;
|
||||
plain.initFixed(&buffer2);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&buffer1);
|
||||
var plain: Writer = .fixed(&buffer2);
|
||||
var compressed: Writer = .fixed(&buffer1);
|
||||
|
||||
var in: std.io.Reader = .fixed(plain_data);
|
||||
try pkg.huffman.compress(&in, &compressed);
|
||||
@ -551,10 +538,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
|
||||
|
||||
// huffman compressor/decompressor
|
||||
{
|
||||
var plain: std.io.BufferedWriter = undefined;
|
||||
plain.initFixed(&buffer2);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&buffer1);
|
||||
var plain: Writer = .fixed(&buffer2);
|
||||
var compressed: Writer = .fixed(&buffer1);
|
||||
|
||||
var in: std.io.Reader = .fixed(plain_data);
|
||||
var cmp = try pkg.huffman.compressor(&compressed);
|
||||
@ -571,10 +556,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
|
||||
{
|
||||
// store compress/decompress
|
||||
{
|
||||
var plain: std.io.BufferedWriter = undefined;
|
||||
plain.initFixed(&buffer2);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&buffer1);
|
||||
var plain: Writer = .fixed(&buffer2);
|
||||
var compressed: Writer = .fixed(&buffer1);
|
||||
|
||||
var in: std.io.Reader = .fixed(plain_data);
|
||||
try pkg.store.compress(&in, &compressed);
|
||||
@ -586,10 +569,8 @@ fn testInterface(comptime pkg: type, gzip_data: []const u8, plain_data: []const
|
||||
|
||||
// store compressor/decompressor
|
||||
{
|
||||
var plain: std.io.BufferedWriter = undefined;
|
||||
plain.initFixed(&buffer2);
|
||||
var compressed: std.io.BufferedWriter = undefined;
|
||||
compressed.initFixed(&buffer1);
|
||||
var plain: Writer = .fixed(&buffer2);
|
||||
var compressed: Writer = .fixed(&buffer1);
|
||||
|
||||
var in: std.io.Reader = .fixed(plain_data);
|
||||
var cmp = try pkg.store.compressor(&compressed);
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
const std = @import("std");
|
||||
const io = std.io;
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const BlockWriter = @This();
|
||||
const flate = @import("../flate.zig");
|
||||
@ -13,7 +14,7 @@ const Token = @import("Token.zig");
|
||||
const codegen_order = huffman.codegen_order;
|
||||
const end_code_mark = 255;
|
||||
|
||||
output: *std.io.BufferedWriter,
|
||||
output: *Writer,
|
||||
|
||||
codegen_freq: [huffman.codegen_code_count]u16 = undefined,
|
||||
literal_freq: [huffman.max_num_lit]u16 = undefined,
|
||||
@ -26,7 +27,7 @@ fixed_literal_encoding: Compress.LiteralEncoder,
|
||||
fixed_distance_encoding: Compress.DistanceEncoder,
|
||||
huff_distance: Compress.DistanceEncoder,
|
||||
|
||||
pub fn init(output: *std.io.BufferedWriter) BlockWriter {
|
||||
pub fn init(output: *Writer) BlockWriter {
|
||||
return .{
|
||||
.output = output,
|
||||
.fixed_literal_encoding = Compress.fixedLiteralEncoder(),
|
||||
@ -41,15 +42,15 @@ pub fn init(output: *std.io.BufferedWriter) BlockWriter {
|
||||
/// That is after final block; when last byte could be incomplete or
|
||||
/// after stored block; which is aligned to the byte boundary (it has x
|
||||
/// padding bits after first 3 bits).
|
||||
pub fn flush(self: *BlockWriter) std.io.Writer.Error!void {
|
||||
pub fn flush(self: *BlockWriter) Writer.Error!void {
|
||||
try self.bit_writer.flush();
|
||||
}
|
||||
|
||||
pub fn setWriter(self: *BlockWriter, new_writer: *std.io.BufferedWriter) void {
|
||||
pub fn setWriter(self: *BlockWriter, new_writer: *Writer) void {
|
||||
self.bit_writer.setWriter(new_writer);
|
||||
}
|
||||
|
||||
fn writeCode(self: *BlockWriter, c: Compress.HuffCode) std.io.Writer.Error!void {
|
||||
fn writeCode(self: *BlockWriter, c: Compress.HuffCode) Writer.Error!void {
|
||||
try self.bit_writer.writeBits(c.code, c.len);
|
||||
}
|
||||
|
||||
@ -231,7 +232,7 @@ fn dynamicHeader(
|
||||
num_distances: u32,
|
||||
num_codegens: u32,
|
||||
eof: bool,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
const first_bits: u32 = if (eof) 5 else 4;
|
||||
try self.bit_writer.writeBits(first_bits, 3);
|
||||
try self.bit_writer.writeBits(num_literals - 257, 5);
|
||||
@ -271,7 +272,7 @@ fn dynamicHeader(
|
||||
}
|
||||
}
|
||||
|
||||
fn storedHeader(self: *BlockWriter, length: usize, eof: bool) std.io.Writer.Error!void {
|
||||
fn storedHeader(self: *BlockWriter, length: usize, eof: bool) Writer.Error!void {
|
||||
assert(length <= 65535);
|
||||
const flag: u32 = if (eof) 1 else 0;
|
||||
try self.bit_writer.writeBits(flag, 3);
|
||||
@ -281,7 +282,7 @@ fn storedHeader(self: *BlockWriter, length: usize, eof: bool) std.io.Writer.Erro
|
||||
try self.bit_writer.writeBits(~l, 16);
|
||||
}
|
||||
|
||||
fn fixedHeader(self: *BlockWriter, eof: bool) std.io.Writer.Error!void {
|
||||
fn fixedHeader(self: *BlockWriter, eof: bool) Writer.Error!void {
|
||||
// Indicate that we are a fixed Huffman block
|
||||
var value: u32 = 2;
|
||||
if (eof) {
|
||||
@ -295,7 +296,7 @@ fn fixedHeader(self: *BlockWriter, eof: bool) std.io.Writer.Error!void {
|
||||
// is larger than the original bytes, the data will be written as a
|
||||
// stored block.
|
||||
// If the input is null, the tokens will always be Huffman encoded.
|
||||
pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]const u8) std.io.Writer.Error!void {
|
||||
pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]const u8) Writer.Error!void {
|
||||
const lit_and_dist = self.indexTokens(tokens);
|
||||
const num_literals = lit_and_dist.num_literals;
|
||||
const num_distances = lit_and_dist.num_distances;
|
||||
@ -373,7 +374,7 @@ pub fn write(self: *BlockWriter, tokens: []const Token, eof: bool, input: ?[]con
|
||||
try self.writeTokens(tokens, &literal_encoding.codes, &distance_encoding.codes);
|
||||
}
|
||||
|
||||
pub fn storedBlock(self: *BlockWriter, input: []const u8, eof: bool) std.io.Writer.Error!void {
|
||||
pub fn storedBlock(self: *BlockWriter, input: []const u8, eof: bool) Writer.Error!void {
|
||||
try self.storedHeader(input.len, eof);
|
||||
try self.bit_writer.writeBytes(input);
|
||||
}
|
||||
@ -388,7 +389,7 @@ fn dynamicBlock(
|
||||
tokens: []const Token,
|
||||
eof: bool,
|
||||
input: ?[]const u8,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
const total_tokens = self.indexTokens(tokens);
|
||||
const num_literals = total_tokens.num_literals;
|
||||
const num_distances = total_tokens.num_distances;
|
||||
@ -485,7 +486,7 @@ fn writeTokens(
|
||||
tokens: []const Token,
|
||||
le_codes: []Compress.HuffCode,
|
||||
oe_codes: []Compress.HuffCode,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
for (tokens) |t| {
|
||||
if (t.kind == Token.Kind.literal) {
|
||||
try self.writeCode(le_codes[t.literal()]);
|
||||
@ -512,7 +513,7 @@ fn writeTokens(
|
||||
|
||||
// Encodes a block of bytes as either Huffman encoded literals or uncompressed bytes
|
||||
// if the results only gains very little from compression.
|
||||
pub fn huffmanBlock(self: *BlockWriter, input: []const u8, eof: bool) std.io.Writer.Error!void {
|
||||
pub fn huffmanBlock(self: *BlockWriter, input: []const u8, eof: bool) Writer.Error!void {
|
||||
// Add everything as literals
|
||||
histogram(input, &self.literal_freq);
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ const testing = std.testing;
|
||||
const expect = testing.expect;
|
||||
const mem = std.mem;
|
||||
const math = std.math;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Compress = @This();
|
||||
const Token = @import("Token.zig");
|
||||
@ -142,7 +143,7 @@ const FlushOption = enum { none, flush, final };
|
||||
/// flush tokens to the token writer.
|
||||
///
|
||||
/// Returns number of bytes consumed from `lh`.
|
||||
fn tokenizeSlice(c: *Compress, bw: *std.io.BufferedWriter, limit: std.io.Limit, lh: []const u8) !usize {
|
||||
fn tokenizeSlice(c: *Compress, bw: *Writer, limit: std.io.Limit, lh: []const u8) !usize {
|
||||
_ = bw;
|
||||
_ = limit;
|
||||
if (true) @panic("TODO");
|
||||
@ -299,7 +300,7 @@ pub fn finish(c: *Compress) !void {
|
||||
|
||||
/// Use another writer while preserving history. Most probably flush
|
||||
/// should be called on old writer before setting new.
|
||||
pub fn setWriter(self: *Compress, new_writer: *std.io.BufferedWriter) void {
|
||||
pub fn setWriter(self: *Compress, new_writer: *Writer) void {
|
||||
self.block_writer.setWriter(new_writer);
|
||||
self.output = new_writer;
|
||||
}
|
||||
@ -767,7 +768,7 @@ fn byFreq(context: void, a: LiteralNode, b: LiteralNode) bool {
|
||||
|
||||
fn read(
|
||||
context: ?*anyopaque,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
limit: std.io.Limit,
|
||||
) std.io.Reader.StreamError!usize {
|
||||
const c: *Compress = @ptrCast(@alignCast(context));
|
||||
@ -1147,8 +1148,7 @@ test "file tokenization" {
|
||||
const data = case.data;
|
||||
|
||||
for (levels, 0..) |level, i| { // for each compression level
|
||||
var original: std.io.Reader = undefined;
|
||||
original.initFixed(data);
|
||||
var original: std.io.Reader = .fixed(data);
|
||||
|
||||
// buffer for decompressed data
|
||||
var al = std.ArrayList(u8).init(testing.allocator);
|
||||
@ -1181,10 +1181,10 @@ test "file tokenization" {
|
||||
}
|
||||
|
||||
const TokenDecoder = struct {
|
||||
output: *std.io.BufferedWriter,
|
||||
output: *Writer,
|
||||
tokens_count: usize,
|
||||
|
||||
pub fn init(output: *std.io.BufferedWriter) TokenDecoder {
|
||||
pub fn init(output: *Writer) TokenDecoder {
|
||||
return .{
|
||||
.output = output,
|
||||
.tokens_count = 0,
|
||||
@ -1222,8 +1222,7 @@ test "store simple compressor" {
|
||||
//0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21,
|
||||
};
|
||||
|
||||
var fbs: std.io.Reader = undefined;
|
||||
fbs.initFixed(data);
|
||||
var fbs: std.io.Reader = .fixed(data);
|
||||
var al = std.ArrayList(u8).init(testing.allocator);
|
||||
defer al.deinit();
|
||||
|
||||
@ -1232,7 +1231,7 @@ test "store simple compressor" {
|
||||
try cmp.finish();
|
||||
try testing.expectEqualSlices(u8, &expected, al.items);
|
||||
|
||||
fbs.initFixed(data);
|
||||
fbs = .fixed(data);
|
||||
try al.resize(0);
|
||||
|
||||
// huffman only compresoor will also emit store block for this small sample
|
||||
@ -1244,7 +1243,7 @@ test "store simple compressor" {
|
||||
|
||||
test "sliding window match" {
|
||||
const data = "Blah blah blah blah blah!";
|
||||
var win: std.io.BufferedWriter = .{};
|
||||
var win: Writer = .{};
|
||||
try expect(win.write(data) == data.len);
|
||||
try expect(win.wp == data.len);
|
||||
try expect(win.rp == 0);
|
||||
@ -1263,9 +1262,9 @@ test "sliding window match" {
|
||||
}
|
||||
|
||||
test "sliding window slide" {
|
||||
var win: std.io.BufferedWriter = .{};
|
||||
win.wp = std.io.BufferedWriter.buffer_len - 11;
|
||||
win.rp = std.io.BufferedWriter.buffer_len - 111;
|
||||
var win: Writer = .{};
|
||||
win.wp = Writer.buffer_len - 11;
|
||||
win.rp = Writer.buffer_len - 111;
|
||||
win.buffer[win.rp] = 0xab;
|
||||
try expect(win.lookahead().len == 100);
|
||||
try expect(win.tokensBuffer().?.len == win.rp);
|
||||
@ -1273,8 +1272,8 @@ test "sliding window slide" {
|
||||
const n = win.slide();
|
||||
try expect(n == 32757);
|
||||
try expect(win.buffer[win.rp] == 0xab);
|
||||
try expect(win.rp == std.io.BufferedWriter.hist_len - 111);
|
||||
try expect(win.wp == std.io.BufferedWriter.hist_len - 11);
|
||||
try expect(win.rp == Writer.hist_len - 111);
|
||||
try expect(win.wp == Writer.hist_len - 11);
|
||||
try expect(win.lookahead().len == 100);
|
||||
try expect(win.tokensBuffer() == null);
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ const Container = flate.Container;
|
||||
const Token = @import("Token.zig");
|
||||
const testing = std.testing;
|
||||
const Decompress = @This();
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
input: *std.io.Reader,
|
||||
// Hashes, produces checksum, of uncompressed data for gzip/zlib footer.
|
||||
@ -141,7 +142,7 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol {
|
||||
|
||||
pub fn read(
|
||||
context: ?*anyopaque,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
limit: std.io.Limit,
|
||||
) std.io.Reader.StreamError!usize {
|
||||
const d: *Decompress = @alignCast(@ptrCast(context));
|
||||
@ -159,7 +160,7 @@ pub fn read(
|
||||
|
||||
fn readInner(
|
||||
d: *Decompress,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
limit: std.io.Limit,
|
||||
) (Error || error{ WriteFailed, EndOfStream })!usize {
|
||||
const in = d.input;
|
||||
@ -347,7 +348,7 @@ fn readInner(
|
||||
|
||||
/// Write match (back-reference to the same data slice) starting at `distance`
|
||||
/// back from current write position, and `length` of bytes.
|
||||
fn writeMatch(bw: *std.io.BufferedWriter, length: u16, distance: u16) !void {
|
||||
fn writeMatch(bw: *Writer, length: u16, distance: u16) !void {
|
||||
_ = bw;
|
||||
_ = length;
|
||||
_ = distance;
|
||||
@ -727,8 +728,7 @@ test "decompress" {
|
||||
},
|
||||
};
|
||||
for (cases) |c| {
|
||||
var fb: std.io.Reader = undefined;
|
||||
fb.initFixed(@constCast(c.in));
|
||||
var fb: std.io.Reader = .fixed(c.in);
|
||||
var aw: std.io.AllocatingWriter = undefined;
|
||||
aw.init(testing.allocator);
|
||||
defer aw.deinit();
|
||||
@ -788,8 +788,7 @@ test "gzip decompress" {
|
||||
},
|
||||
};
|
||||
for (cases) |c| {
|
||||
var fb: std.io.Reader = undefined;
|
||||
fb.initFixed(@constCast(c.in));
|
||||
var fb: std.io.Reader = .fixed(c.in);
|
||||
var aw: std.io.AllocatingWriter = undefined;
|
||||
aw.init(testing.allocator);
|
||||
defer aw.deinit();
|
||||
@ -818,8 +817,7 @@ test "zlib decompress" {
|
||||
},
|
||||
};
|
||||
for (cases) |c| {
|
||||
var fb: std.io.Reader = undefined;
|
||||
fb.initFixed(@constCast(c.in));
|
||||
var fb: std.io.Reader = .fixed(c.in);
|
||||
var aw: std.io.AllocatingWriter = undefined;
|
||||
aw.init(testing.allocator);
|
||||
defer aw.deinit();
|
||||
@ -880,8 +878,7 @@ test "fuzzing tests" {
|
||||
};
|
||||
|
||||
inline for (cases, 0..) |c, case_no| {
|
||||
var in: std.io.Reader = undefined;
|
||||
in.initFixed(@constCast(@embedFile("testdata/fuzz/" ++ c.input ++ ".input")));
|
||||
var in: std.io.Reader = .fixed(@embedFile("testdata/fuzz/" ++ c.input ++ ".input"));
|
||||
var aw: std.io.AllocatingWriter = undefined;
|
||||
aw.init(testing.allocator);
|
||||
defer aw.deinit();
|
||||
@ -903,8 +900,7 @@ test "bug 18966" {
|
||||
const input = @embedFile("testdata/fuzz/bug_18966.input");
|
||||
const expect = @embedFile("testdata/fuzz/bug_18966.expect");
|
||||
|
||||
var in: std.io.Reader = undefined;
|
||||
in.initFixed(@constCast(input));
|
||||
var in: std.io.Reader = .fixed(input);
|
||||
var aw: std.io.AllocatingWriter = undefined;
|
||||
aw.init(testing.allocator);
|
||||
defer aw.deinit();
|
||||
@ -921,8 +917,7 @@ test "reading into empty buffer" {
|
||||
0b0000_0001, 0b0000_1100, 0x00, 0b1111_0011, 0xff, // deflate fixed buffer header len, nlen
|
||||
'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0x0a, // non compressed data
|
||||
};
|
||||
var in: std.io.Reader = undefined;
|
||||
in.initFixed(@constCast(input));
|
||||
var in: std.io.Reader = .fixed(input);
|
||||
var decomp: Decompress = .init(&in, .raw);
|
||||
var decompress_br = decomp.readable(&.{});
|
||||
var buf: [0]u8 = undefined;
|
||||
|
||||
@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator;
|
||||
const testing = std.testing;
|
||||
const expectEqualSlices = std.testing.expectEqualSlices;
|
||||
const expectError = std.testing.expectError;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const RangeDecoder = struct {
|
||||
range: u32,
|
||||
@ -320,7 +321,7 @@ pub const Decode = struct {
|
||||
self: *Decode,
|
||||
allocator: Allocator,
|
||||
br: *std.io.Reader,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
buffer: anytype,
|
||||
decoder: *RangeDecoder,
|
||||
bytes_read: *usize,
|
||||
@ -417,7 +418,7 @@ pub const Decode = struct {
|
||||
self: *Decode,
|
||||
allocator: Allocator,
|
||||
br: *std.io.Reader,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
buffer: anytype,
|
||||
decoder: *RangeDecoder,
|
||||
bytes_read: *usize,
|
||||
@ -429,7 +430,7 @@ pub const Decode = struct {
|
||||
self: *Decode,
|
||||
allocator: Allocator,
|
||||
br: *std.io.Reader,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
buffer: anytype,
|
||||
decoder: *RangeDecoder,
|
||||
bytes_read: *usize,
|
||||
@ -667,8 +668,8 @@ const LzCircularBuffer = struct {
|
||||
self: *Self,
|
||||
allocator: Allocator,
|
||||
lit: u8,
|
||||
bw: *std.io.BufferedWriter,
|
||||
) std.io.Writer.Error!void {
|
||||
bw: *Writer,
|
||||
) Writer.Error!void {
|
||||
try self.set(allocator, self.cursor, lit);
|
||||
self.cursor += 1;
|
||||
self.len += 1;
|
||||
@ -686,8 +687,8 @@ const LzCircularBuffer = struct {
|
||||
allocator: Allocator,
|
||||
len: usize,
|
||||
dist: usize,
|
||||
bw: *std.io.BufferedWriter,
|
||||
) std.io.Writer.Error!void {
|
||||
bw: *Writer,
|
||||
) Writer.Error!void {
|
||||
if (dist > self.dict_size or dist > self.len) {
|
||||
return error.CorruptInput;
|
||||
}
|
||||
@ -704,7 +705,7 @@ const LzCircularBuffer = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(self: *Self, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn finish(self: *Self, bw: *Writer) Writer.Error!void {
|
||||
if (self.cursor > 0) {
|
||||
try bw.writeAll(self.buf.items[0..self.cursor]);
|
||||
self.cursor = 0;
|
||||
@ -839,8 +840,7 @@ test "Vec2D get addition overflow" {
|
||||
|
||||
fn testDecompress(compressed: []const u8) ![]u8 {
|
||||
const allocator = std.testing.allocator;
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(compressed);
|
||||
var br: std.io.Reader = .fixed(compressed);
|
||||
var decompressor = try Decompress.initOptions(allocator, &br, .{});
|
||||
defer decompressor.deinit();
|
||||
const reader = decompressor.reader();
|
||||
@ -927,8 +927,7 @@ test "too small uncompressed size in header" {
|
||||
|
||||
test "reading one byte" {
|
||||
const compressed = @embedFile("testdata/good-known_size-with_eopm.lzma");
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(compressed);
|
||||
var br: std.io.Reader = .fixed(compressed);
|
||||
var decompressor = try Decompress.initOptions(std.testing.allocator, &br, .{});
|
||||
defer decompressor.deinit();
|
||||
var buffer = [1]u8{0};
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
const std = @import("../std.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const lzma = std.compress.lzma;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub fn decompress(gpa: Allocator, reader: *std.io.Reader, writer: *std.io.BufferedWriter) std.io.Reader.StreamError!void {
|
||||
pub fn decompress(gpa: Allocator, reader: *std.io.Reader, writer: *Writer) std.io.Reader.StreamError!void {
|
||||
var decoder = try Decode.init(gpa);
|
||||
defer decoder.deinit(gpa);
|
||||
return decoder.decompress(gpa, reader, writer);
|
||||
@ -34,7 +35,7 @@ pub const Decode = struct {
|
||||
self: *Decode,
|
||||
allocator: Allocator,
|
||||
reader: *std.io.Reader,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
) !void {
|
||||
var accum = LzAccumBuffer.init(std.math.maxInt(usize));
|
||||
defer accum.deinit(allocator);
|
||||
@ -57,7 +58,7 @@ pub const Decode = struct {
|
||||
self: *Decode,
|
||||
allocator: Allocator,
|
||||
br: *std.io.Reader,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
accum: *LzAccumBuffer,
|
||||
status: u8,
|
||||
) !void {
|
||||
@ -150,7 +151,7 @@ pub const Decode = struct {
|
||||
fn parseUncompressed(
|
||||
allocator: Allocator,
|
||||
reader: *std.io.Reader,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
accum: *LzAccumBuffer,
|
||||
reset_dict: bool,
|
||||
) !void {
|
||||
@ -276,8 +277,7 @@ test decompress {
|
||||
0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02,
|
||||
0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00,
|
||||
};
|
||||
var stream: std.io.Reader = undefined;
|
||||
stream.initFixed(&compressed);
|
||||
var stream: std.io.Reader = .fixed(&compressed);
|
||||
var decomp: std.io.AllocatingWriter = undefined;
|
||||
const decomp_bw = decomp.init(std.testing.allocator);
|
||||
defer decomp.deinit();
|
||||
|
||||
@ -3,8 +3,8 @@ const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Reader = std.io.Reader;
|
||||
const Limit = std.io.Limit;
|
||||
const BufferedWriter = std.io.BufferedWriter;
|
||||
const zstd = @import("../zstd.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
input: *Reader,
|
||||
state: State,
|
||||
@ -77,7 +77,7 @@ pub fn reader(self: *Decompress) Reader {
|
||||
};
|
||||
}
|
||||
|
||||
fn read(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) Reader.StreamError!usize {
|
||||
fn read(context: ?*anyopaque, bw: *Writer, limit: Limit) Reader.StreamError!usize {
|
||||
const d: *Decompress = @ptrCast(@alignCast(context));
|
||||
const in = d.input;
|
||||
|
||||
@ -139,7 +139,7 @@ fn initFrame(d: *Decompress, window_size_max: usize, magic: Frame.Magic) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn readInFrame(d: *Decompress, bw: *BufferedWriter, limit: Limit, state: *State.InFrame) !usize {
|
||||
fn readInFrame(d: *Decompress, bw: *Writer, limit: Limit, state: *State.InFrame) !usize {
|
||||
const in = d.input;
|
||||
|
||||
const header_bytes = try in.takeArray(3);
|
||||
@ -649,8 +649,7 @@ pub const Frame = struct {
|
||||
|
||||
if (decode.literal_written_count + literal_length > decode.literal_header.regenerated_size)
|
||||
return error.MalformedLiteralsLength;
|
||||
var sub_bw: BufferedWriter = undefined;
|
||||
sub_bw.initFixed(dest[write_pos..]);
|
||||
var sub_bw: Writer = .fixed(dest[write_pos..]);
|
||||
try decodeLiterals(decode, &sub_bw, literal_length);
|
||||
decode.literal_written_count += literal_length;
|
||||
// This is not a @memmove; it intentionally repeats patterns
|
||||
@ -698,7 +697,7 @@ pub const Frame = struct {
|
||||
}
|
||||
|
||||
/// Decode `len` bytes of literals into `dest`.
|
||||
fn decodeLiterals(self: *Decode, dest: *BufferedWriter, len: usize) !void {
|
||||
fn decodeLiterals(self: *Decode, dest: *Writer, len: usize) !void {
|
||||
switch (self.literal_header.block_type) {
|
||||
.raw => {
|
||||
try dest.writeAll(self.literal_streams.one[self.literal_written_count..][0..len]);
|
||||
|
||||
@ -7,6 +7,7 @@ const std = @import("../std.zig");
|
||||
const mem = std.mem;
|
||||
const math = std.math;
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const block_length = 64;
|
||||
pub const digest_length = 20;
|
||||
@ -252,21 +253,18 @@ pub fn round(d_s: *[5]u32, b: *const [64]u8) void {
|
||||
d_s[4] +%= v[4];
|
||||
}
|
||||
|
||||
pub fn writable(sha1: *Sha1, buffer: []u8) std.io.BufferedWriter {
|
||||
pub fn writer(sha1: *Sha1, buffer: []u8) Writer {
|
||||
return .{
|
||||
.unbuffered_writer = .{
|
||||
.context = sha1,
|
||||
.vtable = &.{
|
||||
.writeSplat = writeSplat,
|
||||
.writeFile = std.io.Writer.unimplementedWriteFile,
|
||||
},
|
||||
},
|
||||
.context = sha1,
|
||||
.vtable = &.{ .drain = drain },
|
||||
.buffer = buffer,
|
||||
};
|
||||
}
|
||||
|
||||
fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
|
||||
const sha1: *Sha1 = @ptrCast(@alignCast(context));
|
||||
fn drain(w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize {
|
||||
const sha1: *Sha1 = @ptrCast(@alignCast(w.context));
|
||||
sha1.update(w.buffered());
|
||||
w.end = 0;
|
||||
const start_total = sha1.total_len;
|
||||
if (sha1.buf_end == 0) {
|
||||
try writeSplatAligned(sha1, data, splat);
|
||||
@ -299,7 +297,7 @@ fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.
|
||||
return @intCast(sha1.total_len - start_total);
|
||||
}
|
||||
|
||||
fn writeSplatAligned(sha1: *Sha1, data: []const []const u8, splat: usize) std.io.Writer.Error!void {
|
||||
fn writeSplatAligned(sha1: *Sha1, data: []const []const u8, splat: usize) Writer.Error!void {
|
||||
assert(sha1.buf_end == 0);
|
||||
for (data[0 .. data.len - 1]) |slice| {
|
||||
var off: usize = 0;
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
//! ASN.1 types for public consumption.
|
||||
|
||||
const std = @import("std");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const der = @import("./asn1/der.zig");
|
||||
pub const Oid = @import("./asn1/Oid.zig");
|
||||
|
||||
@ -90,7 +93,7 @@ pub const Tag = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn encode(self: Tag, writer: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn encode(self: Tag, writer: *Writer) Writer.Error!void {
|
||||
var tag1: FirstTag = .{
|
||||
.number = undefined,
|
||||
.constructed = self.constructed,
|
||||
|
||||
@ -9,7 +9,7 @@ pub const EncodeError = error{
|
||||
MissingPrefix,
|
||||
};
|
||||
|
||||
pub fn encode(dot_notation: []const u8, out: *std.io.BufferedWriter) EncodeError!void {
|
||||
pub fn encode(dot_notation: []const u8, out: *Writer) EncodeError!void {
|
||||
var split = std.mem.splitScalar(u8, dot_notation, '.');
|
||||
const first_str = split.next() orelse return error.MissingPrefix;
|
||||
const second_str = split.next() orelse return error.MissingPrefix;
|
||||
@ -41,8 +41,7 @@ pub fn encode(dot_notation: []const u8, out: *std.io.BufferedWriter) EncodeError
|
||||
pub const InitError = std.fmt.ParseIntError || error{ MissingPrefix, BufferTooSmall };
|
||||
|
||||
pub fn fromDot(dot_notation: []const u8, out: []u8) InitError!Oid {
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(out);
|
||||
var bw: Writer = .fixed(out);
|
||||
encode(dot_notation, &bw) catch |err| switch (err) {
|
||||
error.WriteFailed => return error.BufferTooSmall,
|
||||
else => |e| return e,
|
||||
@ -58,7 +57,7 @@ test fromDot {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toDot(self: Oid, writer: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn toDot(self: Oid, writer: *Writer) Writer.Error!void {
|
||||
const encoded = self.encoded;
|
||||
const first = @divTrunc(encoded[0], 40);
|
||||
const second = encoded[0] - first * 40;
|
||||
@ -90,8 +89,7 @@ test toDot {
|
||||
var buf: [256]u8 = undefined;
|
||||
|
||||
for (test_cases) |t| {
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buf);
|
||||
var bw: Writer = .fixed(&buf);
|
||||
try toDot(Oid{ .encoded = t.encoded }, &bw);
|
||||
try std.testing.expectEqualStrings(t.dot_notation, bw.getWritten());
|
||||
}
|
||||
@ -219,3 +217,4 @@ const encoding_base = 128;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const der = @import("der.zig");
|
||||
const asn1 = @import("../asn1.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
@ -6,6 +6,7 @@ const io = std.io;
|
||||
const mem = std.mem;
|
||||
const sha3 = crypto.hash.sha3;
|
||||
const testing = std.testing;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const EncodingError = crypto.errors.EncodingError;
|
||||
const IdentityElementError = crypto.errors.IdentityElementError;
|
||||
@ -135,8 +136,7 @@ pub fn Ecdsa(comptime Curve: type, comptime Hash: type) type {
|
||||
/// The maximum length of the DER encoding is der_encoded_length_max.
|
||||
/// The function returns a slice, that can be shorter than der_encoded_length_max.
|
||||
pub fn toDer(sig: Signature, buf: *[der_encoded_length_max]u8) []u8 {
|
||||
var w: std.io.BufferedWriter = undefined;
|
||||
w.initFixed(buf);
|
||||
var w: Writer = .fixed(buf);
|
||||
const r_len = @as(u8, @intCast(sig.r.len + (sig.r[0] >> 7)));
|
||||
const s_len = @as(u8, @intCast(sig.s.len + (sig.s[0] >> 7)));
|
||||
const seq_len = @as(u8, @intCast(2 + r_len + 2 + s_len));
|
||||
|
||||
@ -5,6 +5,7 @@ const fmt = std.fmt;
|
||||
const io = std.io;
|
||||
const mem = std.mem;
|
||||
const meta = std.meta;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const fields_delimiter = "$";
|
||||
const fields_delimiter_scalar = '$';
|
||||
@ -188,16 +189,15 @@ pub fn deserialize(comptime HashResult: type, str: []const u8) Error!HashResult
|
||||
///
|
||||
/// `params` can also include any additional parameters.
|
||||
pub fn serialize(params: anytype, str: []u8) Error![]const u8 {
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(str);
|
||||
try serializeTo(params, &bw);
|
||||
return bw.getWritten();
|
||||
var w: Writer = .fixed(str);
|
||||
try serializeTo(params, &w);
|
||||
return w.buffered();
|
||||
}
|
||||
|
||||
/// Compute the number of bytes required to serialize `params`
|
||||
pub fn calcSize(params: anytype) usize {
|
||||
var trash: [128]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = .{
|
||||
var bw: Writer = .{
|
||||
.unbuffered_writer = .discarding,
|
||||
.buffer = &trash,
|
||||
};
|
||||
@ -205,7 +205,7 @@ pub fn calcSize(params: anytype) usize {
|
||||
return bw.count;
|
||||
}
|
||||
|
||||
fn serializeTo(params: anytype, out: *std.io.BufferedWriter) !void {
|
||||
fn serializeTo(params: anytype, out: *Writer) !void {
|
||||
const HashResult = @TypeOf(params);
|
||||
|
||||
if (@hasField(HashResult, version_param_name)) {
|
||||
|
||||
@ -10,6 +10,7 @@ const math = std.math;
|
||||
const mem = std.mem;
|
||||
const meta = std.meta;
|
||||
const pwhash = crypto.pwhash;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const phc_format = @import("phc_encoding.zig");
|
||||
|
||||
@ -304,26 +305,22 @@ const crypt_format = struct {
|
||||
|
||||
/// Serialize parameters into a string in modular crypt format.
|
||||
pub fn serialize(params: anytype, str: []u8) EncodingError![]const u8 {
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(str);
|
||||
try serializeTo(params, &bw);
|
||||
return bw.getWritten();
|
||||
var w: Writer = .fixed(str);
|
||||
try serializeTo(params, &w);
|
||||
return w.getWritten();
|
||||
}
|
||||
|
||||
/// Compute the number of bytes required to serialize `params`
|
||||
pub fn calcSize(params: anytype) usize {
|
||||
var trash: [64]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = .{
|
||||
.unbuffered_writer = .discarding,
|
||||
.buffer = &trash,
|
||||
};
|
||||
serializeTo(params, &bw) catch |err| switch (err) {
|
||||
var w: std.io.Writer = .discarding(&trash);
|
||||
serializeTo(params, &w) catch |err| switch (err) {
|
||||
error.WriteFailed => unreachable,
|
||||
};
|
||||
return bw.count;
|
||||
return w.count;
|
||||
}
|
||||
|
||||
fn serializeTo(params: anytype, out: *std.io.BufferedWriter) !void {
|
||||
fn serializeTo(params: anytype, out: *Writer) !void {
|
||||
var header: [14]u8 = undefined;
|
||||
header[0..3].* = prefix.*;
|
||||
Codec.intEncode(header[3..4], params.ln);
|
||||
|
||||
@ -18,6 +18,7 @@ const builtin = @import("builtin");
|
||||
const mem = std.mem;
|
||||
const math = std.math;
|
||||
const htest = @import("test.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const Sha224 = Sha2x32(iv224, 224);
|
||||
pub const Sha256 = Sha2x32(iv256, 256);
|
||||
@ -382,20 +383,20 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type {
|
||||
for (&d.s, v) |*dv, vv| dv.* +%= vv;
|
||||
}
|
||||
|
||||
pub fn writable(this: *@This(), buffer: []u8) std.io.BufferedWriter {
|
||||
pub fn writable(this: *@This(), buffer: []u8) Writer {
|
||||
return .{
|
||||
.unbuffered_writer = .{
|
||||
.context = this,
|
||||
.vtable = &.{
|
||||
.writeSplat = writeSplat,
|
||||
.writeFile = std.io.Writer.unimplementedWriteFile,
|
||||
.writeFile = Writer.unimplementedWriteFile,
|
||||
},
|
||||
},
|
||||
.buffer = buffer,
|
||||
};
|
||||
}
|
||||
|
||||
fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
|
||||
fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize {
|
||||
const this: *@This() = @ptrCast(@alignCast(context));
|
||||
const start_total = this.total_len;
|
||||
for (data[0 .. data.len - 1]) |slice| this.update(slice);
|
||||
|
||||
@ -25,7 +25,7 @@ input: *std.io.Reader,
|
||||
|
||||
/// The encrypted stream from the client to the server. Bytes are pushed here
|
||||
/// via `writer`.
|
||||
output: *std.io.BufferedWriter,
|
||||
output: *Writer,
|
||||
|
||||
/// Populated when `error.TlsAlert` is returned.
|
||||
alert: ?tls.Alert = null,
|
||||
@ -72,7 +72,7 @@ pub const SslKeyLog = struct {
|
||||
client_key_seq: u64,
|
||||
server_key_seq: u64,
|
||||
client_random: [32]u8,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
|
||||
fn clientCounter(key_log: *@This()) u64 {
|
||||
defer key_log.client_key_seq += 1;
|
||||
@ -176,7 +176,7 @@ const InitError = error{
|
||||
pub fn init(
|
||||
client: *Client,
|
||||
input: *std.io.Reader,
|
||||
output: *std.io.BufferedWriter,
|
||||
output: *Writer,
|
||||
options: Options,
|
||||
) InitError!void {
|
||||
assert(input.buffer.len >= min_buffer_len);
|
||||
@ -1043,7 +1043,7 @@ pub fn eof(c: Client) bool {
|
||||
return c.received_close_notify;
|
||||
}
|
||||
|
||||
fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: std.io.Limit) Reader.StreamError!usize {
|
||||
fn read(context: ?*anyopaque, bw: *Writer, limit: std.io.Limit) Reader.StreamError!usize {
|
||||
const c: *Client = @ptrCast(@alignCast(context));
|
||||
if (c.eof()) return error.EndOfStream;
|
||||
const input = c.input;
|
||||
@ -1226,7 +1226,7 @@ fn failRead(c: *Client, err: ReadError) error{ReadFailed} {
|
||||
return error.ReadFailed;
|
||||
}
|
||||
|
||||
fn logSecrets(bw: *std.io.BufferedWriter, context: anytype, secrets: anytype) void {
|
||||
fn logSecrets(bw: *Writer, context: anytype, secrets: anytype) void {
|
||||
inline for (@typeInfo(@TypeOf(secrets)).@"struct".fields) |field| bw.print("{s}" ++
|
||||
(if (@hasField(@TypeOf(context), "counter")) "_{d}" else "") ++ " {x} {x}\n", .{field.name} ++
|
||||
(if (@hasField(@TypeOf(context), "counter")) .{context.counter} else .{}) ++ .{
|
||||
|
||||
@ -12,6 +12,7 @@ const windows = std.os.windows;
|
||||
const native_arch = builtin.cpu.arch;
|
||||
const native_os = builtin.os.tag;
|
||||
const native_endian = native_arch.endian();
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const MemoryAccessor = @import("debug/MemoryAccessor.zig");
|
||||
pub const FixedBufferReader = @import("debug/FixedBufferReader.zig");
|
||||
@ -208,9 +209,9 @@ pub fn unlockStdErr() void {
|
||||
///
|
||||
/// During the lock, any `std.Progress` information is cleared from the terminal.
|
||||
///
|
||||
/// Returns a `std.io.BufferedWriter` with empty buffer, meaning that it is
|
||||
/// Returns a `Writer` with empty buffer, meaning that it is
|
||||
/// in fact unbuffered and does not need to be flushed.
|
||||
pub fn lockStderrWriter(buffer: []u8) *std.io.BufferedWriter {
|
||||
pub fn lockStderrWriter(buffer: []u8) *Writer {
|
||||
return std.Progress.lockStderrWriter(buffer);
|
||||
}
|
||||
|
||||
@ -252,7 +253,7 @@ pub fn dumpHex(bytes: []const u8) void {
|
||||
}
|
||||
|
||||
/// Prints a hexadecimal view of the bytes, returning any error that occurs.
|
||||
pub fn dumpHexFallible(bw: *std.io.BufferedWriter, ttyconf: std.io.tty.Config, bytes: []const u8) !void {
|
||||
pub fn dumpHexFallible(bw: *Writer, ttyconf: std.io.tty.Config, bytes: []const u8) !void {
|
||||
var chunks = mem.window(u8, bytes, 16, 16);
|
||||
while (chunks.next()) |window| {
|
||||
// 1. Print the address.
|
||||
@ -329,7 +330,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
||||
}
|
||||
|
||||
/// Prints the current stack trace to the provided writer.
|
||||
pub fn dumpCurrentStackTraceToWriter(start_addr: ?usize, writer: *std.io.BufferedWriter) !void {
|
||||
pub fn dumpCurrentStackTraceToWriter(start_addr: ?usize, writer: *Writer) !void {
|
||||
if (builtin.target.cpu.arch.isWasm()) {
|
||||
if (native_os == .wasi) {
|
||||
try writer.writeAll("Unable to dump stack trace: not implemented for Wasm\n");
|
||||
@ -413,7 +414,7 @@ pub inline fn getContext(context: *ThreadContext) bool {
|
||||
/// Tries to print the stack trace starting from the supplied base pointer to stderr,
|
||||
/// unbuffered, and ignores any error returned.
|
||||
/// TODO multithreaded awareness
|
||||
pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *std.io.BufferedWriter) void {
|
||||
pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *Writer) void {
|
||||
nosuspend {
|
||||
if (builtin.target.cpu.arch.isWasm()) {
|
||||
if (native_os == .wasi) {
|
||||
@ -584,8 +585,7 @@ pub fn panicExtra(
|
||||
const size = 0x1000;
|
||||
const trunc_msg = "(msg truncated)";
|
||||
var buf: [size + trunc_msg.len]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(buf[0..size]);
|
||||
var bw: Writer = .fixed(buf[0..size]);
|
||||
// a minor annoyance with this is that it will result in the NoSpaceLeft
|
||||
// error being part of the @panic stack trace (but that error should
|
||||
// only happen rarely)
|
||||
@ -733,7 +733,7 @@ fn waitForOtherThreadToFinishPanicking() void {
|
||||
|
||||
pub fn writeStackTrace(
|
||||
stack_trace: std.builtin.StackTrace,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
debug_info: *SelfInfo,
|
||||
tty_config: io.tty.Config,
|
||||
) !void {
|
||||
@ -964,7 +964,7 @@ pub const StackIterator = struct {
|
||||
};
|
||||
|
||||
pub fn writeCurrentStackTrace(
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
debug_info: *SelfInfo,
|
||||
tty_config: io.tty.Config,
|
||||
start_addr: ?usize,
|
||||
@ -1052,7 +1052,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w
|
||||
}
|
||||
|
||||
pub fn writeStackTraceWindows(
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
debug_info: *SelfInfo,
|
||||
tty_config: io.tty.Config,
|
||||
context: *const windows.CONTEXT,
|
||||
@ -1072,7 +1072,7 @@ pub fn writeStackTraceWindows(
|
||||
}
|
||||
}
|
||||
|
||||
fn printUnknownSource(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, tty_config: io.tty.Config) !void {
|
||||
fn printUnknownSource(debug_info: *SelfInfo, writer: *Writer, address: usize, tty_config: io.tty.Config) !void {
|
||||
const module_name = debug_info.getModuleNameForAddress(address);
|
||||
return printLineInfo(
|
||||
writer,
|
||||
@ -1085,14 +1085,14 @@ fn printUnknownSource(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, add
|
||||
);
|
||||
}
|
||||
|
||||
fn printLastUnwindError(it: *StackIterator, debug_info: *SelfInfo, writer: *std.io.BufferedWriter, tty_config: io.tty.Config) void {
|
||||
fn printLastUnwindError(it: *StackIterator, debug_info: *SelfInfo, writer: *Writer, tty_config: io.tty.Config) void {
|
||||
if (!have_ucontext) return;
|
||||
if (it.getLastError()) |unwind_error| {
|
||||
printUnwindError(debug_info, writer, unwind_error.address, unwind_error.err, tty_config) catch {};
|
||||
}
|
||||
}
|
||||
|
||||
fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, err: UnwindError, tty_config: io.tty.Config) !void {
|
||||
fn printUnwindError(debug_info: *SelfInfo, writer: *Writer, address: usize, err: UnwindError, tty_config: io.tty.Config) !void {
|
||||
const module_name = debug_info.getModuleNameForAddress(address) orelse "???";
|
||||
try tty_config.setColor(writer, .dim);
|
||||
if (err == error.MissingDebugInfo) {
|
||||
@ -1103,7 +1103,7 @@ fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, addre
|
||||
try tty_config.setColor(writer, .reset);
|
||||
}
|
||||
|
||||
pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, tty_config: io.tty.Config) !void {
|
||||
pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *Writer, address: usize, tty_config: io.tty.Config) !void {
|
||||
const module = debug_info.getModuleForAddress(address) catch |err| switch (err) {
|
||||
error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, writer, address, tty_config),
|
||||
else => return err,
|
||||
@ -1127,7 +1127,7 @@ pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *std.io.BufferedWrite
|
||||
}
|
||||
|
||||
fn printLineInfo(
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
source_location: ?SourceLocation,
|
||||
address: usize,
|
||||
symbol_name: []const u8,
|
||||
@ -1174,7 +1174,7 @@ fn printLineInfo(
|
||||
}
|
||||
}
|
||||
|
||||
fn printLineFromFileAnyOs(writer: *std.io.BufferedWriter, source_location: SourceLocation) !void {
|
||||
fn printLineFromFileAnyOs(writer: *Writer, source_location: SourceLocation) !void {
|
||||
// Need this to always block even in async I/O mode, because this could potentially
|
||||
// be called from e.g. the event loop code crashing.
|
||||
var f = try fs.cwd().openFile(source_location.file_name, .{});
|
||||
@ -1567,7 +1567,7 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, msg: u8, label:
|
||||
posix.abort();
|
||||
}
|
||||
|
||||
fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8, stderr: *std.io.BufferedWriter) void {
|
||||
fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8, stderr: *Writer) void {
|
||||
_ = switch (msg) {
|
||||
0 => stderr.print("{s}\n", .{label.?}),
|
||||
1 => stderr.print("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
|
||||
@ -1699,7 +1699,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize
|
||||
t: @This(),
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
) !void {
|
||||
if (fmt.len != 0) std.fmt.invalidFmtError(fmt, t);
|
||||
_ = options;
|
||||
|
||||
@ -9,6 +9,7 @@ const abi = std.debug.Dwarf.abi;
|
||||
const mem = std.mem;
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
/// Expressions can be evaluated in different contexts, each requiring its own set of inputs.
|
||||
/// Callers should specify all the fields relevant to their context. If a field is required
|
||||
@ -826,7 +827,7 @@ pub fn Builder(comptime options: Options) type {
|
||||
|
||||
return struct {
|
||||
/// Zero-operand instructions
|
||||
pub fn writeOpcode(writer: *std.io.BufferedWriter, comptime opcode: u8) !void {
|
||||
pub fn writeOpcode(writer: *Writer, comptime opcode: u8) !void {
|
||||
if (options.call_frame_context and !comptime isOpcodeValidInCFA(opcode)) return error.InvalidCFAOpcode;
|
||||
switch (opcode) {
|
||||
OP.dup,
|
||||
@ -867,14 +868,14 @@ pub fn Builder(comptime options: Options) type {
|
||||
}
|
||||
|
||||
// 2.5.1.1: Literal Encodings
|
||||
pub fn writeLiteral(writer: *std.io.BufferedWriter, literal: u8) !void {
|
||||
pub fn writeLiteral(writer: *Writer, literal: u8) !void {
|
||||
switch (literal) {
|
||||
0...31 => |n| try writer.writeByte(n + OP.lit0),
|
||||
else => return error.InvalidLiteral,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeConst(writer: *std.io.BufferedWriter, comptime T: type, value: T) !void {
|
||||
pub fn writeConst(writer: *Writer, comptime T: type, value: T) !void {
|
||||
if (@typeInfo(T) != .int) @compileError("Constants must be integers");
|
||||
|
||||
switch (T) {
|
||||
@ -906,12 +907,12 @@ pub fn Builder(comptime options: Options) type {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeConstx(writer: *std.io.BufferedWriter, debug_addr_offset: anytype) !void {
|
||||
pub fn writeConstx(writer: *Writer, debug_addr_offset: anytype) !void {
|
||||
try writer.writeByte(OP.constx);
|
||||
try leb.writeUleb128(writer, debug_addr_offset);
|
||||
}
|
||||
|
||||
pub fn writeConstType(writer: *std.io.BufferedWriter, die_offset: anytype, value_bytes: []const u8) !void {
|
||||
pub fn writeConstType(writer: *Writer, die_offset: anytype, value_bytes: []const u8) !void {
|
||||
if (options.call_frame_context) return error.InvalidCFAOpcode;
|
||||
if (value_bytes.len > 0xff) return error.InvalidTypeLength;
|
||||
try writer.writeByte(OP.const_type);
|
||||
@ -920,36 +921,36 @@ pub fn Builder(comptime options: Options) type {
|
||||
try writer.writeAll(value_bytes);
|
||||
}
|
||||
|
||||
pub fn writeAddr(writer: *std.io.BufferedWriter, value: Address) !void {
|
||||
pub fn writeAddr(writer: *Writer, value: Address) !void {
|
||||
try writer.writeByte(OP.addr);
|
||||
try writer.writeInt(Address, value, options.endian);
|
||||
}
|
||||
|
||||
pub fn writeAddrx(writer: *std.io.BufferedWriter, debug_addr_offset: anytype) !void {
|
||||
pub fn writeAddrx(writer: *Writer, debug_addr_offset: anytype) !void {
|
||||
if (options.call_frame_context) return error.InvalidCFAOpcode;
|
||||
try writer.writeByte(OP.addrx);
|
||||
try leb.writeUleb128(writer, debug_addr_offset);
|
||||
}
|
||||
|
||||
// 2.5.1.2: Register Values
|
||||
pub fn writeFbreg(writer: *std.io.BufferedWriter, offset: anytype) !void {
|
||||
pub fn writeFbreg(writer: *Writer, offset: anytype) !void {
|
||||
try writer.writeByte(OP.fbreg);
|
||||
try leb.writeIleb128(writer, offset);
|
||||
}
|
||||
|
||||
pub fn writeBreg(writer: *std.io.BufferedWriter, register: u8, offset: anytype) !void {
|
||||
pub fn writeBreg(writer: *Writer, register: u8, offset: anytype) !void {
|
||||
if (register > 31) return error.InvalidRegister;
|
||||
try writer.writeByte(OP.breg0 + register);
|
||||
try leb.writeIleb128(writer, offset);
|
||||
}
|
||||
|
||||
pub fn writeBregx(writer: *std.io.BufferedWriter, register: anytype, offset: anytype) !void {
|
||||
pub fn writeBregx(writer: *Writer, register: anytype, offset: anytype) !void {
|
||||
try writer.writeByte(OP.bregx);
|
||||
try leb.writeUleb128(writer, register);
|
||||
try leb.writeIleb128(writer, offset);
|
||||
}
|
||||
|
||||
pub fn writeRegvalType(writer: *std.io.BufferedWriter, register: anytype, offset: anytype) !void {
|
||||
pub fn writeRegvalType(writer: *Writer, register: anytype, offset: anytype) !void {
|
||||
if (options.call_frame_context) return error.InvalidCFAOpcode;
|
||||
try writer.writeByte(OP.regval_type);
|
||||
try leb.writeUleb128(writer, register);
|
||||
@ -957,29 +958,29 @@ pub fn Builder(comptime options: Options) type {
|
||||
}
|
||||
|
||||
// 2.5.1.3: Stack Operations
|
||||
pub fn writePick(writer: *std.io.BufferedWriter, index: u8) !void {
|
||||
pub fn writePick(writer: *Writer, index: u8) !void {
|
||||
try writer.writeByte(OP.pick);
|
||||
try writer.writeByte(index);
|
||||
}
|
||||
|
||||
pub fn writeDerefSize(writer: *std.io.BufferedWriter, size: u8) !void {
|
||||
pub fn writeDerefSize(writer: *Writer, size: u8) !void {
|
||||
try writer.writeByte(OP.deref_size);
|
||||
try writer.writeByte(size);
|
||||
}
|
||||
|
||||
pub fn writeXDerefSize(writer: *std.io.BufferedWriter, size: u8) !void {
|
||||
pub fn writeXDerefSize(writer: *Writer, size: u8) !void {
|
||||
try writer.writeByte(OP.xderef_size);
|
||||
try writer.writeByte(size);
|
||||
}
|
||||
|
||||
pub fn writeDerefType(writer: *std.io.BufferedWriter, size: u8, die_offset: anytype) !void {
|
||||
pub fn writeDerefType(writer: *Writer, size: u8, die_offset: anytype) !void {
|
||||
if (options.call_frame_context) return error.InvalidCFAOpcode;
|
||||
try writer.writeByte(OP.deref_type);
|
||||
try writer.writeByte(size);
|
||||
try leb.writeUleb128(writer, die_offset);
|
||||
}
|
||||
|
||||
pub fn writeXDerefType(writer: *std.io.BufferedWriter, size: u8, die_offset: anytype) !void {
|
||||
pub fn writeXDerefType(writer: *Writer, size: u8, die_offset: anytype) !void {
|
||||
try writer.writeByte(OP.xderef_type);
|
||||
try writer.writeByte(size);
|
||||
try leb.writeUleb128(writer, die_offset);
|
||||
@ -987,24 +988,24 @@ pub fn Builder(comptime options: Options) type {
|
||||
|
||||
// 2.5.1.4: Arithmetic and Logical Operations
|
||||
|
||||
pub fn writePlusUconst(writer: *std.io.BufferedWriter, uint_value: anytype) !void {
|
||||
pub fn writePlusUconst(writer: *Writer, uint_value: anytype) !void {
|
||||
try writer.writeByte(OP.plus_uconst);
|
||||
try leb.writeUleb128(writer, uint_value);
|
||||
}
|
||||
|
||||
// 2.5.1.5: Control Flow Operations
|
||||
|
||||
pub fn writeSkip(writer: *std.io.BufferedWriter, offset: i16) !void {
|
||||
pub fn writeSkip(writer: *Writer, offset: i16) !void {
|
||||
try writer.writeByte(OP.skip);
|
||||
try writer.writeInt(i16, offset, options.endian);
|
||||
}
|
||||
|
||||
pub fn writeBra(writer: *std.io.BufferedWriter, offset: i16) !void {
|
||||
pub fn writeBra(writer: *Writer, offset: i16) !void {
|
||||
try writer.writeByte(OP.bra);
|
||||
try writer.writeInt(i16, offset, options.endian);
|
||||
}
|
||||
|
||||
pub fn writeCall(writer: *std.io.BufferedWriter, comptime T: type, offset: T) !void {
|
||||
pub fn writeCall(writer: *Writer, comptime T: type, offset: T) !void {
|
||||
if (options.call_frame_context) return error.InvalidCFAOpcode;
|
||||
switch (T) {
|
||||
u16 => try writer.writeByte(OP.call2),
|
||||
@ -1015,19 +1016,19 @@ pub fn Builder(comptime options: Options) type {
|
||||
try writer.writeInt(T, offset, options.endian);
|
||||
}
|
||||
|
||||
pub fn writeCallRef(writer: *std.io.BufferedWriter, comptime is_64: bool, value: if (is_64) u64 else u32) !void {
|
||||
pub fn writeCallRef(writer: *Writer, comptime is_64: bool, value: if (is_64) u64 else u32) !void {
|
||||
if (options.call_frame_context) return error.InvalidCFAOpcode;
|
||||
try writer.writeByte(OP.call_ref);
|
||||
try writer.writeInt(if (is_64) u64 else u32, value, options.endian);
|
||||
}
|
||||
|
||||
pub fn writeConvert(writer: *std.io.BufferedWriter, die_offset: anytype) !void {
|
||||
pub fn writeConvert(writer: *Writer, die_offset: anytype) !void {
|
||||
if (options.call_frame_context) return error.InvalidCFAOpcode;
|
||||
try writer.writeByte(OP.convert);
|
||||
try leb.writeUleb128(writer, die_offset);
|
||||
}
|
||||
|
||||
pub fn writeReinterpret(writer: *std.io.BufferedWriter, die_offset: anytype) !void {
|
||||
pub fn writeReinterpret(writer: *Writer, die_offset: anytype) !void {
|
||||
if (options.call_frame_context) return error.InvalidCFAOpcode;
|
||||
try writer.writeByte(OP.reinterpret);
|
||||
try leb.writeUleb128(writer, die_offset);
|
||||
@ -1035,23 +1036,23 @@ pub fn Builder(comptime options: Options) type {
|
||||
|
||||
// 2.5.1.7: Special Operations
|
||||
|
||||
pub fn writeEntryValue(writer: *std.io.BufferedWriter, expression: []const u8) !void {
|
||||
pub fn writeEntryValue(writer: *Writer, expression: []const u8) !void {
|
||||
try writer.writeByte(OP.entry_value);
|
||||
try leb.writeUleb128(writer, expression.len);
|
||||
try writer.writeAll(expression);
|
||||
}
|
||||
|
||||
// 2.6: Location Descriptions
|
||||
pub fn writeReg(writer: *std.io.BufferedWriter, register: u8) !void {
|
||||
pub fn writeReg(writer: *Writer, register: u8) !void {
|
||||
try writer.writeByte(OP.reg0 + register);
|
||||
}
|
||||
|
||||
pub fn writeRegx(writer: *std.io.BufferedWriter, register: anytype) !void {
|
||||
pub fn writeRegx(writer: *Writer, register: anytype) !void {
|
||||
try writer.writeByte(OP.regx);
|
||||
try leb.writeUleb128(writer, register);
|
||||
}
|
||||
|
||||
pub fn writeImplicitValue(writer: *std.io.BufferedWriter, value_bytes: []const u8) !void {
|
||||
pub fn writeImplicitValue(writer: *Writer, value_bytes: []const u8) !void {
|
||||
try writer.writeByte(OP.implicit_value);
|
||||
try leb.writeUleb128(writer, value_bytes.len);
|
||||
try writer.writeAll(value_bytes);
|
||||
|
||||
@ -52,8 +52,7 @@ pub fn readIntChecked(
|
||||
}
|
||||
|
||||
pub fn readLeb128(fbr: *FixedBufferReader, comptime T: type) Error!T {
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(@constCast(fbr.buf));
|
||||
var br: std.io.Reader = .fixed(fbr.buf);
|
||||
br.seek = fbr.pos;
|
||||
const result = br.takeLeb128(T);
|
||||
fbr.pos = br.seek;
|
||||
|
||||
@ -13,6 +13,7 @@ const lossyCast = math.lossyCast;
|
||||
const expectFmt = std.testing.expectFmt;
|
||||
const testing = std.testing;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const float = @import("fmt/float.zig");
|
||||
|
||||
@ -92,7 +93,7 @@ pub const Options = struct {
|
||||
/// A user type may be a `struct`, `vector`, `union` or `enum` type.
|
||||
///
|
||||
/// To print literal curly braces, escape them by writing them twice, e.g. `{{` or `}}`.
|
||||
pub fn format(bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytype) std.io.Writer.Error!void {
|
||||
pub fn format(bw: *Writer, comptime fmt: []const u8, args: anytype) Writer.Error!void {
|
||||
const ArgsType = @TypeOf(args);
|
||||
const args_type_info = @typeInfo(ArgsType);
|
||||
if (args_type_info != .@"struct") {
|
||||
@ -452,7 +453,7 @@ fn SliceEscape(comptime case: Case) type {
|
||||
return struct {
|
||||
pub fn format(
|
||||
bytes: []const u8,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime fmt: []const u8,
|
||||
) !void {
|
||||
_ = fmt;
|
||||
@ -494,8 +495,7 @@ pub fn fmtSliceEscapeUpper(bytes: []const u8) std.fmt.Formatter(formatSliceEscap
|
||||
/// Asserts the rendered integer value fits in `buffer`.
|
||||
/// Returns the end index within `buffer`.
|
||||
pub fn printInt(buffer: []u8, value: anytype, base: u8, case: Case, options: Options) usize {
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(buffer);
|
||||
var bw: Writer = .fixed(buffer);
|
||||
bw.printIntOptions(value, base, case, options) catch unreachable;
|
||||
return bw.end;
|
||||
}
|
||||
@ -532,7 +532,7 @@ pub fn Formatter(comptime formatFn: anytype) type {
|
||||
const Data = @typeInfo(@TypeOf(formatFn)).@"fn".params[0].type.?;
|
||||
return struct {
|
||||
data: Data,
|
||||
pub fn format(self: @This(), writer: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: @This(), writer: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
try formatFn(self.data, writer, fmt);
|
||||
}
|
||||
};
|
||||
@ -830,8 +830,7 @@ pub const BufPrintError = error{
|
||||
|
||||
/// Print a Formatter string into `buf`. Returns a slice of the bytes printed.
|
||||
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintError![]u8 {
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(buf);
|
||||
var bw: Writer = .fixed(buf);
|
||||
bw.print(fmt, args) catch |err| switch (err) {
|
||||
error.WriteFailed => return error.NoSpaceLeft,
|
||||
};
|
||||
@ -846,7 +845,7 @@ pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErr
|
||||
/// Count the characters needed for format.
|
||||
pub fn count(comptime fmt: []const u8, args: anytype) usize {
|
||||
var trash_buffer: [64]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = .{
|
||||
var bw: Writer = .{
|
||||
.unbuffered_writer = .discarding,
|
||||
.buffer = &trash_buffer,
|
||||
};
|
||||
@ -1018,16 +1017,15 @@ test "int.padded" {
|
||||
test "buffer" {
|
||||
{
|
||||
var buf1: [32]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buf1);
|
||||
var bw: Writer = .fixed(&buf1);
|
||||
try bw.printValue("", .{}, 1234, std.options.fmt_max_depth);
|
||||
try std.testing.expectEqualStrings("1234", bw.getWritten());
|
||||
|
||||
bw.initFixed(&buf1);
|
||||
bw = .fixed(&buf1);
|
||||
try bw.printValue("c", .{}, 'a', std.options.fmt_max_depth);
|
||||
try std.testing.expectEqualStrings("a", bw.getWritten());
|
||||
|
||||
bw.initFixed(&buf1);
|
||||
bw = .fixed(&buf1);
|
||||
try bw.printValue("b", .{}, 0b1100, std.options.fmt_max_depth);
|
||||
try std.testing.expectEqualStrings("1100", bw.getWritten());
|
||||
}
|
||||
|
||||
@ -844,7 +844,7 @@ pub fn write(self: File, bytes: []const u8) WriteError!usize {
|
||||
return posix.write(self.handle, bytes);
|
||||
}
|
||||
|
||||
/// One-shot alternative to `std.io.BufferedWriter.writeAll` via `writer`.
|
||||
/// One-shot alternative to `std.io.Writer.writeAll` via `writer`.
|
||||
pub fn writeAll(self: File, bytes: []const u8) WriteError!void {
|
||||
var index: usize = 0;
|
||||
while (index < bytes.len) {
|
||||
@ -1029,7 +1029,7 @@ pub const Reader = struct {
|
||||
|
||||
fn stream(
|
||||
io_reader: *std.io.Reader,
|
||||
bw: *BufferedWriter,
|
||||
bw: *std.io.Writer,
|
||||
limit: std.io.Limit,
|
||||
) std.io.Reader.StreamError!usize {
|
||||
const r: *Reader = @fieldParentPtr("interface", io_reader);
|
||||
@ -1180,6 +1180,12 @@ pub const Reader = struct {
|
||||
.failure => return error.ReadFailed,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn atEnd(r: *Reader) bool {
|
||||
// Even if stat fails, size is set when end is encountered.
|
||||
const size = r.getSize() orelse return false;
|
||||
return size - r.pos == 0;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Writer = struct {
|
||||
@ -1189,6 +1195,7 @@ pub const Writer = struct {
|
||||
pos: u64 = 0,
|
||||
sendfile_err: ?SendfileError = null,
|
||||
seek_err: ?SeekError = null,
|
||||
interface: std.io.Writer,
|
||||
|
||||
pub const Mode = Reader.Mode;
|
||||
|
||||
@ -1205,20 +1212,20 @@ pub const Writer = struct {
|
||||
/// vectors through the underlying write calls as possible.
|
||||
const max_buffers_len = 16;
|
||||
|
||||
pub fn interface(w: *Writer) std.io.Writer {
|
||||
pub fn init(file: File, buffer: []u8) std.io.Writer {
|
||||
return .{
|
||||
.context = w,
|
||||
.vtable = &.{
|
||||
.writeSplat = writeSplat,
|
||||
.writeFile = writeFile,
|
||||
.file = file,
|
||||
.interface = .{
|
||||
.context = undefined,
|
||||
.vtable = &.{
|
||||
.drain = drain,
|
||||
.sendFile = sendFile,
|
||||
},
|
||||
.buffer = buffer,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writable(w: *Writer, buffer: []u8) std.io.BufferedWriter {
|
||||
return interface(w).buffered(buffer);
|
||||
}
|
||||
|
||||
pub fn moveToReader(w: *Writer) Reader {
|
||||
defer w.* = undefined;
|
||||
return .{
|
||||
@ -1229,9 +1236,10 @@ pub const Writer = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
|
||||
const w: *Writer = @ptrCast(@alignCast(context));
|
||||
pub fn drain(io_writer: *std.io.Writer, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
|
||||
const w: *Writer = @fieldParentPtr("interface", io_writer);
|
||||
const handle = w.file.handle;
|
||||
if (true) @panic("update to check for buffered data");
|
||||
var splat_buffer: [256]u8 = undefined;
|
||||
if (is_windows) {
|
||||
if (data.len == 1 and splat == 0) return 0;
|
||||
@ -1282,14 +1290,8 @@ pub const Writer = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writeFile(
|
||||
context: ?*anyopaque,
|
||||
file_reader: *Reader,
|
||||
limit: std.io.Limit,
|
||||
headers_and_trailers: []const []const u8,
|
||||
headers_len: usize,
|
||||
) std.io.Writer.FileError!usize {
|
||||
const w: *Writer = @ptrCast(@alignCast(context));
|
||||
pub fn sendFile(io_writer: *Writer, file_reader: *Reader, limit: std.io.Limit) std.io.Writer.FileError!usize {
|
||||
const w: *Writer = @fieldParentPtr("interface", io_writer);
|
||||
const out_fd = w.file.handle;
|
||||
const in_fd = file_reader.file.handle;
|
||||
// TODO try using copy_file_range on Linux
|
||||
@ -1299,9 +1301,8 @@ pub const Writer = struct {
|
||||
if (native_os == .linux and w.mode == .streaming) sf: {
|
||||
// Try using sendfile on Linux.
|
||||
if (w.sendfile_err != null) break :sf;
|
||||
// Linux sendfile does not support headers or trailers but it does
|
||||
// support a streaming read from in_file.
|
||||
if (headers_len > 0) return writeSplat(context, headers_and_trailers[0..headers_len], 1);
|
||||
// Linux sendfile does not support headers.
|
||||
if (io_writer.end != 0) return drain(io_writer, &.{""}, 1);
|
||||
const max_count = 0x7ffff000; // Avoid EINVAL.
|
||||
var off: std.os.linux.off_t = undefined;
|
||||
const off_ptr: ?*std.os.linux.off_t, const count: usize = switch (file_reader.mode) {
|
||||
@ -1315,8 +1316,7 @@ pub const Writer = struct {
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
off = std.math.cast(std.os.linux.off_t, file_reader.pos) orelse
|
||||
return writeSplat(context, headers_and_trailers, 1);
|
||||
off = std.math.cast(std.os.linux.off_t, file_reader.pos) orelse return error.ReadFailed;
|
||||
break :o .{ &off, @min(@intFromEnum(limit), size - file_reader.pos, max_count) };
|
||||
},
|
||||
.streaming => .{ null, limit.minInt(max_count) },
|
||||
@ -1576,4 +1576,3 @@ const linux = std.os.linux;
|
||||
const windows = std.os.windows;
|
||||
const maxInt = std.math.maxInt;
|
||||
const Alignment = std.mem.Alignment;
|
||||
const BufferedWriter = std.io.BufferedWriter;
|
||||
|
||||
@ -150,8 +150,8 @@ pub fn fmtJoin(paths: []const []const u8) std.fmt.Formatter(formatJoin) {
|
||||
return .{ .data = paths };
|
||||
}
|
||||
|
||||
fn formatJoin(paths: []const []const u8, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
_ = fmt;
|
||||
fn formatJoin(paths: []const []const u8, bw: *std.io.Writer, comptime fmt: []const u8) !void {
|
||||
comptime assert(fmt.len == 0);
|
||||
|
||||
const first_path_idx = for (paths, 0..) |p, idx| {
|
||||
if (p.len != 0) break idx;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const std = @import("../std.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub fn Generic(comptime W: type, comptime algorithm: Algorithm(W)) type {
|
||||
return struct {
|
||||
@ -79,21 +80,18 @@ pub fn Generic(comptime W: type, comptime algorithm: Algorithm(W)) type {
|
||||
return c.final();
|
||||
}
|
||||
|
||||
pub fn writable(self: *Self, buffer: []u8) std.io.BufferedWriter {
|
||||
pub fn writer(self: *Self, buffer: []u8) Writer {
|
||||
return .{
|
||||
.unbuffered_writer = .{
|
||||
.context = self,
|
||||
.vtable = &.{
|
||||
.writeSplat = writeSplat,
|
||||
.writeFile = std.io.Writer.unimplementedWriteFile,
|
||||
},
|
||||
},
|
||||
.context = self,
|
||||
.vtable = &.{ .drain = drain },
|
||||
.buffer = buffer,
|
||||
};
|
||||
}
|
||||
|
||||
fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
|
||||
const self: *Self = @ptrCast(@alignCast(context));
|
||||
fn drain(w: *Writer, data: []const []const u8, splat: usize) Writer.Error!usize {
|
||||
const self: *Self = @ptrCast(@alignCast(w.context));
|
||||
self.update(w.buffered());
|
||||
w.end = 0;
|
||||
var n: usize = 0;
|
||||
for (data[0 .. data.len - 1]) |slice| {
|
||||
self.update(slice);
|
||||
|
||||
199
lib/std/http.zig
199
lib/std/http.zig
@ -1,6 +1,8 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std.zig");
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
const File = std.fs.File;
|
||||
|
||||
pub const Client = @import("http/Client.zig");
|
||||
pub const Server = @import("http/Server.zig");
|
||||
@ -504,7 +506,7 @@ pub const Reader = struct {
|
||||
|
||||
fn contentLengthRead(
|
||||
ctx: ?*anyopaque,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
limit: std.io.Limit,
|
||||
) std.io.Reader.StreamError!usize {
|
||||
const reader: *Reader = @alignCast(@ptrCast(ctx));
|
||||
@ -534,7 +536,7 @@ pub const Reader = struct {
|
||||
|
||||
fn chunkedRead(
|
||||
ctx: ?*anyopaque,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
limit: std.io.Limit,
|
||||
) std.io.Reader.StreamError!usize {
|
||||
const reader: *Reader = @alignCast(@ptrCast(ctx));
|
||||
@ -559,7 +561,7 @@ pub const Reader = struct {
|
||||
|
||||
fn chunkedReadEndless(
|
||||
reader: *Reader,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
limit: std.io.Limit,
|
||||
chunk_len_ptr: *RemainingChunkLen,
|
||||
) (BodyError || std.io.Reader.StreamError)!usize {
|
||||
@ -747,11 +749,12 @@ pub const Decompressor = struct {
|
||||
pub const BodyWriter = struct {
|
||||
/// Until the lifetime of `BodyWriter` ends, it is illegal to modify the
|
||||
/// state of this other than via methods of `BodyWriter`.
|
||||
http_protocol_output: *std.io.BufferedWriter,
|
||||
http_protocol_output: *Writer,
|
||||
state: State,
|
||||
elide: bool,
|
||||
interface: Writer,
|
||||
|
||||
pub const WriteError = std.io.Writer.Error;
|
||||
pub const Error = Writer.Error;
|
||||
|
||||
/// How many zeroes to reserve for hex-encoded chunk length.
|
||||
const chunk_len_digits = 8;
|
||||
@ -787,7 +790,7 @@ pub const BodyWriter = struct {
|
||||
};
|
||||
|
||||
/// Sends all buffered data across `BodyWriter.http_protocol_output`.
|
||||
pub fn flush(w: *BodyWriter) WriteError!void {
|
||||
pub fn flush(w: *BodyWriter) Error!void {
|
||||
const out = w.http_protocol_output;
|
||||
switch (w.state) {
|
||||
.end, .none, .content_length => return out.flush(),
|
||||
@ -820,7 +823,7 @@ pub const BodyWriter = struct {
|
||||
/// See also:
|
||||
/// * `endUnflushed`
|
||||
/// * `endChunked`
|
||||
pub fn end(w: *BodyWriter) WriteError!void {
|
||||
pub fn end(w: *BodyWriter) Error!void {
|
||||
try endUnflushed(w);
|
||||
try w.http_protocol_output.flush();
|
||||
}
|
||||
@ -836,7 +839,7 @@ pub const BodyWriter = struct {
|
||||
/// See also:
|
||||
/// * `end`
|
||||
/// * `endChunked`
|
||||
pub fn endUnflushed(w: *BodyWriter) WriteError!void {
|
||||
pub fn endUnflushed(w: *BodyWriter) Error!void {
|
||||
switch (w.state) {
|
||||
.end => unreachable,
|
||||
.content_length => |len| {
|
||||
@ -862,7 +865,7 @@ pub const BodyWriter = struct {
|
||||
/// See also:
|
||||
/// * `endChunkedUnflushed`
|
||||
/// * `end`
|
||||
pub fn endChunked(w: *BodyWriter, options: EndChunkedOptions) WriteError!void {
|
||||
pub fn endChunked(w: *BodyWriter, options: EndChunkedOptions) Error!void {
|
||||
try endChunkedUnflushed(w, options);
|
||||
try w.http_protocol_output.flush();
|
||||
}
|
||||
@ -879,7 +882,7 @@ pub const BodyWriter = struct {
|
||||
/// * `endChunked`
|
||||
/// * `endUnflushed`
|
||||
/// * `end`
|
||||
pub fn endChunkedUnflushed(w: *BodyWriter, options: EndChunkedOptions) WriteError!void {
|
||||
pub fn endChunkedUnflushed(w: *BodyWriter, options: EndChunkedOptions) Error!void {
|
||||
const chunked = &w.state.chunked;
|
||||
if (w.elide) {
|
||||
w.state = .end;
|
||||
@ -910,138 +913,78 @@ pub const BodyWriter = struct {
|
||||
w.state = .end;
|
||||
}
|
||||
|
||||
fn contentLengthWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) WriteError!usize {
|
||||
const w: *BodyWriter = @alignCast(@ptrCast(context));
|
||||
const n = if (w.elide) countSplat(data, splat) else try w.http_protocol_output.writeSplat(data, splat);
|
||||
fn contentLengthDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
|
||||
const bw: *BodyWriter = @fieldParentPtr("interface", w);
|
||||
assert(!bw.elide);
|
||||
const out = w.http_protocol_output;
|
||||
const n = try w.drainTo(out, data, splat);
|
||||
w.state.content_length -= n;
|
||||
return n;
|
||||
}
|
||||
|
||||
fn noneWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) WriteError!usize {
|
||||
const w: *BodyWriter = @alignCast(@ptrCast(context));
|
||||
if (w.elide) return countSplat(data, splat);
|
||||
return w.http_protocol_output.writeSplat(data, splat);
|
||||
}
|
||||
|
||||
fn countSplat(data: []const []const u8, splat: usize) usize {
|
||||
if (data.len == 0) return 0;
|
||||
var total: usize = 0;
|
||||
for (data[0 .. data.len - 1]) |buf| total += buf.len;
|
||||
total += data[data.len - 1].len * splat;
|
||||
return total;
|
||||
}
|
||||
|
||||
fn elideWriteFile(
|
||||
file_reader: *std.fs.File.Reader,
|
||||
limit: std.io.Limit,
|
||||
headers_and_trailers: []const []const u8,
|
||||
headers_len: usize,
|
||||
) error{ReadFailed}!usize {
|
||||
var source = file_reader.readable(&.{});
|
||||
var n = source.discard(limit) catch |err| switch (err) {
|
||||
error.ReadFailed => return error.ReadFailed,
|
||||
error.EndOfStream => {
|
||||
var n: usize = 0;
|
||||
for (headers_and_trailers) |bytes| n += bytes.len;
|
||||
return n;
|
||||
},
|
||||
};
|
||||
if (file_reader.size) |size| {
|
||||
if (size - file_reader.pos == 0) {
|
||||
// End of file reached.
|
||||
for (headers_and_trailers) |bytes| n += bytes.len;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
for (headers_and_trailers[0..headers_len]) |bytes| n += bytes.len;
|
||||
return n;
|
||||
fn noneDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
|
||||
const bw: *BodyWriter = @fieldParentPtr("interface", w);
|
||||
assert(!bw.elide);
|
||||
const out = w.http_protocol_output;
|
||||
return try w.drainTo(out, data, splat);
|
||||
}
|
||||
|
||||
/// Returns `null` if size cannot be computed without making any syscalls.
|
||||
fn countWriteFile(
|
||||
file_reader: *std.fs.File.Reader,
|
||||
limit: std.io.Limit,
|
||||
headers_and_trailers: []const []const u8,
|
||||
) ?usize {
|
||||
var total: u64 = @min(@intFromEnum(limit), file_reader.getSize() orelse return null);
|
||||
for (headers_and_trailers) |bytes| total += bytes.len;
|
||||
return std.math.lossyCast(usize, total);
|
||||
fn noneSendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) Writer.FileError!usize {
|
||||
const bw: *BodyWriter = @fieldParentPtr("interface", w);
|
||||
assert(!bw.elide);
|
||||
return w.sendFileTo(bw.http_protocol_output, file_reader, limit);
|
||||
}
|
||||
|
||||
fn noneWriteFile(
|
||||
context: ?*anyopaque,
|
||||
file_reader: *std.fs.File.Reader,
|
||||
limit: std.io.Limit,
|
||||
headers_and_trailers: []const []const u8,
|
||||
headers_len: usize,
|
||||
) std.io.Writer.FileError!usize {
|
||||
const w: *BodyWriter = @alignCast(@ptrCast(context));
|
||||
if (w.elide) return elideWriteFile(file_reader, limit, headers_and_trailers, headers_len);
|
||||
return w.http_protocol_output.writeFile(file_reader, limit, headers_and_trailers, headers_len);
|
||||
}
|
||||
|
||||
fn contentLengthWriteFile(
|
||||
context: ?*anyopaque,
|
||||
file_reader: *std.fs.File.Reader,
|
||||
limit: std.io.Limit,
|
||||
headers_and_trailers: []const []const u8,
|
||||
headers_len: usize,
|
||||
) std.io.Writer.FileError!usize {
|
||||
const w: *BodyWriter = @alignCast(@ptrCast(context));
|
||||
if (w.elide) return elideWriteFile(file_reader, limit, headers_and_trailers, headers_len);
|
||||
const n = try w.http_protocol_output.writeFile(file_reader, limit, headers_and_trailers, headers_len);
|
||||
w.state.content_length -= n;
|
||||
fn contentLengthSendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) Writer.FileError!usize {
|
||||
const bw: *BodyWriter = @fieldParentPtr("interface", w);
|
||||
assert(!bw.elide);
|
||||
const n = try w.sendFileTo(bw.http_protocol_output, file_reader, limit);
|
||||
bw.state.content_length -= n;
|
||||
return n;
|
||||
}
|
||||
|
||||
fn chunkedWriteFile(
|
||||
context: ?*anyopaque,
|
||||
file_reader: *std.fs.File.Reader,
|
||||
limit: std.io.Limit,
|
||||
headers_and_trailers: []const []const u8,
|
||||
headers_len: usize,
|
||||
) std.io.Writer.FileError!usize {
|
||||
const w: *BodyWriter = @alignCast(@ptrCast(context));
|
||||
if (w.elide) return elideWriteFile(file_reader, limit, headers_and_trailers, headers_len);
|
||||
if (limit == .nothing) return chunkedWriteSplat(context, headers_and_trailers, 1);
|
||||
const data_len = countWriteFile(file_reader, headers_and_trailers) orelse {
|
||||
fn chunkedSendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) Writer.FileError!usize {
|
||||
const bw: *BodyWriter = @fieldParentPtr("interface", w);
|
||||
assert(!bw.elide);
|
||||
const data_len = w.countSendFileUpperBound(file_reader, limit) orelse {
|
||||
// If the file size is unknown, we cannot lower to a `writeFile` since we would
|
||||
// have to flush the chunk header before knowing the chunk length.
|
||||
return error.Unimplemented;
|
||||
};
|
||||
const bw = w.http_protocol_output;
|
||||
const chunked = &w.state.chunked;
|
||||
const out = bw.http_protocol_output;
|
||||
const chunked = &bw.state.chunked;
|
||||
state: switch (chunked.*) {
|
||||
.offset => |off| {
|
||||
// TODO: is it better perf to read small files into the buffer?
|
||||
const buffered_len = bw.end - off - chunk_header_template.len;
|
||||
const buffered_len = out.end - off - chunk_header_template.len;
|
||||
const chunk_len = data_len + buffered_len;
|
||||
writeHex(bw.buffer[off..][0..chunk_len_digits], chunk_len);
|
||||
const n = try bw.writeFile(file_reader, limit, headers_and_trailers, headers_len);
|
||||
writeHex(out.buffer[off..][0..chunk_len_digits], chunk_len);
|
||||
const n = try w.sendFileTo(out, file_reader, limit);
|
||||
chunked.* = .{ .chunk_len = data_len + 2 - n };
|
||||
return n;
|
||||
},
|
||||
.chunk_len => |chunk_len| l: switch (chunk_len) {
|
||||
0 => {
|
||||
const off = bw.end;
|
||||
const header_buf = try bw.writableArray(chunk_header_template.len);
|
||||
const off = out.end;
|
||||
const header_buf = try out.writableArray(chunk_header_template.len);
|
||||
@memcpy(header_buf, chunk_header_template);
|
||||
chunked.* = .{ .offset = off };
|
||||
continue :state .{ .offset = off };
|
||||
},
|
||||
1 => {
|
||||
try bw.writeByte('\n');
|
||||
try out.writeByte('\n');
|
||||
chunked.chunk_len = 0;
|
||||
continue :l 0;
|
||||
},
|
||||
2 => {
|
||||
try bw.writeByte('\r');
|
||||
try out.writeByte('\r');
|
||||
chunked.chunk_len = 1;
|
||||
continue :l 1;
|
||||
},
|
||||
else => {
|
||||
const new_limit = limit.min(.limited(chunk_len - 2));
|
||||
const n = try bw.writeFile(file_reader, new_limit, headers_and_trailers, headers_len);
|
||||
const n = try w.sendFileTo(out, file_reader, new_limit);
|
||||
chunked.chunk_len = chunk_len - n;
|
||||
return n;
|
||||
},
|
||||
@ -1049,47 +992,45 @@ pub const BodyWriter = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn chunkedWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) WriteError!usize {
|
||||
const w: *BodyWriter = @alignCast(@ptrCast(context));
|
||||
const data_len = countSplat(data, splat);
|
||||
if (w.elide) return data_len;
|
||||
|
||||
const bw = w.http_protocol_output;
|
||||
const chunked = &w.state.chunked;
|
||||
|
||||
fn chunkedDrain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
|
||||
const bw: *BodyWriter = @fieldParentPtr("interface", w);
|
||||
assert(!bw.elide);
|
||||
const out = w.http_protocol_output;
|
||||
const data_len = Writer.countSplat(w.end, data, splat);
|
||||
const chunked = &bw.state.chunked;
|
||||
state: switch (chunked.*) {
|
||||
.offset => |offset| {
|
||||
if (bw.unusedCapacitySlice().len >= data_len) {
|
||||
assert(data_len == (bw.writeSplat(data, splat) catch unreachable));
|
||||
if (out.unusedCapacityLen() >= data_len) {
|
||||
assert(data_len == (w.drainTo(out, data, splat) catch unreachable));
|
||||
return data_len;
|
||||
}
|
||||
const buffered_len = bw.end - offset - chunk_header_template.len;
|
||||
const buffered_len = out.end - offset - chunk_header_template.len;
|
||||
const chunk_len = data_len + buffered_len;
|
||||
writeHex(bw.buffer[offset..][0..chunk_len_digits], chunk_len);
|
||||
const n = try bw.writeSplat(data, splat);
|
||||
writeHex(out.buffer[offset..][0..chunk_len_digits], chunk_len);
|
||||
const n = try w.drainTo(w, data, splat);
|
||||
chunked.* = .{ .chunk_len = data_len + 2 - n };
|
||||
return n;
|
||||
},
|
||||
.chunk_len => |chunk_len| l: switch (chunk_len) {
|
||||
0 => {
|
||||
const offset = bw.end;
|
||||
const header_buf = try bw.writableArray(chunk_header_template.len);
|
||||
const offset = out.end;
|
||||
const header_buf = try out.writableArray(chunk_header_template.len);
|
||||
@memcpy(header_buf, chunk_header_template);
|
||||
chunked.* = .{ .offset = offset };
|
||||
continue :state .{ .offset = offset };
|
||||
},
|
||||
1 => {
|
||||
try bw.writeByte('\n');
|
||||
try out.writeByte('\n');
|
||||
chunked.chunk_len = 0;
|
||||
continue :l 0;
|
||||
},
|
||||
2 => {
|
||||
try bw.writeByte('\r');
|
||||
try out.writeByte('\r');
|
||||
chunked.chunk_len = 1;
|
||||
continue :l 1;
|
||||
},
|
||||
else => {
|
||||
const n = try bw.writeSplatLimit(data, splat, .limited(chunk_len - 2));
|
||||
const n = try w.drainToLimit(data, splat, .limited(chunk_len - 2));
|
||||
chunked.chunk_len = chunk_len - n;
|
||||
return n;
|
||||
},
|
||||
@ -1112,21 +1053,21 @@ pub const BodyWriter = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writer(w: *BodyWriter) std.io.Writer {
|
||||
return .{
|
||||
pub fn writer(w: *BodyWriter) Writer {
|
||||
return if (w.elide) .discarding else .{
|
||||
.context = w,
|
||||
.vtable = switch (w.state) {
|
||||
.none => &.{
|
||||
.writeSplat = noneWriteSplat,
|
||||
.writeFile = noneWriteFile,
|
||||
.drain = noneDrain,
|
||||
.sendFile = noneSendFile,
|
||||
},
|
||||
.content_length => &.{
|
||||
.writeSplat = contentLengthWriteSplat,
|
||||
.writeFile = contentLengthWriteFile,
|
||||
.drain = contentLengthDrain,
|
||||
.sendFile = contentLengthSendFile,
|
||||
},
|
||||
.chunked => &.{
|
||||
.writeSplat = chunkedWriteSplat,
|
||||
.writeFile = chunkedWriteFile,
|
||||
.drain = chunkedDrain,
|
||||
.sendFile = chunkedSendFile,
|
||||
},
|
||||
.end => unreachable,
|
||||
},
|
||||
|
||||
@ -13,6 +13,7 @@ const net = std.net;
|
||||
const Uri = std.Uri;
|
||||
const Allocator = mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Client = @This();
|
||||
|
||||
@ -229,7 +230,7 @@ pub const Connection = struct {
|
||||
stream_reader: net.Stream.Reader,
|
||||
/// HTTP protocol from client to server.
|
||||
/// This either goes directly to `stream_writer`, or to a TLS client.
|
||||
writer: std.io.BufferedWriter,
|
||||
writer: Writer,
|
||||
/// HTTP protocol from server to client.
|
||||
/// This either comes directly from `stream_reader`, or from a TLS client.
|
||||
reader: std.io.Reader,
|
||||
@ -297,7 +298,7 @@ pub const Connection = struct {
|
||||
|
||||
const Tls = struct {
|
||||
/// Data from `client` to `Connection.stream`.
|
||||
writer: std.io.BufferedWriter,
|
||||
writer: Writer,
|
||||
/// Data from `Connection.stream` to `client`.
|
||||
reader: std.io.Reader,
|
||||
client: std.crypto.tls.Client,
|
||||
@ -403,7 +404,7 @@ pub const Connection = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flush(c: *Connection) std.io.Writer.Error!void {
|
||||
pub fn flush(c: *Connection) Writer.Error!void {
|
||||
try c.writer.flush();
|
||||
if (c.protocol == .tls) {
|
||||
if (disable_tls) unreachable;
|
||||
@ -415,7 +416,7 @@ pub const Connection = struct {
|
||||
/// If the connection is a TLS connection, sends the close_notify alert.
|
||||
///
|
||||
/// Flushes all buffers.
|
||||
pub fn end(c: *Connection) std.io.Writer.Error!void {
|
||||
pub fn end(c: *Connection) Writer.Error!void {
|
||||
try c.writer.flush();
|
||||
if (c.protocol == .tls) {
|
||||
if (disable_tls) unreachable;
|
||||
@ -818,13 +819,13 @@ pub const Request = struct {
|
||||
}
|
||||
|
||||
/// Sends and flushes a complete request as only HTTP head, no body.
|
||||
pub fn sendBodiless(r: *Request) std.io.Writer.Error!void {
|
||||
pub fn sendBodiless(r: *Request) Writer.Error!void {
|
||||
try sendBodilessUnflushed(r);
|
||||
try r.connection.?.flush();
|
||||
}
|
||||
|
||||
/// Sends but does not flush a complete request as only HTTP head, no body.
|
||||
pub fn sendBodilessUnflushed(r: *Request) std.io.Writer.Error!void {
|
||||
pub fn sendBodilessUnflushed(r: *Request) Writer.Error!void {
|
||||
assert(r.transfer_encoding == .none);
|
||||
assert(!r.method.requestHasBody());
|
||||
try sendHead(r);
|
||||
@ -834,7 +835,7 @@ pub const Request = struct {
|
||||
///
|
||||
/// See also:
|
||||
/// * `sendBodyUnflushed`
|
||||
pub fn sendBody(r: *Request) std.io.Writer.Error!http.BodyWriter {
|
||||
pub fn sendBody(r: *Request) Writer.Error!http.BodyWriter {
|
||||
const result = try sendBodyUnflushed(r);
|
||||
try r.connection.?.flush();
|
||||
return result;
|
||||
@ -845,7 +846,7 @@ pub const Request = struct {
|
||||
///
|
||||
/// See also:
|
||||
/// * `sendBody`
|
||||
pub fn sendBodyUnflushed(r: *Request) std.io.Writer.Error!http.BodyWriter {
|
||||
pub fn sendBodyUnflushed(r: *Request) Writer.Error!http.BodyWriter {
|
||||
assert(r.method.requestHasBody());
|
||||
try sendHead(r);
|
||||
return .{
|
||||
@ -860,7 +861,7 @@ pub const Request = struct {
|
||||
}
|
||||
|
||||
/// Sends HTTP headers without flushing.
|
||||
fn sendHead(r: *Request) std.io.Writer.Error!void {
|
||||
fn sendHead(r: *Request) Writer.Error!void {
|
||||
const uri = r.uri;
|
||||
const connection = r.connection.?;
|
||||
const w = &connection.writer;
|
||||
@ -1134,7 +1135,7 @@ pub const Request = struct {
|
||||
|
||||
/// Returns true if the default behavior is required, otherwise handles
|
||||
/// writing (or not writing) the header.
|
||||
fn emitOverridableHeader(prefix: []const u8, v: Headers.Value, bw: *std.io.BufferedWriter) std.io.Writer.Error!bool {
|
||||
fn emitOverridableHeader(prefix: []const u8, v: Headers.Value, bw: *Writer) Writer.Error!bool {
|
||||
switch (v) {
|
||||
.default => return true,
|
||||
.omit => return false,
|
||||
@ -1242,16 +1243,14 @@ pub const basic_authorization = struct {
|
||||
}
|
||||
|
||||
pub fn value(uri: Uri, out: []u8) []u8 {
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(out);
|
||||
var bw: Writer = .fixed(out);
|
||||
write(uri, &bw) catch unreachable;
|
||||
return bw.getWritten();
|
||||
}
|
||||
|
||||
pub fn write(uri: Uri, out: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn write(uri: Uri, out: *Writer) Writer.Error!void {
|
||||
var buf: [max_user_len + ":".len + max_password_len]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buf);
|
||||
var bw: Writer = .fixed(&buf);
|
||||
bw.print("{fuser}:{fpassword}", .{
|
||||
uri.user orelse Uri.Component.empty,
|
||||
uri.password orelse Uri.Component.empty,
|
||||
|
||||
@ -6,11 +6,12 @@ const mem = std.mem;
|
||||
const Uri = std.Uri;
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Server = @This();
|
||||
|
||||
/// Data from the HTTP server to the HTTP client.
|
||||
out: *std.io.BufferedWriter,
|
||||
out: *Writer,
|
||||
reader: http.Reader,
|
||||
|
||||
/// Initialize an HTTP server that can respond to multiple requests on the same
|
||||
@ -20,7 +21,7 @@ reader: http.Reader,
|
||||
/// header, otherwise `receiveHead` returns `error.HttpHeadersOversize`.
|
||||
///
|
||||
/// The returned `Server` is ready for `receiveHead` to be called.
|
||||
pub fn init(in: *std.io.Reader, out: *std.io.BufferedWriter) Server {
|
||||
pub fn init(in: *std.io.Reader, out: *Writer) Server {
|
||||
return .{
|
||||
.reader = .{
|
||||
.in = in,
|
||||
@ -397,7 +398,7 @@ pub const Request = struct {
|
||||
/// be done to satisfy the request.
|
||||
///
|
||||
/// Asserts status is not `continue`.
|
||||
pub fn respondStreaming(request: *Request, options: RespondStreamingOptions) std.io.Writer.Error!http.BodyWriter {
|
||||
pub fn respondStreaming(request: *Request, options: RespondStreamingOptions) Writer.Error!http.BodyWriter {
|
||||
try writeExpectContinue(request);
|
||||
const o = options.respond_options;
|
||||
assert(o.status != .@"continue");
|
||||
@ -485,7 +486,7 @@ pub const Request = struct {
|
||||
|
||||
/// The header is not guaranteed to be sent until `WebSocket.flush` is
|
||||
/// called on the returned struct.
|
||||
pub fn respondWebSocket(request: *Request, options: WebSocketOptions) std.io.Writer.Error!WebSocket {
|
||||
pub fn respondWebSocket(request: *Request, options: WebSocketOptions) Writer.Error!WebSocket {
|
||||
if (request.head.expect != null) return error.HttpExpectationFailed;
|
||||
|
||||
const out = request.server.out;
|
||||
@ -611,7 +612,7 @@ pub const Request = struct {
|
||||
pub const WebSocket = struct {
|
||||
key: []const u8,
|
||||
input: *std.io.Reader,
|
||||
output: *std.io.BufferedWriter,
|
||||
output: *Writer,
|
||||
|
||||
pub const Header0 = packed struct(u8) {
|
||||
opcode: Opcode,
|
||||
@ -701,21 +702,21 @@ pub const WebSocket = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeMessage(ws: *WebSocket, data: []const u8, op: Opcode) std.io.Writer.Error!void {
|
||||
pub fn writeMessage(ws: *WebSocket, data: []const u8, op: Opcode) Writer.Error!void {
|
||||
try writeMessageVecUnflushed(ws, &.{data}, op);
|
||||
try ws.output.flush();
|
||||
}
|
||||
|
||||
pub fn writeMessageUnflushed(ws: *WebSocket, data: []const u8, op: Opcode) std.io.Writer.Error!void {
|
||||
pub fn writeMessageUnflushed(ws: *WebSocket, data: []const u8, op: Opcode) Writer.Error!void {
|
||||
try writeMessageVecUnflushed(ws, &.{data}, op);
|
||||
}
|
||||
|
||||
pub fn writeMessageVec(ws: *WebSocket, data: []const []const u8, op: Opcode) std.io.Writer.Error!void {
|
||||
pub fn writeMessageVec(ws: *WebSocket, data: []const []const u8, op: Opcode) Writer.Error!void {
|
||||
try writeMessageVecUnflushed(ws, data, op);
|
||||
try ws.output.flush();
|
||||
}
|
||||
|
||||
pub fn writeMessageVecUnflushed(ws: *WebSocket, data: []const []const u8, op: Opcode) std.io.Writer.Error!void {
|
||||
pub fn writeMessageVecUnflushed(ws: *WebSocket, data: []const []const u8, op: Opcode) Writer.Error!void {
|
||||
const total_len = l: {
|
||||
var total_len: u64 = 0;
|
||||
for (data) |iovec| total_len += iovec.len;
|
||||
@ -749,7 +750,7 @@ pub const WebSocket = struct {
|
||||
try out.writeVecAll(data);
|
||||
}
|
||||
|
||||
pub fn flush(ws: *WebSocket) std.io.Writer.Error!void {
|
||||
pub fn flush(ws: *WebSocket) Writer.Error!void {
|
||||
try ws.output.flush();
|
||||
}
|
||||
};
|
||||
|
||||
@ -72,8 +72,6 @@ pub const Limit = enum(usize) {
|
||||
pub const Reader = @import("io/Reader.zig");
|
||||
pub const Writer = @import("io/Writer.zig");
|
||||
|
||||
pub const AllocatingWriter = @import("io/AllocatingWriter.zig");
|
||||
|
||||
pub const ChangeDetectionStream = @import("io/change_detection_stream.zig").ChangeDetectionStream;
|
||||
pub const changeDetectionStream = @import("io/change_detection_stream.zig").changeDetectionStream;
|
||||
|
||||
@ -485,7 +483,6 @@ pub fn PollFiles(comptime StreamEnum: type) type {
|
||||
}
|
||||
|
||||
test {
|
||||
_ = AllocatingWriter;
|
||||
_ = Reader;
|
||||
_ = Writer;
|
||||
_ = @import("io/test.zig");
|
||||
|
||||
@ -1,215 +0,0 @@
|
||||
//! While it is possible to use `std.ArrayList` as the underlying writer when
|
||||
//! using `std.io.BufferedWriter` by populating the `std.io.Writer` interface
|
||||
//! and then using an empty buffer, it means that every use of
|
||||
//! `std.io.BufferedWriter` will go through the vtable, including for
|
||||
//! functions such as `writeByte`. This API instead maintains
|
||||
//! `std.io.BufferedWriter` state such that it writes to the unused capacity of
|
||||
//! an array list, filling it up completely before making a call through the
|
||||
//! vtable, causing a resize. Consequently, the same, optimized, non-generic
|
||||
//! machine code that uses `std.io.Reader`, such as formatted printing,
|
||||
//! takes the hot paths when using this API.
|
||||
|
||||
const std = @import("../std.zig");
|
||||
const AllocatingWriter = @This();
|
||||
const assert = std.debug.assert;
|
||||
|
||||
/// This is missing the data stored in `buffered_writer`. See `getWritten` for
|
||||
/// returning a slice that includes both.
|
||||
written: []u8,
|
||||
allocator: std.mem.Allocator,
|
||||
/// When using this API, it is not necessary to call
|
||||
/// `std.io.BufferedWriter.flush`.
|
||||
buffered_writer: std.io.BufferedWriter,
|
||||
|
||||
const vtable: std.io.Writer.VTable = .{
|
||||
.writeSplat = writeSplat,
|
||||
.writeFile = writeFile,
|
||||
};
|
||||
|
||||
/// Sets the `AllocatingWriter` to an empty state.
|
||||
pub fn init(aw: *AllocatingWriter, allocator: std.mem.Allocator) void {
|
||||
aw.initOwnedSlice(allocator, &.{});
|
||||
}
|
||||
|
||||
pub fn initCapacity(aw: *AllocatingWriter, allocator: std.mem.Allocator, capacity: usize) error{OutOfMemory}!void {
|
||||
const initial_buffer = try allocator.alloc(u8, capacity);
|
||||
aw.initOwnedSlice(allocator, initial_buffer);
|
||||
}
|
||||
|
||||
pub fn initOwnedSlice(aw: *AllocatingWriter, allocator: std.mem.Allocator, slice: []u8) void {
|
||||
aw.* = .{
|
||||
.written = slice[0..0],
|
||||
.allocator = allocator,
|
||||
.buffered_writer = .{
|
||||
.unbuffered_writer = .{
|
||||
.context = aw,
|
||||
.vtable = &vtable,
|
||||
},
|
||||
.buffer = slice,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(aw: *AllocatingWriter) void {
|
||||
const written = aw.written;
|
||||
aw.allocator.free(written.ptr[0 .. written.len + aw.buffered_writer.buffer.len]);
|
||||
aw.* = undefined;
|
||||
}
|
||||
|
||||
/// Replaces `array_list` with empty, taking ownership of the memory.
|
||||
pub fn fromArrayList(
|
||||
aw: *AllocatingWriter,
|
||||
allocator: std.mem.Allocator,
|
||||
array_list: *std.ArrayListUnmanaged(u8),
|
||||
) *std.io.BufferedWriter {
|
||||
aw.* = .{
|
||||
.written = array_list.items,
|
||||
.allocator = allocator,
|
||||
.buffered_writer = .{
|
||||
.unbuffered_writer = .{
|
||||
.context = aw,
|
||||
.vtable = &vtable,
|
||||
},
|
||||
.buffer = array_list.unusedCapacitySlice(),
|
||||
},
|
||||
};
|
||||
array_list.* = .empty;
|
||||
return &aw.buffered_writer;
|
||||
}
|
||||
|
||||
/// Returns an array list that takes ownership of the allocated memory.
|
||||
/// Resets the `AllocatingWriter` to an empty state.
|
||||
pub fn toArrayList(aw: *AllocatingWriter) std.ArrayListUnmanaged(u8) {
|
||||
const bw = &aw.buffered_writer;
|
||||
const written = aw.written;
|
||||
const result: std.ArrayListUnmanaged(u8) = .{
|
||||
.items = written.ptr[0 .. written.len + bw.end],
|
||||
.capacity = written.len + bw.buffer.len,
|
||||
};
|
||||
aw.written = &.{};
|
||||
bw.buffer = &.{};
|
||||
bw.end = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn toOwnedSlice(aw: *AllocatingWriter) error{OutOfMemory}![]u8 {
|
||||
var list = aw.toArrayList();
|
||||
return list.toOwnedSlice(aw.allocator);
|
||||
}
|
||||
|
||||
pub fn toOwnedSliceSentinel(aw: *AllocatingWriter, comptime sentinel: u8) error{OutOfMemory}![:sentinel]u8 {
|
||||
const gpa = aw.allocator;
|
||||
var list = toArrayList(aw);
|
||||
return list.toOwnedSliceSentinel(gpa, sentinel);
|
||||
}
|
||||
|
||||
fn setArrayList(aw: *AllocatingWriter, list: std.ArrayListUnmanaged(u8)) void {
|
||||
aw.written = list.items;
|
||||
aw.buffered_writer.buffer = list.unusedCapacitySlice();
|
||||
}
|
||||
|
||||
pub fn getWritten(aw: *AllocatingWriter) []u8 {
|
||||
const bw = &aw.buffered_writer;
|
||||
const end = aw.buffered_writer.end;
|
||||
const written = aw.written.ptr[0 .. aw.written.len + end];
|
||||
aw.written = written;
|
||||
bw.buffer = bw.buffer[end..];
|
||||
bw.end = 0;
|
||||
return written;
|
||||
}
|
||||
|
||||
pub fn shrinkRetainingCapacity(aw: *AllocatingWriter, new_len: usize) void {
|
||||
const bw = &aw.buffered_writer;
|
||||
bw.buffer = aw.written.ptr[new_len .. aw.written.len + bw.buffer.len];
|
||||
bw.end = 0;
|
||||
aw.written.len = new_len;
|
||||
}
|
||||
|
||||
pub fn clearRetainingCapacity(aw: *AllocatingWriter) void {
|
||||
aw.shrinkRetainingCapacity(0);
|
||||
}
|
||||
|
||||
fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize {
|
||||
assert(data.len != 0);
|
||||
const aw: *AllocatingWriter = @alignCast(@ptrCast(context));
|
||||
const start_len = aw.written.len;
|
||||
const bw = &aw.buffered_writer;
|
||||
const skip_first = data[0].ptr == aw.written.ptr + start_len;
|
||||
const items_len = if (skip_first) start_len + data[0].len else start_len;
|
||||
var list: std.ArrayListUnmanaged(u8) = .{
|
||||
.items = aw.written.ptr[0..items_len],
|
||||
.capacity = start_len + bw.buffer.len,
|
||||
};
|
||||
defer setArrayList(aw, list);
|
||||
const rest = if (splat == 0) data[1 .. data.len - 1] else data[1..];
|
||||
const pattern = data[data.len - 1];
|
||||
const remaining_splat = splat - 1;
|
||||
var new_capacity: usize = list.capacity + pattern.len * remaining_splat;
|
||||
for (rest) |bytes| new_capacity += bytes.len;
|
||||
list.ensureTotalCapacity(aw.allocator, new_capacity + 1) catch return error.WriteFailed;
|
||||
for (rest) |bytes| list.appendSliceAssumeCapacity(bytes);
|
||||
if (pattern.len == 1) {
|
||||
list.appendNTimesAssumeCapacity(pattern[0], remaining_splat);
|
||||
} else {
|
||||
for (0..remaining_splat) |_| list.appendSliceAssumeCapacity(pattern);
|
||||
}
|
||||
aw.written = list.items;
|
||||
bw.buffer = list.unusedCapacitySlice();
|
||||
return list.items.len - start_len;
|
||||
}
|
||||
|
||||
fn writeFile(
|
||||
context: ?*anyopaque,
|
||||
file_reader: *std.fs.File.Reader,
|
||||
limit: std.io.Limit,
|
||||
headers_and_trailers_full: []const []const u8,
|
||||
headers_len_full: usize,
|
||||
) std.io.Writer.FileError!usize {
|
||||
if (std.fs.File.Handle == void) return error.Unimplemented;
|
||||
const aw: *AllocatingWriter = @alignCast(@ptrCast(context));
|
||||
const gpa = aw.allocator;
|
||||
var list = aw.toArrayList();
|
||||
defer setArrayList(aw, list);
|
||||
const start_len = list.items.len;
|
||||
const headers_and_trailers, const headers_len = if (headers_len_full >= 1) b: {
|
||||
assert(headers_and_trailers_full[0].ptr == list.items.ptr + start_len);
|
||||
list.items.len += headers_and_trailers_full[0].len;
|
||||
break :b .{ headers_and_trailers_full[1..], headers_len_full - 1 };
|
||||
} else .{ headers_and_trailers_full, headers_len_full };
|
||||
const trailers = headers_and_trailers[headers_len..];
|
||||
const pos = file_reader.pos;
|
||||
|
||||
const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line;
|
||||
var new_capacity: usize = list.capacity + limit.minInt(additional);
|
||||
for (headers_and_trailers) |bytes| new_capacity += bytes.len;
|
||||
list.ensureTotalCapacity(gpa, new_capacity) catch return error.WriteFailed;
|
||||
for (headers_and_trailers[0..headers_len]) |bytes| list.appendSliceAssumeCapacity(bytes);
|
||||
const dest = limit.slice(list.items.ptr[list.items.len..list.capacity]);
|
||||
const n = file_reader.read(dest) catch |err| switch (err) {
|
||||
error.ReadFailed => return error.ReadFailed,
|
||||
error.EndOfStream => 0,
|
||||
};
|
||||
const is_end = if (file_reader.getSize()) |size| n >= size - pos else |_| n == 0;
|
||||
if (is_end) {
|
||||
new_capacity = list.capacity;
|
||||
for (trailers) |bytes| new_capacity += bytes.len;
|
||||
list.ensureTotalCapacity(gpa, new_capacity) catch return error.WriteFailed;
|
||||
for (trailers) |bytes| list.appendSliceAssumeCapacity(bytes);
|
||||
} else {
|
||||
list.items.len += n;
|
||||
}
|
||||
return list.items.len - start_len;
|
||||
}
|
||||
|
||||
test AllocatingWriter {
|
||||
var aw: AllocatingWriter = undefined;
|
||||
aw.init(std.testing.allocator);
|
||||
defer aw.deinit();
|
||||
const bw = &aw.buffered_writer;
|
||||
|
||||
const x: i32 = 42;
|
||||
const y: i32 = 1234;
|
||||
try bw.print("x: {}\ny: {}\n", .{ x, y });
|
||||
|
||||
try std.testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", aw.getWritten());
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1149,8 +1149,7 @@ pub fn restitute(r: *Reader, n: usize) void {
|
||||
}
|
||||
|
||||
test fixed {
|
||||
var r: Reader = undefined;
|
||||
r.initFixed("a\x02");
|
||||
var r: Reader = .fixed("a\x02");
|
||||
try testing.expect((try r.takeByte()) == 'a');
|
||||
try testing.expect((try r.takeEnum(enum(u8) {
|
||||
a = 0,
|
||||
@ -1186,8 +1185,7 @@ test peekArray {
|
||||
}
|
||||
|
||||
test discardAll {
|
||||
var r: Reader = undefined;
|
||||
r.initFixed("foobar");
|
||||
var r: Reader = .fixed("foobar");
|
||||
try r.discard(3);
|
||||
try testing.expectEqualStrings("bar", try r.take(3));
|
||||
try r.discard(0);
|
||||
@ -1300,8 +1298,7 @@ test readVec {
|
||||
|
||||
test "expected error.EndOfStream" {
|
||||
// Unit test inspired by https://github.com/ziglang/zig/issues/17733
|
||||
var r: std.io.Reader = undefined;
|
||||
r.initFixed("");
|
||||
var r: std.io.Reader = .fixed("");
|
||||
try std.testing.expectError(error.EndOfStream, r.readEnum(enum(u8) { a, b }, .little));
|
||||
try std.testing.expectError(error.EndOfStream, r.isBytes("foo"));
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ const Limited = @This();
|
||||
|
||||
const std = @import("../../std.zig");
|
||||
const Reader = std.io.Reader;
|
||||
const BufferedWriter = std.io.BufferedWriter;
|
||||
const Writer = std.io.Writer;
|
||||
const Limit = std.io.Limit;
|
||||
|
||||
unlimited: *Reader,
|
||||
@ -25,10 +25,10 @@ pub fn init(reader: *Reader, limit: Limit, buffer: []u8) Limited {
|
||||
};
|
||||
}
|
||||
|
||||
fn stream(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) Reader.StreamError!usize {
|
||||
fn stream(context: ?*anyopaque, w: *Writer, limit: Limit) Reader.StreamError!usize {
|
||||
const l: *Limited = @alignCast(@ptrCast(context));
|
||||
const combined_limit = limit.min(l.remaining);
|
||||
const n = try l.unlimited_reader.read(bw, combined_limit);
|
||||
const n = try l.unlimited_reader.read(w, combined_limit);
|
||||
l.remaining = l.remaining.subtract(n).?;
|
||||
return n;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -73,7 +73,7 @@ pub const Config = union(enum) {
|
||||
|
||||
pub const SetColorError = std.os.windows.SetConsoleTextAttributeError || std.io.Writer.Error;
|
||||
|
||||
pub fn setColor(conf: Config, bw: *std.io.BufferedWriter, color: Color) SetColorError!void {
|
||||
pub fn setColor(conf: Config, w: *std.io.Writer, color: Color) SetColorError!void {
|
||||
nosuspend switch (conf) {
|
||||
.no_color => return,
|
||||
.escape_codes => {
|
||||
@ -98,7 +98,7 @@ pub const Config = union(enum) {
|
||||
.dim => "\x1b[2m",
|
||||
.reset => "\x1b[0m",
|
||||
};
|
||||
try bw.writeAll(color_string);
|
||||
try w.writeAll(color_string);
|
||||
},
|
||||
.windows_api => |ctx| if (native_os == .windows) {
|
||||
const attributes = switch (color) {
|
||||
|
||||
@ -127,9 +127,9 @@ pub fn Formatter(comptime T: type) type {
|
||||
self: @This(),
|
||||
comptime fmt_spec: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *std.io.Writer,
|
||||
) !void {
|
||||
_ = fmt_spec;
|
||||
comptime std.debug.assert(fmt_spec.len == 0);
|
||||
_ = options;
|
||||
try Stringify.value(self.value, self.options, writer);
|
||||
}
|
||||
|
||||
@ -23,13 +23,14 @@ const Allocator = std.mem.Allocator;
|
||||
const ArrayList = std.ArrayList;
|
||||
const BitStack = std.BitStack;
|
||||
const Stringify = @This();
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const IndentationMode = enum(u1) {
|
||||
object = 0,
|
||||
array = 1,
|
||||
};
|
||||
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
options: Options = .{},
|
||||
indent_level: usize = 0,
|
||||
next_punctuation: enum {
|
||||
@ -77,7 +78,7 @@ const safety_checks: @TypeOf(safety_checks_hint) = if (build_mode_has_safety)
|
||||
else
|
||||
.assumed_correct;
|
||||
|
||||
pub const Error = std.io.Writer.Error;
|
||||
pub const Error = Writer.Error;
|
||||
|
||||
pub fn beginArray(self: *Stringify) Error!void {
|
||||
if (build_mode_has_safety) assert(self.raw_streaming_mode == .none);
|
||||
@ -224,8 +225,7 @@ pub fn print(self: *Stringify, comptime fmt: []const u8, args: anytype) Error!vo
|
||||
|
||||
test print {
|
||||
var out_buf: [1024]u8 = undefined;
|
||||
var out: std.io.BufferedWriter = undefined;
|
||||
out.initFixed(&out_buf);
|
||||
var out: Writer = .fixed(&out_buf);
|
||||
|
||||
var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } };
|
||||
|
||||
@ -567,10 +567,10 @@ pub const Options = struct {
|
||||
emit_nonportable_numbers_as_strings: bool = false,
|
||||
};
|
||||
|
||||
/// Writes the given value to the `std.io.Writer` writer.
|
||||
/// Writes the given value to the `Writer` writer.
|
||||
/// See `Stringify` for how the given value is serialized into JSON.
|
||||
/// The maximum nesting depth of the output JSON document is 256.
|
||||
pub fn value(v: anytype, options: Options, writer: *std.io.BufferedWriter) Error!void {
|
||||
pub fn value(v: anytype, options: Options, writer: *Writer) Error!void {
|
||||
var s: Stringify = .{ .writer = writer, .options = options };
|
||||
try s.write(v);
|
||||
}
|
||||
@ -634,7 +634,7 @@ test valueAlloc {
|
||||
try std.testing.expectEqualStrings(expected, actual);
|
||||
}
|
||||
|
||||
fn outputUnicodeEscape(codepoint: u21, bw: *std.io.BufferedWriter) Error!void {
|
||||
fn outputUnicodeEscape(codepoint: u21, bw: *Writer) Error!void {
|
||||
if (codepoint <= 0xFFFF) {
|
||||
// If the character is in the Basic Multilingual Plane (U+0000 through U+FFFF),
|
||||
// then it may be represented as a six-character sequence: a reverse solidus, followed
|
||||
@ -654,7 +654,7 @@ fn outputUnicodeEscape(codepoint: u21, bw: *std.io.BufferedWriter) Error!void {
|
||||
}
|
||||
}
|
||||
|
||||
fn outputSpecialEscape(c: u8, writer: *std.io.BufferedWriter) Error!void {
|
||||
fn outputSpecialEscape(c: u8, writer: *Writer) Error!void {
|
||||
switch (c) {
|
||||
'\\' => try writer.writeAll("\\\\"),
|
||||
'\"' => try writer.writeAll("\\\""),
|
||||
@ -668,14 +668,14 @@ fn outputSpecialEscape(c: u8, writer: *std.io.BufferedWriter) Error!void {
|
||||
}
|
||||
|
||||
/// Write `string` to `writer` as a JSON encoded string.
|
||||
pub fn encodeJsonString(string: []const u8, options: Options, writer: *std.io.BufferedWriter) Error!void {
|
||||
pub fn encodeJsonString(string: []const u8, options: Options, writer: *Writer) Error!void {
|
||||
try writer.writeByte('\"');
|
||||
try encodeJsonStringChars(string, options, writer);
|
||||
try writer.writeByte('\"');
|
||||
}
|
||||
|
||||
/// Write `chars` to `writer` as JSON encoded string characters.
|
||||
pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *std.io.BufferedWriter) Error!void {
|
||||
pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *Writer) Error!void {
|
||||
var write_cursor: usize = 0;
|
||||
var i: usize = 0;
|
||||
if (options.escape_unicode) {
|
||||
@ -718,8 +718,7 @@ pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *std.i
|
||||
|
||||
test "json write stream" {
|
||||
var out_buf: [1024]u8 = undefined;
|
||||
var out: std.io.BufferedWriter = undefined;
|
||||
out.initFixed(&out_buf);
|
||||
var out: Writer = .fixed(&out_buf);
|
||||
var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } };
|
||||
try testBasicWriteStream(&w);
|
||||
}
|
||||
@ -971,16 +970,14 @@ test "stringify struct with custom stringifier" {
|
||||
|
||||
fn testStringify(expected: []const u8, v: anytype, options: Options) !void {
|
||||
var buffer: [4096]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buffer);
|
||||
var bw: Writer = .fixed(&buffer);
|
||||
try value(v, options, &bw);
|
||||
try std.testing.expectEqualStrings(expected, bw.getWritten());
|
||||
}
|
||||
|
||||
test "raw streaming" {
|
||||
var out_buf: [1024]u8 = undefined;
|
||||
var out: std.io.BufferedWriter = undefined;
|
||||
out.initFixed(&out_buf);
|
||||
var out: Writer = .fixed(&out_buf);
|
||||
|
||||
var w: Stringify = .{ .writer = &out, .options = .{ .whitespace = .indent_2 } };
|
||||
try w.beginObject();
|
||||
|
||||
@ -4,6 +4,7 @@ const mem = std.mem;
|
||||
const testing = std.testing;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const ObjectMap = @import("dynamic.zig").ObjectMap;
|
||||
const Array = @import("dynamic.zig").Array;
|
||||
@ -73,8 +74,7 @@ test "json.parser.dynamic" {
|
||||
|
||||
test "write json then parse it" {
|
||||
var out_buffer: [1000]u8 = undefined;
|
||||
var fixed_writer: std.io.BufferedWriter = undefined;
|
||||
fixed_writer.initFixed(&out_buffer);
|
||||
var fixed_writer: Writer = .fixed(&out_buffer);
|
||||
var jw: json.Stringify = .{ .writer = &fixed_writer, .options = .{} };
|
||||
|
||||
try jw.beginObject();
|
||||
@ -240,8 +240,7 @@ test "Value.jsonStringify" {
|
||||
.{ .object = obj },
|
||||
};
|
||||
var buffer: [0x1000]u8 = undefined;
|
||||
var fixed_writer: std.io.BufferedWriter = undefined;
|
||||
fixed_writer.initFixed(&buffer);
|
||||
var fixed_writer: Writer = .fixed(&buffer);
|
||||
|
||||
var jw: json.Stringify = .{ .writer = &fixed_writer, .options = .{ .whitespace = .indent_1 } };
|
||||
try jw.write(array);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
/// This is an "advanced" function. It allows one to use a fixed amount of memory to store a
|
||||
/// ULEB128. This defeats the entire purpose of using this data encoding; it will no longer use
|
||||
@ -241,7 +242,7 @@ fn test_write_leb128(value: anytype) !void {
|
||||
const signedness = @typeInfo(T).int.signedness;
|
||||
const t_signed = signedness == .signed;
|
||||
|
||||
const writeStream = if (t_signed) std.io.BufferedWriter.writeIleb128 else std.io.BufferedWriter.writeUleb128;
|
||||
const writeStream = if (t_signed) Writer.writeIleb128 else Writer.writeUleb128;
|
||||
const readStream = if (t_signed) std.io.Reader.readIleb128 else std.io.Reader.readUleb128;
|
||||
|
||||
// decode to a larger bit size too, to ensure sign extension
|
||||
@ -261,8 +262,7 @@ fn test_write_leb128(value: anytype) !void {
|
||||
const max_groups = if (@typeInfo(T).int.bits == 0) 1 else (@typeInfo(T).int.bits + 6) / 7;
|
||||
|
||||
var buf: [max_groups]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buf);
|
||||
var bw: Writer = .fixed(&buf);
|
||||
|
||||
// stream write
|
||||
try testing.expect((try writeStream(&bw, value)) == bytes_needed);
|
||||
|
||||
@ -2322,7 +2322,7 @@ pub const Const = struct {
|
||||
/// this function will fail to print the string, printing "(BigInt)" instead of a number.
|
||||
/// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
|
||||
/// See `toString` and `toStringAlloc` for a way to print big integers without failure.
|
||||
pub fn format(self: Const, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
pub fn format(self: Const, bw: *std.io.Writer, comptime fmt: []const u8) !void {
|
||||
comptime var base = 10;
|
||||
comptime var case: std.fmt.Case = .lower;
|
||||
|
||||
|
||||
@ -1915,7 +1915,7 @@ pub const Stream = struct {
|
||||
|
||||
fn read(
|
||||
context: ?*anyopaque,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *std.io.Writer,
|
||||
limit: std.io.Limit,
|
||||
) std.io.Reader.Error!usize {
|
||||
const buf = limit.slice(try bw.writableSliceGreedy(1));
|
||||
|
||||
@ -358,7 +358,7 @@ pub const Iterator = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn read(context: ?*anyopaque, bw: *std.io.BufferedWriter, limit: std.io.Limit) std.io.Reader.StreamError!usize {
|
||||
fn read(context: ?*anyopaque, bw: *std.io.Writer, limit: std.io.Limit) std.io.Reader.StreamError!usize {
|
||||
const file: *File = @ptrCast(@alignCast(context));
|
||||
if (file.unread_bytes.* == 0) return error.EndOfStream;
|
||||
const n = try file.parent_reader.read(bw, limit.min(.limited(file.unread_bytes.*)));
|
||||
@ -381,7 +381,7 @@ pub const Iterator = struct {
|
||||
return n;
|
||||
}
|
||||
|
||||
pub fn readRemaining(file: *File, out: *std.io.BufferedWriter) std.io.Reader.StreamRemainingError!void {
|
||||
pub fn readRemaining(file: *File, out: *std.io.Writer) std.io.Reader.StreamRemainingError!void {
|
||||
return file.reader().readRemaining(out);
|
||||
}
|
||||
};
|
||||
@ -818,8 +818,7 @@ test PaxIterator {
|
||||
var buffer: [1024]u8 = undefined;
|
||||
|
||||
outer: for (cases) |case| {
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(case.data);
|
||||
var br: std.io.Reader = .fixed(case.data);
|
||||
var iter: PaxIterator = .init(&br, case.data.len);
|
||||
|
||||
var i: usize = 0;
|
||||
@ -955,8 +954,7 @@ test Iterator {
|
||||
// example/empty/
|
||||
|
||||
const data = @embedFile("tar/testdata/example.tar");
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(data);
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
|
||||
// User provided buffers to the iterator
|
||||
var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined;
|
||||
@ -1015,8 +1013,7 @@ test pipeToFileSystem {
|
||||
// example/empty/
|
||||
|
||||
const data = @embedFile("tar/testdata/example.tar");
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(data);
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
|
||||
var tmp = testing.tmpDir(.{ .no_follow = true });
|
||||
defer tmp.cleanup();
|
||||
@ -1047,8 +1044,7 @@ test pipeToFileSystem {
|
||||
|
||||
test "pipeToFileSystem root_dir" {
|
||||
const data = @embedFile("tar/testdata/example.tar");
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(data);
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
|
||||
// with strip_components = 1
|
||||
{
|
||||
@ -1073,7 +1069,7 @@ test "pipeToFileSystem root_dir" {
|
||||
|
||||
// with strip_components = 0
|
||||
{
|
||||
br.initFixed(data);
|
||||
br = .fixed(data);
|
||||
var tmp = testing.tmpDir(.{ .no_follow = true });
|
||||
defer tmp.cleanup();
|
||||
var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
|
||||
@ -1096,8 +1092,7 @@ test "pipeToFileSystem root_dir" {
|
||||
|
||||
test "findRoot with single file archive" {
|
||||
const data = @embedFile("tar/testdata/22752.tar");
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(data);
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
|
||||
var tmp = testing.tmpDir(.{});
|
||||
defer tmp.cleanup();
|
||||
@ -1111,8 +1106,7 @@ test "findRoot with single file archive" {
|
||||
|
||||
test "findRoot without explicit root dir" {
|
||||
const data = @embedFile("tar/testdata/19820.tar");
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(data);
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
|
||||
var tmp = testing.tmpDir(.{});
|
||||
defer tmp.cleanup();
|
||||
@ -1126,8 +1120,7 @@ test "findRoot without explicit root dir" {
|
||||
|
||||
test "pipeToFileSystem strip_components" {
|
||||
const data = @embedFile("tar/testdata/example.tar");
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(data);
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
|
||||
var tmp = testing.tmpDir(.{ .no_follow = true });
|
||||
defer tmp.cleanup();
|
||||
@ -1188,8 +1181,7 @@ test "executable bit" {
|
||||
const data = @embedFile("tar/testdata/example.tar");
|
||||
|
||||
for ([_]PipeOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| {
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(data);
|
||||
var br: std.io.Reader = .fixed(data);
|
||||
|
||||
var tmp = testing.tmpDir(.{ .no_follow = true });
|
||||
//defer tmp.cleanup();
|
||||
|
||||
@ -14,7 +14,7 @@ pub const Options = struct {
|
||||
mtime: u64 = 0,
|
||||
};
|
||||
|
||||
underlying_writer: *std.io.BufferedWriter,
|
||||
underlying_writer: *std.io.Writer,
|
||||
prefix: []const u8 = "",
|
||||
mtime_now: u64 = 0,
|
||||
|
||||
@ -277,7 +277,7 @@ pub const Header = extern struct {
|
||||
try octal(&w.checksum, checksum);
|
||||
}
|
||||
|
||||
pub fn write(h: *Header, bw: *std.io.BufferedWriter) error{ OctalOverflow, WriteFailed }!void {
|
||||
pub fn write(h: *Header, bw: *std.io.Writer) error{ OctalOverflow, WriteFailed }!void {
|
||||
try h.updateChecksum();
|
||||
try bw.writeAll(std.mem.asBytes(h));
|
||||
}
|
||||
@ -433,16 +433,14 @@ test "write files" {
|
||||
{
|
||||
const root = "root";
|
||||
|
||||
var output: std.io.AllocatingWriter = undefined;
|
||||
output.init(testing.allocator);
|
||||
var output: std.io.AllocatingWriter = .init(testing.allocator);
|
||||
var wrt: Writer = .{ .underlying_writer = &output.buffered_writer };
|
||||
defer output.deinit();
|
||||
try wrt.setRoot(root);
|
||||
for (files) |file|
|
||||
try wrt.writeFileBytes(file.path, file.content, .{});
|
||||
|
||||
var input: std.io.Reader = undefined;
|
||||
input.initFixed(output.getWritten());
|
||||
var input: std.io.Reader = .fixed(output.getWritten());
|
||||
var iter = std.tar.iterator(&input, .{
|
||||
.file_name_buffer = &file_name_buffer,
|
||||
.link_name_buffer = &link_name_buffer,
|
||||
@ -476,13 +474,11 @@ test "write files" {
|
||||
var wrt: Writer = .{ .underlying_writer = &output.buffered_writer };
|
||||
defer output.deinit();
|
||||
for (files) |file| {
|
||||
var content: std.io.Reader = undefined;
|
||||
content.initFixed(file.content);
|
||||
var content: std.io.Reader = .fixed(file.content);
|
||||
try wrt.writeFileStream(file.path, file.content.len, &content, .{});
|
||||
}
|
||||
|
||||
var input: std.io.Reader = undefined;
|
||||
input.initFixed(output.getWritten());
|
||||
var input: std.io.Reader = .fixed(output.getWritten());
|
||||
var iter = std.tar.iterator(&input, .{
|
||||
.file_name_buffer = &file_name_buffer,
|
||||
.link_name_buffer = &link_name_buffer,
|
||||
|
||||
@ -2,6 +2,7 @@ const std = @import("std.zig");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const math = std.math;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
/// Provides deterministic randomness in unit tests.
|
||||
/// Initialized on startup. Read-only after that.
|
||||
@ -459,7 +460,7 @@ fn SliceDiffer(comptime T: type) type {
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn write(self: Self, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn write(self: Self, bw: *Writer) !void {
|
||||
for (self.expected, 0..) |value, i| {
|
||||
const full_index = self.start_index + i;
|
||||
const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true;
|
||||
@ -480,7 +481,7 @@ const BytesDiffer = struct {
|
||||
actual: []const u8,
|
||||
ttyconf: std.io.tty.Config,
|
||||
|
||||
pub fn write(self: BytesDiffer, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn write(self: BytesDiffer, bw: *Writer) !void {
|
||||
var expected_iterator = std.mem.window(u8, self.expected, 16, 16);
|
||||
var row: usize = 0;
|
||||
while (expected_iterator.next()) |chunk| {
|
||||
@ -526,7 +527,7 @@ const BytesDiffer = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeDiff(self: BytesDiffer, bw: *std.io.BufferedWriter, comptime fmt: []const u8, args: anytype, diff: bool) !void {
|
||||
fn writeDiff(self: BytesDiffer, bw: *Writer, comptime fmt: []const u8, args: anytype, diff: bool) !void {
|
||||
if (diff) try self.ttyconf.setColor(bw, .red);
|
||||
try bw.print(fmt, args);
|
||||
if (diff) try self.ttyconf.setColor(bw, .reset);
|
||||
|
||||
@ -215,8 +215,7 @@ pub const Tz = struct {
|
||||
|
||||
test "slim" {
|
||||
const data = @embedFile("tz/asia_tokyo.tzif");
|
||||
var in_stream: std.io.Reader = undefined;
|
||||
in_stream.initFixed(data);
|
||||
var in_stream: std.io.Reader = .fixed(data);
|
||||
|
||||
var tz = try std.Tz.parse(std.testing.allocator, &in_stream);
|
||||
defer tz.deinit();
|
||||
@ -229,8 +228,7 @@ test "slim" {
|
||||
|
||||
test "fat" {
|
||||
const data = @embedFile("tz/antarctica_davis.tzif");
|
||||
var in_stream: std.io.Reader = undefined;
|
||||
in_stream.initFixed(data);
|
||||
var in_stream: std.io.Reader = .fixed(data);
|
||||
|
||||
var tz = try std.Tz.parse(std.testing.allocator, &in_stream);
|
||||
defer tz.deinit();
|
||||
@ -243,8 +241,7 @@ test "fat" {
|
||||
test "legacy" {
|
||||
// Taken from Slackware 8.0, from 2001
|
||||
const data = @embedFile("tz/europe_vatican.tzif");
|
||||
var in_stream: std.io.Reader = undefined;
|
||||
in_stream.initFixed(data);
|
||||
var in_stream: std.io.Reader = .fixed(data);
|
||||
|
||||
var tz = try std.Tz.parse(std.testing.allocator, &in_stream);
|
||||
defer tz.deinit();
|
||||
|
||||
@ -2,6 +2,12 @@
|
||||
//! source lives here. These APIs are provided as-is and have absolutely no API
|
||||
//! guarantees whatsoever.
|
||||
|
||||
const std = @import("std.zig");
|
||||
const tokenizer = @import("zig/tokenizer.zig");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const ErrorBundle = @import("zig/ErrorBundle.zig");
|
||||
pub const Server = @import("zig/Server.zig");
|
||||
pub const Client = @import("zig/Client.zig");
|
||||
@ -356,11 +362,6 @@ pub fn serializeCpuAlloc(ally: Allocator, cpu: std.Target.Cpu) Allocator.Error![
|
||||
return buffer.toOwnedSlice();
|
||||
}
|
||||
|
||||
const std = @import("std.zig");
|
||||
const tokenizer = @import("zig/tokenizer.zig");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
/// Return a Formatter for a Zig identifier, escaping it with `@""` syntax if needed.
|
||||
///
|
||||
/// - An empty `{}` format specifier escapes invalid identifiers, identifiers that shadow primitives
|
||||
@ -412,11 +413,7 @@ test fmtId {
|
||||
}
|
||||
|
||||
/// Print the string as a Zig identifier, escaping it with `@""` syntax if needed.
|
||||
fn formatId(
|
||||
bytes: []const u8,
|
||||
bw: *std.io.BufferedWriter,
|
||||
comptime fmt: []const u8,
|
||||
) !void {
|
||||
fn formatId(bytes: []const u8, bw: *Writer, comptime fmt: []const u8) !void {
|
||||
const allow_primitive, const allow_underscore = comptime parse_fmt: {
|
||||
var allow_primitive = false;
|
||||
var allow_underscore = false;
|
||||
@ -470,11 +467,7 @@ test fmtEscapes {
|
||||
/// Print the string as escaped contents of a double quoted or single-quoted string.
|
||||
/// Format `{}` treats contents as a double-quoted string.
|
||||
/// Format `{'}` treats contents as a single-quoted string.
|
||||
pub fn stringEscape(
|
||||
bytes: []const u8,
|
||||
bw: *std.io.BufferedWriter,
|
||||
comptime f: []const u8,
|
||||
) !void {
|
||||
pub fn stringEscape(bytes: []const u8, bw: *Writer, comptime f: []const u8) !void {
|
||||
for (bytes) |byte| switch (byte) {
|
||||
'\n' => try bw.writeAll("\\n"),
|
||||
'\r' => try bw.writeAll("\\r"),
|
||||
|
||||
@ -4,6 +4,16 @@
|
||||
//! For Zon syntax, the root node is at nodes[0] and contains lhs as the node
|
||||
//! index of the main expression.
|
||||
|
||||
const std = @import("../std.zig");
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const mem = std.mem;
|
||||
const Token = std.zig.Token;
|
||||
const Ast = @This();
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Parse = @import("Parse.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
/// Reference to externally-owned data.
|
||||
source: [:0]const u8,
|
||||
|
||||
@ -205,7 +215,7 @@ pub fn renderAlloc(tree: Ast, gpa: Allocator) error{OutOfMemory}![]u8 {
|
||||
|
||||
pub const Render = @import("Ast/Render.zig");
|
||||
|
||||
pub fn render(tree: Ast, gpa: Allocator, bw: *std.io.BufferedWriter, fixups: Render.Fixups) Render.Error!void {
|
||||
pub fn render(tree: Ast, gpa: Allocator, bw: *Writer, fixups: Render.Fixups) Render.Error!void {
|
||||
return Render.tree(gpa, bw, tree, fixups);
|
||||
}
|
||||
|
||||
@ -311,7 +321,7 @@ pub fn rootDecls(tree: Ast) []const Node.Index {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn renderError(tree: Ast, parse_error: Error, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn renderError(tree: Ast, parse_error: Error, bw: *Writer) Writer.Error!void {
|
||||
switch (parse_error.tag) {
|
||||
.asterisk_after_ptr_deref => {
|
||||
// Note that the token will point at the `.*` but ideally the source
|
||||
@ -4118,15 +4128,6 @@ pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex
|
||||
return Span{ .start = start_off, .end = end_off, .main = tree.tokenStart(main) };
|
||||
}
|
||||
|
||||
const std = @import("../std.zig");
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const mem = std.mem;
|
||||
const Token = std.zig.Token;
|
||||
const Ast = @This();
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Parse = @import("Parse.zig");
|
||||
|
||||
test {
|
||||
_ = Parse;
|
||||
_ = Render;
|
||||
|
||||
@ -6,6 +6,7 @@ const meta = std.meta;
|
||||
const Ast = std.zig.Ast;
|
||||
const Token = std.zig.Token;
|
||||
const primitives = std.zig.primitives;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Render = @This();
|
||||
|
||||
@ -82,7 +83,7 @@ pub const Fixups = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub fn renderTree(gpa: Allocator, bw: *std.io.BufferedWriter, tree: Ast, fixups: Fixups) Error!void {
|
||||
pub fn renderTree(gpa: Allocator, bw: *Writer, tree: Ast, fixups: Fixups) Error!void {
|
||||
assert(tree.errors.len == 0); // Cannot render an invalid tree.
|
||||
var auto_indenting_stream: AutoIndentingStream = .init(gpa, bw, indent_delta);
|
||||
defer auto_indenting_stream.deinit();
|
||||
@ -3136,7 +3137,7 @@ fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenI
|
||||
return false;
|
||||
}
|
||||
|
||||
fn writeFixingWhitespace(bw: *std.io.BufferedWriter, slice: []const u8) Error!void {
|
||||
fn writeFixingWhitespace(bw: *Writer, slice: []const u8) Error!void {
|
||||
for (slice) |byte| switch (byte) {
|
||||
'\t' => try bw.splatByteAll(' ', indent_delta),
|
||||
'\r' => {},
|
||||
@ -3266,7 +3267,7 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi
|
||||
/// This should be done whenever a scope that ends in a .semicolon or a
|
||||
/// .comma is introduced.
|
||||
const AutoIndentingStream = struct {
|
||||
underlying_writer: *std.io.BufferedWriter,
|
||||
underlying_writer: *Writer,
|
||||
|
||||
/// Offset into the source at which formatting has been disabled with
|
||||
/// a `zig fmt: off` comment.
|
||||
@ -3301,10 +3302,10 @@ const AutoIndentingStream = struct {
|
||||
indent_count: usize,
|
||||
};
|
||||
|
||||
pub fn init(gpa: Allocator, bw: *std.io.BufferedWriter, indent_delta_: usize) AutoIndentingStream {
|
||||
pub fn init(gpa: Allocator, bw: *Writer, starting_indent_delta: usize) AutoIndentingStream {
|
||||
return .{
|
||||
.underlying_writer = bw,
|
||||
.indent_delta = indent_delta_,
|
||||
.indent_delta = starting_indent_delta,
|
||||
.indent_stack = .init(gpa),
|
||||
.space_stack = .init(gpa),
|
||||
};
|
||||
|
||||
@ -7,6 +7,12 @@
|
||||
//! empty, it means there are no errors. This special encoding exists so that
|
||||
//! heap allocation is not needed in the common case of no errors.
|
||||
|
||||
const std = @import("std");
|
||||
const ErrorBundle = @This();
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
string_bytes: []const u8,
|
||||
/// The first thing in this array is an `ErrorMessageList`.
|
||||
extra: []const u32,
|
||||
@ -163,7 +169,7 @@ pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void {
|
||||
renderToWriter(eb, options, bw) catch return;
|
||||
}
|
||||
|
||||
pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *std.io.BufferedWriter) (std.io.Writer.Error || std.posix.UnexpectedError)!void {
|
||||
pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, bw: *Writer) (Writer.Error || std.posix.UnexpectedError)!void {
|
||||
if (eb.extra.len == 0) return;
|
||||
for (eb.getMessages()) |err_msg| {
|
||||
try renderErrorMessageToWriter(eb, options, err_msg, bw, "error", .red, 0);
|
||||
@ -182,11 +188,11 @@ fn renderErrorMessageToWriter(
|
||||
eb: ErrorBundle,
|
||||
options: RenderOptions,
|
||||
err_msg_index: MessageIndex,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
kind: []const u8,
|
||||
color: std.io.tty.Color,
|
||||
indent: usize,
|
||||
) (std.io.Writer.Error || std.posix.UnexpectedError)!void {
|
||||
) (Writer.Error || std.posix.UnexpectedError)!void {
|
||||
const ttyconf = options.ttyconf;
|
||||
const err_msg = eb.getErrorMessage(err_msg_index);
|
||||
const prefix_start = bw.count;
|
||||
@ -294,7 +300,7 @@ fn renderErrorMessageToWriter(
|
||||
/// to allow for long, good-looking error messages.
|
||||
///
|
||||
/// This is used to split the message in `@compileError("hello\nworld")` for example.
|
||||
fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *std.io.BufferedWriter, indent: usize) !void {
|
||||
fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *Writer, indent: usize) !void {
|
||||
var lines = std.mem.splitScalar(u8, eb.nullTerminatedString(err_msg.msg), '\n');
|
||||
while (lines.next()) |line| {
|
||||
try bw.writeAll(line);
|
||||
@ -304,11 +310,6 @@ fn writeMsg(eb: ErrorBundle, err_msg: ErrorMessage, bw: *std.io.BufferedWriter,
|
||||
}
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const ErrorBundle = @This();
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
pub const Wip = struct {
|
||||
gpa: Allocator,
|
||||
string_bytes: std.ArrayListUnmanaged(u8),
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
in: *std.io.Reader,
|
||||
out: *std.io.BufferedWriter,
|
||||
out: *Writer,
|
||||
|
||||
pub const Message = struct {
|
||||
pub const Header = extern struct {
|
||||
@ -94,7 +94,7 @@ pub const Message = struct {
|
||||
|
||||
pub const Options = struct {
|
||||
in: *std.io.Reader,
|
||||
out: *std.io.BufferedWriter,
|
||||
out: *Writer,
|
||||
zig_version: []const u8,
|
||||
};
|
||||
|
||||
@ -215,3 +215,4 @@ const assert = std.debug.assert;
|
||||
const native_endian = builtin.target.cpu.arch.endian();
|
||||
const need_bswap = native_endian != .little;
|
||||
const Cache = std.Build.Cache;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
const WindowsSdk = @This();
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
windows10sdk: ?Installation,
|
||||
windows81sdk: ?Installation,
|
||||
msvc_lib_dir: ?[]const u8,
|
||||
|
||||
const WindowsSdk = @This();
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const windows = std.os.windows;
|
||||
const RRF = windows.advapi32.RRF;
|
||||
|
||||
@ -759,8 +760,7 @@ const MsvcLibDir = struct {
|
||||
while (instances_dir_it.next() catch return error.PathNotFound) |entry| {
|
||||
if (entry.kind != .directory) continue;
|
||||
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&state_subpath_buf);
|
||||
var bw: Writer = .fixed(&state_subpath_buf);
|
||||
|
||||
bw.writeAll(entry.name) catch unreachable;
|
||||
bw.writeByte(std.fs.path.sep) catch unreachable;
|
||||
|
||||
@ -521,8 +521,8 @@ pub fn strLitSizeHint(tree: Ast, node: Ast.Node.Index) usize {
|
||||
pub fn parseStrLit(
|
||||
tree: Ast,
|
||||
node: Ast.Node.Index,
|
||||
writer: *std.io.BufferedWriter,
|
||||
) std.io.Writer.Error!std.zig.string_literal.Result {
|
||||
writer: *Writer,
|
||||
) Writer.Error!std.zig.string_literal.Result {
|
||||
switch (tree.nodeTag(node)) {
|
||||
.string_literal => {
|
||||
const token = tree.nodeMainToken(node);
|
||||
@ -933,3 +933,4 @@ const StringIndexContext = std.hash_map.StringIndexContext;
|
||||
const ZonGen = @This();
|
||||
const Zoir = @import("Zoir.zig");
|
||||
const Ast = @import("Ast.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
@ -91,7 +91,7 @@ pub const String = enum(u32) {
|
||||
string: String,
|
||||
builder: *const Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_|
|
||||
@compileError("invalid format string: '" ++ fmt_str ++ "'");
|
||||
assert(data.string != .none);
|
||||
@ -649,7 +649,7 @@ pub const Type = enum(u32) {
|
||||
type: Type,
|
||||
builder: *const Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
assert(data.type != .none);
|
||||
if (comptime std.mem.eql(u8, fmt_str, "m")) {
|
||||
const item = data.builder.type_items.items[@intFromEnum(data.type)];
|
||||
@ -1129,7 +1129,7 @@ pub const Attribute = union(Kind) {
|
||||
attribute_index: Index,
|
||||
builder: *const Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
if (comptime std.mem.indexOfNone(u8, fmt_str, "\"#")) |_|
|
||||
@compileError("invalid format string: '" ++ fmt_str ++ "'");
|
||||
const attribute = data.attribute_index.toAttribute(data.builder);
|
||||
@ -1568,7 +1568,7 @@ pub const Attributes = enum(u32) {
|
||||
attributes: Attributes,
|
||||
builder: *const Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
for (data.attributes.slice(data.builder)) |attribute_index| try Attribute.Index.format(.{
|
||||
.attribute_index = attribute_index,
|
||||
.builder = data.builder,
|
||||
@ -1761,11 +1761,11 @@ pub const Linkage = enum(u4) {
|
||||
extern_weak = 7,
|
||||
external = 0,
|
||||
|
||||
pub fn format(self: Linkage, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: Linkage, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
if (self != .external) try bw.print(" {s}", .{@tagName(self)});
|
||||
}
|
||||
|
||||
fn formatOptional(data: ?Linkage, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn formatOptional(data: ?Linkage, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
if (data) |linkage| try bw.print(" {s}", .{@tagName(linkage)});
|
||||
}
|
||||
pub fn fmtOptional(self: ?Linkage) std.fmt.Formatter(formatOptional) {
|
||||
@ -1778,7 +1778,7 @@ pub const Preemption = enum {
|
||||
dso_local,
|
||||
implicit_dso_local,
|
||||
|
||||
pub fn format(self: Preemption, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: Preemption, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
if (self == .dso_local) try bw.print(" {s}", .{@tagName(self)});
|
||||
}
|
||||
};
|
||||
@ -1796,11 +1796,7 @@ pub const Visibility = enum(u2) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
self: Visibility,
|
||||
comptime format_string: []const u8,
|
||||
writer: *std.io.BufferedWriter,
|
||||
) std.io.Writer.Error!void {
|
||||
pub fn format(self: Visibility, comptime format_string: []const u8, writer: *Writer) Writer.Error!void {
|
||||
comptime assert(format_string.len == 0);
|
||||
if (self != .default) try writer.print(" {s}", .{@tagName(self)});
|
||||
}
|
||||
@ -1811,7 +1807,7 @@ pub const DllStorageClass = enum(u2) {
|
||||
dllimport = 1,
|
||||
dllexport = 2,
|
||||
|
||||
pub fn format(self: DllStorageClass, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: DllStorageClass, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
if (self != .default) try bw.print(" {s}", .{@tagName(self)});
|
||||
}
|
||||
};
|
||||
@ -1823,7 +1819,7 @@ pub const ThreadLocal = enum(u3) {
|
||||
initialexec = 3,
|
||||
localexec = 4,
|
||||
|
||||
pub fn format(self: ThreadLocal, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: ThreadLocal, bw: *Writer, comptime prefix: []const u8) Writer.Error!void {
|
||||
if (self == .default) return;
|
||||
try bw.print("{s}thread_local", .{prefix});
|
||||
if (self != .generaldynamic) try bw.print("({s})", .{@tagName(self)});
|
||||
@ -1837,7 +1833,7 @@ pub const UnnamedAddr = enum(u2) {
|
||||
unnamed_addr = 1,
|
||||
local_unnamed_addr = 2,
|
||||
|
||||
pub fn format(self: UnnamedAddr, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: UnnamedAddr, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
if (self != .default) try bw.print(" {s}", .{@tagName(self)});
|
||||
}
|
||||
};
|
||||
@ -1931,7 +1927,7 @@ pub const AddrSpace = enum(u24) {
|
||||
pub const funcref: AddrSpace = @enumFromInt(20);
|
||||
};
|
||||
|
||||
pub fn format(self: AddrSpace, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: AddrSpace, bw: *Writer, comptime prefix: []const u8) Writer.Error!void {
|
||||
if (self != .default) try bw.print("{s}addrspace({d})", .{ prefix, @intFromEnum(self) });
|
||||
}
|
||||
};
|
||||
@ -1940,7 +1936,7 @@ pub const ExternallyInitialized = enum {
|
||||
default,
|
||||
externally_initialized,
|
||||
|
||||
pub fn format(self: ExternallyInitialized, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: ExternallyInitialized, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
if (self != .default) try bw.print(" {s}", .{@tagName(self)});
|
||||
}
|
||||
};
|
||||
@ -1964,7 +1960,7 @@ pub const Alignment = enum(u6) {
|
||||
return if (self == .default) 0 else (@intFromEnum(self) + 1);
|
||||
}
|
||||
|
||||
pub fn format(self: Alignment, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: Alignment, bw: *Writer, comptime prefix: []const u8) Writer.Error!void {
|
||||
try bw.print("{s}align {d}", .{ prefix, self.toByteUnits() orelse return });
|
||||
}
|
||||
};
|
||||
@ -2038,7 +2034,7 @@ pub const CallConv = enum(u10) {
|
||||
|
||||
pub const default = CallConv.ccc;
|
||||
|
||||
pub fn format(self: CallConv, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: CallConv, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
switch (self) {
|
||||
default => {},
|
||||
.fastcc,
|
||||
@ -2119,7 +2115,7 @@ pub const StrtabString = enum(u32) {
|
||||
string: StrtabString,
|
||||
builder: *const Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_|
|
||||
@compileError("invalid format string: '" ++ fmt_str ++ "'");
|
||||
assert(data.string != .none);
|
||||
@ -2306,7 +2302,7 @@ pub const Global = struct {
|
||||
global: Index,
|
||||
builder: *const Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
try bw.print("@{f}", .{
|
||||
data.global.unwrap(data.builder).name(data.builder).fmt(data.builder),
|
||||
});
|
||||
@ -4752,7 +4748,7 @@ pub const Function = struct {
|
||||
function: Function.Index,
|
||||
builder: *Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_|
|
||||
@compileError("invalid format string: '" ++ fmt_str ++ "'");
|
||||
if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) {
|
||||
@ -6944,7 +6940,7 @@ pub const MemoryAccessKind = enum(u1) {
|
||||
normal,
|
||||
@"volatile",
|
||||
|
||||
pub fn format(self: MemoryAccessKind, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: MemoryAccessKind, bw: *Writer, comptime prefix: []const u8) Writer.Error!void {
|
||||
if (self != .normal) try bw.print("{s}{s}", .{ prefix, @tagName(self) });
|
||||
}
|
||||
};
|
||||
@ -6953,7 +6949,7 @@ pub const SyncScope = enum(u1) {
|
||||
singlethread,
|
||||
system,
|
||||
|
||||
pub fn format(self: SyncScope, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: SyncScope, bw: *Writer, comptime prefix: []const u8) Writer.Error!void {
|
||||
if (self != .system) try bw.print(
|
||||
\\{s}syncscope("{s}")
|
||||
, .{ prefix, @tagName(self) });
|
||||
@ -6969,7 +6965,7 @@ pub const AtomicOrdering = enum(u3) {
|
||||
acq_rel = 5,
|
||||
seq_cst = 6,
|
||||
|
||||
pub fn format(self: AtomicOrdering, bw: *std.io.BufferedWriter, comptime prefix: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: AtomicOrdering, bw: *Writer, comptime prefix: []const u8) Writer.Error!void {
|
||||
if (self != .none) try bw.print("{s}{s}", .{ prefix, @tagName(self) });
|
||||
}
|
||||
};
|
||||
@ -7385,7 +7381,7 @@ pub const Constant = enum(u32) {
|
||||
constant: Constant,
|
||||
builder: *Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_|
|
||||
@compileError("invalid format string: '" ++ fmt_str ++ "'");
|
||||
if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) {
|
||||
@ -7712,7 +7708,7 @@ pub const Value = enum(u32) {
|
||||
function: Function.Index,
|
||||
builder: *Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
switch (data.value.unwrap()) {
|
||||
.instruction => |instruction| try Function.Instruction.Index.format(.{
|
||||
.instruction = instruction,
|
||||
@ -7757,7 +7753,7 @@ pub const MetadataString = enum(u32) {
|
||||
metadata_string: MetadataString,
|
||||
builder: *const Builder,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
try printEscapedString(data.metadata_string.slice(data.builder), .always_quote, bw);
|
||||
}
|
||||
fn fmt(self: MetadataString, builder: *const Builder) std.fmt.Formatter(format) {
|
||||
@ -7922,7 +7918,7 @@ pub const Metadata = enum(u32) {
|
||||
AllCallsDescribed: bool = false,
|
||||
Unused: u2 = 0,
|
||||
|
||||
pub fn format(self: DIFlags, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: DIFlags, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
var need_pipe = false;
|
||||
inline for (@typeInfo(DIFlags).@"struct".fields) |field| {
|
||||
switch (@typeInfo(field.type)) {
|
||||
@ -7979,7 +7975,7 @@ pub const Metadata = enum(u32) {
|
||||
ObjCDirect: bool = false,
|
||||
Unused: u20 = 0,
|
||||
|
||||
pub fn format(self: DISPFlags, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: DISPFlags, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
var need_pipe = false;
|
||||
inline for (@typeInfo(DISPFlags).@"struct".fields) |field| {
|
||||
switch (@typeInfo(field.type)) {
|
||||
@ -8196,7 +8192,7 @@ pub const Metadata = enum(u32) {
|
||||
};
|
||||
};
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime fmt_str: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *Writer, comptime fmt_str: []const u8) Writer.Error!void {
|
||||
if (data.node == .none) return;
|
||||
|
||||
const is_specialized = fmt_str.len > 0 and fmt_str[0] == 'S';
|
||||
@ -8370,7 +8366,7 @@ pub const Metadata = enum(u32) {
|
||||
DIGlobalVariableExpression,
|
||||
},
|
||||
nodes: anytype,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
) !void {
|
||||
comptime var fmt_str: []const u8 = "";
|
||||
const names = comptime std.meta.fieldNames(@TypeOf(nodes));
|
||||
@ -8623,12 +8619,12 @@ pub fn deinit(self: *Builder) void {
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn setModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter {
|
||||
pub fn setModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *Writer {
|
||||
self.module_asm.clearRetainingCapacity();
|
||||
return self.appendModuleAsm(aw);
|
||||
}
|
||||
|
||||
pub fn appendModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *std.io.BufferedWriter {
|
||||
pub fn appendModuleAsm(self: *Builder, aw: *std.io.AllocatingWriter) *Writer {
|
||||
return aw.fromArrayList(self.gpa, &self.module_asm);
|
||||
}
|
||||
|
||||
@ -9379,14 +9375,14 @@ pub fn printToFile(self: *Builder, path: []const u8) bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn printBuffered(self: *Builder, writer: std.io.Writer) std.io.Writer.Error!void {
|
||||
pub fn printBuffered(self: *Builder, writer: Writer) Writer.Error!void {
|
||||
var buffer: [4096]u8 = undefined;
|
||||
var bw = writer.buffered(&buffer);
|
||||
try self.print(&bw);
|
||||
try bw.flush();
|
||||
}
|
||||
|
||||
pub fn print(self: *Builder, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn print(self: *Builder, bw: *Writer) Writer.Error!void {
|
||||
var need_newline = false;
|
||||
var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined };
|
||||
defer metadata_formatter.map.deinit(self.gpa);
|
||||
@ -10458,7 +10454,7 @@ fn isValidIdentifier(id: []const u8) bool {
|
||||
}
|
||||
|
||||
const QuoteBehavior = enum { always_quote, quote_unless_valid_identifier };
|
||||
fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, bw: *std.io.BufferedWriter) std.io.Writer.Error!void {
|
||||
fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, bw: *Writer) Writer.Error!void {
|
||||
const need_quotes = switch (quotes) {
|
||||
.always_quote => true,
|
||||
.quote_unless_valid_identifier => !isValidIdentifier(slice),
|
||||
@ -15097,6 +15093,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
|
||||
return bitcode.toOwnedSlice();
|
||||
}
|
||||
|
||||
const std = @import("../../std.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
const bitcode_writer = @import("bitcode_writer.zig");
|
||||
@ -15105,4 +15102,4 @@ const builtin = @import("builtin");
|
||||
const DW = std.dwarf;
|
||||
const ir = @import("ir.zig");
|
||||
const log = std.log.scoped(.llvm);
|
||||
const std = @import("../../std.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
const std = @import("../std.zig");
|
||||
const assert = std.debug.assert;
|
||||
const utf8Encode = std.unicode.utf8Encode;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const ParseError = error{
|
||||
OutOfMemory,
|
||||
@ -44,7 +45,7 @@ pub const Error = union(enum) {
|
||||
raw_string: []const u8,
|
||||
};
|
||||
|
||||
fn formatMessage(self: FormatMessage, bw: *std.io.BufferedWriter, comptime f: []const u8) !void {
|
||||
fn formatMessage(self: FormatMessage, bw: *Writer, comptime f: []const u8) !void {
|
||||
_ = f;
|
||||
switch (self.err) {
|
||||
.invalid_escape_character => |bad_index| try bw.print(
|
||||
@ -316,9 +317,9 @@ test parseCharLiteral {
|
||||
);
|
||||
}
|
||||
|
||||
/// Parses `bytes` as a Zig string literal and writes the result to the `std.io.Writer` type.
|
||||
/// Parses `bytes` as a Zig string literal and writes the result to the `Writer` type.
|
||||
/// Asserts `bytes` has '"' at beginning and end.
|
||||
pub fn parseWrite(writer: *std.io.BufferedWriter, bytes: []const u8) std.io.Writer.Error!Result {
|
||||
pub fn parseWrite(writer: *Writer, bytes: []const u8) Writer.Error!Result {
|
||||
assert(bytes.len >= 2 and bytes[0] == '"' and bytes[bytes.len - 1] == '"');
|
||||
|
||||
var index: usize = 1;
|
||||
|
||||
@ -7,6 +7,7 @@ const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const File = std.fs.File;
|
||||
const is_le = builtin.target.cpu.arch.endian() == .little;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
pub const CompressionMethod = enum(u16) {
|
||||
store = 0,
|
||||
@ -200,7 +201,7 @@ pub const Decompress = union {
|
||||
|
||||
fn readStore(
|
||||
context: ?*anyopaque,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
limit: std.io.Limit,
|
||||
) std.io.Reader.StreamError!usize {
|
||||
const d: *Decompress = @ptrCast(@alignCast(context));
|
||||
@ -209,7 +210,7 @@ pub const Decompress = union {
|
||||
|
||||
fn readDeflate(
|
||||
context: ?*anyopaque,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
limit: std.io.Limit,
|
||||
) std.io.Reader.StreamError!usize {
|
||||
const d: *Decompress = @ptrCast(@alignCast(context));
|
||||
|
||||
@ -3,6 +3,7 @@ const testing = std.testing;
|
||||
const zip = @import("../zip.zig");
|
||||
const maxInt = std.math.maxInt;
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const File = struct {
|
||||
name: []const u8,
|
||||
@ -103,7 +104,7 @@ const Zip64Options = struct {
|
||||
};
|
||||
|
||||
fn writeZip(
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
files: []const File,
|
||||
store: []FileStore,
|
||||
options: WriteZipOptions,
|
||||
@ -129,13 +130,13 @@ fn writeZip(
|
||||
/// Provides methods to format and write the contents of a zip archive
|
||||
/// to the underlying Writer.
|
||||
const Zipper = struct {
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
init_count: u64,
|
||||
central_count: u64 = 0,
|
||||
first_central_offset: ?u64 = null,
|
||||
last_central_limit: ?u64 = null,
|
||||
|
||||
fn init(writer: *std.io.BufferedWriter) Zipper {
|
||||
fn init(writer: *Writer) Zipper {
|
||||
return .{ .writer = writer, .init_count = writer.count };
|
||||
}
|
||||
|
||||
@ -198,8 +199,7 @@ const Zipper = struct {
|
||||
},
|
||||
.deflate => {
|
||||
const offset = writer.count;
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(@constCast(opt.content));
|
||||
var br: std.io.Reader = .fixed(opt.content);
|
||||
var compress: std.compress.flate.Compress = .init(&br, .{});
|
||||
var compress_br = compress.readable(&.{});
|
||||
const n = try compress_br.readRemaining(writer);
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const BufferedWriter = std.io.BufferedWriter;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
/// Options for `serialize`.
|
||||
pub const SerializeOptions = struct {
|
||||
@ -41,7 +41,7 @@ pub const SerializeOptions = struct {
|
||||
/// Serialize the given value as ZON.
|
||||
///
|
||||
/// It is asserted at comptime that `@TypeOf(val)` is not a recursive type.
|
||||
pub fn serialize(val: anytype, options: SerializeOptions, writer: *BufferedWriter) std.io.Writer.Error!void {
|
||||
pub fn serialize(val: anytype, options: SerializeOptions, writer: *Writer) Writer.Error!void {
|
||||
var s: Serializer = .{
|
||||
.writer = writer,
|
||||
.options = .{ .whitespace = options.whitespace },
|
||||
@ -60,7 +60,7 @@ pub fn serialize(val: anytype, options: SerializeOptions, writer: *BufferedWrite
|
||||
pub fn serializeMaxDepth(
|
||||
val: anytype,
|
||||
options: SerializeOptions,
|
||||
writer: *BufferedWriter,
|
||||
writer: *Writer,
|
||||
depth: usize,
|
||||
) Serializer.DepthError!void {
|
||||
var s: Serializer = .{
|
||||
@ -80,7 +80,7 @@ pub fn serializeMaxDepth(
|
||||
pub fn serializeArbitraryDepth(
|
||||
val: anytype,
|
||||
options: SerializeOptions,
|
||||
writer: *BufferedWriter,
|
||||
writer: *Writer,
|
||||
) Serializer.Error!void {
|
||||
var s: Serializer = .{
|
||||
.writer = writer,
|
||||
@ -437,9 +437,9 @@ pub const SerializeContainerOptions = struct {
|
||||
pub const Serializer = struct {
|
||||
options: Options = .{},
|
||||
indent_level: u8 = 0,
|
||||
writer: *BufferedWriter,
|
||||
writer: *Writer,
|
||||
|
||||
pub const Error = std.io.Writer.Error;
|
||||
pub const Error = Writer.Error;
|
||||
pub const DepthError = Error || error{ExceededMaxDepth};
|
||||
|
||||
pub const Options = struct {
|
||||
@ -1040,7 +1040,7 @@ pub const Serializer = struct {
|
||||
};
|
||||
|
||||
test Serializer {
|
||||
var bw: std.io.BufferedWriter = .{
|
||||
var bw: Writer = .{
|
||||
.unbuffered_writer = .discarding,
|
||||
.buffer = &.{},
|
||||
};
|
||||
|
||||
@ -119,7 +119,7 @@ const Value = extern struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format(value: Value, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
pub fn format(value: Value, bw: *std.io.Writer, comptime fmt: []const u8) !void {
|
||||
comptime assert(fmt.len == 0);
|
||||
|
||||
// Work around x86_64 backend limitation.
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Air = @This();
|
||||
const InternPool = @import("InternPool.zig");
|
||||
@ -957,7 +958,8 @@ pub const Inst = struct {
|
||||
return index.unwrap().target;
|
||||
}
|
||||
|
||||
pub fn format(index: Index, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(index: Index, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
try bw.writeByte('%');
|
||||
switch (index.unwrap()) {
|
||||
.ref => {},
|
||||
|
||||
@ -10,6 +10,7 @@ const log = std.log.scoped(.liveness);
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Log2Int = std.math.Log2Int;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Liveness = @This();
|
||||
const trace = @import("../tracy.zig").trace;
|
||||
@ -2036,7 +2037,7 @@ fn fmtInstSet(set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void)) FmtIns
|
||||
const FmtInstSet = struct {
|
||||
set: *const std.AutoHashMapUnmanaged(Air.Inst.Index, void),
|
||||
|
||||
pub fn format(val: FmtInstSet, bw: *std.io.BufferedWriter, comptime _: []const u8) !void {
|
||||
pub fn format(val: FmtInstSet, bw: *Writer, comptime _: []const u8) !void {
|
||||
if (val.set.count() == 0) {
|
||||
try bw.writeAll("[no instructions]");
|
||||
return;
|
||||
@ -2056,7 +2057,8 @@ fn fmtInstList(list: []const Air.Inst.Index) FmtInstList {
|
||||
const FmtInstList = struct {
|
||||
list: []const Air.Inst.Index,
|
||||
|
||||
pub fn format(val: FmtInstList, bw: *std.io.BufferedWriter, comptime _: []const u8) !void {
|
||||
pub fn format(val: FmtInstList, bw: *Writer, comptime fmt: []const u8) !void {
|
||||
comptime assert(fmt.len == 0);
|
||||
if (val.list.len == 0) {
|
||||
try bw.writeAll("[no instructions]");
|
||||
return;
|
||||
|
||||
@ -8,7 +8,7 @@ const Type = @import("../Type.zig");
|
||||
const Air = @import("../Air.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
|
||||
pub fn write(air: Air, stream: *std.io.BufferedWriter, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
|
||||
pub fn write(air: Air, stream: *std.io.Writer, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
|
||||
comptime std.debug.assert(build_options.enable_debug_extensions);
|
||||
const instruction_bytes = air.instructions.len *
|
||||
// Here we don't use @sizeOf(Air.Inst.Data) because it would include
|
||||
@ -54,7 +54,7 @@ pub fn write(air: Air, stream: *std.io.BufferedWriter, pt: Zcu.PerThread, livene
|
||||
|
||||
pub fn writeInst(
|
||||
air: Air,
|
||||
stream: *std.io.BufferedWriter,
|
||||
stream: *std.io.Writer,
|
||||
inst: Air.Inst.Index,
|
||||
pt: Zcu.PerThread,
|
||||
liveness: ?Air.Liveness,
|
||||
@ -93,14 +93,14 @@ const Writer = struct {
|
||||
|
||||
const Error = std.io.Writer.Error;
|
||||
|
||||
fn writeBody(w: *Writer, s: *std.io.BufferedWriter, body: []const Air.Inst.Index) Error!void {
|
||||
fn writeBody(w: *Writer, s: *std.io.Writer, body: []const Air.Inst.Index) Error!void {
|
||||
for (body) |inst| {
|
||||
try w.writeInst(s, inst);
|
||||
try s.writeByte('\n');
|
||||
}
|
||||
}
|
||||
|
||||
fn writeInst(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeInst(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const tag = w.air.instructions.items(.tag)[@intFromEnum(inst)];
|
||||
try s.splatByteAll(' ', w.indent);
|
||||
try s.print("{f}{c}= {s}(", .{
|
||||
@ -340,48 +340,48 @@ const Writer = struct {
|
||||
try s.writeByte(')');
|
||||
}
|
||||
|
||||
fn writeBinOp(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeBinOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const bin_op = w.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
|
||||
try w.writeOperand(s, inst, 0, bin_op.lhs);
|
||||
try s.writeAll(", ");
|
||||
try w.writeOperand(s, inst, 1, bin_op.rhs);
|
||||
}
|
||||
|
||||
fn writeUnOp(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeUnOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const un_op = w.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
|
||||
try w.writeOperand(s, inst, 0, un_op);
|
||||
}
|
||||
|
||||
fn writeNoOp(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeNoOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
_ = w;
|
||||
_ = s;
|
||||
_ = inst;
|
||||
// no-op, no argument to write
|
||||
}
|
||||
|
||||
fn writeType(w: *Writer, s: *std.io.BufferedWriter, ty: Type) !void {
|
||||
fn writeType(w: *Writer, s: *std.io.Writer, ty: Type) !void {
|
||||
return ty.print(s, w.pt);
|
||||
}
|
||||
|
||||
fn writeTy(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeTy(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty = w.air.instructions.items(.data)[@intFromEnum(inst)].ty;
|
||||
try w.writeType(s, ty);
|
||||
}
|
||||
|
||||
fn writeArg(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeArg(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
|
||||
try w.writeType(s, arg.ty.toType());
|
||||
try s.print(", {d}", .{arg.zir_param_index});
|
||||
}
|
||||
|
||||
fn writeTyOp(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeTyOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_op = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
||||
try w.writeType(s, ty_op.ty.toType());
|
||||
try s.writeAll(", ");
|
||||
try w.writeOperand(s, inst, 0, ty_op.operand);
|
||||
}
|
||||
|
||||
fn writeBlock(w: *Writer, s: *std.io.BufferedWriter, tag: Air.Inst.Tag, inst: Air.Inst.Index) Error!void {
|
||||
fn writeBlock(w: *Writer, s: *std.io.Writer, tag: Air.Inst.Tag, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
try w.writeType(s, ty_pl.ty.toType());
|
||||
const body: []const Air.Inst.Index = @ptrCast(switch (tag) {
|
||||
@ -422,7 +422,7 @@ const Writer = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeLoop(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeLoop(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.Block, ty_pl.payload);
|
||||
const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]);
|
||||
@ -438,7 +438,7 @@ const Writer = struct {
|
||||
try s.writeAll("}");
|
||||
}
|
||||
|
||||
fn writeAggregateInit(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeAggregateInit(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const zcu = w.pt.zcu;
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const vector_ty = ty_pl.ty.toType();
|
||||
@ -454,7 +454,7 @@ const Writer = struct {
|
||||
try s.writeAll("]");
|
||||
}
|
||||
|
||||
fn writeUnionInit(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeUnionInit(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.UnionInit, ty_pl.payload).data;
|
||||
|
||||
@ -462,7 +462,7 @@ const Writer = struct {
|
||||
try w.writeOperand(s, inst, 0, extra.init);
|
||||
}
|
||||
|
||||
fn writeStructField(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeStructField(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.StructField, ty_pl.payload).data;
|
||||
|
||||
@ -470,7 +470,7 @@ const Writer = struct {
|
||||
try s.print(", {d}", .{extra.field_index});
|
||||
}
|
||||
|
||||
fn writeTyPlBin(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeTyPlBin(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const data = w.air.instructions.items(.data);
|
||||
const ty_pl = data[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.Bin, ty_pl.payload).data;
|
||||
@ -483,7 +483,7 @@ const Writer = struct {
|
||||
try w.writeOperand(s, inst, 1, extra.rhs);
|
||||
}
|
||||
|
||||
fn writeCmpxchg(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeCmpxchg(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
|
||||
|
||||
@ -497,7 +497,7 @@ const Writer = struct {
|
||||
});
|
||||
}
|
||||
|
||||
fn writeMulAdd(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeMulAdd(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
|
||||
|
||||
@ -508,7 +508,7 @@ const Writer = struct {
|
||||
try w.writeOperand(s, inst, 2, pl_op.operand);
|
||||
}
|
||||
|
||||
fn writeShuffleOne(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeShuffleOne(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const unwrapped = w.air.unwrapShuffleOne(w.pt.zcu, inst);
|
||||
try w.writeType(s, unwrapped.result_ty);
|
||||
try s.writeAll(", ");
|
||||
@ -543,7 +543,7 @@ const Writer = struct {
|
||||
try s.writeByte(']');
|
||||
}
|
||||
|
||||
fn writeSelect(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeSelect(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const zcu = w.pt.zcu;
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
|
||||
@ -558,14 +558,14 @@ const Writer = struct {
|
||||
try w.writeOperand(s, inst, 2, extra.rhs);
|
||||
}
|
||||
|
||||
fn writeReduce(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeReduce(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const reduce = w.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
|
||||
|
||||
try w.writeOperand(s, inst, 0, reduce.operand);
|
||||
try s.print(", {s}", .{@tagName(reduce.operation)});
|
||||
}
|
||||
|
||||
fn writeCmpVector(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeCmpVector(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.VectorCmp, ty_pl.payload).data;
|
||||
|
||||
@ -575,7 +575,7 @@ const Writer = struct {
|
||||
try w.writeOperand(s, inst, 1, extra.rhs);
|
||||
}
|
||||
|
||||
fn writeVectorStoreElem(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeVectorStoreElem(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const data = w.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
|
||||
const extra = w.air.extraData(Air.VectorCmp, data.payload).data;
|
||||
|
||||
@ -586,21 +586,21 @@ const Writer = struct {
|
||||
try w.writeOperand(s, inst, 2, extra.rhs);
|
||||
}
|
||||
|
||||
fn writeRuntimeNavPtr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeRuntimeNavPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ip = &w.pt.zcu.intern_pool;
|
||||
const ty_nav = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav;
|
||||
try w.writeType(s, .fromInterned(ty_nav.ty));
|
||||
try s.print(", '{}'", .{ip.getNav(ty_nav.nav).fqn.fmt(ip)});
|
||||
}
|
||||
|
||||
fn writeAtomicLoad(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeAtomicLoad(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const atomic_load = w.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
|
||||
|
||||
try w.writeOperand(s, inst, 0, atomic_load.ptr);
|
||||
try s.print(", {s}", .{@tagName(atomic_load.order)});
|
||||
}
|
||||
|
||||
fn writePrefetch(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writePrefetch(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const prefetch = w.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
|
||||
|
||||
try w.writeOperand(s, inst, 0, prefetch.ptr);
|
||||
@ -611,7 +611,7 @@ const Writer = struct {
|
||||
|
||||
fn writeAtomicStore(
|
||||
w: *Writer,
|
||||
s: *std.io.BufferedWriter,
|
||||
s: *std.io.Writer,
|
||||
inst: Air.Inst.Index,
|
||||
order: std.builtin.AtomicOrder,
|
||||
) Error!void {
|
||||
@ -622,7 +622,7 @@ const Writer = struct {
|
||||
try s.print(", {s}", .{@tagName(order)});
|
||||
}
|
||||
|
||||
fn writeAtomicRmw(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeAtomicRmw(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const extra = w.air.extraData(Air.AtomicRmw, pl_op.payload).data;
|
||||
|
||||
@ -632,7 +632,7 @@ const Writer = struct {
|
||||
try s.print(", {s}, {s}", .{ @tagName(extra.op()), @tagName(extra.ordering()) });
|
||||
}
|
||||
|
||||
fn writeFieldParentPtr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeFieldParentPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
|
||||
|
||||
@ -640,7 +640,7 @@ const Writer = struct {
|
||||
try s.print(", {d}", .{extra.field_index});
|
||||
}
|
||||
|
||||
fn writeAssembly(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeAssembly(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.Asm, ty_pl.payload);
|
||||
const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
|
||||
@ -713,19 +713,19 @@ const Writer = struct {
|
||||
try s.print(", \"{f}\"", .{std.zig.fmtEscapes(asm_source)});
|
||||
}
|
||||
|
||||
fn writeDbgStmt(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeDbgStmt(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const dbg_stmt = w.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
|
||||
try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
|
||||
}
|
||||
|
||||
fn writeDbgVar(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeDbgVar(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
try w.writeOperand(s, inst, 0, pl_op.operand);
|
||||
const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload);
|
||||
try s.print(", \"{f}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))});
|
||||
}
|
||||
|
||||
fn writeCall(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeCall(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const extra = w.air.extraData(Air.Call, pl_op.payload);
|
||||
const args = @as([]const Air.Inst.Ref, @ptrCast(w.air.extra.items[extra.end..][0..extra.data.args_len]));
|
||||
@ -738,19 +738,19 @@ const Writer = struct {
|
||||
try s.writeAll("]");
|
||||
}
|
||||
|
||||
fn writeBr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const br = w.air.instructions.items(.data)[@intFromEnum(inst)].br;
|
||||
try w.writeInstIndex(s, br.block_inst, false);
|
||||
try s.writeAll(", ");
|
||||
try w.writeOperand(s, inst, 0, br.operand);
|
||||
}
|
||||
|
||||
fn writeRepeat(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeRepeat(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const repeat = w.air.instructions.items(.data)[@intFromEnum(inst)].repeat;
|
||||
try w.writeInstIndex(s, repeat.loop_inst, false);
|
||||
}
|
||||
|
||||
fn writeTry(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeTry(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const extra = w.air.extraData(Air.Try, pl_op.payload);
|
||||
const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]);
|
||||
@ -784,7 +784,7 @@ const Writer = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeTryPtr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeTryPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = w.air.extraData(Air.TryPtr, ty_pl.payload);
|
||||
const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]);
|
||||
@ -821,7 +821,7 @@ const Writer = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeCondBr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeCondBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const extra = w.air.extraData(Air.CondBr, pl_op.payload);
|
||||
const then_body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.then_body_len]);
|
||||
@ -880,7 +880,7 @@ const Writer = struct {
|
||||
try s.writeAll("}");
|
||||
}
|
||||
|
||||
fn writeSwitchBr(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeSwitchBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const switch_br = w.air.unwrapSwitch(inst);
|
||||
|
||||
const liveness: Air.Liveness.SwitchBrTable = if (w.liveness) |liveness|
|
||||
@ -966,25 +966,25 @@ const Writer = struct {
|
||||
try s.splatByteAll(' ', old_indent);
|
||||
}
|
||||
|
||||
fn writeWasmMemorySize(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeWasmMemorySize(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
try s.print("{d}", .{pl_op.payload});
|
||||
}
|
||||
|
||||
fn writeWasmMemoryGrow(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeWasmMemoryGrow(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
try s.print("{d}, ", .{pl_op.payload});
|
||||
try w.writeOperand(s, inst, 0, pl_op.operand);
|
||||
}
|
||||
|
||||
fn writeWorkDimension(w: *Writer, s: *std.io.BufferedWriter, inst: Air.Inst.Index) Error!void {
|
||||
fn writeWorkDimension(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void {
|
||||
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
try s.print("{d}", .{pl_op.payload});
|
||||
}
|
||||
|
||||
fn writeOperand(
|
||||
w: *Writer,
|
||||
s: *std.io.BufferedWriter,
|
||||
s: *std.io.Writer,
|
||||
inst: Air.Inst.Index,
|
||||
op_index: usize,
|
||||
operand: Air.Inst.Ref,
|
||||
@ -1030,7 +1030,7 @@ const Writer = struct {
|
||||
|
||||
fn writeInstIndex(
|
||||
w: *Writer,
|
||||
s: *std.io.BufferedWriter,
|
||||
s: *std.io.Writer,
|
||||
inst: Air.Inst.Index,
|
||||
dies: bool,
|
||||
) Error!void {
|
||||
|
||||
@ -12,6 +12,7 @@ const ThreadPool = std.Thread.Pool;
|
||||
const WaitGroup = std.Thread.WaitGroup;
|
||||
const ErrorBundle = std.zig.ErrorBundle;
|
||||
const fatal = std.process.fatal;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Value = @import("Value.zig");
|
||||
const Type = @import("Type.zig");
|
||||
@ -1000,15 +1001,12 @@ pub const CObject = struct {
|
||||
|
||||
const file = std.fs.cwd().openFile(file_name, .{}) catch break :source_line 0;
|
||||
defer file.close();
|
||||
file.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0;
|
||||
|
||||
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);
|
||||
var fr = file.reader(&buffer);
|
||||
fr.seekTo(diag.src_loc.offset + 1 - diag.src_loc.column) catch break :source_line 0;
|
||||
var bw: Writer = .fixed(&buffer);
|
||||
break :source_line try eb.addString(
|
||||
buffer[0 .. br.readDelimiterEnding(&bw, '\n') catch break :source_line 0],
|
||||
buffer[0 .. fr.interface.readDelimiterEnding(&bw, '\n') catch break :source_line 0],
|
||||
);
|
||||
};
|
||||
|
||||
@ -6026,8 +6024,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
|
||||
|
||||
// In .rc files, a " within a quoted string is escaped as ""
|
||||
const fmtRcEscape = struct {
|
||||
fn formatRcEscape(bytes: []const u8, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
_ = fmt;
|
||||
fn formatRcEscape(bytes: []const u8, bw: *Writer, comptime fmt: []const u8) !void {
|
||||
comptime assert(fmt.len == 0);
|
||||
for (bytes) |byte| switch (byte) {
|
||||
'"' => try bw.writeAll("\"\""),
|
||||
'\\' => try bw.writeAll("\\\\"),
|
||||
|
||||
@ -1888,7 +1888,7 @@ pub const NullTerminatedString = enum(u32) {
|
||||
string: NullTerminatedString,
|
||||
ip: *const InternPool,
|
||||
};
|
||||
fn format(data: FormatData, bw: *std.io.BufferedWriter, comptime specifier: []const u8) std.io.Writer.Error!void {
|
||||
fn format(data: FormatData, bw: *std.io.Writer, comptime specifier: []const u8) std.io.Writer.Error!void {
|
||||
const slice = data.string.toSlice(data.ip);
|
||||
if (comptime std.mem.eql(u8, specifier, "")) {
|
||||
try bw.writeAll(slice);
|
||||
|
||||
@ -1366,9 +1366,9 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource.Git) anyerror!U
|
||||
const index_prog_node = f.prog_node.start("Index pack", 0);
|
||||
defer index_prog_node.end();
|
||||
var buffer: [4096]u8 = undefined;
|
||||
var index_buffered_writer: std.io.BufferedWriter = index_file.writer().buffered(&buffer);
|
||||
try git.indexPack(gpa, object_format, pack_file, &index_buffered_writer);
|
||||
try index_buffered_writer.flush();
|
||||
var index_file_writer = index_file.writer(&buffer);
|
||||
try git.indexPack(gpa, object_format, pack_file, &index_file_writer.interface);
|
||||
try index_file_writer.flush();
|
||||
try index_file.sync();
|
||||
}
|
||||
|
||||
@ -1639,14 +1639,14 @@ fn computeHash(f: *Fetch, pkg_path: Cache.Path, filter: Filter) RunError!Compute
|
||||
|
||||
fn dumpHashInfo(all_files: []const *const HashedFile) !void {
|
||||
var buffer: [4096]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = std.fs.File.stdout().writer().buffered(&buffer);
|
||||
var file_writer = std.fs.File.stdout().writer(&buffer);
|
||||
const w = &file_writer.interface;
|
||||
for (all_files) |hashed_file| {
|
||||
try bw.print("{s}: {x}: {s}\n", .{
|
||||
try w.print("{s}: {x}: {s}\n", .{
|
||||
@tagName(hashed_file.kind), &hashed_file.hash, hashed_file.normalized_path,
|
||||
});
|
||||
}
|
||||
|
||||
try bw.flush();
|
||||
try file_writer.flush();
|
||||
}
|
||||
|
||||
fn workerHashFile(dir: fs.Dir, hashed_file: *HashedFile) void {
|
||||
|
||||
@ -12,6 +12,7 @@ const Sha1 = std.crypto.hash.Sha1;
|
||||
const Sha256 = std.crypto.hash.sha2.Sha256;
|
||||
const assert = std.debug.assert;
|
||||
const zlib = std.compress.zlib;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
/// The ID of a Git object.
|
||||
pub const Oid = union(Format) {
|
||||
@ -65,7 +66,7 @@ pub const Oid = union(Format) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writable(hasher: *Hasher, buffer: []u8) std.io.BufferedWriter {
|
||||
pub fn writer(hasher: *Hasher, buffer: []u8) Writer {
|
||||
return switch (hasher.*) {
|
||||
inline else => |*inner| inner.writable(buffer),
|
||||
};
|
||||
@ -134,9 +135,9 @@ pub const Oid = union(Format) {
|
||||
} else error.InvalidOid;
|
||||
}
|
||||
|
||||
pub fn format(oid: Oid, bw: *std.io.BufferedWriter, comptime fmt: []const u8) std.io.Writer.Error!void {
|
||||
_ = fmt;
|
||||
try bw.print("{x}", .{oid.slice()});
|
||||
pub fn format(oid: Oid, w: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
try w.print("{x}", .{oid.slice()});
|
||||
}
|
||||
|
||||
pub fn slice(oid: *const Oid) []const u8 {
|
||||
@ -608,7 +609,7 @@ const Packet = union(enum) {
|
||||
}
|
||||
|
||||
/// Writes a packet in pkt-line format.
|
||||
fn write(packet: Packet, writer: *std.io.BufferedWriter) !void {
|
||||
fn write(packet: Packet, writer: *Writer) !void {
|
||||
switch (packet) {
|
||||
.flush => try writer.writeAll("0000"),
|
||||
.delimiter => try writer.writeAll("0001"),
|
||||
@ -1481,8 +1482,7 @@ fn resolveDeltaChain(
|
||||
const expanded_alloc_size = std.math.cast(usize, expanded_size) orelse return error.ObjectTooLarge;
|
||||
const expanded_data = try allocator.alloc(u8, expanded_alloc_size);
|
||||
errdefer allocator.free(expanded_data);
|
||||
var expanded_delta_stream: std.io.BufferedWriter = undefined;
|
||||
expanded_delta_stream.initFixed(expanded_data);
|
||||
var expanded_delta_stream: Writer = .fixed(expanded_data);
|
||||
try expandDelta(base_data, &delta_reader, &expanded_delta_stream);
|
||||
if (expanded_delta_stream.end != expanded_size) return error.InvalidObject;
|
||||
|
||||
@ -1505,7 +1505,7 @@ fn readObjectRaw(gpa: Allocator, reader: *std.io.Reader, size: u64) ![]u8 {
|
||||
|
||||
/// The format of the delta data is documented in
|
||||
/// [pack-format](https://git-scm.com/docs/pack-format).
|
||||
fn expandDelta(base_object: []const u8, delta_reader: *std.io.Reader, writer: *std.io.BufferedWriter) !void {
|
||||
fn expandDelta(base_object: []const u8, delta_reader: *std.io.Reader, writer: *Writer) !void {
|
||||
var base_offset: u32 = 0;
|
||||
while (true) {
|
||||
const inst: packed struct { value: u7, copy: bool } = @bitCast(delta_reader.takeByte() catch |e| switch (e) {
|
||||
|
||||
@ -9544,8 +9544,8 @@ fn callConvSupportsVarArgs(cc: std.builtin.CallingConvention.Tag) bool {
|
||||
fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: std.builtin.CallingConvention.Tag) CompileError!void {
|
||||
const CallingConventionsSupportingVarArgsList = struct {
|
||||
arch: std.Target.Cpu.Arch,
|
||||
pub fn format(ctx: @This(), bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
_ = fmt;
|
||||
pub fn format(ctx: @This(), bw: *std.io.Writer, comptime fmt: []const u8) !void {
|
||||
comptime assert(fmt.len == 0);
|
||||
var first = true;
|
||||
for (calling_conventions_supporting_var_args) |cc_inner| {
|
||||
for (std.Target.Cpu.Arch.fromCallingConvention(cc_inner)) |supported_arch| {
|
||||
@ -9990,8 +9990,8 @@ fn finishFunc(
|
||||
.bad_arch => |allowed_archs| {
|
||||
const ArchListFormatter = struct {
|
||||
archs: []const std.Target.Cpu.Arch,
|
||||
pub fn format(formatter: @This(), bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
_ = fmt;
|
||||
pub fn format(formatter: @This(), bw: *std.io.Writer, comptime fmt: []const u8) !void {
|
||||
comptime assert(fmt.len == 0);
|
||||
for (formatter.archs, 0..) |arch, i| {
|
||||
if (i != 0)
|
||||
try bw.writeAll(", ");
|
||||
|
||||
@ -18,6 +18,7 @@ const Alignment = InternPool.Alignment;
|
||||
const Zir = std.zig.Zir;
|
||||
const Type = @This();
|
||||
const SemaError = Zcu.SemaError;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
ip_index: InternPool.Index,
|
||||
|
||||
@ -121,7 +122,7 @@ pub fn eql(a: Type, b: Type, zcu: *const Zcu) bool {
|
||||
return a.toIntern() == b.toIntern();
|
||||
}
|
||||
|
||||
pub fn format(ty: Type, bw: *std.io.BufferedWriter, comptime f: []const u8) !usize {
|
||||
pub fn format(ty: Type, bw: *Writer, comptime f: []const u8) !usize {
|
||||
_ = ty;
|
||||
_ = f;
|
||||
_ = bw;
|
||||
@ -142,7 +143,7 @@ const FormatContext = struct {
|
||||
pt: Zcu.PerThread,
|
||||
};
|
||||
|
||||
fn format2(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime f: []const u8) !void {
|
||||
fn format2(ctx: FormatContext, bw: *Writer, comptime f: []const u8) !void {
|
||||
comptime assert(f.len == 0);
|
||||
try print(ctx.ty, bw, ctx.pt);
|
||||
}
|
||||
@ -153,14 +154,14 @@ pub fn fmtDebug(ty: Type) std.fmt.Formatter(dump) {
|
||||
|
||||
/// This is a debug function. In order to print types in a meaningful way
|
||||
/// we also need access to the module.
|
||||
pub fn dump(start_type: Type, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) !void {
|
||||
pub fn dump(start_type: Type, bw: *Writer, comptime unused_format_string: []const u8) !void {
|
||||
comptime assert(unused_format_string.len == 0);
|
||||
return bw.print("{any}", .{start_type.ip_index});
|
||||
}
|
||||
|
||||
/// Prints a name suitable for `@typeName`.
|
||||
/// TODO: take an `opt_sema` to pass to `fmtValue` when printing sentinels.
|
||||
pub fn print(ty: Type, bw: *std.io.BufferedWriter, pt: Zcu.PerThread) std.io.Writer.Error!void {
|
||||
pub fn print(ty: Type, bw: *Writer, pt: Zcu.PerThread) Writer.Error!void {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
switch (ip.indexToKey(ty.toIntern())) {
|
||||
|
||||
@ -15,6 +15,7 @@ const BigIntConst = std.math.big.int.Const;
|
||||
const BigIntMutable = std.math.big.int.Mutable;
|
||||
const Target = std.Target;
|
||||
const Ast = std.zig.Ast;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Zcu = @This();
|
||||
const Compilation = @import("Compilation.zig");
|
||||
@ -1101,8 +1102,7 @@ pub const File = struct {
|
||||
const gpa = pt.zcu.gpa;
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed((try strings.addManyAsSlice(file.fullyQualifiedNameLen()))[0]);
|
||||
var bw: Writer = .fixed((try strings.addManyAsSlice(file.fullyQualifiedNameLen()))[0]);
|
||||
file.renderFullyQualifiedName(&bw) catch unreachable;
|
||||
assert(bw.end == bw.buffer.len);
|
||||
return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(bw.end), .no_embedded_nulls);
|
||||
@ -4260,7 +4260,7 @@ pub fn fmtDependee(zcu: *Zcu, d: InternPool.Dependee) std.fmt.Formatter(formatDe
|
||||
return .{ .data = .{ .dependee = d, .zcu = zcu } };
|
||||
}
|
||||
|
||||
fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *Writer, comptime fmt: []const u8) !void {
|
||||
_ = fmt;
|
||||
const zcu = data.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
@ -4284,7 +4284,7 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, bw: *std.io.Buffer
|
||||
.memoized_state => return bw.writeAll("memoized_state"),
|
||||
}
|
||||
}
|
||||
fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, bw: *Writer, comptime fmt: []const u8) !void {
|
||||
_ = fmt;
|
||||
const zcu = data.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
@ -6,6 +6,7 @@ const mem = std.mem;
|
||||
const math = std.math;
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = mem.Allocator;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Air = @import("../../Air.zig");
|
||||
const Mir = @import("Mir.zig");
|
||||
@ -566,7 +567,8 @@ const InstTracking = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format(inst_tracking: InstTracking, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(inst_tracking: InstTracking, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
if (!std.meta.eql(inst_tracking.long, inst_tracking.short)) try bw.print("|{}| ", .{inst_tracking.long});
|
||||
try bw.print("{}", .{inst_tracking.short});
|
||||
}
|
||||
@ -932,7 +934,7 @@ const FormatWipMirData = struct {
|
||||
func: *Func,
|
||||
inst: Mir.Inst.Index,
|
||||
};
|
||||
fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn formatWipMir(data: FormatWipMirData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
const pt = data.func.pt;
|
||||
const comp = pt.zcu.comp;
|
||||
var lower: Lower = .{
|
||||
@ -980,7 +982,7 @@ const FormatNavData = struct {
|
||||
ip: *const InternPool,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
};
|
||||
fn formatNav(data: FormatNavData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn formatNav(data: FormatNavData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
try bw.print("{f}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
|
||||
}
|
||||
fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) {
|
||||
@ -994,8 +996,13 @@ const FormatAirData = struct {
|
||||
func: *Func,
|
||||
inst: Air.Inst.Index,
|
||||
};
|
||||
fn formatAir(data: FormatAirData, _: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
data.func.air.dumpInst(data.inst, data.func.pt, data.func.liveness);
|
||||
fn formatAir(data: FormatAirData, w: *std.io.Writer, comptime fmt: []const u8) std.io.Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
// not acceptable implementation:
|
||||
// data.func.air.dumpInst(data.inst, data.func.pt, data.func.liveness);
|
||||
_ = data;
|
||||
_ = w;
|
||||
@panic("TODO: unimplemented");
|
||||
}
|
||||
fn fmtAir(func: *Func, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
|
||||
return .{ .data = .{ .func = func, .inst = inst } };
|
||||
@ -1004,7 +1011,8 @@ fn fmtAir(func: *Func, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
|
||||
const FormatTrackingData = struct {
|
||||
func: *Func,
|
||||
};
|
||||
fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn formatTracking(data: FormatTrackingData, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
var it = data.func.inst_tracking.iterator();
|
||||
while (it.next()) |entry| try bw.print("\n%{d} = {f}", .{ entry.key_ptr.*, entry.value_ptr.* });
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ pub const Inst = struct {
|
||||
},
|
||||
};
|
||||
|
||||
pub fn format(inst: Inst, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
pub fn format(inst: Inst, bw: *std.io.Writer, comptime fmt: []const u8) !void {
|
||||
assert(fmt.len == 0);
|
||||
try bw.print("Tag: {s}, Data: {s}", .{ @tagName(inst.tag), @tagName(inst.data) });
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const Target = std.Target;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Zcu = @import("../../Zcu.zig");
|
||||
const Mir = @import("Mir.zig");
|
||||
@ -256,7 +257,8 @@ pub const FrameIndex = enum(u32) {
|
||||
return @intFromEnum(fi) < named_count;
|
||||
}
|
||||
|
||||
pub fn format(fi: FrameIndex, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(fi: FrameIndex, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
try bw.writeAll("FrameIndex");
|
||||
if (fi.isNamed())
|
||||
try bw.print(".{s}", .{@tagName(fi)})
|
||||
|
||||
@ -5,6 +5,7 @@ const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const mem = std.mem;
|
||||
const log = std.log.scoped(.codegen);
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const CodeGen = @This();
|
||||
const codegen = @import("../../codegen.zig");
|
||||
|
||||
@ -4,6 +4,7 @@ const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const leb = std.leb;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Wasm = link.File.Wasm;
|
||||
const Mir = @import("Mir.zig");
|
||||
@ -15,7 +16,7 @@ const codegen = @import("../../codegen.zig");
|
||||
mir: Mir,
|
||||
wasm: *Wasm,
|
||||
/// The binary representation of this module is written here.
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
|
||||
pub const Error = error{
|
||||
OutOfMemory,
|
||||
@ -893,12 +894,12 @@ pub fn lowerToCode(emit: *Emit) Error!void {
|
||||
}
|
||||
|
||||
/// Asserts 20 unused capacity.
|
||||
fn encodeMemArg(bw: *std.io.BufferedWriter, mem_arg: Mir.MemArg) std.io.Writer.Error!void {
|
||||
fn encodeMemArg(bw: *Writer, mem_arg: Mir.MemArg) Writer.Error!void {
|
||||
try bw.writeLeb128(Wasm.Alignment.fromNonzeroByteUnits(mem_arg.alignment).toLog2Units());
|
||||
try bw.writeLeb128(mem_arg.offset);
|
||||
}
|
||||
|
||||
fn uavRefObj(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) std.io.Writer.Error!void {
|
||||
fn uavRefObj(wasm: *Wasm, bw: *Writer, value: InternPool.Index, offset: i32, is_wasm32: bool) Writer.Error!void {
|
||||
const comp = wasm.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
|
||||
@ -914,7 +915,7 @@ fn uavRefObj(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, o
|
||||
try bw.splatByteAll(0, if (is_wasm32) 5 else 10);
|
||||
}
|
||||
|
||||
fn uavRefExe(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
|
||||
fn uavRefExe(wasm: *Wasm, bw: *Writer, value: InternPool.Index, offset: i32, is_wasm32: bool) !void {
|
||||
const opcode: std.wasm.Opcode = if (is_wasm32) .i32_const else .i64_const;
|
||||
try bw.writeByte(@intFromEnum(opcode));
|
||||
|
||||
@ -922,7 +923,7 @@ fn uavRefExe(wasm: *Wasm, bw: *std.io.BufferedWriter, value: InternPool.Index, o
|
||||
try bw.writeLeb128(@as(u32, @intCast(@as(i64, addr) + offset)));
|
||||
}
|
||||
|
||||
fn navRefOff(wasm: *Wasm, bw: *std.io.BufferedWriter, data: Mir.NavRefOff, is_wasm32: bool) !void {
|
||||
fn navRefOff(wasm: *Wasm, bw: *Writer, data: Mir.NavRefOff, is_wasm32: bool) !void {
|
||||
const comp = wasm.base.comp;
|
||||
const zcu = comp.zcu.?;
|
||||
const ip = &zcu.intern_pool;
|
||||
@ -947,6 +948,6 @@ fn navRefOff(wasm: *Wasm, bw: *std.io.BufferedWriter, data: Mir.NavRefOff, is_wa
|
||||
}
|
||||
}
|
||||
|
||||
fn appendOutputFunctionIndex(bw: *std.io.BufferedWriter, i: Wasm.OutputFunctionIndex) std.io.Writer.Error!void {
|
||||
fn appendOutputFunctionIndex(bw: *Writer, i: Wasm.OutputFunctionIndex) Writer.Error!void {
|
||||
return bw.writeLeb128(@intFromEnum(i));
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ const log = std.log.scoped(.codegen);
|
||||
const tracking_log = std.log.scoped(.tracking);
|
||||
const verbose_tracking_log = std.log.scoped(.verbose_tracking);
|
||||
const wip_mir_log = std.log.scoped(.wip_mir);
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Air = @import("../../Air.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
@ -524,7 +525,7 @@ pub const MCValue = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn format(mcv: MCValue, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(mcv: MCValue, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
switch (mcv) {
|
||||
.none, .unreach, .dead, .undef => try bw.print("({s})", .{@tagName(mcv)}),
|
||||
.immediate => |pl| try bw.print("0x{x}", .{pl}),
|
||||
@ -811,7 +812,7 @@ const InstTracking = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format(tracking: InstTracking, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(tracking: InstTracking, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
if (!std.meta.eql(tracking.long, tracking.short)) try bw.print("|{f}| ", .{tracking.long});
|
||||
try bw.print("{f}", .{tracking.short});
|
||||
}
|
||||
@ -1087,7 +1088,7 @@ const FormatNavData = struct {
|
||||
ip: *const InternPool,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
};
|
||||
fn formatNav(data: FormatNavData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn formatNav(data: FormatNavData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
try bw.print("{f}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
|
||||
}
|
||||
fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) {
|
||||
@ -1101,8 +1102,13 @@ const FormatAirData = struct {
|
||||
self: *CodeGen,
|
||||
inst: Air.Inst.Index,
|
||||
};
|
||||
fn formatAir(data: FormatAirData, _: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
data.self.air.dumpInst(data.inst, data.self.pt, data.self.liveness);
|
||||
fn formatAir(data: FormatAirData, w: *std.io.Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
// not acceptable implementation:
|
||||
//data.self.air.dumpInst(data.inst, data.self.pt, data.self.liveness);
|
||||
_ = data;
|
||||
_ = w;
|
||||
@panic("TODO: unimplemented");
|
||||
}
|
||||
fn fmtAir(self: *CodeGen, inst: Air.Inst.Index) std.fmt.Formatter(formatAir) {
|
||||
return .{ .data = .{ .self = self, .inst = inst } };
|
||||
@ -1112,7 +1118,7 @@ const FormatWipMirData = struct {
|
||||
self: *CodeGen,
|
||||
inst: Mir.Inst.Index,
|
||||
};
|
||||
fn formatWipMir(data: FormatWipMirData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn formatWipMir(data: FormatWipMirData, bw: *Writer, comptime _: []const u8) Writer.Error!void {
|
||||
var lower: Lower = .{
|
||||
.target = data.self.target,
|
||||
.allocator = data.self.gpa,
|
||||
@ -1208,7 +1214,8 @@ fn fmtWipMir(self: *CodeGen, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMi
|
||||
const FormatTrackingData = struct {
|
||||
self: *CodeGen,
|
||||
};
|
||||
fn formatTracking(data: FormatTrackingData, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
fn formatTracking(data: FormatTrackingData, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
var it = data.self.inst_tracking.iterator();
|
||||
while (it.next()) |entry| try bw.print("\n{f} = {f}", .{ entry.key_ptr.*, entry.value_ptr.* });
|
||||
}
|
||||
|
||||
@ -372,8 +372,7 @@ fn parseGpRegister(low_enc: u3, is_extended: bool, rex: Rex, bit_size: u64) Regi
|
||||
}
|
||||
|
||||
fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate {
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(dis.code[dis.pos..]);
|
||||
var br: std.io.Reader = .fixed(dis.code[dis.pos..]);
|
||||
defer dis.pos += br.seek;
|
||||
return switch (kind) {
|
||||
.imm8s, .rel8 => .s(try br.takeInt(i8, .little)),
|
||||
@ -388,8 +387,7 @@ fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate {
|
||||
}
|
||||
|
||||
fn parseOffset(dis: *Disassembler) !u64 {
|
||||
var br: std.io.Reader = undefined;
|
||||
br.initFixed(dis.code[dis.pos..]);
|
||||
var br: std.io.Reader = .fixed(dis.code[dis.pos..]);
|
||||
defer dis.pos += br.seek;
|
||||
return br.takeInt(u64, .little);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ const Encoding = @This();
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const math = std.math;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const bits = @import("bits.zig");
|
||||
const encoder = @import("encoder.zig");
|
||||
@ -158,8 +159,8 @@ pub fn modRmExt(encoding: Encoding) u3 {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn format(encoding: Encoding, bw: *std.io.BufferedWriter, comptime fmt: []const u8) !void {
|
||||
_ = fmt;
|
||||
pub fn format(encoding: Encoding, bw: *Writer, comptime fmt: []const u8) !void {
|
||||
comptime assert(fmt.len == 0);
|
||||
|
||||
var opc = encoding.opcode();
|
||||
if (encoding.data.mode.isVex()) {
|
||||
@ -1016,8 +1017,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op
|
||||
@memcpy(inst.ops[0..ops.len], ops);
|
||||
|
||||
var buf: [15]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buf);
|
||||
var bw: Writer = .fixed(&buf);
|
||||
inst.encode(&bw, .{
|
||||
.allow_frame_locs = true,
|
||||
.allow_symbols = true,
|
||||
|
||||
@ -6,6 +6,8 @@ const Allocator = std.mem.Allocator;
|
||||
const ArrayList = std.ArrayList;
|
||||
const InternPool = @import("../../InternPool.zig");
|
||||
const link = @import("../../link.zig");
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Mir = @import("Mir.zig");
|
||||
|
||||
/// EFLAGS condition codes
|
||||
@ -728,7 +730,8 @@ pub const FrameIndex = enum(u32) {
|
||||
return @intFromEnum(fi) < named_count;
|
||||
}
|
||||
|
||||
pub fn format(fi: FrameIndex, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(fi: FrameIndex, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
try bw.writeAll("FrameIndex");
|
||||
if (fi.isNamed())
|
||||
try bw.print(".{s}", .{@tagName(fi)})
|
||||
@ -835,7 +838,8 @@ pub const Memory = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn format(s: Size, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(s: Size, bw: *Writer, comptime fmt: []const u8) Writer.Error!void {
|
||||
comptime assert(fmt.len == 0);
|
||||
if (s == .none) return;
|
||||
try bw.writeAll(@tagName(s));
|
||||
switch (s) {
|
||||
|
||||
@ -3,6 +3,7 @@ const assert = std.debug.assert;
|
||||
const log = std.log.scoped(.x86_64_encoder);
|
||||
const math = std.math;
|
||||
const testing = std.testing;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const bits = @import("bits.zig");
|
||||
const Encoding = @import("Encoding.zig");
|
||||
@ -226,7 +227,7 @@ pub const Instruction = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn format(op: Operand, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) !void {
|
||||
fn format(op: Operand, bw: *Writer, comptime unused_format_string: []const u8) !void {
|
||||
_ = op;
|
||||
_ = bw;
|
||||
_ = unused_format_string;
|
||||
@ -238,7 +239,7 @@ pub const Instruction = struct {
|
||||
enc_op: Encoding.Op,
|
||||
};
|
||||
|
||||
fn fmtContext(ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void {
|
||||
fn fmtContext(ctx: FormatContext, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void {
|
||||
_ = unused_format_string;
|
||||
const op = ctx.op;
|
||||
const enc_op = ctx.enc_op;
|
||||
@ -360,7 +361,7 @@ pub const Instruction = struct {
|
||||
return inst;
|
||||
}
|
||||
|
||||
pub fn format(inst: Instruction, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(inst: Instruction, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void {
|
||||
_ = unused_format_string;
|
||||
switch (inst.prefix) {
|
||||
.none, .directive => {},
|
||||
@ -374,7 +375,7 @@ pub const Instruction = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode(inst: Instruction, bw: *std.io.BufferedWriter, comptime opts: Options) !void {
|
||||
pub fn encode(inst: Instruction, bw: *Writer, comptime opts: Options) !void {
|
||||
assert(inst.prefix != .directive);
|
||||
const encoder: Encoder(opts) = .{ .bw = bw };
|
||||
const enc = inst.encoding;
|
||||
@ -784,7 +785,7 @@ pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool
|
||||
|
||||
fn Encoder(comptime opts: Options) type {
|
||||
return struct {
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
|
||||
const Self = @This();
|
||||
pub const options = opts;
|
||||
@ -2198,7 +2199,7 @@ const Assembler = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn assemble(as: *Assembler, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn assemble(as: *Assembler, bw: *Writer) !void {
|
||||
while (try as.next()) |parsed_inst| {
|
||||
const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops);
|
||||
try inst.encode(bw, .{});
|
||||
|
||||
@ -8,6 +8,7 @@ const mem = std.mem;
|
||||
const math = std.math;
|
||||
const target_util = @import("target.zig");
|
||||
const trace = @import("tracy.zig").trace;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const Air = @import("Air.zig");
|
||||
const Allocator = mem.Allocator;
|
||||
@ -326,7 +327,7 @@ pub fn generateSymbolInner(
|
||||
pt: Zcu.PerThread,
|
||||
src_loc: Zcu.LazySrcLoc,
|
||||
val: Value,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
) GenerateSymbolError!void {
|
||||
const zcu = pt.zcu;
|
||||
@ -707,7 +708,7 @@ fn lowerPtr(
|
||||
pt: Zcu.PerThread,
|
||||
src_loc: Zcu.LazySrcLoc,
|
||||
ptr_val: InternPool.Index,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
prev_offset: u64,
|
||||
) GenerateSymbolError!void {
|
||||
@ -760,7 +761,7 @@ fn lowerUavRef(
|
||||
pt: Zcu.PerThread,
|
||||
src_loc: Zcu.LazySrcLoc,
|
||||
uav: InternPool.Key.Ptr.BaseAddr.Uav,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
offset: u64,
|
||||
) GenerateSymbolError!void {
|
||||
@ -814,7 +815,7 @@ fn lowerNavRef(
|
||||
lf: *link.File,
|
||||
pt: Zcu.PerThread,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
reloc_parent: link.File.RelocInfo.Parent,
|
||||
offset: u64,
|
||||
) GenerateSymbolError!void {
|
||||
|
||||
@ -4,6 +4,7 @@ const assert = std.debug.assert;
|
||||
const mem = std.mem;
|
||||
const log = std.log.scoped(.c);
|
||||
const Allocator = mem.Allocator;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const dev = @import("../dev.zig");
|
||||
const link = @import("../link.zig");
|
||||
@ -69,7 +70,7 @@ pub const Mir = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const Error = std.io.Writer.Error || std.mem.Allocator.Error || error{AnalysisFail};
|
||||
pub const Error = Writer.Error || std.mem.Allocator.Error || error{AnalysisFail};
|
||||
|
||||
pub const CType = @import("c/Type.zig");
|
||||
|
||||
@ -344,9 +345,9 @@ fn isReservedIdent(ident: []const u8) bool {
|
||||
|
||||
fn formatIdent(
|
||||
ident: []const u8,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime fmt_str: []const u8,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
const solo = fmt_str.len != 0 and fmt_str[0] == ' '; // space means solo; not part of a bigger ident.
|
||||
if (solo and isReservedIdent(ident)) {
|
||||
try bw.writeAll("zig_e_");
|
||||
@ -374,9 +375,9 @@ const CTypePoolStringFormatData = struct {
|
||||
};
|
||||
fn formatCTypePoolString(
|
||||
data: CTypePoolStringFormatData,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime fmt_str: []const u8,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice|
|
||||
try formatIdent(slice, bw, fmt_str)
|
||||
else
|
||||
@ -504,7 +505,7 @@ pub const Function = struct {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn writeCValue(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue, location: ValueRenderLocation) !void {
|
||||
fn writeCValue(f: *Function, bw: *Writer, c_value: CValue, location: ValueRenderLocation) !void {
|
||||
switch (c_value) {
|
||||
.none => unreachable,
|
||||
.new_local, .local => |i| try bw.print("t{d}", .{i}),
|
||||
@ -517,7 +518,7 @@ pub const Function = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeCValueDeref(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue) !void {
|
||||
fn writeCValueDeref(f: *Function, bw: *Writer, c_value: CValue) !void {
|
||||
switch (c_value) {
|
||||
.none => unreachable,
|
||||
.new_local, .local, .constant => {
|
||||
@ -538,7 +539,7 @@ pub const Function = struct {
|
||||
|
||||
fn writeCValueMember(
|
||||
f: *Function,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
c_value: CValue,
|
||||
member: CValue,
|
||||
) Error!void {
|
||||
@ -552,7 +553,7 @@ pub const Function = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeCValueDerefMember(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue, member: CValue) !void {
|
||||
fn writeCValueDerefMember(f: *Function, bw: *Writer, c_value: CValue, member: CValue) !void {
|
||||
switch (c_value) {
|
||||
.new_local, .local, .arg, .arg_array => {
|
||||
try f.writeCValue(bw, c_value, .Other);
|
||||
@ -584,15 +585,15 @@ pub const Function = struct {
|
||||
return f.object.dg.byteSize(ctype);
|
||||
}
|
||||
|
||||
fn renderType(f: *Function, bw: *std.io.BufferedWriter, ctype: Type) !void {
|
||||
fn renderType(f: *Function, bw: *Writer, ctype: Type) !void {
|
||||
return f.object.dg.renderType(bw, ctype);
|
||||
}
|
||||
|
||||
fn renderCType(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !void {
|
||||
fn renderCType(f: *Function, bw: *Writer, ctype: CType) !void {
|
||||
return f.object.dg.renderCType(bw, ctype);
|
||||
}
|
||||
|
||||
fn renderIntCast(f: *Function, bw: *std.io.BufferedWriter, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
|
||||
fn renderIntCast(f: *Function, bw: *Writer, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
|
||||
return f.object.dg.renderIntCast(bw, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
|
||||
}
|
||||
|
||||
@ -757,7 +758,7 @@ pub const DeclGen = struct {
|
||||
|
||||
fn renderUav(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
uav: InternPool.Key.Ptr.BaseAddr.Uav,
|
||||
location: ValueRenderLocation,
|
||||
) Error!void {
|
||||
@ -819,7 +820,7 @@ pub const DeclGen = struct {
|
||||
|
||||
fn renderNav(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
location: ValueRenderLocation,
|
||||
) Error!void {
|
||||
@ -868,7 +869,7 @@ pub const DeclGen = struct {
|
||||
|
||||
fn renderPointer(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
derivation: Value.PointerDeriveStep,
|
||||
location: ValueRenderLocation,
|
||||
) Error!void {
|
||||
@ -972,13 +973,13 @@ pub const DeclGen = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn renderErrorName(dg: *DeclGen, bw: *std.io.BufferedWriter, err_name: InternPool.NullTerminatedString) !void {
|
||||
fn renderErrorName(dg: *DeclGen, bw: *Writer, err_name: InternPool.NullTerminatedString) !void {
|
||||
try bw.print("zig_error_{f}", .{fmtIdent(err_name.toSlice(&dg.pt.zcu.intern_pool))});
|
||||
}
|
||||
|
||||
fn renderValue(
|
||||
dg: *DeclGen,
|
||||
writer: *std.io.BufferedWriter,
|
||||
writer: *Writer,
|
||||
val: Value,
|
||||
location: ValueRenderLocation,
|
||||
) Error!void {
|
||||
@ -1587,7 +1588,7 @@ pub const DeclGen = struct {
|
||||
|
||||
fn renderUndefValue(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
ty: Type,
|
||||
location: ValueRenderLocation,
|
||||
) Error!void {
|
||||
@ -1890,7 +1891,7 @@ pub const DeclGen = struct {
|
||||
|
||||
fn renderFunctionSignature(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
fn_val: Value,
|
||||
fn_align: InternPool.Alignment,
|
||||
kind: CType.Kind,
|
||||
@ -2011,11 +2012,11 @@ pub const DeclGen = struct {
|
||||
/// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
|
||||
/// | `renderType` | "uint8_t *" | "uint8_t *[10]" |
|
||||
///
|
||||
fn renderType(dg: *DeclGen, bw: *std.io.BufferedWriter, t: Type) Error!void {
|
||||
fn renderType(dg: *DeclGen, bw: *Writer, t: Type) Error!void {
|
||||
try dg.renderCType(bw, try dg.ctypeFromType(t, .complete));
|
||||
}
|
||||
|
||||
fn renderCType(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) Error!void {
|
||||
fn renderCType(dg: *DeclGen, bw: *Writer, ctype: CType) Error!void {
|
||||
_ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{});
|
||||
try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{});
|
||||
}
|
||||
@ -2030,7 +2031,7 @@ pub const DeclGen = struct {
|
||||
value: Value,
|
||||
},
|
||||
|
||||
pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, bw: *std.io.BufferedWriter, location: ValueRenderLocation) !void {
|
||||
pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, bw: *Writer, location: ValueRenderLocation) !void {
|
||||
switch (self.*) {
|
||||
.c_value => |v| {
|
||||
try v.f.writeCValue(bw, v.value, location);
|
||||
@ -2076,7 +2077,7 @@ pub const DeclGen = struct {
|
||||
/// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
|
||||
fn renderIntCast(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
dest_ty: Type,
|
||||
context: IntCastContext,
|
||||
src_ty: Type,
|
||||
@ -2160,7 +2161,7 @@ pub const DeclGen = struct {
|
||||
///
|
||||
fn renderTypeAndName(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
ty: Type,
|
||||
name: CValue,
|
||||
qualifiers: CQualifiers,
|
||||
@ -2181,7 +2182,7 @@ pub const DeclGen = struct {
|
||||
|
||||
fn renderCTypeAndName(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
ctype: CType,
|
||||
name: CValue,
|
||||
qualifiers: CQualifiers,
|
||||
@ -2201,7 +2202,7 @@ pub const DeclGen = struct {
|
||||
try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, bw, ctype, .suffix, .{});
|
||||
}
|
||||
|
||||
fn writeName(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) !void {
|
||||
fn writeName(dg: *DeclGen, bw: *Writer, c_value: CValue) !void {
|
||||
switch (c_value) {
|
||||
.new_local, .local => |i| try bw.print("t{d}", .{i}),
|
||||
.constant => |uav| try renderUavName(bw, uav),
|
||||
@ -2211,7 +2212,7 @@ pub const DeclGen = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeCValue(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) Error!void {
|
||||
fn writeCValue(dg: *DeclGen, bw: *Writer, c_value: CValue) Error!void {
|
||||
switch (c_value) {
|
||||
.none, .new_local, .local, .local_ref => unreachable,
|
||||
.constant => |uav| try renderUavName(bw, uav),
|
||||
@ -2234,7 +2235,7 @@ pub const DeclGen = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeCValueDeref(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) !void {
|
||||
fn writeCValueDeref(dg: *DeclGen, bw: *Writer, c_value: CValue) !void {
|
||||
switch (c_value) {
|
||||
.none,
|
||||
.new_local,
|
||||
@ -2263,7 +2264,7 @@ pub const DeclGen = struct {
|
||||
|
||||
fn writeCValueMember(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
c_value: CValue,
|
||||
member: CValue,
|
||||
) Error!void {
|
||||
@ -2274,7 +2275,7 @@ pub const DeclGen = struct {
|
||||
|
||||
fn writeCValueDerefMember(
|
||||
dg: *DeclGen,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
c_value: CValue,
|
||||
member: CValue,
|
||||
) !void {
|
||||
@ -2341,7 +2342,7 @@ pub const DeclGen = struct {
|
||||
try fwd.writeAll(";\n");
|
||||
}
|
||||
|
||||
fn renderNavName(dg: *DeclGen, bw: *std.io.BufferedWriter, nav_index: InternPool.Nav.Index) !void {
|
||||
fn renderNavName(dg: *DeclGen, bw: *Writer, nav_index: InternPool.Nav.Index) !void {
|
||||
const zcu = dg.pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const nav = ip.getNav(nav_index);
|
||||
@ -2360,15 +2361,15 @@ pub const DeclGen = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn renderUavName(bw: *std.io.BufferedWriter, uav: Value) !void {
|
||||
fn renderUavName(bw: *Writer, uav: Value) !void {
|
||||
try bw.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
|
||||
}
|
||||
|
||||
fn renderTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ty: Type) !void {
|
||||
fn renderTypeForBuiltinFnName(dg: *DeclGen, bw: *Writer, ty: Type) !void {
|
||||
try dg.renderCTypeForBuiltinFnName(bw, try dg.ctypeFromType(ty, .complete));
|
||||
}
|
||||
|
||||
fn renderCTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) !void {
|
||||
fn renderCTypeForBuiltinFnName(dg: *DeclGen, bw: *Writer, ctype: CType) !void {
|
||||
switch (ctype.info(&dg.ctype_pool)) {
|
||||
else => |ctype_info| try bw.print("{c}{d}", .{
|
||||
if (ctype.isBool())
|
||||
@ -2387,7 +2388,7 @@ pub const DeclGen = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn renderBuiltinInfo(dg: *DeclGen, bw: *std.io.BufferedWriter, ty: Type, info: BuiltinInfo) !void {
|
||||
fn renderBuiltinInfo(dg: *DeclGen, bw: *Writer, ty: Type, info: BuiltinInfo) !void {
|
||||
const ctype = try dg.ctypeFromType(ty, .complete);
|
||||
const is_big = ctype.info(&dg.ctype_pool) == .array;
|
||||
switch (info) {
|
||||
@ -2436,9 +2437,9 @@ const RenderCTypeTrailing = enum {
|
||||
|
||||
pub fn format(
|
||||
self: @This(),
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime fmt: []const u8,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
if (fmt.len != 0) @compileError("invalid format string '" ++
|
||||
fmt ++ "' for type '" ++ @typeName(@This()) ++ "'");
|
||||
switch (self) {
|
||||
@ -2447,12 +2448,12 @@ const RenderCTypeTrailing = enum {
|
||||
}
|
||||
}
|
||||
};
|
||||
fn renderAlignedTypeName(bw: *std.io.BufferedWriter, ctype: CType) !void {
|
||||
fn renderAlignedTypeName(bw: *Writer, ctype: CType) !void {
|
||||
try bw.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});
|
||||
}
|
||||
fn renderFwdDeclTypeName(
|
||||
zcu: *Zcu,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
ctype: CType,
|
||||
fwd_decl: CType.Info.FwdDecl,
|
||||
attributes: []const u8,
|
||||
@ -2471,11 +2472,11 @@ fn renderTypePrefix(
|
||||
pass: DeclGen.Pass,
|
||||
ctype_pool: *const CType.Pool,
|
||||
zcu: *Zcu,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
ctype: CType,
|
||||
parent_fix: CTypeFix,
|
||||
qualifiers: CQualifiers,
|
||||
) std.io.Writer.Error!RenderCTypeTrailing {
|
||||
) Writer.Error!RenderCTypeTrailing {
|
||||
var trailing = RenderCTypeTrailing.maybe_space;
|
||||
switch (ctype.info(ctype_pool)) {
|
||||
.basic => |basic_info| try bw.writeAll(@tagName(basic_info)),
|
||||
@ -2588,11 +2589,11 @@ fn renderTypeSuffix(
|
||||
pass: DeclGen.Pass,
|
||||
ctype_pool: *const CType.Pool,
|
||||
zcu: *Zcu,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
ctype: CType,
|
||||
parent_fix: CTypeFix,
|
||||
qualifiers: CQualifiers,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
switch (ctype.info(ctype_pool)) {
|
||||
.basic, .aligned, .fwd_decl, .aggregate => {},
|
||||
.pointer => |pointer_info| try renderTypeSuffix(
|
||||
@ -2644,7 +2645,7 @@ fn renderTypeSuffix(
|
||||
}
|
||||
fn renderFields(
|
||||
zcu: *Zcu,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
ctype_pool: *const CType.Pool,
|
||||
aggregate_info: CType.Info.Aggregate,
|
||||
indent: usize,
|
||||
@ -2686,7 +2687,7 @@ fn renderFields(
|
||||
|
||||
pub fn genTypeDecl(
|
||||
zcu: *Zcu,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
global_ctype_pool: *const CType.Pool,
|
||||
global_ctype: CType,
|
||||
pass: DeclGen.Pass,
|
||||
@ -2766,7 +2767,7 @@ pub fn genTypeDecl(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn genGlobalAsm(zcu: *Zcu, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn genGlobalAsm(zcu: *Zcu, bw: *Writer) !void {
|
||||
for (zcu.global_assembly.values()) |asm_source| {
|
||||
try bw.print("__asm({fs});\n", .{fmtStringLiteral(asm_source, null)});
|
||||
}
|
||||
@ -5247,7 +5248,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
|
||||
return local;
|
||||
}
|
||||
|
||||
fn airTrap(f: *Function, bw: *std.io.BufferedWriter) !void {
|
||||
fn airTrap(f: *Function, bw: *Writer) !void {
|
||||
// Not even allowed to call trap in a naked function.
|
||||
if (f.object.dg.is_naked_fn) return;
|
||||
try bw.writeAll("zig_trap();\n");
|
||||
@ -7052,7 +7053,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
|
||||
return .none;
|
||||
}
|
||||
|
||||
fn writeSliceOrPtr(f: *Function, bw: *std.io.BufferedWriter, ptr: CValue, ptr_ty: Type) !void {
|
||||
fn writeSliceOrPtr(f: *Function, bw: *Writer, ptr: CValue, ptr_ty: Type) !void {
|
||||
const pt = f.object.dg.pt;
|
||||
const zcu = pt.zcu;
|
||||
if (ptr_ty.isSlice(zcu)) {
|
||||
@ -7980,7 +7981,7 @@ fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
|
||||
};
|
||||
}
|
||||
|
||||
fn writeMemoryOrder(bw: *std.io.BufferedWriter, order: std.builtin.AtomicOrder) !void {
|
||||
fn writeMemoryOrder(bw: *Writer, order: std.builtin.AtomicOrder) !void {
|
||||
return bw.writeAll(toMemoryOrder(order));
|
||||
}
|
||||
|
||||
@ -8125,7 +8126,7 @@ const StringLiteral = struct {
|
||||
len: usize,
|
||||
cur_len: usize,
|
||||
start_count: usize,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
|
||||
// MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal,
|
||||
// regardless of the length of the string literal initializing it. Array initializer syntax is
|
||||
@ -8138,7 +8139,7 @@ const StringLiteral = struct {
|
||||
const max_char_len = 4;
|
||||
const max_literal_len = @min(16380 - max_char_len, 4095);
|
||||
|
||||
fn init(bw: *std.io.BufferedWriter, len: usize) StringLiteral {
|
||||
fn init(bw: *Writer, len: usize) StringLiteral {
|
||||
return .{
|
||||
.cur_len = 0,
|
||||
.len = len,
|
||||
@ -8147,7 +8148,7 @@ const StringLiteral = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn start(sl: *StringLiteral) std.io.Writer.Error!void {
|
||||
pub fn start(sl: *StringLiteral) Writer.Error!void {
|
||||
if (sl.len <= max_string_initializer_len) {
|
||||
try sl.bw.writeByte('\"');
|
||||
} else {
|
||||
@ -8155,7 +8156,7 @@ const StringLiteral = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end(sl: *StringLiteral) std.io.Writer.Error!void {
|
||||
pub fn end(sl: *StringLiteral) Writer.Error!void {
|
||||
if (sl.len <= max_string_initializer_len) {
|
||||
try sl.bw.writeByte('\"');
|
||||
} else {
|
||||
@ -8163,7 +8164,7 @@ const StringLiteral = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeStringLiteralChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void {
|
||||
fn writeStringLiteralChar(sl: *StringLiteral, c: u8) Writer.Error!void {
|
||||
switch (c) {
|
||||
7 => try sl.bw.writeAll("\\a"),
|
||||
8 => try sl.bw.writeAll("\\b"),
|
||||
@ -8180,7 +8181,7 @@ const StringLiteral = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void {
|
||||
pub fn writeChar(sl: *StringLiteral, c: u8) Writer.Error!void {
|
||||
if (sl.len <= max_string_initializer_len) {
|
||||
if (sl.cur_len == 0 and sl.bw.count - sl.start_count > 1)
|
||||
try sl.bw.writeAll("\"\"");
|
||||
@ -8202,9 +8203,9 @@ const StringLiteral = struct {
|
||||
const FormatStringContext = struct { str: []const u8, sentinel: ?u8 };
|
||||
fn formatStringLiteral(
|
||||
data: FormatStringContext,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime fmt: []const u8,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt);
|
||||
|
||||
var literal: StringLiteral = .init(bw, data.str.len + @intFromBool(data.sentinel != null));
|
||||
@ -8233,9 +8234,9 @@ const FormatIntLiteralContext = struct {
|
||||
};
|
||||
fn formatIntLiteral(
|
||||
data: FormatIntLiteralContext,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime fmt: []const u8,
|
||||
) std.io.Writer.Error!void {
|
||||
) Writer.Error!void {
|
||||
const pt = data.dg.pt;
|
||||
const zcu = pt.zcu;
|
||||
const target = &data.dg.mod.resolved_target.result;
|
||||
@ -8423,7 +8424,7 @@ const Materialize = struct {
|
||||
} };
|
||||
}
|
||||
|
||||
pub fn mat(self: Materialize, f: *Function, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn mat(self: Materialize, f: *Function, bw: *Writer) !void {
|
||||
try f.writeCValue(bw, self.local, .Other);
|
||||
}
|
||||
|
||||
@ -8435,27 +8436,27 @@ const Materialize = struct {
|
||||
const Assignment = struct {
|
||||
ctype: CType,
|
||||
|
||||
pub fn start(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !Assignment {
|
||||
pub fn start(f: *Function, bw: *Writer, ctype: CType) !Assignment {
|
||||
const self: Assignment = .{ .ctype = ctype };
|
||||
try self.restart(f, bw);
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn restart(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn restart(self: Assignment, f: *Function, bw: *Writer) !void {
|
||||
switch (self.strategy(f)) {
|
||||
.assign => {},
|
||||
.memcpy => try bw.writeAll("memcpy("),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assign(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn assign(self: Assignment, f: *Function, bw: *Writer) !void {
|
||||
switch (self.strategy(f)) {
|
||||
.assign => try bw.writeAll(" = "),
|
||||
.memcpy => try bw.writeAll(", "),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn end(self: Assignment, f: *Function, bw: *Writer) !void {
|
||||
switch (self.strategy(f)) {
|
||||
.assign => {},
|
||||
.memcpy => {
|
||||
@ -8479,7 +8480,7 @@ const Assignment = struct {
|
||||
const Vectorize = struct {
|
||||
index: CValue = .none,
|
||||
|
||||
pub fn start(f: *Function, inst: Air.Inst.Index, writer: *std.io.BufferedWriter, ty: Type) !Vectorize {
|
||||
pub fn start(f: *Function, inst: Air.Inst.Index, writer: *Writer, ty: Type) !Vectorize {
|
||||
const pt = f.object.dg.pt;
|
||||
const zcu = pt.zcu;
|
||||
return if (ty.zigTypeTag(zcu) == .vector) index: {
|
||||
@ -8499,7 +8500,7 @@ const Vectorize = struct {
|
||||
} else .{};
|
||||
}
|
||||
|
||||
pub fn elem(self: Vectorize, f: *Function, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn elem(self: Vectorize, f: *Function, bw: *Writer) !void {
|
||||
if (self.index != .none) {
|
||||
try bw.writeByte('[');
|
||||
try f.writeCValue(bw, self.index, .Other);
|
||||
@ -8507,7 +8508,7 @@ const Vectorize = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, bw: *std.io.BufferedWriter) !void {
|
||||
pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, bw: *Writer) !void {
|
||||
if (self.index != .none) {
|
||||
try f.object.outdent();
|
||||
try bw.writeByte('}');
|
||||
|
||||
@ -209,7 +209,7 @@ pub fn getStandardDefineAbbrev(ctype: CType) ?[]const u8 {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn renderLiteralPrefix(ctype: CType, bw: *std.io.BufferedWriter, kind: Kind, pool: *const Pool) std.io.Writer.Error!void {
|
||||
pub fn renderLiteralPrefix(ctype: CType, bw: *Writer, kind: Kind, pool: *const Pool) Writer.Error!void {
|
||||
switch (ctype.info(pool)) {
|
||||
.basic => |basic_info| switch (basic_info) {
|
||||
.void => unreachable,
|
||||
@ -270,7 +270,7 @@ pub fn renderLiteralPrefix(ctype: CType, bw: *std.io.BufferedWriter, kind: Kind,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn renderLiteralSuffix(ctype: CType, bw: *std.io.BufferedWriter, pool: *const Pool) std.io.Writer.Error!void {
|
||||
pub fn renderLiteralSuffix(ctype: CType, bw: *Writer, pool: *const Pool) Writer.Error!void {
|
||||
switch (ctype.info(pool)) {
|
||||
.basic => |basic_info| switch (basic_info) {
|
||||
.void => unreachable,
|
||||
@ -940,10 +940,10 @@ pub const Pool = struct {
|
||||
const FormatData = struct { string: String, pool: *const Pool };
|
||||
fn format(
|
||||
data: FormatData,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime fmt_str: []const u8,
|
||||
) std.io.Writer.Error!void {
|
||||
if (fmt_str.len > 0) @compileError("invalid format string '" ++ fmt_str ++ "'");
|
||||
) Writer.Error!void {
|
||||
comptime assert(fmt_str.len == 0);
|
||||
if (data.string.toSlice(data.pool)) |slice|
|
||||
try bw.writeAll(slice)
|
||||
else
|
||||
@ -3280,10 +3280,12 @@ pub const AlignAs = packed struct {
|
||||
}
|
||||
};
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const CType = @This();
|
||||
const InternPool = @import("../../InternPool.zig");
|
||||
const Module = @import("../../Package/Module.zig");
|
||||
const std = @import("std");
|
||||
const Type = @import("../../Type.zig");
|
||||
const Zcu = @import("../../Zcu.zig");
|
||||
|
||||
@ -18,7 +18,8 @@ pub const IdResult = enum(Word) {
|
||||
none,
|
||||
_,
|
||||
|
||||
pub fn format(self: IdResult, bw: *std.io.BufferedWriter, comptime _: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(self: IdResult, bw: *std.io.Writer, comptime fmt: []const u8) std.io.Writer.Error!void {
|
||||
comptime std.debug.assert(fmt.len == 0);
|
||||
switch (self) {
|
||||
.none => try bw.writeAll("(none)"),
|
||||
else => try bw.print("%{}", .{@intFromEnum(self)}),
|
||||
|
||||
37
src/fmt.zig
37
src/fmt.zig
@ -1,3 +1,12 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const fs = std.fs;
|
||||
const process = std.process;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Color = std.zig.Color;
|
||||
const fatal = std.process.fatal;
|
||||
const File = std.fs.File;
|
||||
|
||||
const usage_fmt =
|
||||
\\Usage: zig fmt [file]...
|
||||
\\
|
||||
@ -27,7 +36,7 @@ const Fmt = struct {
|
||||
gpa: Allocator,
|
||||
arena: Allocator,
|
||||
out_buffer: std.ArrayListUnmanaged(u8),
|
||||
stdout: *std.io.BufferedWriter,
|
||||
stdout_writer: *File.Writer,
|
||||
|
||||
const SeenMap = std.AutoHashMap(fs.File.INode, void);
|
||||
};
|
||||
@ -49,7 +58,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
const arg = args[i];
|
||||
if (mem.startsWith(u8, arg, "-")) {
|
||||
if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) {
|
||||
try std.fs.File.stdout().writeAll(usage_fmt);
|
||||
try File.stdout().writeAll(usage_fmt);
|
||||
return process.cleanExit();
|
||||
} else if (mem.eql(u8, arg, "--color")) {
|
||||
if (i + 1 >= args.len) {
|
||||
@ -133,10 +142,9 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
try std.zig.printAstErrorsToStderr(gpa, tree, "<stdin>", color);
|
||||
process.exit(2);
|
||||
}
|
||||
var aw: std.io.AllocatingWriter = undefined;
|
||||
aw.init(gpa);
|
||||
var aw: std.io.AllocatingWriter = .init(gpa);
|
||||
defer aw.deinit();
|
||||
try tree.render(gpa, &aw.buffered_writer, .{});
|
||||
try tree.render(gpa, &aw.interface, .{});
|
||||
const formatted = aw.getWritten();
|
||||
|
||||
if (check_flag) {
|
||||
@ -144,7 +152,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
return std.fs.File.stdout().writeAll(formatted);
|
||||
return File.stdout().writeAll(formatted);
|
||||
}
|
||||
|
||||
if (input_files.items.len == 0) {
|
||||
@ -152,7 +160,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
}
|
||||
|
||||
var stdout_buffer: [4096]u8 = undefined;
|
||||
var stdout: std.io.BufferedWriter = std.fs.File.stdout().writer().buffered(&stdout_buffer);
|
||||
var stdout_writer = File.stdout().writer(&stdout_buffer);
|
||||
|
||||
var fmt: Fmt = .{
|
||||
.gpa = gpa,
|
||||
@ -163,7 +171,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
.force_zon = force_zon,
|
||||
.color = color,
|
||||
.out_buffer = .empty,
|
||||
.stdout = &stdout,
|
||||
.stdout_writer = &stdout_writer,
|
||||
};
|
||||
defer fmt.seen.deinit();
|
||||
defer fmt.out_buffer.deinit(gpa);
|
||||
@ -190,6 +198,7 @@ pub fn run(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
if (fmt.any_error) {
|
||||
process.exit(1);
|
||||
}
|
||||
try fmt.stdout_writer.flush();
|
||||
}
|
||||
|
||||
fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) anyerror!void {
|
||||
@ -336,7 +345,7 @@ fn fmtPathFile(
|
||||
return;
|
||||
|
||||
if (check_mode) {
|
||||
try fmt.stdout.print("{s}\n", .{file_path});
|
||||
try fmt.stdout_writer.interface.print("{s}\n", .{file_path});
|
||||
fmt.any_error = true;
|
||||
} else {
|
||||
var af = try dir.atomicFile(sub_path, .{ .mode = stat.mode });
|
||||
@ -344,18 +353,10 @@ fn fmtPathFile(
|
||||
|
||||
try af.file.writeAll(fmt.out_buffer.items);
|
||||
try af.finish();
|
||||
try fmt.stdout.print("{s}\n", .{file_path});
|
||||
try fmt.stdout_writer.interface.print("{s}\n", .{file_path});
|
||||
}
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const fs = std.fs;
|
||||
const process = std.process;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Color = std.zig.Color;
|
||||
const fatal = std.process.fatal;
|
||||
|
||||
/// Provided for debugging/testing purposes; unused by the compiler.
|
||||
pub fn main() !void {
|
||||
const gpa = std.heap.smp_allocator;
|
||||
|
||||
@ -1,5 +1,41 @@
|
||||
//! The main driver of the self-hosted COFF linker.
|
||||
|
||||
const Coff = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const build_options = @import("build_options");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const coff_util = std.coff;
|
||||
const fmt = std.fmt;
|
||||
const fs = std.fs;
|
||||
const log = std.log.scoped(.link);
|
||||
const math = std.math;
|
||||
const mem = std.mem;
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Path = std.Build.Cache.Path;
|
||||
const Directory = std.Build.Cache.Directory;
|
||||
const Cache = std.Build.Cache;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const aarch64_util = @import("../arch/aarch64/bits.zig");
|
||||
const allocPrint = std.fmt.allocPrint;
|
||||
const codegen = @import("../codegen.zig");
|
||||
const link = @import("../link.zig");
|
||||
const target_util = @import("../target.zig");
|
||||
const trace = @import("../tracy.zig").trace;
|
||||
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const Zcu = @import("../Zcu.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const TableSection = @import("table_section.zig").TableSection;
|
||||
const StringTable = @import("StringTable.zig");
|
||||
const Type = @import("../Type.zig");
|
||||
const Value = @import("../Value.zig");
|
||||
const AnalUnit = InternPool.AnalUnit;
|
||||
const dev = @import("../dev.zig");
|
||||
|
||||
base: link.File,
|
||||
image_base: u64,
|
||||
/// TODO this and minor_subsystem_version should be combined into one property and left as
|
||||
@ -2175,8 +2211,7 @@ fn writeDataDirectoriesHeaders(coff: *Coff) !void {
|
||||
fn writeHeader(coff: *Coff) !void {
|
||||
const target = &coff.base.comp.root_mod.resolved_target.result;
|
||||
const gpa = coff.base.comp.gpa;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(try gpa.alloc(u8, coff.getSizeOfHeaders()));
|
||||
var bw: Writer = .fixed(try gpa.alloc(u8, coff.getSizeOfHeaders()));
|
||||
defer gpa.free(bw.buffer);
|
||||
|
||||
bw.writeAll(&msdos_stub) catch unreachable;
|
||||
@ -3066,14 +3101,14 @@ const ImportTable = struct {
|
||||
ctx: Context,
|
||||
};
|
||||
|
||||
fn format(itab: ImportTable, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void {
|
||||
fn format(itab: ImportTable, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void {
|
||||
_ = itab;
|
||||
_ = bw;
|
||||
_ = unused_format_string;
|
||||
@compileError("do not format ImportTable directly; use itab.fmtDebug()");
|
||||
}
|
||||
|
||||
fn format2(fmt_ctx: FormatContext, bw: *std.io.BufferedWriter, comptime unused_format_string: []const u8) std.io.Writer.Error!void {
|
||||
fn format2(fmt_ctx: FormatContext, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void {
|
||||
comptime assert(unused_format_string.len == 0);
|
||||
const lib_name = fmt_ctx.ctx.coff.temp_strtab.getAssumeExists(fmt_ctx.ctx.name_off);
|
||||
const base_vaddr = getBaseAddress(fmt_ctx.ctx);
|
||||
@ -3105,41 +3140,6 @@ fn pwriteAll(coff: *Coff, bytes: []const u8, offset: u64) error{LinkFailure}!voi
|
||||
};
|
||||
}
|
||||
|
||||
const Coff = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const build_options = @import("build_options");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const coff_util = std.coff;
|
||||
const fmt = std.fmt;
|
||||
const fs = std.fs;
|
||||
const log = std.log.scoped(.link);
|
||||
const math = std.math;
|
||||
const mem = std.mem;
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Path = std.Build.Cache.Path;
|
||||
const Directory = std.Build.Cache.Directory;
|
||||
const Cache = std.Build.Cache;
|
||||
|
||||
const aarch64_util = @import("../arch/aarch64/bits.zig");
|
||||
const allocPrint = std.fmt.allocPrint;
|
||||
const codegen = @import("../codegen.zig");
|
||||
const link = @import("../link.zig");
|
||||
const target_util = @import("../target.zig");
|
||||
const trace = @import("../tracy.zig").trace;
|
||||
|
||||
const Compilation = @import("../Compilation.zig");
|
||||
const Zcu = @import("../Zcu.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const TableSection = @import("table_section.zig").TableSection;
|
||||
const StringTable = @import("StringTable.zig");
|
||||
const Type = @import("../Type.zig");
|
||||
const Value = @import("../Value.zig");
|
||||
const AnalUnit = InternPool.AnalUnit;
|
||||
const dev = @import("../dev.zig");
|
||||
|
||||
/// This is the start of a Portable Executable (PE) file.
|
||||
/// It starts with a MS-DOS header followed by a MS-DOS stub program.
|
||||
/// This data does not change so we include it as follows in all binaries.
|
||||
|
||||
@ -648,8 +648,7 @@ const Unit = struct {
|
||||
assert(len >= unit.trailer_len);
|
||||
if (sec == &dwarf.debug_line.section) {
|
||||
var buf: [1 + uleb128Bytes(std.math.maxInt(u32)) + 1]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buf);
|
||||
var bw: Writer = .fixed(&buf);
|
||||
bw.writeByte(DW.LNS.extended_op) catch unreachable;
|
||||
const extended_op_bytes = bw.end;
|
||||
var op_len_bytes: u5 = 1;
|
||||
@ -668,8 +667,7 @@ const Unit = struct {
|
||||
assert(bw.end >= unit.trailer_len and bw.end <= len);
|
||||
return dwarf.getFile().?.pwriteAll(bw.getWritten(), sec.off(dwarf) + start);
|
||||
}
|
||||
var trailer_bw: std.io.BufferedWriter = undefined;
|
||||
trailer_bw.initFixed(try dwarf.gpa.alloc(u8, len));
|
||||
var trailer_bw: Writer = .fixed(try dwarf.gpa.alloc(u8, len));
|
||||
defer dwarf.gpa.free(trailer_bw.buffer);
|
||||
const fill_byte: u8 = if (sec == &dwarf.debug_abbrev.section) fill: {
|
||||
assert(uleb128Bytes(@intFromEnum(AbbrevCode.null)) == 1);
|
||||
@ -833,8 +831,7 @@ const Entry = struct {
|
||||
1 + uleb128Bytes(std.math.maxInt(u32)) + 1,
|
||||
)
|
||||
]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buf);
|
||||
var bw: Writer = .fixed(&buf);
|
||||
if (sec == &dwarf.debug_info.section) switch (len) {
|
||||
0 => {},
|
||||
1 => bw.writeLeb128(try dwarf.refAbbrevCode(.pad_1)) catch unreachable,
|
||||
@ -1134,7 +1131,7 @@ pub const Loc = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
fn writeReg(bw: *std.io.BufferedWriter, reg: u32, op0: u8, opx: u8) std.io.Writer.Error!void {
|
||||
fn writeReg(bw: *Writer, reg: u32, op0: u8, opx: u8) Writer.Error!void {
|
||||
if (std.math.cast(u5, reg)) |small_reg| {
|
||||
try bw.writeByte(op0 + small_reg);
|
||||
} else {
|
||||
@ -1143,7 +1140,7 @@ pub const Loc = union(enum) {
|
||||
}
|
||||
}
|
||||
|
||||
fn write(loc: Loc, bw: *std.io.BufferedWriter, adapter: anytype) UpdateError!void {
|
||||
fn write(loc: Loc, bw: *Writer, adapter: anytype) UpdateError!void {
|
||||
switch (loc) {
|
||||
.empty => {},
|
||||
.addr_reloc => |sym_index| {
|
||||
@ -1795,10 +1792,10 @@ pub const WipNav = struct {
|
||||
fn endian(_: ExprLocCounter) std.builtin.Endian {
|
||||
return @import("builtin").cpu.arch.endian();
|
||||
}
|
||||
fn addrSym(counter: ExprLocCounter, bw: *std.io.BufferedWriter, _: u32) error{}!void {
|
||||
fn addrSym(counter: ExprLocCounter, bw: *Writer, _: u32) error{}!void {
|
||||
bw.count += @intFromEnum(counter.address_size);
|
||||
}
|
||||
fn infoEntry(counter: ExprLocCounter, bw: *std.io.BufferedWriter, _: Unit.Index, _: Entry.Index) error{}!void {
|
||||
fn infoEntry(counter: ExprLocCounter, bw: *Writer, _: Unit.Index, _: Entry.Index) error{}!void {
|
||||
bw.count += counter.section_offset_bytes;
|
||||
}
|
||||
};
|
||||
@ -1817,10 +1814,10 @@ pub const WipNav = struct {
|
||||
fn endian(ctx: @This()) std.builtin.Endian {
|
||||
return ctx.wip_nav.dwarf.endian;
|
||||
}
|
||||
fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) UpdateError!void {
|
||||
fn addrSym(ctx: @This(), _: *Writer, sym_index: u32) UpdateError!void {
|
||||
try ctx.wip_nav.infoAddrSym(sym_index, 0);
|
||||
}
|
||||
fn infoEntry(ctx: @This(), _: *std.io.BufferedWriter, unit: Unit.Index, entry: Entry.Index) UpdateError!void {
|
||||
fn infoEntry(ctx: @This(), _: *Writer, unit: Unit.Index, entry: Entry.Index) UpdateError!void {
|
||||
try ctx.wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
|
||||
}
|
||||
} = .{ .wip_nav = wip_nav };
|
||||
@ -1852,10 +1849,10 @@ pub const WipNav = struct {
|
||||
fn endian(ctx: @This()) std.builtin.Endian {
|
||||
return ctx.wip_nav.dwarf.endian;
|
||||
}
|
||||
fn addrSym(ctx: @This(), _: *std.io.BufferedWriter, sym_index: u32) UpdateError!void {
|
||||
fn addrSym(ctx: @This(), _: *Writer, sym_index: u32) UpdateError!void {
|
||||
try ctx.wip_nav.frameAddrSym(sym_index, 0);
|
||||
}
|
||||
fn infoEntry(ctx: @This(), _: *std.io.BufferedWriter, unit: Unit.Index, entry: Entry.Index) UpdateError!void {
|
||||
fn infoEntry(ctx: @This(), _: *Writer, unit: Unit.Index, entry: Entry.Index) UpdateError!void {
|
||||
try ctx.wip_nav.sectionOffset(.debug_frame, .debug_info, unit, entry, 0);
|
||||
}
|
||||
} = .{ .wip_nav = wip_nav };
|
||||
@ -2756,8 +2753,7 @@ fn finishWipNavFuncInner(
|
||||
try dibw.writeLeb128(@intFromEnum(AbbrevCode.null));
|
||||
} else {
|
||||
const abbrev_code_buf = wip_nav.debug_info.getWritten()[0..AbbrevCode.decl_bytes];
|
||||
var abbrev_code_br: std.io.Reader = undefined;
|
||||
abbrev_code_br.initFixed(abbrev_code_buf);
|
||||
var abbrev_code_br: std.io.Reader = .fixed(abbrev_code_buf);
|
||||
const abbrev_code: AbbrevCode = @enumFromInt(abbrev_code_br.takeLeb128(@typeInfo(AbbrevCode).@"enum".tag_type) catch unreachable);
|
||||
std.leb.writeUnsignedFixed(
|
||||
AbbrevCode.decl_bytes,
|
||||
@ -4565,14 +4561,14 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
||||
|
||||
var header: std.ArrayListUnmanaged(u8) = .empty;
|
||||
defer header.deinit(gpa);
|
||||
var header_bw: std.io.BufferedWriter = undefined;
|
||||
var header_bw: Writer = undefined;
|
||||
if (dwarf.debug_aranges.section.dirty) {
|
||||
for (dwarf.debug_aranges.section.units.items, 0..) |*unit_ptr, unit_index| {
|
||||
const unit: Unit.Index = @enumFromInt(unit_index);
|
||||
unit_ptr.clear();
|
||||
try unit_ptr.cross_section_relocs.ensureTotalCapacity(gpa, 1);
|
||||
try header.resize(gpa, unit_ptr.header_len);
|
||||
header_bw.initFixed(header.items);
|
||||
header_bw = .fixed(header.items);
|
||||
const unit_len = (if (unit_ptr.next.unwrap()) |next_unit|
|
||||
dwarf.debug_aranges.section.getUnit(next_unit).off
|
||||
else
|
||||
@ -4610,7 +4606,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
||||
const Register = @import("../arch/x86_64/bits.zig").Register;
|
||||
for (dwarf.debug_frame.section.units.items) |*unit| {
|
||||
try header.resize(gpa, unit.header_len);
|
||||
header_bw.initFixed(header.items);
|
||||
header_bw = .fixed(header.items);
|
||||
const unit_len = unit.header_len - dwarf.unitLengthBytes();
|
||||
switch (dwarf.format) {
|
||||
.@"32" => header_bw.writeInt(u32, @intCast(unit_len), dwarf.endian) catch unreachable,
|
||||
@ -4651,7 +4647,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
||||
try unit_ptr.cross_unit_relocs.ensureTotalCapacity(gpa, 1);
|
||||
try unit_ptr.cross_section_relocs.ensureTotalCapacity(gpa, 7);
|
||||
try header.resize(gpa, unit_ptr.header_len);
|
||||
header_bw.initFixed(header.items);
|
||||
header_bw = .fixed(header.items);
|
||||
const unit_len = (if (unit_ptr.next.unwrap()) |next_unit|
|
||||
dwarf.debug_info.section.getUnit(next_unit).off
|
||||
else
|
||||
@ -4751,7 +4747,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
||||
unit.clear();
|
||||
try unit.cross_section_relocs.ensureTotalCapacity(gpa, mod_info.dirs.count() + 2 * (mod_info.files.count()));
|
||||
try header.resize(gpa, unit.header_len);
|
||||
header_bw.initFixed(header.items);
|
||||
header_bw = .fixed(header.items);
|
||||
const unit_len = (if (unit.next.unwrap()) |next_unit|
|
||||
dwarf.debug_line.section.getUnit(next_unit).off
|
||||
else
|
||||
@ -4859,7 +4855,7 @@ pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
||||
if (dwarf.debug_rnglists.section.dirty) {
|
||||
for (dwarf.debug_rnglists.section.units.items) |*unit| {
|
||||
try header.resize(gpa, unit.header_len);
|
||||
header_bw.initFixed(header.items);
|
||||
header_bw = .fixed(header.items);
|
||||
const unit_len = (if (unit.next.unwrap()) |next_unit|
|
||||
dwarf.debug_rnglists.section.getUnit(next_unit).off
|
||||
else
|
||||
@ -6078,7 +6074,7 @@ fn writeInt(dwarf: *Dwarf, buf: []u8, int: u64) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeIntTo(dwarf: *Dwarf, bw: *std.io.BufferedWriter, len: usize, int: u64) !void {
|
||||
fn writeIntTo(dwarf: *Dwarf, bw: *Writer, len: usize, int: u64) !void {
|
||||
dwarf.writeInt(try bw.writableSlice(len), int);
|
||||
}
|
||||
|
||||
@ -6127,8 +6123,7 @@ fn leb128Bytes(value: anytype) u32 {
|
||||
var buffer: [
|
||||
std.math.divCeil(u16, @intFromBool(value_info.signedness == .signed) + value_info.bits, 7) catch unreachable
|
||||
]u8 = undefined;
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(&buffer);
|
||||
var bw: Writer = .fixed(&buffer);
|
||||
bw.writeLeb128(value) catch unreachable;
|
||||
return @intCast(bw.end);
|
||||
}
|
||||
@ -6155,3 +6150,4 @@ const log = std.log.scoped(.dwarf);
|
||||
const std = @import("std");
|
||||
const target_info = @import("../target.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
@ -3029,8 +3029,7 @@ fn writeAtoms(self: *Elf) !void {
|
||||
if (self.requiresThunks()) {
|
||||
for (self.thunks.items) |th| {
|
||||
try buffer.resize(th.size(self));
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
bw.initFixed(buffer.items);
|
||||
var bw: Writer = .fixed(buffer.items);
|
||||
const shdr = slice.items(.shdr)[th.output_section_index];
|
||||
const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset;
|
||||
try th.write(self, &bw);
|
||||
@ -3136,7 +3135,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
|
||||
var buffer: std.ArrayListUnmanaged(u8) = .empty;
|
||||
defer buffer.deinit(gpa);
|
||||
var bw: std.io.BufferedWriter = undefined;
|
||||
var bw: Writer = undefined;
|
||||
|
||||
if (self.section_indexes.interp) |shndx| {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
@ -3156,7 +3155,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
if (self.section_indexes.gnu_hash) |shndx| {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
try buffer.resize(gpa, self.gnu_hash.size());
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try self.gnu_hash.write(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3170,7 +3169,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
if (self.section_indexes.verneed) |shndx| {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
try buffer.resize(gpa, self.verneed.size());
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try self.verneed.write(&bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3179,7 +3178,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
if (self.section_indexes.dynamic) |shndx| {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
try buffer.resize(gpa, self.dynamic.size(self));
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try self.dynamic.write(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3188,7 +3187,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
if (self.section_indexes.dynsymtab) |shndx| {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
try buffer.resize(gpa, self.dynsym.size());
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try self.dynsym.write(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3208,7 +3207,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
const sh_size = try self.cast(usize, shdr.sh_size);
|
||||
try buffer.resize(gpa, @intCast(sh_size - existing_size));
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try eh_frame.writeEhFrame(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset + existing_size);
|
||||
@ -3218,7 +3217,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
const sh_size = try self.cast(usize, shdr.sh_size);
|
||||
try buffer.resize(gpa, sh_size);
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try eh_frame.writeEhFrameHdr(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3227,7 +3226,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
if (self.section_indexes.got) |index| {
|
||||
const shdr = slice.items(.shdr)[index];
|
||||
try buffer.resize(gpa, self.got.size(self));
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try self.got.write(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3244,7 +3243,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
if (self.section_indexes.plt) |shndx| {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
try buffer.resize(gpa, self.plt.size(self));
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try self.plt.write(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3253,7 +3252,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
if (self.section_indexes.got_plt) |shndx| {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
try buffer.resize(gpa, self.got_plt.size(self));
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try self.got_plt.write(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3262,7 +3261,7 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||
if (self.section_indexes.plt_got) |shndx| {
|
||||
const shdr = slice.items(.shdr)[shndx];
|
||||
try buffer.resize(gpa, self.plt_got.size(self));
|
||||
bw.initFixed(buffer.items);
|
||||
bw = .fixed(buffer.items);
|
||||
try self.plt_got.write(self, &bw);
|
||||
assert(bw.end == bw.buffer.len);
|
||||
try self.pwriteAll(bw.buffer, shdr.sh_offset);
|
||||
@ -3883,7 +3882,7 @@ fn fmtShdr(self: *Elf, shdr: elf.Elf64_Shdr) std.fmt.Formatter(formatShdr) {
|
||||
} };
|
||||
}
|
||||
|
||||
fn formatShdr(ctx: FormatShdrCtx, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
|
||||
fn formatShdr(ctx: FormatShdrCtx, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
|
||||
_ = unused_fmt_string;
|
||||
const shdr = ctx.shdr;
|
||||
try bw.print("{s} : @{x} ({x}) : align({x}) : size({x}) : entsize({x}) : flags({f})", .{
|
||||
@ -3898,7 +3897,7 @@ pub fn fmtShdrFlags(sh_flags: u64) std.fmt.Formatter(formatShdrFlags) {
|
||||
return .{ .data = sh_flags };
|
||||
}
|
||||
|
||||
fn formatShdrFlags(sh_flags: u64, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) !void {
|
||||
fn formatShdrFlags(sh_flags: u64, bw: *Writer, comptime unused_fmt_string: []const u8) !void {
|
||||
_ = unused_fmt_string;
|
||||
if (elf.SHF_WRITE & sh_flags != 0) {
|
||||
try bw.writeByte('W');
|
||||
@ -3958,7 +3957,7 @@ fn fmtPhdr(self: *Elf, phdr: elf.Elf64_Phdr) std.fmt.Formatter(formatPhdr) {
|
||||
|
||||
fn formatPhdr(
|
||||
ctx: FormatPhdrCtx,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime unused_fmt_string: []const u8,
|
||||
) !void {
|
||||
_ = unused_fmt_string;
|
||||
@ -3994,7 +3993,7 @@ pub fn dumpState(self: *Elf) std.fmt.Formatter(fmtDumpState) {
|
||||
|
||||
fn fmtDumpState(
|
||||
self: *Elf,
|
||||
bw: *std.io.BufferedWriter,
|
||||
bw: *Writer,
|
||||
comptime unused_fmt_string: []const u8,
|
||||
) !void {
|
||||
_ = unused_fmt_string;
|
||||
@ -4216,7 +4215,7 @@ pub const Ref = struct {
|
||||
return ref.index == other.index and ref.file == other.file;
|
||||
}
|
||||
|
||||
pub fn format(ref: Ref, bw: *std.io.BufferedWriter, comptime unused_fmt_string: []const u8) std.io.Writer.Error!void {
|
||||
pub fn format(ref: Ref, bw: *Writer, comptime unused_fmt_string: []const u8) Writer.Error!void {
|
||||
_ = unused_fmt_string;
|
||||
try bw.print("ref({},{})", .{ ref.index, ref.file });
|
||||
}
|
||||
@ -4493,6 +4492,7 @@ const Allocator = std.mem.Allocator;
|
||||
const Hash = std.hash.Wyhash;
|
||||
const Path = std.Build.Cache.Path;
|
||||
const Stat = std.Build.Cache.File.Stat;
|
||||
const Writer = std.io.Writer;
|
||||
|
||||
const codegen = @import("../codegen.zig");
|
||||
const dev = @import("../dev.zig");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user