authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-16 03:46:12-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:25-07:00
logff3581ca2d21ed0557aa6bc10fba8168375a77c7
tree6fefb478e5428707b92c77c09cf2cb619596676e
parent1d0495678dc3729feb40939ddcaaef552efadbda

update some of the build system to new API


8 files changed, 506 insertions(+), 474 deletions(-)

lib/std/Build/Cache/DepTokenizer.zig+7-9
......@@ -435,7 +435,7 @@ pub const Token = union(enum) {
435435 .incomplete_quoted_prerequisite,
436436 .incomplete_target,
437437 => |index_and_bytes| {
438 try list.print("{s} '", .{self.errStr()});
438 try list.print(gpa, "{s} '", .{self.errStr()});
439439 if (self == .incomplete_target) {
440440 const tmp = Token{ .target_must_resolve = index_and_bytes.bytes };
441441 try tmp.resolve(gpa, list);
......@@ -451,7 +451,7 @@ pub const Token = union(enum) {
451451 .incomplete_escape,
452452 .expected_colon,
453453 => |index_and_char| {
454 try list.appendSlice("illegal char ");
454 try list.appendSlice(gpa, "illegal char ");
455455 try printUnderstandableChar(gpa, list, index_and_char.char);
456456 try list.print(gpa, " at position {d}: {s}", .{ index_and_char.index, self.errStr() });
457457 },
......@@ -1076,17 +1076,15 @@ fn depTokenizer(input: []const u8, expect: []const u8) !void {
10761076 try testing.expectEqualStrings(expect, buffer.items);
10771077}
10781078
1079fn printCharValues(out: anytype, bytes: []const u8) !void {
1080 for (bytes) |b| {
1081 try out.writeAll(&[_]u8{printable_char_tab[b]});
1082 }
1079fn printCharValues(gpa: Allocator, list: *std.ArrayListUnmanaged(u8), bytes: []const u8) !void {
1080 for (bytes) |b| try list.append(gpa, printable_char_tab[b]);
10831081}
10841082
1085fn printUnderstandableChar(out: anytype, char: u8) !void {
1083fn printUnderstandableChar(gpa: Allocator, list: *std.ArrayListUnmanaged(u8), char: u8) !void {
10861084 if (std.ascii.isPrint(char)) {
1087 try out.print("'{c}'", .{char});
1085 try list.print(gpa, "'{c}'", .{char});
10881086 } else {
1089 try out.print("\\x{X:0>2}", .{char});
1087 try list.print(gpa, "\\x{X:0>2}", .{char});
10901088 }
10911089}
10921090
lib/std/Build/Step.zig+19-19
......@@ -287,26 +287,26 @@ pub fn cast(step: *Step, comptime T: type) ?*T {
287287
288288/// For debugging purposes, prints identifying information about this Step.
289289pub fn dump(step: *Step, file: std.fs.File) void {
290 const w = file.writer();
290 var bw = file.unbufferedWriter();
291291 const tty_config = std.io.tty.detectConfig(file);
292292 const debug_info = std.debug.getSelfDebugInfo() catch |err| {
293 w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{
293 bw.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{
294294 @errorName(err),
295295 }) catch {};
296296 return;
297297 };
298298 if (step.getStackTrace()) |stack_trace| {
299 w.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {};
300 std.debug.writeStackTrace(stack_trace, w, debug_info, tty_config) catch |err| {
301 w.print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch {};
299 bw.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {};
300 std.debug.writeStackTrace(stack_trace, &bw, debug_info, tty_config) catch |err| {
301 bw.print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch {};
302302 return;
303303 };
304304 } else {
305305 const field = "debug_stack_frames_count";
306306 comptime assert(@hasField(Build, field));
307 tty_config.setColor(w, .yellow) catch {};
308 w.print("name: '{s}'. no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{step.name}) catch {};
309 tty_config.setColor(w, .reset) catch {};
307 tty_config.setColor(&bw, .yellow) catch {};
308 bw.print("name: '{s}'. no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{step.name}) catch {};
309 tty_config.setColor(&bw, .reset) catch {};
310310 }
311311}
312312
......@@ -738,7 +738,7 @@ pub fn allocPrintCmd2(
738738 argv: []const []const u8,
739739) Allocator.Error![]u8 {
740740 const shell = struct {
741 fn escape(writer: anytype, string: []const u8, is_argv0: bool) !void {
741 fn escape(writer: *std.io.Writer, string: []const u8, is_argv0: bool) !void {
742742 for (string) |c| {
743743 if (switch (c) {
744744 else => true,
......@@ -772,9 +772,9 @@ pub fn allocPrintCmd2(
772772 }
773773 };
774774
775 var buf: std.ArrayListUnmanaged(u8) = .empty;
776 const writer = buf.writer(arena);
777 if (opt_cwd) |cwd| try writer.print("cd {s} && ", .{cwd});
775 var aw: std.io.Writer.Allocating = .init(arena);
776 const w = &aw.interface;
777 if (opt_cwd) |cwd| try w.print(arena, "cd {s} && ", .{cwd});
778778 if (opt_env) |env| {
779779 const process_env_map = std.process.getEnvMap(arena) catch std.process.EnvMap.init(arena);
780780 var it = env.iterator();
......@@ -784,17 +784,17 @@ pub fn allocPrintCmd2(
784784 if (process_env_map.get(key)) |process_value| {
785785 if (std.mem.eql(u8, value, process_value)) continue;
786786 }
787 try writer.print("{s}=", .{key});
788 try shell.escape(writer, value, false);
789 try writer.writeByte(' ');
787 try w.print(arena, "{s}=", .{key});
788 try shell.escape(w, value, false);
789 try w.writeByte(arena, ' ');
790790 }
791791 }
792 try shell.escape(writer, argv[0], true);
792 try shell.escape(w, argv[0], true);
793793 for (argv[1..]) |arg| {
794 try writer.writeByte(' ');
795 try shell.escape(writer, arg, false);
794 try w.writeByte(arena, ' ');
795 try shell.escape(w, arg, false);
796796 }
797 return buf.toOwnedSlice(arena);
797 return aw.getWritten();
798798}
799799
800800/// Prefer `cacheHitAndWatch` unless you already added watch inputs
lib/std/Build/Step/CheckObject.zig+321-314
......@@ -248,56 +248,63 @@ const ComputeCompareExpected = struct {
248248const Check = struct {
249249 kind: Kind,
250250 payload: Payload,
251 data: std.ArrayList(u8),
252 actions: std.ArrayList(Action),
251 allocator: Allocator,
252 data: std.ArrayListUnmanaged(u8),
253 actions: std.ArrayListUnmanaged(Action),
253254
254255 fn create(allocator: Allocator, kind: Kind) Check {
255256 return .{
256257 .kind = kind,
257258 .payload = .{ .none = {} },
258 .data = std.ArrayList(u8).init(allocator),
259 .actions = std.ArrayList(Action).init(allocator),
259 .allocator = allocator,
260 .data = .empty,
261 .actions = .empty,
260262 };
261263 }
262264
263 fn dumpSection(allocator: Allocator, name: [:0]const u8) Check {
264 var check = Check.create(allocator, .dump_section);
265 fn dumpSection(gpa: Allocator, name: [:0]const u8) Check {
266 var check = Check.create(gpa, .dump_section);
265267 const off: u32 = @intCast(check.data.items.len);
266 check.data.writer().print("{s}\x00", .{name}) catch @panic("OOM");
268 check.data.print(gpa, "{s}\x00", .{name}) catch @panic("OOM");
267269 check.payload = .{ .dump_section = off };
268270 return check;
269271 }
270272
271273 fn extract(check: *Check, phrase: SearchPhrase) void {
272 check.actions.append(.{
274 const gpa = check.allocator;
275 check.actions.append(gpa, .{
273276 .tag = .extract,
274277 .phrase = phrase,
275278 }) catch @panic("OOM");
276279 }
277280
278281 fn exact(check: *Check, phrase: SearchPhrase) void {
279 check.actions.append(.{
282 const gpa = check.allocator;
283 check.actions.append(gpa, .{
280284 .tag = .exact,
281285 .phrase = phrase,
282286 }) catch @panic("OOM");
283287 }
284288
285289 fn contains(check: *Check, phrase: SearchPhrase) void {
286 check.actions.append(.{
290 const gpa = check.allocator;
291 check.actions.append(gpa, .{
287292 .tag = .contains,
288293 .phrase = phrase,
289294 }) catch @panic("OOM");
290295 }
291296
292297 fn notPresent(check: *Check, phrase: SearchPhrase) void {
293 check.actions.append(.{
298 const gpa = check.allocator;
299 check.actions.append(gpa, .{
294300 .tag = .not_present,
295301 .phrase = phrase,
296302 }) catch @panic("OOM");
297303 }
298304
299305 fn computeCmp(check: *Check, phrase: SearchPhrase, expected: ComputeCompareExpected) void {
300 check.actions.append(.{
306 const gpa = check.allocator;
307 check.actions.append(gpa, .{
301308 .tag = .compute_cmp,
302309 .phrase = phrase,
303310 .expected = expected,
......@@ -810,7 +817,7 @@ const MachODumper = struct {
810817 return null;
811818 }
812819
813 fn dumpHeader(hdr: macho.mach_header_64, writer: anytype) !void {
820 fn dumpHeader(hdr: macho.mach_header_64, bw: *std.io.BufferedWriter) !void {
814821 const cputype = switch (hdr.cputype) {
815822 macho.CPU_TYPE_ARM64 => "ARM64",
816823 macho.CPU_TYPE_X86_64 => "X86_64",
......@@ -831,7 +838,7 @@ const MachODumper = struct {
831838 else => "Unknown",
832839 };
833840
834 try writer.print(
841 try bw.print(
835842 \\header
836843 \\cputype {s}
837844 \\filetype {s}
......@@ -846,41 +853,41 @@ const MachODumper = struct {
846853 });
847854
848855 if (hdr.flags > 0) {
849 if (hdr.flags & macho.MH_NOUNDEFS != 0) try writer.writeAll(" NOUNDEFS");
850 if (hdr.flags & macho.MH_INCRLINK != 0) try writer.writeAll(" INCRLINK");
851 if (hdr.flags & macho.MH_DYLDLINK != 0) try writer.writeAll(" DYLDLINK");
852 if (hdr.flags & macho.MH_BINDATLOAD != 0) try writer.writeAll(" BINDATLOAD");
853 if (hdr.flags & macho.MH_PREBOUND != 0) try writer.writeAll(" PREBOUND");
854 if (hdr.flags & macho.MH_SPLIT_SEGS != 0) try writer.writeAll(" SPLIT_SEGS");
855 if (hdr.flags & macho.MH_LAZY_INIT != 0) try writer.writeAll(" LAZY_INIT");
856 if (hdr.flags & macho.MH_TWOLEVEL != 0) try writer.writeAll(" TWOLEVEL");
857 if (hdr.flags & macho.MH_FORCE_FLAT != 0) try writer.writeAll(" FORCE_FLAT");
858 if (hdr.flags & macho.MH_NOMULTIDEFS != 0) try writer.writeAll(" NOMULTIDEFS");
859 if (hdr.flags & macho.MH_NOFIXPREBINDING != 0) try writer.writeAll(" NOFIXPREBINDING");
860 if (hdr.flags & macho.MH_PREBINDABLE != 0) try writer.writeAll(" PREBINDABLE");
861 if (hdr.flags & macho.MH_ALLMODSBOUND != 0) try writer.writeAll(" ALLMODSBOUND");
862 if (hdr.flags & macho.MH_SUBSECTIONS_VIA_SYMBOLS != 0) try writer.writeAll(" SUBSECTIONS_VIA_SYMBOLS");
863 if (hdr.flags & macho.MH_CANONICAL != 0) try writer.writeAll(" CANONICAL");
864 if (hdr.flags & macho.MH_WEAK_DEFINES != 0) try writer.writeAll(" WEAK_DEFINES");
865 if (hdr.flags & macho.MH_BINDS_TO_WEAK != 0) try writer.writeAll(" BINDS_TO_WEAK");
866 if (hdr.flags & macho.MH_ALLOW_STACK_EXECUTION != 0) try writer.writeAll(" ALLOW_STACK_EXECUTION");
867 if (hdr.flags & macho.MH_ROOT_SAFE != 0) try writer.writeAll(" ROOT_SAFE");
868 if (hdr.flags & macho.MH_SETUID_SAFE != 0) try writer.writeAll(" SETUID_SAFE");
869 if (hdr.flags & macho.MH_NO_REEXPORTED_DYLIBS != 0) try writer.writeAll(" NO_REEXPORTED_DYLIBS");
870 if (hdr.flags & macho.MH_PIE != 0) try writer.writeAll(" PIE");
871 if (hdr.flags & macho.MH_DEAD_STRIPPABLE_DYLIB != 0) try writer.writeAll(" DEAD_STRIPPABLE_DYLIB");
872 if (hdr.flags & macho.MH_HAS_TLV_DESCRIPTORS != 0) try writer.writeAll(" HAS_TLV_DESCRIPTORS");
873 if (hdr.flags & macho.MH_NO_HEAP_EXECUTION != 0) try writer.writeAll(" NO_HEAP_EXECUTION");
874 if (hdr.flags & macho.MH_APP_EXTENSION_SAFE != 0) try writer.writeAll(" APP_EXTENSION_SAFE");
875 if (hdr.flags & macho.MH_NLIST_OUTOFSYNC_WITH_DYLDINFO != 0) try writer.writeAll(" NLIST_OUTOFSYNC_WITH_DYLDINFO");
856 if (hdr.flags & macho.MH_NOUNDEFS != 0) try bw.writeAll(" NOUNDEFS");
857 if (hdr.flags & macho.MH_INCRLINK != 0) try bw.writeAll(" INCRLINK");
858 if (hdr.flags & macho.MH_DYLDLINK != 0) try bw.writeAll(" DYLDLINK");
859 if (hdr.flags & macho.MH_BINDATLOAD != 0) try bw.writeAll(" BINDATLOAD");
860 if (hdr.flags & macho.MH_PREBOUND != 0) try bw.writeAll(" PREBOUND");
861 if (hdr.flags & macho.MH_SPLIT_SEGS != 0) try bw.writeAll(" SPLIT_SEGS");
862 if (hdr.flags & macho.MH_LAZY_INIT != 0) try bw.writeAll(" LAZY_INIT");
863 if (hdr.flags & macho.MH_TWOLEVEL != 0) try bw.writeAll(" TWOLEVEL");
864 if (hdr.flags & macho.MH_FORCE_FLAT != 0) try bw.writeAll(" FORCE_FLAT");
865 if (hdr.flags & macho.MH_NOMULTIDEFS != 0) try bw.writeAll(" NOMULTIDEFS");
866 if (hdr.flags & macho.MH_NOFIXPREBINDING != 0) try bw.writeAll(" NOFIXPREBINDING");
867 if (hdr.flags & macho.MH_PREBINDABLE != 0) try bw.writeAll(" PREBINDABLE");
868 if (hdr.flags & macho.MH_ALLMODSBOUND != 0) try bw.writeAll(" ALLMODSBOUND");
869 if (hdr.flags & macho.MH_SUBSECTIONS_VIA_SYMBOLS != 0) try bw.writeAll(" SUBSECTIONS_VIA_SYMBOLS");
870 if (hdr.flags & macho.MH_CANONICAL != 0) try bw.writeAll(" CANONICAL");
871 if (hdr.flags & macho.MH_WEAK_DEFINES != 0) try bw.writeAll(" WEAK_DEFINES");
872 if (hdr.flags & macho.MH_BINDS_TO_WEAK != 0) try bw.writeAll(" BINDS_TO_WEAK");
873 if (hdr.flags & macho.MH_ALLOW_STACK_EXECUTION != 0) try bw.writeAll(" ALLOW_STACK_EXECUTION");
874 if (hdr.flags & macho.MH_ROOT_SAFE != 0) try bw.writeAll(" ROOT_SAFE");
875 if (hdr.flags & macho.MH_SETUID_SAFE != 0) try bw.writeAll(" SETUID_SAFE");
876 if (hdr.flags & macho.MH_NO_REEXPORTED_DYLIBS != 0) try bw.writeAll(" NO_REEXPORTED_DYLIBS");
877 if (hdr.flags & macho.MH_PIE != 0) try bw.writeAll(" PIE");
878 if (hdr.flags & macho.MH_DEAD_STRIPPABLE_DYLIB != 0) try bw.writeAll(" DEAD_STRIPPABLE_DYLIB");
879 if (hdr.flags & macho.MH_HAS_TLV_DESCRIPTORS != 0) try bw.writeAll(" HAS_TLV_DESCRIPTORS");
880 if (hdr.flags & macho.MH_NO_HEAP_EXECUTION != 0) try bw.writeAll(" NO_HEAP_EXECUTION");
881 if (hdr.flags & macho.MH_APP_EXTENSION_SAFE != 0) try bw.writeAll(" APP_EXTENSION_SAFE");
882 if (hdr.flags & macho.MH_NLIST_OUTOFSYNC_WITH_DYLDINFO != 0) try bw.writeAll(" NLIST_OUTOFSYNC_WITH_DYLDINFO");
876883 }
877884
878 try writer.writeByte('\n');
885 try bw.writeByte('\n');
879886 }
880887
881 fn dumpLoadCommand(lc: macho.LoadCommandIterator.LoadCommand, index: usize, writer: anytype) !void {
888 fn dumpLoadCommand(lc: macho.LoadCommandIterator.LoadCommand, index: usize, bw: *std.io.BufferedWriter) !void {
882889 // print header first
883 try writer.print(
890 try bw.print(
884891 \\LC {d}
885892 \\cmd {s}
886893 \\cmdsize {d}
......@@ -889,8 +896,8 @@ const MachODumper = struct {
889896 switch (lc.cmd()) {
890897 .SEGMENT_64 => {
891898 const seg = lc.cast(macho.segment_command_64).?;
892 try writer.writeByte('\n');
893 try writer.print(
899 try bw.writeByte('\n');
900 try bw.print(
894901 \\segname {s}
895902 \\vmaddr {x}
896903 \\vmsize {x}
......@@ -905,8 +912,8 @@ const MachODumper = struct {
905912 });
906913
907914 for (lc.getSections()) |sect| {
908 try writer.writeByte('\n');
909 try writer.print(
915 try bw.writeByte('\n');
916 try bw.print(
910917 \\sectname {s}
911918 \\addr {x}
912919 \\size {x}
......@@ -928,8 +935,8 @@ const MachODumper = struct {
928935 .REEXPORT_DYLIB,
929936 => {
930937 const dylib = lc.cast(macho.dylib_command).?;
931 try writer.writeByte('\n');
932 try writer.print(
938 try bw.writeByte('\n');
939 try bw.print(
933940 \\name {s}
934941 \\timestamp {d}
935942 \\current version {x}
......@@ -944,16 +951,16 @@ const MachODumper = struct {
944951
945952 .MAIN => {
946953 const main = lc.cast(macho.entry_point_command).?;
947 try writer.writeByte('\n');
948 try writer.print(
954 try bw.writeByte('\n');
955 try bw.print(
949956 \\entryoff {x}
950957 \\stacksize {x}
951958 , .{ main.entryoff, main.stacksize });
952959 },
953960
954961 .RPATH => {
955 try writer.writeByte('\n');
956 try writer.print(
962 try bw.writeByte('\n');
963 try bw.print(
957964 \\path {s}
958965 , .{
959966 lc.getRpathPathName(),
......@@ -962,8 +969,8 @@ const MachODumper = struct {
962969
963970 .UUID => {
964971 const uuid = lc.cast(macho.uuid_command).?;
965 try writer.writeByte('\n');
966 try writer.print("uuid {x}", .{&uuid.uuid});
972 try bw.writeByte('\n');
973 try bw.print("uuid {x}", .{&uuid.uuid});
967974 },
968975
969976 .DATA_IN_CODE,
......@@ -971,8 +978,8 @@ const MachODumper = struct {
971978 .CODE_SIGNATURE,
972979 => {
973980 const llc = lc.cast(macho.linkedit_data_command).?;
974 try writer.writeByte('\n');
975 try writer.print(
981 try bw.writeByte('\n');
982 try bw.print(
976983 \\dataoff {x}
977984 \\datasize {x}
978985 , .{ llc.dataoff, llc.datasize });
......@@ -980,8 +987,8 @@ const MachODumper = struct {
980987
981988 .DYLD_INFO_ONLY => {
982989 const dlc = lc.cast(macho.dyld_info_command).?;
983 try writer.writeByte('\n');
984 try writer.print(
990 try bw.writeByte('\n');
991 try bw.print(
985992 \\rebaseoff {x}
986993 \\rebasesize {x}
987994 \\bindoff {x}
......@@ -1008,8 +1015,8 @@ const MachODumper = struct {
10081015
10091016 .SYMTAB => {
10101017 const slc = lc.cast(macho.symtab_command).?;
1011 try writer.writeByte('\n');
1012 try writer.print(
1018 try bw.writeByte('\n');
1019 try bw.print(
10131020 \\symoff {x}
10141021 \\nsyms {x}
10151022 \\stroff {x}
......@@ -1024,8 +1031,8 @@ const MachODumper = struct {
10241031
10251032 .DYSYMTAB => {
10261033 const dlc = lc.cast(macho.dysymtab_command).?;
1027 try writer.writeByte('\n');
1028 try writer.print(
1034 try bw.writeByte('\n');
1035 try bw.print(
10291036 \\ilocalsym {x}
10301037 \\nlocalsym {x}
10311038 \\iextdefsym {x}
......@@ -1048,8 +1055,8 @@ const MachODumper = struct {
10481055
10491056 .BUILD_VERSION => {
10501057 const blc = lc.cast(macho.build_version_command).?;
1051 try writer.writeByte('\n');
1052 try writer.print(
1058 try bw.writeByte('\n');
1059 try bw.print(
10531060 \\platform {s}
10541061 \\minos {d}.{d}.{d}
10551062 \\sdk {d}.{d}.{d}
......@@ -1065,12 +1072,12 @@ const MachODumper = struct {
10651072 blc.ntools,
10661073 });
10671074 for (lc.getBuildVersionTools()) |tool| {
1068 try writer.writeByte('\n');
1075 try bw.writeByte('\n');
10691076 switch (tool.tool) {
1070 .CLANG, .SWIFT, .LD, .LLD, .ZIG => try writer.print("tool {s}\n", .{@tagName(tool.tool)}),
1071 else => |x| try writer.print("tool {d}\n", .{@intFromEnum(x)}),
1077 .CLANG, .SWIFT, .LD, .LLD, .ZIG => try bw.print("tool {s}\n", .{@tagName(tool.tool)}),
1078 else => |x| try bw.print("tool {d}\n", .{@intFromEnum(x)}),
10721079 }
1073 try writer.print(
1080 try bw.print(
10741081 \\version {d}.{d}.{d}
10751082 , .{
10761083 tool.version >> 16,
......@@ -1086,8 +1093,8 @@ const MachODumper = struct {
10861093 .VERSION_MIN_TVOS,
10871094 => {
10881095 const vlc = lc.cast(macho.version_min_command).?;
1089 try writer.writeByte('\n');
1090 try writer.print(
1096 try bw.writeByte('\n');
1097 try bw.print(
10911098 \\version {d}.{d}.{d}
10921099 \\sdk {d}.{d}.{d}
10931100 , .{
......@@ -1104,8 +1111,8 @@ const MachODumper = struct {
11041111 }
11051112 }
11061113
1107 fn dumpSymtab(ctx: ObjectContext, writer: anytype) !void {
1108 try writer.writeAll(symtab_label ++ "\n");
1114 fn dumpSymtab(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
1115 try bw.writeAll(symtab_label ++ "\n");
11091116
11101117 for (ctx.symtab.items) |sym| {
11111118 const sym_name = ctx.getString(sym.n_strx);
......@@ -1120,32 +1127,32 @@ const MachODumper = struct {
11201127 macho.N_STSYM => "STSYM",
11211128 else => "UNKNOWN STAB",
11221129 };
1123 try writer.print("{x}", .{sym.n_value});
1130 try bw.print("{x}", .{sym.n_value});
11241131 if (sym.n_sect > 0) {
11251132 const sect = ctx.sections.items[sym.n_sect - 1];
1126 try writer.print(" ({s},{s})", .{ sect.segName(), sect.sectName() });
1133 try bw.print(" ({s},{s})", .{ sect.segName(), sect.sectName() });
11271134 }
1128 try writer.print(" {s} (stab) {s}\n", .{ tt, sym_name });
1135 try bw.print(" {s} (stab) {s}\n", .{ tt, sym_name });
11291136 } else if (sym.sect()) {
11301137 const sect = ctx.sections.items[sym.n_sect - 1];
1131 try writer.print("{x} ({s},{s})", .{
1138 try bw.print("{x} ({s},{s})", .{
11321139 sym.n_value,
11331140 sect.segName(),
11341141 sect.sectName(),
11351142 });
1136 if (sym.n_desc & macho.REFERENCED_DYNAMICALLY != 0) try writer.writeAll(" [referenced dynamically]");
1137 if (sym.weakDef()) try writer.writeAll(" weak");
1138 if (sym.weakRef()) try writer.writeAll(" weakref");
1143 if (sym.n_desc & macho.REFERENCED_DYNAMICALLY != 0) try bw.writeAll(" [referenced dynamically]");
1144 if (sym.weakDef()) try bw.writeAll(" weak");
1145 if (sym.weakRef()) try bw.writeAll(" weakref");
11391146 if (sym.ext()) {
1140 if (sym.pext()) try writer.writeAll(" private");
1141 try writer.writeAll(" external");
1142 } else if (sym.pext()) try writer.writeAll(" (was private external)");
1143 try writer.print(" {s}\n", .{sym_name});
1147 if (sym.pext()) try bw.writeAll(" private");
1148 try bw.writeAll(" external");
1149 } else if (sym.pext()) try bw.writeAll(" (was private external)");
1150 try bw.print(" {s}\n", .{sym_name});
11441151 } else if (sym.tentative()) {
11451152 const alignment = (sym.n_desc >> 8) & 0x0F;
1146 try writer.print(" 0x{x:0>16} (common) (alignment 2^{d})", .{ sym.n_value, alignment });
1147 if (sym.ext()) try writer.writeAll(" external");
1148 try writer.print(" {s}\n", .{sym_name});
1153 try bw.print(" 0x{x:0>16} (common) (alignment 2^{d})", .{ sym.n_value, alignment });
1154 if (sym.ext()) try bw.writeAll(" external");
1155 try bw.print(" {s}\n", .{sym_name});
11491156 } else if (sym.undf()) {
11501157 const ordinal = @divFloor(@as(i16, @bitCast(sym.n_desc)), macho.N_SYMBOL_RESOLVER);
11511158 const import_name = blk: {
......@@ -1164,10 +1171,10 @@ const MachODumper = struct {
11641171 const ext = mem.lastIndexOfScalar(u8, basename, '.') orelse basename.len;
11651172 break :blk basename[0..ext];
11661173 };
1167 try writer.writeAll("(undefined)");
1168 if (sym.weakRef()) try writer.writeAll(" weakref");
1169 if (sym.ext()) try writer.writeAll(" external");
1170 try writer.print(" {s} (from {s})\n", .{
1174 try bw.writeAll("(undefined)");
1175 if (sym.weakRef()) try bw.writeAll(" weakref");
1176 if (sym.ext()) try bw.writeAll(" external");
1177 try bw.print(" {s} (from {s})\n", .{
11711178 sym_name,
11721179 import_name,
11731180 });
......@@ -1175,8 +1182,8 @@ const MachODumper = struct {
11751182 }
11761183 }
11771184
1178 fn dumpIndirectSymtab(ctx: ObjectContext, writer: anytype) !void {
1179 try writer.writeAll(indirect_symtab_label ++ "\n");
1185 fn dumpIndirectSymtab(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
1186 try bw.writeAll(indirect_symtab_label ++ "\n");
11801187
11811188 var sects_buffer: [3]macho.section_64 = undefined;
11821189 const sects = blk: {
......@@ -1214,23 +1221,23 @@ const MachODumper = struct {
12141221 break :blk @sizeOf(u64);
12151222 };
12161223
1217 try writer.print("{s},{s}\n", .{ sect.segName(), sect.sectName() });
1218 try writer.print("nentries {d}\n", .{end - start});
1224 try bw.print("{s},{s}\n", .{ sect.segName(), sect.sectName() });
1225 try bw.print("nentries {d}\n", .{end - start});
12191226 for (ctx.indsymtab.items[start..end], 0..) |index, j| {
12201227 const sym = ctx.symtab.items[index];
12211228 const addr = sect.addr + entry_size * j;
1222 try writer.print("0x{x} {d} {s}\n", .{ addr, index, ctx.getString(sym.n_strx) });
1229 try bw.print("0x{x} {d} {s}\n", .{ addr, index, ctx.getString(sym.n_strx) });
12231230 }
12241231 }
12251232 }
12261233
1227 fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, writer: anytype) !void {
1234 fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
12281235 var rebases = std.ArrayList(u64).init(ctx.gpa);
12291236 defer rebases.deinit();
12301237 try ctx.parseRebaseInfo(data, &rebases);
12311238 mem.sort(u64, rebases.items, {}, std.sort.asc(u64));
12321239 for (rebases.items) |addr| {
1233 try writer.print("0x{x}\n", .{addr});
1240 try bw.print("0x{x}\n", .{addr});
12341241 }
12351242 }
12361243
......@@ -1323,7 +1330,7 @@ const MachODumper = struct {
13231330 };
13241331 };
13251332
1326 fn dumpBindInfo(ctx: ObjectContext, data: []const u8, writer: anytype) !void {
1333 fn dumpBindInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
13271334 var bindings = std.ArrayList(Binding).init(ctx.gpa);
13281335 defer {
13291336 for (bindings.items) |*b| {
......@@ -1334,15 +1341,15 @@ const MachODumper = struct {
13341341 try ctx.parseBindInfo(data, &bindings);
13351342 mem.sort(Binding, bindings.items, {}, Binding.lessThan);
13361343 for (bindings.items) |binding| {
1337 try writer.print("0x{x} [addend: {d}]", .{ binding.address, binding.addend });
1338 try writer.writeAll(" (");
1344 try bw.print("0x{x} [addend: {d}]", .{ binding.address, binding.addend });
1345 try bw.writeAll(" (");
13391346 switch (binding.tag) {
1340 .self => try writer.writeAll("self"),
1341 .exe => try writer.writeAll("main executable"),
1342 .flat => try writer.writeAll("flat lookup"),
1343 .ord => try writer.writeAll(std.fs.path.basename(ctx.imports.items[binding.ordinal - 1])),
1347 .self => try bw.writeAll("self"),
1348 .exe => try bw.writeAll("main executable"),
1349 .flat => try bw.writeAll("flat lookup"),
1350 .ord => try bw.writeAll(std.fs.path.basename(ctx.imports.items[binding.ordinal - 1])),
13441351 }
1345 try writer.print(") {s}\n", .{binding.name});
1352 try bw.print(") {s}\n", .{binding.name});
13461353 }
13471354 }
13481355
......@@ -1439,7 +1446,7 @@ const MachODumper = struct {
14391446 }
14401447 }
14411448
1442 fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, writer: anytype) !void {
1449 fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void {
14431450 const seg = ctx.getSegmentByName("__TEXT") orelse return;
14441451
14451452 var arena = std.heap.ArenaAllocator.init(ctx.gpa);
......@@ -1456,23 +1463,23 @@ const MachODumper = struct {
14561463 .@"export" => {
14571464 const info = exp.data.@"export";
14581465 if (info.kind != .regular or info.weak) {
1459 try writer.writeByte('[');
1466 try bw.writeByte('[');
14601467 }
14611468 switch (info.kind) {
14621469 .regular => {},
1463 .absolute => try writer.writeAll("ABS, "),
1464 .tlv => try writer.writeAll("THREAD_LOCAL, "),
1470 .absolute => try bw.writeAll("ABS, "),
1471 .tlv => try bw.writeAll("THREAD_LOCAL, "),
14651472 }
1466 if (info.weak) try writer.writeAll("WEAK");
1473 if (info.weak) try bw.writeAll("WEAK");
14671474 if (info.kind != .regular or info.weak) {
1468 try writer.writeAll("] ");
1475 try bw.writeAll("] ");
14691476 }
1470 try writer.print("{x} ", .{seg.vmaddr + info.vmoffset});
1477 try bw.print("{x} ", .{seg.vmaddr + info.vmoffset});
14711478 },
14721479 else => {},
14731480 }
14741481
1475 try writer.print("{s}\n", .{exp.name});
1482 try bw.print("{s}\n", .{exp.name});
14761483 }
14771484 }
14781485
......@@ -1616,9 +1623,9 @@ const MachODumper = struct {
16161623 }
16171624 }
16181625
1619 fn dumpSection(ctx: ObjectContext, sect: macho.section_64, writer: anytype) !void {
1626 fn dumpSection(ctx: ObjectContext, sect: macho.section_64, bw: *std.io.BufferedWriter) !void {
16201627 const data = ctx.data[sect.offset..][0..sect.size];
1621 try writer.print("{s}", .{data});
1628 try bw.print("{s}", .{data});
16221629 }
16231630 };
16241631
......@@ -1632,29 +1639,29 @@ const MachODumper = struct {
16321639 var ctx = ObjectContext{ .gpa = gpa, .data = bytes, .header = hdr };
16331640 try ctx.parse();
16341641
1635 var output = std.ArrayList(u8).init(gpa);
1636 const writer = output.writer();
1642 var output: std.io.AllocatingWriter = undefined;
1643 const bw = output.init(gpa);
16371644
16381645 switch (check.kind) {
16391646 .headers => {
1640 try ObjectContext.dumpHeader(ctx.header, writer);
1647 try ObjectContext.dumpHeader(ctx.header, bw);
16411648
16421649 var it = ctx.getLoadCommandIterator();
16431650 var i: usize = 0;
16441651 while (it.next()) |cmd| {
1645 try ObjectContext.dumpLoadCommand(cmd, i, writer);
1646 try writer.writeByte('\n');
1652 try ObjectContext.dumpLoadCommand(cmd, i, bw);
1653 try bw.writeByte('\n');
16471654
16481655 i += 1;
16491656 }
16501657 },
16511658
16521659 .symtab => if (ctx.symtab.items.len > 0) {
1653 try ctx.dumpSymtab(writer);
1660 try ctx.dumpSymtab(bw);
16541661 } else return step.fail("no symbol table found", .{}),
16551662
16561663 .indirect_symtab => if (ctx.symtab.items.len > 0 and ctx.indsymtab.items.len > 0) {
1657 try ctx.dumpIndirectSymtab(writer);
1664 try ctx.dumpIndirectSymtab(bw);
16581665 } else return step.fail("no indirect symbol table found", .{}),
16591666
16601667 .dyld_rebase,
......@@ -1669,26 +1676,26 @@ const MachODumper = struct {
16691676 switch (check.kind) {
16701677 .dyld_rebase => if (lc.rebase_size > 0) {
16711678 const data = ctx.data[lc.rebase_off..][0..lc.rebase_size];
1672 try writer.writeAll(dyld_rebase_label ++ "\n");
1673 try ctx.dumpRebaseInfo(data, writer);
1679 try bw.writeAll(dyld_rebase_label ++ "\n");
1680 try ctx.dumpRebaseInfo(data, bw);
16741681 } else return step.fail("no rebase data found", .{}),
16751682
16761683 .dyld_bind => if (lc.bind_size > 0) {
16771684 const data = ctx.data[lc.bind_off..][0..lc.bind_size];
1678 try writer.writeAll(dyld_bind_label ++ "\n");
1679 try ctx.dumpBindInfo(data, writer);
1685 try bw.writeAll(dyld_bind_label ++ "\n");
1686 try ctx.dumpBindInfo(data, bw);
16801687 } else return step.fail("no bind data found", .{}),
16811688
16821689 .dyld_weak_bind => if (lc.weak_bind_size > 0) {
16831690 const data = ctx.data[lc.weak_bind_off..][0..lc.weak_bind_size];
1684 try writer.writeAll(dyld_weak_bind_label ++ "\n");
1685 try ctx.dumpBindInfo(data, writer);
1691 try bw.writeAll(dyld_weak_bind_label ++ "\n");
1692 try ctx.dumpBindInfo(data, bw);
16861693 } else return step.fail("no weak bind data found", .{}),
16871694
16881695 .dyld_lazy_bind => if (lc.lazy_bind_size > 0) {
16891696 const data = ctx.data[lc.lazy_bind_off..][0..lc.lazy_bind_size];
1690 try writer.writeAll(dyld_lazy_bind_label ++ "\n");
1691 try ctx.dumpBindInfo(data, writer);
1697 try bw.writeAll(dyld_lazy_bind_label ++ "\n");
1698 try ctx.dumpBindInfo(data, bw);
16921699 } else return step.fail("no lazy bind data found", .{}),
16931700
16941701 else => unreachable,
......@@ -1700,8 +1707,8 @@ const MachODumper = struct {
17001707 const lc = cmd.cast(macho.dyld_info_command).?;
17011708 if (lc.export_size > 0) {
17021709 const data = ctx.data[lc.export_off..][0..lc.export_size];
1703 try writer.writeAll(exports_label ++ "\n");
1704 try ctx.dumpExportsTrie(data, writer);
1710 try bw.writeAll(exports_label ++ "\n");
1711 try ctx.dumpExportsTrie(data, bw);
17051712 break :blk;
17061713 }
17071714 }
......@@ -1716,7 +1723,7 @@ const MachODumper = struct {
17161723 const sectname = name[sep_index + 1 ..];
17171724 const sect = ctx.getSectionByName(segname, sectname) orelse
17181725 return step.fail("section '{s}' not found", .{name});
1719 try ctx.dumpSection(sect, writer);
1726 try ctx.dumpSection(sect, bw);
17201727 },
17211728
17221729 else => return step.fail("invalid check kind for MachO file format: {s}", .{@tagName(check.kind)}),
......@@ -1850,7 +1857,7 @@ const ElfDumper = struct {
18501857 }
18511858 }
18521859
1853 fn dumpSymtab(ctx: ArchiveContext, writer: anytype) !void {
1860 fn dumpSymtab(ctx: ArchiveContext, bw: *std.io.BufferedWriter) !void {
18541861 var files = std.AutoHashMap(usize, []const u8).init(ctx.gpa);
18551862 defer files.deinit();
18561863 try files.ensureUnusedCapacity(@intCast(ctx.objects.items.len));
......@@ -1875,21 +1882,21 @@ const ElfDumper = struct {
18751882 try gop.value_ptr.append(entry.name);
18761883 }
18771884
1878 try writer.print("{s}\n", .{archive_symtab_label});
1885 try bw.print("{s}\n", .{archive_symtab_label});
18791886 for (symbols.keys(), symbols.values()) |off, values| {
1880 try writer.print("in object {s}\n", .{files.get(off).?});
1887 try bw.print("in object {s}\n", .{files.get(off).?});
18811888 for (values.items) |value| {
1882 try writer.print("{s}\n", .{value});
1889 try bw.print("{s}\n", .{value});
18831890 }
18841891 }
18851892 }
18861893
1887 fn dumpObjects(ctx: ArchiveContext, step: *Step, check: Check, writer: anytype) !void {
1894 fn dumpObjects(ctx: ArchiveContext, step: *Step, check: Check, bw: *std.io.BufferedWriter) !void {
18881895 for (ctx.objects.items) |object| {
1889 try writer.print("object {s}\n", .{object.name});
1896 try bw.print("object {s}\n", .{object.name});
18901897 const output = try parseAndDumpObject(step, check, ctx.data[object.off..][0..object.len]);
18911898 defer ctx.gpa.free(output);
1892 try writer.print("{s}\n", .{output});
1899 try bw.print("{s}\n", .{output});
18931900 }
18941901 }
18951902
......@@ -1955,32 +1962,32 @@ const ElfDumper = struct {
19551962 else => {},
19561963 };
19571964
1958 var output = std.ArrayList(u8).init(gpa);
1959 const writer = output.writer();
1965 var output: std.io.AllocatingWriter = undefined;
1966 const bw = output.init(gpa);
19601967
19611968 switch (check.kind) {
19621969 .headers => {
1963 try ctx.dumpHeader(writer);
1964 try ctx.dumpShdrs(writer);
1965 try ctx.dumpPhdrs(writer);
1970 try ctx.dumpHeader(bw);
1971 try ctx.dumpShdrs(bw);
1972 try ctx.dumpPhdrs(bw);
19661973 },
19671974
19681975 .symtab => if (ctx.symtab.symbols.len > 0) {
1969 try ctx.dumpSymtab(.symtab, writer);
1976 try ctx.dumpSymtab(.symtab, bw);
19701977 } else return step.fail("no symbol table found", .{}),
19711978
19721979 .dynamic_symtab => if (ctx.dysymtab.symbols.len > 0) {
1973 try ctx.dumpSymtab(.dysymtab, writer);
1980 try ctx.dumpSymtab(.dysymtab, bw);
19741981 } else return step.fail("no dynamic symbol table found", .{}),
19751982
19761983 .dynamic_section => if (ctx.getSectionByName(".dynamic")) |shndx| {
1977 try ctx.dumpDynamicSection(shndx, writer);
1984 try ctx.dumpDynamicSection(shndx, bw);
19781985 } else return step.fail("no .dynamic section found", .{}),
19791986
19801987 .dump_section => {
19811988 const name = mem.sliceTo(@as([*:0]const u8, @ptrCast(check.data.items.ptr + check.payload.dump_section)), 0);
19821989 const shndx = ctx.getSectionByName(name) orelse return step.fail("no '{s}' section found", .{name});
1983 try ctx.dumpSection(shndx, writer);
1990 try ctx.dumpSection(shndx, bw);
19841991 },
19851992
19861993 else => return step.fail("invalid check kind for ELF file format: {s}", .{@tagName(check.kind)}),
......@@ -1999,76 +2006,76 @@ const ElfDumper = struct {
19992006 symtab: Symtab = .{},
20002007 dysymtab: Symtab = .{},
20012008
2002 fn dumpHeader(ctx: ObjectContext, writer: anytype) !void {
2003 try writer.writeAll("header\n");
2004 try writer.print("type {s}\n", .{@tagName(ctx.hdr.e_type)});
2005 try writer.print("entry {x}\n", .{ctx.hdr.e_entry});
2009 fn dumpHeader(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
2010 try bw.writeAll("header\n");
2011 try bw.print("type {s}\n", .{@tagName(ctx.hdr.e_type)});
2012 try bw.print("entry {x}\n", .{ctx.hdr.e_entry});
20062013 }
20072014
2008 fn dumpPhdrs(ctx: ObjectContext, writer: anytype) !void {
2015 fn dumpPhdrs(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
20092016 if (ctx.phdrs.len == 0) return;
20102017
2011 try writer.writeAll("program headers\n");
2018 try bw.writeAll("program headers\n");
20122019
20132020 for (ctx.phdrs, 0..) |phdr, phndx| {
2014 try writer.print("phdr {d}\n", .{phndx});
2015 try writer.print("type {s}\n", .{fmtPhType(phdr.p_type)});
2016 try writer.print("vaddr {x}\n", .{phdr.p_vaddr});
2017 try writer.print("paddr {x}\n", .{phdr.p_paddr});
2018 try writer.print("offset {x}\n", .{phdr.p_offset});
2019 try writer.print("memsz {x}\n", .{phdr.p_memsz});
2020 try writer.print("filesz {x}\n", .{phdr.p_filesz});
2021 try writer.print("align {x}\n", .{phdr.p_align});
2021 try bw.print("phdr {d}\n", .{phndx});
2022 try bw.print("type {s}\n", .{fmtPhType(phdr.p_type)});
2023 try bw.print("vaddr {x}\n", .{phdr.p_vaddr});
2024 try bw.print("paddr {x}\n", .{phdr.p_paddr});
2025 try bw.print("offset {x}\n", .{phdr.p_offset});
2026 try bw.print("memsz {x}\n", .{phdr.p_memsz});
2027 try bw.print("filesz {x}\n", .{phdr.p_filesz});
2028 try bw.print("align {x}\n", .{phdr.p_align});
20222029
20232030 {
20242031 const flags = phdr.p_flags;
2025 try writer.writeAll("flags");
2026 if (flags > 0) try writer.writeByte(' ');
2032 try bw.writeAll("flags");
2033 if (flags > 0) try bw.writeByte(' ');
20272034 if (flags & elf.PF_R != 0) {
2028 try writer.writeByte('R');
2035 try bw.writeByte('R');
20292036 }
20302037 if (flags & elf.PF_W != 0) {
2031 try writer.writeByte('W');
2038 try bw.writeByte('W');
20322039 }
20332040 if (flags & elf.PF_X != 0) {
2034 try writer.writeByte('E');
2041 try bw.writeByte('E');
20352042 }
20362043 if (flags & elf.PF_MASKOS != 0) {
2037 try writer.writeAll("OS");
2044 try bw.writeAll("OS");
20382045 }
20392046 if (flags & elf.PF_MASKPROC != 0) {
2040 try writer.writeAll("PROC");
2047 try bw.writeAll("PROC");
20412048 }
2042 try writer.writeByte('\n');
2049 try bw.writeByte('\n');
20432050 }
20442051 }
20452052 }
20462053
2047 fn dumpShdrs(ctx: ObjectContext, writer: anytype) !void {
2054 fn dumpShdrs(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void {
20482055 if (ctx.shdrs.len == 0) return;
20492056
2050 try writer.writeAll("section headers\n");
2057 try bw.writeAll("section headers\n");
20512058
20522059 for (ctx.shdrs, 0..) |shdr, shndx| {
2053 try writer.print("shdr {d}\n", .{shndx});
2054 try writer.print("name {s}\n", .{ctx.getSectionName(shndx)});
2055 try writer.print("type {s}\n", .{fmtShType(shdr.sh_type)});
2056 try writer.print("addr {x}\n", .{shdr.sh_addr});
2057 try writer.print("offset {x}\n", .{shdr.sh_offset});
2058 try writer.print("size {x}\n", .{shdr.sh_size});
2059 try writer.print("addralign {x}\n", .{shdr.sh_addralign});
2060 try bw.print("shdr {d}\n", .{shndx});
2061 try bw.print("name {s}\n", .{ctx.getSectionName(shndx)});
2062 try bw.print("type {s}\n", .{fmtShType(shdr.sh_type)});
2063 try bw.print("addr {x}\n", .{shdr.sh_addr});
2064 try bw.print("offset {x}\n", .{shdr.sh_offset});
2065 try bw.print("size {x}\n", .{shdr.sh_size});
2066 try bw.print("addralign {x}\n", .{shdr.sh_addralign});
20602067 // TODO dump formatted sh_flags
20612068 }
20622069 }
20632070
2064 fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, writer: anytype) !void {
2071 fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, bw: *std.io.BufferedWriter) !void {
20652072 const shdr = ctx.shdrs[shndx];
20662073 const strtab = ctx.getSectionContents(shdr.sh_link);
20672074 const data = ctx.getSectionContents(shndx);
20682075 const nentries = @divExact(data.len, @sizeOf(elf.Elf64_Dyn));
20692076 const entries = @as([*]align(1) const elf.Elf64_Dyn, @ptrCast(data.ptr))[0..nentries];
20702077
2071 try writer.writeAll(ElfDumper.dynamic_section_label ++ "\n");
2078 try bw.writeAll(ElfDumper.dynamic_section_label ++ "\n");
20722079
20732080 for (entries) |entry| {
20742081 const key = @as(u64, @bitCast(entry.d_tag));
......@@ -2109,7 +2116,7 @@ const ElfDumper = struct {
21092116 elf.DT_NULL => "NULL",
21102117 else => "UNKNOWN",
21112118 };
2112 try writer.print("{s}", .{key_str});
2119 try bw.print("{s}", .{key_str});
21132120
21142121 switch (key) {
21152122 elf.DT_NEEDED,
......@@ -2118,7 +2125,7 @@ const ElfDumper = struct {
21182125 elf.DT_RUNPATH,
21192126 => {
21202127 const name = getString(strtab, @intCast(value));
2121 try writer.print(" {s}", .{name});
2128 try bw.print(" {s}", .{name});
21222129 },
21232130
21242131 elf.DT_INIT_ARRAY,
......@@ -2136,7 +2143,7 @@ const ElfDumper = struct {
21362143 elf.DT_INIT,
21372144 elf.DT_FINI,
21382145 elf.DT_NULL,
2139 => try writer.print(" {x}", .{value}),
2146 => try bw.print(" {x}", .{value}),
21402147
21412148 elf.DT_INIT_ARRAYSZ,
21422149 elf.DT_FINI_ARRAYSZ,
......@@ -2146,77 +2153,77 @@ const ElfDumper = struct {
21462153 elf.DT_RELASZ,
21472154 elf.DT_RELAENT,
21482155 elf.DT_RELACOUNT,
2149 => try writer.print(" {d}", .{value}),
2156 => try bw.print(" {d}", .{value}),
21502157
2151 elf.DT_PLTREL => try writer.writeAll(switch (value) {
2158 elf.DT_PLTREL => try bw.writeAll(switch (value) {
21522159 elf.DT_REL => " REL",
21532160 elf.DT_RELA => " RELA",
21542161 else => " UNKNOWN",
21552162 }),
21562163
21572164 elf.DT_FLAGS => if (value > 0) {
2158 if (value & elf.DF_ORIGIN != 0) try writer.writeAll(" ORIGIN");
2159 if (value & elf.DF_SYMBOLIC != 0) try writer.writeAll(" SYMBOLIC");
2160 if (value & elf.DF_TEXTREL != 0) try writer.writeAll(" TEXTREL");
2161 if (value & elf.DF_BIND_NOW != 0) try writer.writeAll(" BIND_NOW");
2162 if (value & elf.DF_STATIC_TLS != 0) try writer.writeAll(" STATIC_TLS");
2165 if (value & elf.DF_ORIGIN != 0) try bw.writeAll(" ORIGIN");
2166 if (value & elf.DF_SYMBOLIC != 0) try bw.writeAll(" SYMBOLIC");
2167 if (value & elf.DF_TEXTREL != 0) try bw.writeAll(" TEXTREL");
2168 if (value & elf.DF_BIND_NOW != 0) try bw.writeAll(" BIND_NOW");
2169 if (value & elf.DF_STATIC_TLS != 0) try bw.writeAll(" STATIC_TLS");
21632170 },
21642171
21652172 elf.DT_FLAGS_1 => if (value > 0) {
2166 if (value & elf.DF_1_NOW != 0) try writer.writeAll(" NOW");
2167 if (value & elf.DF_1_GLOBAL != 0) try writer.writeAll(" GLOBAL");
2168 if (value & elf.DF_1_GROUP != 0) try writer.writeAll(" GROUP");
2169 if (value & elf.DF_1_NODELETE != 0) try writer.writeAll(" NODELETE");
2170 if (value & elf.DF_1_LOADFLTR != 0) try writer.writeAll(" LOADFLTR");
2171 if (value & elf.DF_1_INITFIRST != 0) try writer.writeAll(" INITFIRST");
2172 if (value & elf.DF_1_NOOPEN != 0) try writer.writeAll(" NOOPEN");
2173 if (value & elf.DF_1_ORIGIN != 0) try writer.writeAll(" ORIGIN");
2174 if (value & elf.DF_1_DIRECT != 0) try writer.writeAll(" DIRECT");
2175 if (value & elf.DF_1_TRANS != 0) try writer.writeAll(" TRANS");
2176 if (value & elf.DF_1_INTERPOSE != 0) try writer.writeAll(" INTERPOSE");
2177 if (value & elf.DF_1_NODEFLIB != 0) try writer.writeAll(" NODEFLIB");
2178 if (value & elf.DF_1_NODUMP != 0) try writer.writeAll(" NODUMP");
2179 if (value & elf.DF_1_CONFALT != 0) try writer.writeAll(" CONFALT");
2180 if (value & elf.DF_1_ENDFILTEE != 0) try writer.writeAll(" ENDFILTEE");
2181 if (value & elf.DF_1_DISPRELDNE != 0) try writer.writeAll(" DISPRELDNE");
2182 if (value & elf.DF_1_DISPRELPND != 0) try writer.writeAll(" DISPRELPND");
2183 if (value & elf.DF_1_NODIRECT != 0) try writer.writeAll(" NODIRECT");
2184 if (value & elf.DF_1_IGNMULDEF != 0) try writer.writeAll(" IGNMULDEF");
2185 if (value & elf.DF_1_NOKSYMS != 0) try writer.writeAll(" NOKSYMS");
2186 if (value & elf.DF_1_NOHDR != 0) try writer.writeAll(" NOHDR");
2187 if (value & elf.DF_1_EDITED != 0) try writer.writeAll(" EDITED");
2188 if (value & elf.DF_1_NORELOC != 0) try writer.writeAll(" NORELOC");
2189 if (value & elf.DF_1_SYMINTPOSE != 0) try writer.writeAll(" SYMINTPOSE");
2190 if (value & elf.DF_1_GLOBAUDIT != 0) try writer.writeAll(" GLOBAUDIT");
2191 if (value & elf.DF_1_SINGLETON != 0) try writer.writeAll(" SINGLETON");
2192 if (value & elf.DF_1_STUB != 0) try writer.writeAll(" STUB");
2193 if (value & elf.DF_1_PIE != 0) try writer.writeAll(" PIE");
2173 if (value & elf.DF_1_NOW != 0) try bw.writeAll(" NOW");
2174 if (value & elf.DF_1_GLOBAL != 0) try bw.writeAll(" GLOBAL");
2175 if (value & elf.DF_1_GROUP != 0) try bw.writeAll(" GROUP");
2176 if (value & elf.DF_1_NODELETE != 0) try bw.writeAll(" NODELETE");
2177 if (value & elf.DF_1_LOADFLTR != 0) try bw.writeAll(" LOADFLTR");
2178 if (value & elf.DF_1_INITFIRST != 0) try bw.writeAll(" INITFIRST");
2179 if (value & elf.DF_1_NOOPEN != 0) try bw.writeAll(" NOOPEN");
2180 if (value & elf.DF_1_ORIGIN != 0) try bw.writeAll(" ORIGIN");
2181 if (value & elf.DF_1_DIRECT != 0) try bw.writeAll(" DIRECT");
2182 if (value & elf.DF_1_TRANS != 0) try bw.writeAll(" TRANS");
2183 if (value & elf.DF_1_INTERPOSE != 0) try bw.writeAll(" INTERPOSE");
2184 if (value & elf.DF_1_NODEFLIB != 0) try bw.writeAll(" NODEFLIB");
2185 if (value & elf.DF_1_NODUMP != 0) try bw.writeAll(" NODUMP");
2186 if (value & elf.DF_1_CONFALT != 0) try bw.writeAll(" CONFALT");
2187 if (value & elf.DF_1_ENDFILTEE != 0) try bw.writeAll(" ENDFILTEE");
2188 if (value & elf.DF_1_DISPRELDNE != 0) try bw.writeAll(" DISPRELDNE");
2189 if (value & elf.DF_1_DISPRELPND != 0) try bw.writeAll(" DISPRELPND");
2190 if (value & elf.DF_1_NODIRECT != 0) try bw.writeAll(" NODIRECT");
2191 if (value & elf.DF_1_IGNMULDEF != 0) try bw.writeAll(" IGNMULDEF");
2192 if (value & elf.DF_1_NOKSYMS != 0) try bw.writeAll(" NOKSYMS");
2193 if (value & elf.DF_1_NOHDR != 0) try bw.writeAll(" NOHDR");
2194 if (value & elf.DF_1_EDITED != 0) try bw.writeAll(" EDITED");
2195 if (value & elf.DF_1_NORELOC != 0) try bw.writeAll(" NORELOC");
2196 if (value & elf.DF_1_SYMINTPOSE != 0) try bw.writeAll(" SYMINTPOSE");
2197 if (value & elf.DF_1_GLOBAUDIT != 0) try bw.writeAll(" GLOBAUDIT");
2198 if (value & elf.DF_1_SINGLETON != 0) try bw.writeAll(" SINGLETON");
2199 if (value & elf.DF_1_STUB != 0) try bw.writeAll(" STUB");
2200 if (value & elf.DF_1_PIE != 0) try bw.writeAll(" PIE");
21942201 },
21952202
2196 else => try writer.print(" {x}", .{value}),
2203 else => try bw.print(" {x}", .{value}),
21972204 }
2198 try writer.writeByte('\n');
2205 try bw.writeByte('\n');
21992206 }
22002207 }
22012208
2202 fn dumpSymtab(ctx: ObjectContext, comptime @"type": enum { symtab, dysymtab }, writer: anytype) !void {
2209 fn dumpSymtab(ctx: ObjectContext, comptime @"type": enum { symtab, dysymtab }, bw: *std.io.BufferedWriter) !void {
22032210 const symtab = switch (@"type") {
22042211 .symtab => ctx.symtab,
22052212 .dysymtab => ctx.dysymtab,
22062213 };
22072214
2208 try writer.writeAll(switch (@"type") {
2215 try bw.writeAll(switch (@"type") {
22092216 .symtab => symtab_label,
22102217 .dysymtab => dynamic_symtab_label,
22112218 } ++ "\n");
22122219
22132220 for (symtab.symbols, 0..) |sym, index| {
2214 try writer.print("{x} {x}", .{ sym.st_value, sym.st_size });
2221 try bw.print("{x} {x}", .{ sym.st_value, sym.st_size });
22152222
22162223 {
22172224 if (elf.SHN_LORESERVE <= sym.st_shndx and sym.st_shndx < elf.SHN_HIRESERVE) {
22182225 if (elf.SHN_LOPROC <= sym.st_shndx and sym.st_shndx < elf.SHN_HIPROC) {
2219 try writer.print(" LO+{d}", .{sym.st_shndx - elf.SHN_LOPROC});
2226 try bw.print(" LO+{d}", .{sym.st_shndx - elf.SHN_LOPROC});
22202227 } else {
22212228 const sym_ndx = switch (sym.st_shndx) {
22222229 elf.SHN_ABS => "ABS",
......@@ -2224,12 +2231,12 @@ const ElfDumper = struct {
22242231 elf.SHN_LIVEPATCH => "LIV",
22252232 else => "UNK",
22262233 };
2227 try writer.print(" {s}", .{sym_ndx});
2234 try bw.print(" {s}", .{sym_ndx});
22282235 }
22292236 } else if (sym.st_shndx == elf.SHN_UNDEF) {
2230 try writer.writeAll(" UND");
2237 try bw.writeAll(" UND");
22312238 } else {
2232 try writer.print(" {x}", .{sym.st_shndx});
2239 try bw.print(" {x}", .{sym.st_shndx});
22332240 }
22342241 }
22352242
......@@ -2246,12 +2253,12 @@ const ElfDumper = struct {
22462253 elf.STT_NUM => "NUM",
22472254 elf.STT_GNU_IFUNC => "IFUNC",
22482255 else => if (elf.STT_LOPROC <= tt and tt < elf.STT_HIPROC) {
2249 break :blk try writer.print(" LOPROC+{d}", .{tt - elf.STT_LOPROC});
2256 break :blk try bw.print(" LOPROC+{d}", .{tt - elf.STT_LOPROC});
22502257 } else if (elf.STT_LOOS <= tt and tt < elf.STT_HIOS) {
2251 break :blk try writer.print(" LOOS+{d}", .{tt - elf.STT_LOOS});
2258 break :blk try bw.print(" LOOS+{d}", .{tt - elf.STT_LOOS});
22522259 } else "UNK",
22532260 };
2254 try writer.print(" {s}", .{sym_type});
2261 try bw.print(" {s}", .{sym_type});
22552262 }
22562263
22572264 blk: {
......@@ -2262,28 +2269,28 @@ const ElfDumper = struct {
22622269 elf.STB_WEAK => "WEAK",
22632270 elf.STB_NUM => "NUM",
22642271 else => if (elf.STB_LOPROC <= bind and bind < elf.STB_HIPROC) {
2265 break :blk try writer.print(" LOPROC+{d}", .{bind - elf.STB_LOPROC});
2272 break :blk try bw.print(" LOPROC+{d}", .{bind - elf.STB_LOPROC});
22662273 } else if (elf.STB_LOOS <= bind and bind < elf.STB_HIOS) {
2267 break :blk try writer.print(" LOOS+{d}", .{bind - elf.STB_LOOS});
2274 break :blk try bw.print(" LOOS+{d}", .{bind - elf.STB_LOOS});
22682275 } else "UNKNOWN",
22692276 };
2270 try writer.print(" {s}", .{sym_bind});
2277 try bw.print(" {s}", .{sym_bind});
22712278 }
22722279
22732280 const sym_vis = @as(elf.STV, @enumFromInt(sym.st_other));
2274 try writer.print(" {s}", .{@tagName(sym_vis)});
2281 try bw.print(" {s}", .{@tagName(sym_vis)});
22752282
22762283 const sym_name = switch (sym.st_type()) {
22772284 elf.STT_SECTION => ctx.getSectionName(sym.st_shndx),
22782285 else => symtab.getName(index).?,
22792286 };
2280 try writer.print(" {s}\n", .{sym_name});
2287 try bw.print(" {s}\n", .{sym_name});
22812288 }
22822289 }
22832290
2284 fn dumpSection(ctx: ObjectContext, shndx: usize, writer: anytype) !void {
2291 fn dumpSection(ctx: ObjectContext, shndx: usize, bw: *std.io.BufferedWriter) !void {
22852292 const data = ctx.getSectionContents(shndx);
2286 try writer.print("{s}", .{data});
2293 try bw.print("{s}", .{data});
22872294 }
22882295
22892296 inline fn getSectionName(ctx: ObjectContext, shndx: usize) []const u8 {
......@@ -2333,7 +2340,7 @@ const ElfDumper = struct {
23332340 sh_type: u32,
23342341 comptime unused_fmt_string: []const u8,
23352342 options: std.fmt.FormatOptions,
2336 writer: anytype,
2343 bw: *std.io.BufferedWriter,
23372344 ) !void {
23382345 _ = unused_fmt_string;
23392346 _ = options;
......@@ -2362,14 +2369,14 @@ const ElfDumper = struct {
23622369 elf.SHT_GNU_VERNEED => "VERNEED",
23632370 elf.SHT_GNU_VERSYM => "VERSYM",
23642371 else => if (elf.SHT_LOOS <= sh_type and sh_type < elf.SHT_HIOS) {
2365 return try writer.print("LOOS+0x{x}", .{sh_type - elf.SHT_LOOS});
2372 return try bw.print("LOOS+0x{x}", .{sh_type - elf.SHT_LOOS});
23662373 } else if (elf.SHT_LOPROC <= sh_type and sh_type < elf.SHT_HIPROC) {
2367 return try writer.print("LOPROC+0x{x}", .{sh_type - elf.SHT_LOPROC});
2374 return try bw.print("LOPROC+0x{x}", .{sh_type - elf.SHT_LOPROC});
23682375 } else if (elf.SHT_LOUSER <= sh_type and sh_type < elf.SHT_HIUSER) {
2369 return try writer.print("LOUSER+0x{x}", .{sh_type - elf.SHT_LOUSER});
2376 return try bw.print("LOUSER+0x{x}", .{sh_type - elf.SHT_LOUSER});
23702377 } else "UNKNOWN",
23712378 };
2372 try writer.writeAll(name);
2379 try bw.writeAll(name);
23732380 }
23742381
23752382 fn fmtPhType(ph_type: u32) std.fmt.Formatter(formatPhType) {
......@@ -2380,7 +2387,7 @@ const ElfDumper = struct {
23802387 ph_type: u32,
23812388 comptime unused_fmt_string: []const u8,
23822389 options: std.fmt.FormatOptions,
2383 writer: anytype,
2390 bw: *std.io.BufferedWriter,
23842391 ) !void {
23852392 _ = unused_fmt_string;
23862393 _ = options;
......@@ -2398,12 +2405,12 @@ const ElfDumper = struct {
23982405 elf.PT_GNU_STACK => "GNU_STACK",
23992406 elf.PT_GNU_RELRO => "GNU_RELRO",
24002407 else => if (elf.PT_LOOS <= ph_type and ph_type < elf.PT_HIOS) {
2401 return try writer.print("LOOS+0x{x}", .{ph_type - elf.PT_LOOS});
2408 return try bw.print("LOOS+0x{x}", .{ph_type - elf.PT_LOOS});
24022409 } else if (elf.PT_LOPROC <= ph_type and ph_type < elf.PT_HIPROC) {
2403 return try writer.print("LOPROC+0x{x}", .{ph_type - elf.PT_LOPROC});
2410 return try bw.print("LOPROC+0x{x}", .{ph_type - elf.PT_LOPROC});
24042411 } else "UNKNOWN",
24052412 };
2406 try writer.writeAll(p_type);
2413 try bw.writeAll(p_type);
24072414 }
24082415};
24092416
......@@ -2463,12 +2470,12 @@ const WasmDumper = struct {
24632470 step: *Step,
24642471 section: std.wasm.Section,
24652472 data: []const u8,
2466 writer: anytype,
2473 bw: *std.io.BufferedWriter,
24672474 ) !void {
24682475 var fbs = std.io.fixedBufferStream(data);
24692476 const reader = fbs.reader();
24702477
2471 try writer.print(
2478 try bw.print(
24722479 \\Section {s}
24732480 \\size {d}
24742481 , .{ @tagName(section), data.len });
......@@ -2486,37 +2493,37 @@ const WasmDumper = struct {
24862493 .data,
24872494 => {
24882495 const entries = try std.leb.readUleb128(u32, reader);
2489 try writer.print("\nentries {d}\n", .{entries});
2490 try parseSection(step, section, data[fbs.pos..], entries, writer);
2496 try bw.print("\nentries {d}\n", .{entries});
2497 try parseSection(step, section, data[fbs.pos..], entries, bw);
24912498 },
24922499 .custom => {
24932500 const name_length = try std.leb.readUleb128(u32, reader);
24942501 const name = data[fbs.pos..][0..name_length];
24952502 fbs.pos += name_length;
2496 try writer.print("\nname {s}\n", .{name});
2503 try bw.print("\nname {s}\n", .{name});
24972504
24982505 if (mem.eql(u8, name, "name")) {
2499 try parseDumpNames(step, reader, writer, data);
2506 try parseDumpNames(step, reader, bw, data);
25002507 } else if (mem.eql(u8, name, "producers")) {
2501 try parseDumpProducers(reader, writer, data);
2508 try parseDumpProducers(reader, bw, data);
25022509 } else if (mem.eql(u8, name, "target_features")) {
2503 try parseDumpFeatures(reader, writer, data);
2510 try parseDumpFeatures(reader, bw, data);
25042511 }
25052512 // TODO: Implement parsing and dumping other custom sections (such as relocations)
25062513 },
25072514 .start => {
25082515 const start = try std.leb.readUleb128(u32, reader);
2509 try writer.print("\nstart {d}\n", .{start});
2516 try bw.print("\nstart {d}\n", .{start});
25102517 },
25112518 .data_count => {
25122519 const count = try std.leb.readUleb128(u32, reader);
2513 try writer.print("\ncount {d}\n", .{count});
2520 try bw.print("\ncount {d}\n", .{count});
25142521 },
25152522 else => {}, // skip unknown sections
25162523 }
25172524 }
25182525
2519 fn parseSection(step: *Step, section: std.wasm.Section, data: []const u8, entries: u32, writer: anytype) !void {
2526 fn parseSection(step: *Step, section: std.wasm.Section, data: []const u8, entries: u32, bw: *std.io.BufferedWriter) !void {
25202527 var fbs = std.io.fixedBufferStream(data);
25212528 const reader = fbs.reader();
25222529
......@@ -2529,15 +2536,15 @@ const WasmDumper = struct {
25292536 return step.fail("expected function type, found byte '{d}'", .{func_type});
25302537 }
25312538 const params = try std.leb.readUleb128(u32, reader);
2532 try writer.print("params {d}\n", .{params});
2539 try bw.print("params {d}\n", .{params});
25332540 var index: u32 = 0;
25342541 while (index < params) : (index += 1) {
2535 _ = try parseDumpType(step, std.wasm.Valtype, reader, writer);
2542 _ = try parseDumpType(step, std.wasm.Valtype, reader, bw);
25362543 } else index = 0;
25372544 const returns = try std.leb.readUleb128(u32, reader);
2538 try writer.print("returns {d}\n", .{returns});
2545 try bw.print("returns {d}\n", .{returns});
25392546 while (index < returns) : (index += 1) {
2540 _ = try parseDumpType(step, std.wasm.Valtype, reader, writer);
2547 _ = try parseDumpType(step, std.wasm.Valtype, reader, bw);
25412548 }
25422549 }
25432550 },
......@@ -2555,26 +2562,26 @@ const WasmDumper = struct {
25552562 return step.fail("invalid import kind", .{});
25562563 };
25572564
2558 try writer.print(
2565 try bw.print(
25592566 \\module {s}
25602567 \\name {s}
25612568 \\kind {s}
25622569 , .{ module_name, name, @tagName(kind) });
2563 try writer.writeByte('\n');
2570 try bw.writeByte('\n');
25642571 switch (kind) {
25652572 .function => {
2566 try writer.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)});
2573 try bw.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)});
25672574 },
25682575 .memory => {
2569 try parseDumpLimits(reader, writer);
2576 try parseDumpLimits(reader, bw);
25702577 },
25712578 .global => {
2572 _ = try parseDumpType(step, std.wasm.Valtype, reader, writer);
2573 try writer.print("mutable {}\n", .{0x01 == try std.leb.readUleb128(u32, reader)});
2579 _ = try parseDumpType(step, std.wasm.Valtype, reader, bw);
2580 try bw.print("mutable {}\n", .{0x01 == try std.leb.readUleb128(u32, reader)});
25742581 },
25752582 .table => {
2576 _ = try parseDumpType(step, std.wasm.RefType, reader, writer);
2577 try parseDumpLimits(reader, writer);
2583 _ = try parseDumpType(step, std.wasm.RefType, reader, bw);
2584 try parseDumpLimits(reader, bw);
25782585 },
25792586 }
25802587 }
......@@ -2582,28 +2589,28 @@ const WasmDumper = struct {
25822589 .function => {
25832590 var i: u32 = 0;
25842591 while (i < entries) : (i += 1) {
2585 try writer.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)});
2592 try bw.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)});
25862593 }
25872594 },
25882595 .table => {
25892596 var i: u32 = 0;
25902597 while (i < entries) : (i += 1) {
2591 _ = try parseDumpType(step, std.wasm.RefType, reader, writer);
2592 try parseDumpLimits(reader, writer);
2598 _ = try parseDumpType(step, std.wasm.RefType, reader, bw);
2599 try parseDumpLimits(reader, bw);
25932600 }
25942601 },
25952602 .memory => {
25962603 var i: u32 = 0;
25972604 while (i < entries) : (i += 1) {
2598 try parseDumpLimits(reader, writer);
2605 try parseDumpLimits(reader, bw);
25992606 }
26002607 },
26012608 .global => {
26022609 var i: u32 = 0;
26032610 while (i < entries) : (i += 1) {
2604 _ = try parseDumpType(step, std.wasm.Valtype, reader, writer);
2605 try writer.print("mutable {}\n", .{0x01 == try std.leb.readUleb128(u1, reader)});
2606 try parseDumpInit(step, reader, writer);
2611 _ = try parseDumpType(step, std.wasm.Valtype, reader, bw);
2612 try bw.print("mutable {}\n", .{0x01 == try std.leb.readUleb128(u1, reader)});
2613 try parseDumpInit(step, reader, bw);
26072614 }
26082615 },
26092616 .@"export" => {
......@@ -2617,25 +2624,25 @@ const WasmDumper = struct {
26172624 return step.fail("invalid export kind value '{d}'", .{kind_byte});
26182625 };
26192626 const index = try std.leb.readUleb128(u32, reader);
2620 try writer.print(
2627 try bw.print(
26212628 \\name {s}
26222629 \\kind {s}
26232630 \\index {d}
26242631 , .{ name, @tagName(kind), index });
2625 try writer.writeByte('\n');
2632 try bw.writeByte('\n');
26262633 }
26272634 },
26282635 .element => {
26292636 var i: u32 = 0;
26302637 while (i < entries) : (i += 1) {
2631 try writer.print("table index {d}\n", .{try std.leb.readUleb128(u32, reader)});
2632 try parseDumpInit(step, reader, writer);
2638 try bw.print("table index {d}\n", .{try std.leb.readUleb128(u32, reader)});
2639 try parseDumpInit(step, reader, bw);
26332640
26342641 const function_indexes = try std.leb.readUleb128(u32, reader);
26352642 var function_index: u32 = 0;
2636 try writer.print("indexes {d}\n", .{function_indexes});
2643 try bw.print("indexes {d}\n", .{function_indexes});
26372644 while (function_index < function_indexes) : (function_index += 1) {
2638 try writer.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)});
2645 try bw.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)});
26392646 }
26402647 }
26412648 },
......@@ -2648,13 +2655,13 @@ const WasmDumper = struct {
26482655 try std.leb.readUleb128(u32, reader)
26492656 else
26502657 0;
2651 try writer.print("memory index 0x{x}\n", .{index});
2658 try bw.print("memory index 0x{x}\n", .{index});
26522659 if (flags == 0) {
2653 try parseDumpInit(step, reader, writer);
2660 try parseDumpInit(step, reader, bw);
26542661 }
26552662
26562663 const size = try std.leb.readUleb128(u32, reader);
2657 try writer.print("size {d}\n", .{size});
2664 try bw.print("size {d}\n", .{size});
26582665 try reader.skipBytes(size, .{}); // we do not care about the content of the segments
26592666 }
26602667 },
......@@ -2662,36 +2669,36 @@ const WasmDumper = struct {
26622669 }
26632670 }
26642671
2665 fn parseDumpType(step: *Step, comptime E: type, reader: anytype, writer: anytype) !E {
2672 fn parseDumpType(step: *Step, comptime E: type, reader: anytype, bw: *std.io.BufferedWriter) !E {
26662673 const byte = try reader.readByte();
26672674 const tag = std.enums.fromInt(E, byte) orelse {
26682675 return step.fail("invalid wasm type value '{d}'", .{byte});
26692676 };
2670 try writer.print("type {s}\n", .{@tagName(tag)});
2677 try bw.print("type {s}\n", .{@tagName(tag)});
26712678 return tag;
26722679 }
26732680
2674 fn parseDumpLimits(reader: anytype, writer: anytype) !void {
2681 fn parseDumpLimits(reader: anytype, bw: *std.io.BufferedWriter) !void {
26752682 const flags = try std.leb.readUleb128(u8, reader);
26762683 const min = try std.leb.readUleb128(u32, reader);
26772684
2678 try writer.print("min {x}\n", .{min});
2685 try bw.print("min {x}\n", .{min});
26792686 if (flags != 0) {
2680 try writer.print("max {x}\n", .{try std.leb.readUleb128(u32, reader)});
2687 try bw.print("max {x}\n", .{try std.leb.readUleb128(u32, reader)});
26812688 }
26822689 }
26832690
2684 fn parseDumpInit(step: *Step, reader: anytype, writer: anytype) !void {
2691 fn parseDumpInit(step: *Step, reader: anytype, bw: *std.io.BufferedWriter) !void {
26852692 const byte = try reader.readByte();
26862693 const opcode = std.enums.fromInt(std.wasm.Opcode, byte) orelse {
26872694 return step.fail("invalid wasm opcode '{d}'", .{byte});
26882695 };
26892696 switch (opcode) {
2690 .i32_const => try writer.print("i32.const {x}\n", .{try std.leb.readIleb128(i32, reader)}),
2691 .i64_const => try writer.print("i64.const {x}\n", .{try std.leb.readIleb128(i64, reader)}),
2692 .f32_const => try writer.print("f32.const {x}\n", .{@as(f32, @bitCast(try reader.readInt(u32, .little)))}),
2693 .f64_const => try writer.print("f64.const {x}\n", .{@as(f64, @bitCast(try reader.readInt(u64, .little)))}),
2694 .global_get => try writer.print("global.get {x}\n", .{try std.leb.readUleb128(u32, reader)}),
2697 .i32_const => try bw.print("i32.const {x}\n", .{try std.leb.readIleb128(i32, reader)}),
2698 .i64_const => try bw.print("i64.const {x}\n", .{try std.leb.readIleb128(i64, reader)}),
2699 .f32_const => try bw.print("f32.const {x}\n", .{@as(f32, @bitCast(try reader.readInt(u32, .little)))}),
2700 .f64_const => try bw.print("f64.const {x}\n", .{@as(f64, @bitCast(try reader.readInt(u64, .little)))}),
2701 .global_get => try bw.print("global.get {x}\n", .{try std.leb.readUleb128(u32, reader)}),
26952702 else => unreachable,
26962703 }
26972704 const end_opcode = try std.leb.readUleb128(u8, reader);
......@@ -2701,9 +2708,9 @@ const WasmDumper = struct {
27012708 }
27022709
27032710 /// https://webassembly.github.io/spec/core/appendix/custom.html
2704 fn parseDumpNames(step: *Step, reader: anytype, writer: anytype, data: []const u8) !void {
2711 fn parseDumpNames(step: *Step, reader: anytype, bw: *std.io.BufferedWriter, data: []const u8) !void {
27052712 while (reader.context.pos < data.len) {
2706 switch (try parseDumpType(step, std.wasm.NameSubsection, reader, writer)) {
2713 switch (try parseDumpType(step, std.wasm.NameSubsection, reader, bw)) {
27072714 // The module name subsection ... consists of a single name
27082715 // that is assigned to the module itself.
27092716 .module => {
......@@ -2711,7 +2718,7 @@ const WasmDumper = struct {
27112718 const name_len = try std.leb.readUleb128(u32, reader);
27122719 if (size != name_len + 1) return error.BadSubsectionSize;
27132720 if (reader.context.pos + name_len > data.len) return error.UnexpectedEndOfStream;
2714 try writer.print("name {s}\n", .{data[reader.context.pos..][0..name_len]});
2721 try bw.print("name {s}\n", .{data[reader.context.pos..][0..name_len]});
27152722 reader.context.pos += name_len;
27162723 },
27172724
......@@ -2720,7 +2727,7 @@ const WasmDumper = struct {
27202727 .function, .global, .data_segment => {
27212728 const size = try std.leb.readUleb128(u32, reader);
27222729 const entries = try std.leb.readUleb128(u32, reader);
2723 try writer.print(
2730 try bw.print(
27242731 \\size {d}
27252732 \\names {d}
27262733 \\
......@@ -2732,7 +2739,7 @@ const WasmDumper = struct {
27322739 const name = data[reader.context.pos..][0..name_len];
27332740 reader.context.pos += name.len;
27342741
2735 try writer.print(
2742 try bw.print(
27362743 \\index {d}
27372744 \\name {s}
27382745 \\
......@@ -2752,9 +2759,9 @@ const WasmDumper = struct {
27522759 }
27532760 }
27542761
2755 fn parseDumpProducers(reader: anytype, writer: anytype, data: []const u8) !void {
2762 fn parseDumpProducers(reader: anytype, bw: *std.io.BufferedWriter, data: []const u8) !void {
27562763 const field_count = try std.leb.readUleb128(u32, reader);
2757 try writer.print("fields {d}\n", .{field_count});
2764 try bw.print("fields {d}\n", .{field_count});
27582765 var current_field: u32 = 0;
27592766 while (current_field < field_count) : (current_field += 1) {
27602767 const field_name_length = try std.leb.readUleb128(u32, reader);
......@@ -2762,11 +2769,11 @@ const WasmDumper = struct {
27622769 reader.context.pos += field_name_length;
27632770
27642771 const value_count = try std.leb.readUleb128(u32, reader);
2765 try writer.print(
2772 try bw.print(
27662773 \\field_name {s}
27672774 \\values {d}
27682775 , .{ field_name, value_count });
2769 try writer.writeByte('\n');
2776 try bw.writeByte('\n');
27702777 var current_value: u32 = 0;
27712778 while (current_value < value_count) : (current_value += 1) {
27722779 const value_length = try std.leb.readUleb128(u32, reader);
......@@ -2777,18 +2784,18 @@ const WasmDumper = struct {
27772784 const version = data[reader.context.pos..][0..version_length];
27782785 reader.context.pos += version_length;
27792786
2780 try writer.print(
2787 try bw.print(
27812788 \\value_name {s}
27822789 \\version {s}
27832790 , .{ value, version });
2784 try writer.writeByte('\n');
2791 try bw.writeByte('\n');
27852792 }
27862793 }
27872794 }
27882795
2789 fn parseDumpFeatures(reader: anytype, writer: anytype, data: []const u8) !void {
2796 fn parseDumpFeatures(reader: anytype, bw: *std.io.BufferedWriter, data: []const u8) !void {
27902797 const feature_count = try std.leb.readUleb128(u32, reader);
2791 try writer.print("features {d}\n", .{feature_count});
2798 try bw.print("features {d}\n", .{feature_count});
27922799
27932800 var index: u32 = 0;
27942801 while (index < feature_count) : (index += 1) {
......@@ -2797,7 +2804,7 @@ const WasmDumper = struct {
27972804 const feature_name = data[reader.context.pos..][0..name_length];
27982805 reader.context.pos += name_length;
27992806
2800 try writer.print("{c} {s}\n", .{ prefix_byte, feature_name });
2807 try bw.print("{c} {s}\n", .{ prefix_byte, feature_name });
28012808 }
28022809 }
28032810};
lib/std/Build/Step/Compile.zig+5-5
......@@ -1769,12 +1769,12 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
17691769 for (arg, 0..) |c, arg_idx| {
17701770 if (c == '\\' or c == '"') {
17711771 // Slow path for arguments that need to be escaped. We'll need to allocate and copy
1772 var escaped = try ArrayList(u8).initCapacity(arena, arg.len + 1);
1773 const writer = escaped.writer();
1774 try writer.writeAll(arg[0..arg_idx]);
1772 var escaped: std.ArrayListUnmanaged(u8) = .empty;
1773 try escaped.ensureTotalCapacityPrecise(arena, arg.len + 1);
1774 try escaped.appendSlice(arena, arg[0..arg_idx]);
17751775 for (arg[arg_idx..]) |to_escape| {
1776 if (to_escape == '\\' or to_escape == '"') try writer.writeByte('\\');
1777 try writer.writeByte(to_escape);
1776 if (to_escape == '\\' or to_escape == '"') try escaped.append(arena, '\\');
1777 try escaped.append(arena, to_escape);
17781778 }
17791779 escaped_args.appendAssumeCapacity(escaped.items);
17801780 continue :arg_blk;
lib/std/Build/Step/ConfigHeader.zig+3-3
......@@ -569,14 +569,14 @@ fn renderValueC(output: *std.ArrayList(u8), name: []const u8, value: Value) !voi
569569 try output.appendSlice(if (b) " 1\n" else " 0\n");
570570 },
571571 .int => |i| {
572 try output.writer().print("#define {s} {d}\n", .{ name, i });
572 try output.print("#define {s} {d}\n", .{ name, i });
573573 },
574574 .ident => |ident| {
575 try output.writer().print("#define {s} {s}\n", .{ name, ident });
575 try output.print("#define {s} {s}\n", .{ name, ident });
576576 },
577577 .string => |string| {
578578 // TODO: use C-specific escaping instead of zig string literals
579 try output.writer().print("#define {s} \"{}\"\n", .{ name, std.zig.fmtEscapes(string) });
579 try output.print("#define {s} \"{}\"\n", .{ name, std.zig.fmtEscapes(string) });
580580 },
581581 }
582582}
lib/std/Build/Step/Options.zig+125-103
......@@ -12,9 +12,9 @@ pub const base_id: Step.Id = .options;
1212step: Step,
1313generated_file: GeneratedFile,
1414
15contents: std.ArrayList(u8),
16args: std.ArrayList(Arg),
17encountered_types: std.StringHashMap(void),
15contents: std.ArrayListUnmanaged(u8),
16args: std.ArrayListUnmanaged(Arg),
17encountered_types: std.StringHashMapUnmanaged(void),
1818
1919pub fn create(owner: *std.Build) *Options {
2020 const options = owner.allocator.create(Options) catch @panic("OOM");
......@@ -26,9 +26,9 @@ pub fn create(owner: *std.Build) *Options {
2626 .makeFn = make,
2727 }),
2828 .generated_file = undefined,
29 .contents = std.ArrayList(u8).init(owner.allocator),
30 .args = std.ArrayList(Arg).init(owner.allocator),
31 .encountered_types = std.StringHashMap(void).init(owner.allocator),
29 .contents = .empty,
30 .args = .empty,
31 .encountered_types = .empty,
3232 };
3333 options.generated_file = .{ .step = &options.step };
3434
......@@ -40,110 +40,117 @@ pub fn addOption(options: *Options, comptime T: type, name: []const u8, value: T
4040}
4141
4242fn addOptionFallible(options: *Options, comptime T: type, name: []const u8, value: T) !void {
43 const out = options.contents.writer();
44 try printType(options, out, T, value, 0, name);
43 try printType(options, &options.contents, T, value, 0, name);
4544}
4645
47fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent: u8, name: ?[]const u8) !void {
46fn printType(
47 options: *Options,
48 out: *std.ArrayListUnmanaged(u8),
49 comptime T: type,
50 value: T,
51 indent: u8,
52 name: ?[]const u8,
53) !void {
54 const gpa = options.step.owner.allocator;
4855 switch (T) {
4956 []const []const u8 => {
5057 if (name) |payload| {
51 try out.print("pub const {}: []const []const u8 = ", .{std.zig.fmtId(payload)});
58 try out.print(gpa, "pub const {}: []const []const u8 = ", .{std.zig.fmtId(payload)});
5259 }
5360
54 try out.writeAll("&[_][]const u8{\n");
61 try out.appendSlice(gpa, "&[_][]const u8{\n");
5562
5663 for (value) |slice| {
57 try out.writeByteNTimes(' ', indent);
58 try out.print(" \"{}\",\n", .{std.zig.fmtEscapes(slice)});
64 try out.appendNTimes(gpa, ' ', indent);
65 try out.print(gpa, " \"{}\",\n", .{std.zig.fmtEscapes(slice)});
5966 }
6067
6168 if (name != null) {
62 try out.writeAll("};\n");
69 try out.appendSlice(gpa, "};\n");
6370 } else {
64 try out.writeAll("},\n");
71 try out.appendSlice(gpa, "},\n");
6572 }
6673
6774 return;
6875 },
6976 []const u8 => {
7077 if (name) |some| {
71 try out.print("pub const {}: []const u8 = \"{}\";", .{ std.zig.fmtId(some), std.zig.fmtEscapes(value) });
78 try out.print(gpa, "pub const {}: []const u8 = \"{}\";", .{ std.zig.fmtId(some), std.zig.fmtEscapes(value) });
7279 } else {
73 try out.print("\"{}\",", .{std.zig.fmtEscapes(value)});
80 try out.print(gpa, "\"{}\",", .{std.zig.fmtEscapes(value)});
7481 }
75 return out.writeAll("\n");
82 return out.appendSlice(gpa, "\n");
7683 },
7784 [:0]const u8 => {
7885 if (name) |some| {
79 try out.print("pub const {}: [:0]const u8 = \"{}\";", .{ std.zig.fmtId(some), std.zig.fmtEscapes(value) });
86 try out.print(gpa, "pub const {}: [:0]const u8 = \"{}\";", .{ std.zig.fmtId(some), std.zig.fmtEscapes(value) });
8087 } else {
81 try out.print("\"{}\",", .{std.zig.fmtEscapes(value)});
88 try out.print(gpa, "\"{}\",", .{std.zig.fmtEscapes(value)});
8289 }
83 return out.writeAll("\n");
90 return out.appendSlice(gpa, "\n");
8491 },
8592 ?[]const u8 => {
8693 if (name) |some| {
87 try out.print("pub const {}: ?[]const u8 = ", .{std.zig.fmtId(some)});
94 try out.print(gpa, "pub const {}: ?[]const u8 = ", .{std.zig.fmtId(some)});
8895 }
8996
9097 if (value) |payload| {
91 try out.print("\"{}\"", .{std.zig.fmtEscapes(payload)});
98 try out.print(gpa, "\"{}\"", .{std.zig.fmtEscapes(payload)});
9299 } else {
93 try out.writeAll("null");
100 try out.appendSlice(gpa, "null");
94101 }
95102
96103 if (name != null) {
97 try out.writeAll(";\n");
104 try out.appendSlice(gpa, ";\n");
98105 } else {
99 try out.writeAll(",\n");
106 try out.appendSlice(gpa, ",\n");
100107 }
101108 return;
102109 },
103110 ?[:0]const u8 => {
104111 if (name) |some| {
105 try out.print("pub const {}: ?[:0]const u8 = ", .{std.zig.fmtId(some)});
112 try out.print(gpa, "pub const {}: ?[:0]const u8 = ", .{std.zig.fmtId(some)});
106113 }
107114
108115 if (value) |payload| {
109 try out.print("\"{}\"", .{std.zig.fmtEscapes(payload)});
116 try out.print(gpa, "\"{}\"", .{std.zig.fmtEscapes(payload)});
110117 } else {
111 try out.writeAll("null");
118 try out.appendSlice(gpa, "null");
112119 }
113120
114121 if (name != null) {
115 try out.writeAll(";\n");
122 try out.appendSlice(gpa, ";\n");
116123 } else {
117 try out.writeAll(",\n");
124 try out.appendSlice(gpa, ",\n");
118125 }
119126 return;
120127 },
121128 std.SemanticVersion => {
122129 if (name) |some| {
123 try out.print("pub const {}: @import(\"std\").SemanticVersion = ", .{std.zig.fmtId(some)});
130 try out.print(gpa, "pub const {}: @import(\"std\").SemanticVersion = ", .{std.zig.fmtId(some)});
124131 }
125132
126 try out.writeAll(".{\n");
127 try out.writeByteNTimes(' ', indent);
128 try out.print(" .major = {d},\n", .{value.major});
129 try out.writeByteNTimes(' ', indent);
130 try out.print(" .minor = {d},\n", .{value.minor});
131 try out.writeByteNTimes(' ', indent);
132 try out.print(" .patch = {d},\n", .{value.patch});
133 try out.appendSlice(gpa, ".{\n");
134 try out.appendNTimes(gpa, ' ', indent);
135 try out.print(gpa, " .major = {d},\n", .{value.major});
136 try out.appendNTimes(gpa, ' ', indent);
137 try out.print(gpa, " .minor = {d},\n", .{value.minor});
138 try out.appendNTimes(gpa, ' ', indent);
139 try out.print(gpa, " .patch = {d},\n", .{value.patch});
133140
134141 if (value.pre) |some| {
135 try out.writeByteNTimes(' ', indent);
136 try out.print(" .pre = \"{}\",\n", .{std.zig.fmtEscapes(some)});
142 try out.appendNTimes(gpa, ' ', indent);
143 try out.print(gpa, " .pre = \"{}\",\n", .{std.zig.fmtEscapes(some)});
137144 }
138145 if (value.build) |some| {
139 try out.writeByteNTimes(' ', indent);
140 try out.print(" .build = \"{}\",\n", .{std.zig.fmtEscapes(some)});
146 try out.appendNTimes(gpa, ' ', indent);
147 try out.print(gpa, " .build = \"{}\",\n", .{std.zig.fmtEscapes(some)});
141148 }
142149
143150 if (name != null) {
144 try out.writeAll("};\n");
151 try out.appendSlice(gpa, "};\n");
145152 } else {
146 try out.writeAll("},\n");
153 try out.appendSlice(gpa, "},\n");
147154 }
148155 return;
149156 },
......@@ -153,21 +160,21 @@ fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent
153160 switch (@typeInfo(T)) {
154161 .array => {
155162 if (name) |some| {
156 try out.print("pub const {}: {s} = ", .{ std.zig.fmtId(some), @typeName(T) });
163 try out.print(gpa, "pub const {}: {s} = ", .{ std.zig.fmtId(some), @typeName(T) });
157164 }
158165
159 try out.print("{s} {{\n", .{@typeName(T)});
166 try out.print(gpa, "{s} {{\n", .{@typeName(T)});
160167 for (value) |item| {
161 try out.writeByteNTimes(' ', indent + 4);
168 try out.appendNTimes(gpa, ' ', indent + 4);
162169 try printType(options, out, @TypeOf(item), item, indent + 4, null);
163170 }
164 try out.writeByteNTimes(' ', indent);
165 try out.writeAll("}");
171 try out.appendNTimes(gpa, ' ', indent);
172 try out.appendSlice(gpa, "}");
166173
167174 if (name != null) {
168 try out.writeAll(";\n");
175 try out.appendSlice(gpa, ";\n");
169176 } else {
170 try out.writeAll(",\n");
177 try out.appendSlice(gpa, ",\n");
171178 }
172179 return;
173180 },
......@@ -177,27 +184,27 @@ fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent
177184 }
178185
179186 if (name) |some| {
180 try out.print("pub const {}: {s} = ", .{ std.zig.fmtId(some), @typeName(T) });
187 try out.print(gpa, "pub const {}: {s} = ", .{ std.zig.fmtId(some), @typeName(T) });
181188 }
182189
183 try out.print("&[_]{s} {{\n", .{@typeName(p.child)});
190 try out.print(gpa, "&[_]{s} {{\n", .{@typeName(p.child)});
184191 for (value) |item| {
185 try out.writeByteNTimes(' ', indent + 4);
192 try out.appendNTimes(gpa, ' ', indent + 4);
186193 try printType(options, out, @TypeOf(item), item, indent + 4, null);
187194 }
188 try out.writeByteNTimes(' ', indent);
189 try out.writeAll("}");
195 try out.appendNTimes(gpa, ' ', indent);
196 try out.appendSlice(gpa, "}");
190197
191198 if (name != null) {
192 try out.writeAll(";\n");
199 try out.appendSlice(gpa, ";\n");
193200 } else {
194 try out.writeAll(",\n");
201 try out.appendSlice(gpa, ",\n");
195202 }
196203 return;
197204 },
198205 .optional => {
199206 if (name) |some| {
200 try out.print("pub const {}: {s} = ", .{ std.zig.fmtId(some), @typeName(T) });
207 try out.print(gpa, "pub const {}: {s} = ", .{ std.zig.fmtId(some), @typeName(T) });
201208 }
202209
203210 if (value) |inner| {
......@@ -206,13 +213,13 @@ fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent
206213 _ = options.contents.pop();
207214 _ = options.contents.pop();
208215 } else {
209 try out.writeAll("null");
216 try out.appendSlice(gpa, "null");
210217 }
211218
212219 if (name != null) {
213 try out.writeAll(";\n");
220 try out.appendSlice(gpa, ";\n");
214221 } else {
215 try out.writeAll(",\n");
222 try out.appendSlice(gpa, ",\n");
216223 }
217224 return;
218225 },
......@@ -224,9 +231,9 @@ fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent
224231 .null,
225232 => {
226233 if (name) |some| {
227 try out.print("pub const {}: {s} = {any};\n", .{ std.zig.fmtId(some), @typeName(T), value });
234 try out.print(gpa, "pub const {}: {s} = {any};\n", .{ std.zig.fmtId(some), @typeName(T), value });
228235 } else {
229 try out.print("{any},\n", .{value});
236 try out.print(gpa, "{any},\n", .{value});
230237 }
231238 return;
232239 },
......@@ -234,7 +241,7 @@ fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent
234241 try printEnum(options, out, T, info, indent);
235242
236243 if (name) |some| {
237 try out.print("pub const {}: {} = .{p_};\n", .{
244 try out.print(gpa, "pub const {}: {} = .{p_};\n", .{
238245 std.zig.fmtId(some),
239246 std.zig.fmtId(@typeName(T)),
240247 std.zig.fmtId(@tagName(value)),
......@@ -246,7 +253,7 @@ fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent
246253 try printStruct(options, out, T, info, indent);
247254
248255 if (name) |some| {
249 try out.print("pub const {}: {} = ", .{
256 try out.print(gpa, "pub const {}: {} = ", .{
250257 std.zig.fmtId(some),
251258 std.zig.fmtId(@typeName(T)),
252259 });
......@@ -258,7 +265,7 @@ fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent
258265 }
259266}
260267
261fn printUserDefinedType(options: *Options, out: anytype, comptime T: type, indent: u8) !void {
268fn printUserDefinedType(options: *Options, out: *std.ArrayListUnmanaged(u8), comptime T: type, indent: u8) !void {
262269 switch (@typeInfo(T)) {
263270 .@"enum" => |info| {
264271 return try printEnum(options, out, T, info, indent);
......@@ -270,94 +277,109 @@ fn printUserDefinedType(options: *Options, out: anytype, comptime T: type, inden
270277 }
271278}
272279
273fn printEnum(options: *Options, out: anytype, comptime T: type, comptime val: std.builtin.Type.Enum, indent: u8) !void {
274 const gop = try options.encountered_types.getOrPut(@typeName(T));
280fn printEnum(
281 options: *Options,
282 out: *std.ArrayListUnmanaged(u8),
283 comptime T: type,
284 comptime val: std.builtin.Type.Enum,
285 indent: u8,
286) !void {
287 const gpa = options.step.owner.allocator;
288 const gop = try options.encountered_types.getOrPut(gpa, @typeName(T));
275289 if (gop.found_existing) return;
276290
277 try out.writeByteNTimes(' ', indent);
278 try out.print("pub const {} = enum ({s}) {{\n", .{ std.zig.fmtId(@typeName(T)), @typeName(val.tag_type) });
291 try out.appendNTimes(gpa, ' ', indent);
292 try out.print(gpa, "pub const {} = enum ({s}) {{\n", .{ std.zig.fmtId(@typeName(T)), @typeName(val.tag_type) });
279293
280294 inline for (val.fields) |field| {
281 try out.writeByteNTimes(' ', indent);
282 try out.print(" {p} = {d},\n", .{ std.zig.fmtId(field.name), field.value });
295 try out.appendNTimes(gpa, ' ', indent);
296 try out.print(gpa, " {p} = {d},\n", .{ std.zig.fmtId(field.name), field.value });
283297 }
284298
285299 if (!val.is_exhaustive) {
286 try out.writeByteNTimes(' ', indent);
287 try out.writeAll(" _,\n");
300 try out.appendNTimes(gpa, ' ', indent);
301 try out.appendSlice(gpa, " _,\n");
288302 }
289303
290 try out.writeByteNTimes(' ', indent);
291 try out.writeAll("};\n");
304 try out.appendNTimes(gpa, ' ', indent);
305 try out.appendSlice(gpa, "};\n");
292306}
293307
294fn printStruct(options: *Options, out: anytype, comptime T: type, comptime val: std.builtin.Type.Struct, indent: u8) !void {
295 const gop = try options.encountered_types.getOrPut(@typeName(T));
308fn printStruct(options: *Options, out: *std.ArrayListUnmanaged(u8), comptime T: type, comptime val: std.builtin.Type.Struct, indent: u8) !void {
309 const gpa = options.step.owner.allocator;
310 const gop = try options.encountered_types.getOrPut(gpa, @typeName(T));
296311 if (gop.found_existing) return;
297312
298 try out.writeByteNTimes(' ', indent);
299 try out.print("pub const {} = ", .{std.zig.fmtId(@typeName(T))});
313 try out.appendNTimes(gpa, ' ', indent);
314 try out.print(gpa, "pub const {} = ", .{std.zig.fmtId(@typeName(T))});
300315
301316 switch (val.layout) {
302 .@"extern" => try out.writeAll("extern struct"),
303 .@"packed" => try out.writeAll("packed struct"),
304 else => try out.writeAll("struct"),
317 .@"extern" => try out.appendSlice(gpa, "extern struct"),
318 .@"packed" => try out.appendSlice(gpa, "packed struct"),
319 else => try out.appendSlice(gpa, "struct"),
305320 }
306321
307 try out.writeAll(" {\n");
322 try out.appendSlice(gpa, " {\n");
308323
309324 inline for (val.fields) |field| {
310 try out.writeByteNTimes(' ', indent);
325 try out.appendNTimes(gpa, ' ', indent);
311326
312327 const type_name = @typeName(field.type);
313328
314329 // If the type name doesn't contains a '.' the type is from zig builtins.
315330 if (std.mem.containsAtLeast(u8, type_name, 1, ".")) {
316 try out.print(" {p_}: {}", .{ std.zig.fmtId(field.name), std.zig.fmtId(type_name) });
331 try out.print(gpa, " {p_}: {}", .{ std.zig.fmtId(field.name), std.zig.fmtId(type_name) });
317332 } else {
318 try out.print(" {p_}: {s}", .{ std.zig.fmtId(field.name), type_name });
333 try out.print(gpa, " {p_}: {s}", .{ std.zig.fmtId(field.name), type_name });
319334 }
320335
321336 if (field.defaultValue()) |default_value| {
322 try out.writeAll(" = ");
337 try out.appendSlice(gpa, " = ");
323338 switch (@typeInfo(@TypeOf(default_value))) {
324 .@"enum" => try out.print(".{s},\n", .{@tagName(default_value)}),
339 .@"enum" => try out.print(gpa, ".{s},\n", .{@tagName(default_value)}),
325340 .@"struct" => |info| {
326341 try printStructValue(options, out, info, default_value, indent + 4);
327342 },
328343 else => try printType(options, out, @TypeOf(default_value), default_value, indent, null),
329344 }
330345 } else {
331 try out.writeAll(",\n");
346 try out.appendSlice(gpa, ",\n");
332347 }
333348 }
334349
335350 // TODO: write declarations
336351
337 try out.writeByteNTimes(' ', indent);
338 try out.writeAll("};\n");
352 try out.appendNTimes(gpa, ' ', indent);
353 try out.appendSlice(gpa, "};\n");
339354
340355 inline for (val.fields) |field| {
341356 try printUserDefinedType(options, out, field.type, 0);
342357 }
343358}
344359
345fn printStructValue(options: *Options, out: anytype, comptime struct_val: std.builtin.Type.Struct, val: anytype, indent: u8) !void {
346 try out.writeAll(".{\n");
360fn printStructValue(
361 options: *Options,
362 out: *std.ArrayListUnmanaged(u8),
363 comptime struct_val: std.builtin.Type.Struct,
364 val: anytype,
365 indent: u8,
366) !void {
367 const gpa = options.step.owner.allocator;
368 try out.appendSlice(gpa, ".{\n");
347369
348370 if (struct_val.is_tuple) {
349371 inline for (struct_val.fields) |field| {
350 try out.writeByteNTimes(' ', indent);
372 try out.appendNTimes(gpa, ' ', indent);
351373 try printType(options, out, @TypeOf(@field(val, field.name)), @field(val, field.name), indent, null);
352374 }
353375 } else {
354376 inline for (struct_val.fields) |field| {
355 try out.writeByteNTimes(' ', indent);
356 try out.print(" .{p_} = ", .{std.zig.fmtId(field.name)});
377 try out.appendNTimes(gpa, ' ', indent);
378 try out.print(gpa, " .{p_} = ", .{std.zig.fmtId(field.name)});
357379
358380 const field_name = @field(val, field.name);
359381 switch (@typeInfo(@TypeOf(field_name))) {
360 .@"enum" => try out.print(".{s},\n", .{@tagName(field_name)}),
382 .@"enum" => try out.print(gpa, ".{s},\n", .{@tagName(field_name)}),
361383 .@"struct" => |struct_info| {
362384 try printStructValue(options, out, struct_info, field_name, indent + 4);
363385 },
......@@ -367,10 +389,10 @@ fn printStructValue(options: *Options, out: anytype, comptime struct_val: std.bu
367389 }
368390
369391 if (indent == 0) {
370 try out.writeAll("};\n");
392 try out.appendSlice(gpa, "};\n");
371393 } else {
372 try out.writeByteNTimes(' ', indent);
373 try out.writeAll("},\n");
394 try out.appendNTimes(gpa, ' ', indent);
395 try out.appendSlice(gpa, "},\n");
374396 }
375397}
376398
lib/std/Target/Query.zig+20-21
......@@ -394,25 +394,24 @@ pub fn canDetectLibC(self: Query) bool {
394394
395395/// Formats a version with the patch component omitted if it is zero,
396396/// unlike SemanticVersion.format which formats all its version components regardless.
397fn formatVersion(version: SemanticVersion, writer: anytype) !void {
397fn formatVersion(version: SemanticVersion, gpa: Allocator, list: *std.ArrayListUnmanaged(u8)) !void {
398398 if (version.patch == 0) {
399 try writer.print("{d}.{d}", .{ version.major, version.minor });
399 try list.print(gpa, "{d}.{d}", .{ version.major, version.minor });
400400 } else {
401 try writer.print("{d}.{d}.{d}", .{ version.major, version.minor, version.patch });
401 try list.print(gpa, "{d}.{d}.{d}", .{ version.major, version.minor, version.patch });
402402 }
403403}
404404
405pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 {
406 if (self.isNativeTriple())
407 return allocator.dupe(u8, "native");
405pub fn zigTriple(self: Query, gpa: Allocator) Allocator.Error![]u8 {
406 if (self.isNativeTriple()) return gpa.dupe(u8, "native");
408407
409408 const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
410409 const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
411410
412 var result = std.ArrayList(u8).init(allocator);
413 defer result.deinit();
411 var result: std.ArrayListUnmanaged(u8) = .empty;
412 defer result.deinit(gpa);
414413
415 try result.writer().print("{s}-{s}", .{ arch_name, os_name });
414 try result.print(gpa, "{s}-{s}", .{ arch_name, os_name });
416415
417416 // The zig target syntax does not allow specifying a max os version with no min, so
418417 // if either are present, we need the min.
......@@ -420,11 +419,11 @@ pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 {
420419 switch (min) {
421420 .none => {},
422421 .semver => |v| {
423 try result.writer().writeAll(".");
424 try formatVersion(v, result.writer());
422 try result.appendSlice(gpa, ".");
423 try formatVersion(v, gpa, &result);
425424 },
426425 .windows => |v| {
427 try result.writer().print("{s}", .{v});
426 try result.print(gpa, "{s}", .{v});
428427 },
429428 }
430429 }
......@@ -432,39 +431,39 @@ pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 {
432431 switch (max) {
433432 .none => {},
434433 .semver => |v| {
435 try result.writer().writeAll("...");
436 try formatVersion(v, result.writer());
434 try result.appendSlice(gpa, "...");
435 try formatVersion(v, gpa, &result);
437436 },
438437 .windows => |v| {
439438 // This is counting on a custom format() function defined on `WindowsVersion`
440439 // to add a prefix '.' and make there be a total of three dots.
441 try result.writer().print("..{s}", .{v});
440 try result.print(gpa, "..{s}", .{v});
442441 },
443442 }
444443 }
445444
446445 if (self.glibc_version) |v| {
447446 const name = if (self.abi) |abi| @tagName(abi) else "gnu";
448 try result.ensureUnusedCapacity(name.len + 2);
447 try result.ensureUnusedCapacity(gpa, name.len + 2);
449448 result.appendAssumeCapacity('-');
450449 result.appendSliceAssumeCapacity(name);
451450 result.appendAssumeCapacity('.');
452 try formatVersion(v, result.writer());
451 try formatVersion(v, gpa, &result);
453452 } else if (self.android_api_level) |lvl| {
454453 const name = if (self.abi) |abi| @tagName(abi) else "android";
455 try result.ensureUnusedCapacity(name.len + 2);
454 try result.ensureUnusedCapacity(gpa, name.len + 2);
456455 result.appendAssumeCapacity('-');
457456 result.appendSliceAssumeCapacity(name);
458457 result.appendAssumeCapacity('.');
459 try result.writer().print("{d}", .{lvl});
458 try result.print(gpa, "{d}", .{lvl});
460459 } else if (self.abi) |abi| {
461460 const name = @tagName(abi);
462 try result.ensureUnusedCapacity(name.len + 1);
461 try result.ensureUnusedCapacity(gpa, name.len + 1);
463462 result.appendAssumeCapacity('-');
464463 result.appendSliceAssumeCapacity(name);
465464 }
466465
467 return result.toOwnedSlice();
466 return result.toOwnedSlice(gpa);
468467}
469468
470469/// Renders the query into a textual representation that can be parsed via the
lib/std/io/AllocatingWriter.zig+6
......@@ -77,6 +77,12 @@ pub fn toArrayList(aw: *AllocatingWriter) std.ArrayListUnmanaged(u8) {
7777 return result;
7878}
7979
80pub fn toOwnedSlice(aw: *AllocatingWriter) error{OutOfMemory}![]u8 {
81 const gpa = aw.allocator;
82 var list = toArrayList(aw);
83 return list.toOwnedSlice(gpa);
84}
85
8086fn setArrayList(aw: *AllocatingWriter, list: std.ArrayListUnmanaged(u8)) void {
8187 aw.written = list.items;
8288 aw.buffered_writer.buffer = list.unusedCapacitySlice();