| author | |
| committer | |
| log | a21e7ab64f66c83c57b2d87b71c19d50d94ed543 |
| tree | 9e47decd91c6bf7079344d2f40ca999d6dc043cf |
| parent | 1164d5ece5b12b573c6501c94b9ad9e326199ba9 |
46 files changed, 818 insertions(+), 845 deletions(-)
build.zig+5-5| ... | ... | @@ -279,7 +279,7 @@ pub fn build(b: *std.Build) !void { |
| 279 | 279 | |
| 280 | 280 | const ancestor_ver = try std.SemanticVersion.parse(tagged_ancestor); |
| 281 | 281 | if (zig_version.order(ancestor_ver) != .gt) { |
| 282 | std.debug.print("Zig version '{}' must be greater than tagged ancestor '{}'\n", .{ zig_version, ancestor_ver }); | |
| 282 | std.debug.print("Zig version '{f}' must be greater than tagged ancestor '{f}'\n", .{ zig_version, ancestor_ver }); | |
| 283 | 283 | std.process.exit(1); |
| 284 | 284 | } |
| 285 | 285 | |
| ... | ... | @@ -304,7 +304,7 @@ pub fn build(b: *std.Build) !void { |
| 304 | 304 | if (enable_llvm) { |
| 305 | 305 | const cmake_cfg = if (static_llvm) null else blk: { |
| 306 | 306 | if (findConfigH(b, config_h_path_option)) |config_h_path| { |
| 307 | const file_contents = fs.cwd().readFileAlloc(b.allocator, config_h_path, max_config_h_bytes) catch unreachable; | |
| 307 | const file_contents = fs.cwd().readFileAlloc(config_h_path, b.allocator, .limited(max_config_h_bytes)) catch unreachable; | |
| 308 | 308 | break :blk parseConfigH(b, file_contents); |
| 309 | 309 | } else { |
| 310 | 310 | std.log.warn("config.h could not be located automatically. Consider providing it explicitly via \"-Dconfig_h\"", .{}); |
| ... | ... | @@ -912,7 +912,7 @@ fn addCxxKnownPath( |
| 912 | 912 | return error.RequiredLibraryNotFound; |
| 913 | 913 | |
| 914 | 914 | const path_padded = run: { |
| 915 | var args = std.ArrayList([]const u8).init(b.allocator); | |
| 915 | var args: std.ArrayList([]const u8) = .init(b.allocator); | |
| 916 | 916 | try args.append(ctx.cxx_compiler); |
| 917 | 917 | var it = std.mem.tokenizeAny(u8, ctx.cxx_compiler_arg1, &std.ascii.whitespace); |
| 918 | 918 | while (it.next()) |arg| try args.append(arg); |
| ... | ... | @@ -1418,7 +1418,7 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath { |
| 1418 | 1418 | }); |
| 1419 | 1419 | |
| 1420 | 1420 | var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| { |
| 1421 | std.debug.panic("unable to open '{}doc/langref' directory: {s}", .{ | |
| 1421 | std.debug.panic("unable to open '{f}doc/langref' directory: {s}", .{ | |
| 1422 | 1422 | b.build_root, @errorName(err), |
| 1423 | 1423 | }); |
| 1424 | 1424 | }; |
| ... | ... | @@ -1439,7 +1439,7 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath { |
| 1439 | 1439 | // in a temporary directory |
| 1440 | 1440 | "--cache-root", b.cache_root.path orelse ".", |
| 1441 | 1441 | }); |
| 1442 | cmd.addArgs(&.{ "--zig-lib-dir", b.fmt("{}", .{b.graph.zig_lib_directory}) }); | |
| 1442 | cmd.addArgs(&.{ "--zig-lib-dir", b.fmt("{f}", .{b.graph.zig_lib_directory}) }); | |
| 1443 | 1443 | cmd.addArgs(&.{"-i"}); |
| 1444 | 1444 | cmd.addFileArg(b.path(b.fmt("doc/langref/{s}", .{entry.name}))); |
| 1445 | 1445 |
lib/compiler/build_runner.zig+10-15| ... | ... | @@ -330,7 +330,7 @@ pub fn main() !void { |
| 330 | 330 | } |
| 331 | 331 | } |
| 332 | 332 | |
| 333 | const stderr = std.io.getStdErr(); | |
| 333 | const stderr: std.fs.File = .stderr(); | |
| 334 | 334 | const ttyconf = get_tty_conf(color, stderr); |
| 335 | 335 | switch (ttyconf) { |
| 336 | 336 | .no_color => try graph.env_map.put("NO_COLOR", "1"), |
| ... | ... | @@ -365,7 +365,7 @@ pub fn main() !void { |
| 365 | 365 | .data = buffer.items, |
| 366 | 366 | .flags = .{ .exclusive = true }, |
| 367 | 367 | }) catch |err| { |
| 368 | fatal("unable to write configuration results to '{}{s}': {s}", .{ | |
| 368 | fatal("unable to write configuration results to '{f}{s}': {s}", .{ | |
| 369 | 369 | local_cache_directory, tmp_sub_path, @errorName(err), |
| 370 | 370 | }); |
| 371 | 371 | }; |
| ... | ... | @@ -378,16 +378,11 @@ pub fn main() !void { |
| 378 | 378 | |
| 379 | 379 | validateSystemLibraryOptions(builder); |
| 380 | 380 | |
| 381 | var stdout_writer: std.io.BufferedWriter = .{ | |
| 382 | .buffer = &stdout_buffer, | |
| 383 | .unbuffered_writer = std.io.getStdOut().writer(), | |
| 384 | }; | |
| 385 | ||
| 386 | if (help_menu) | |
| 387 | return usage(builder, &stdout_writer); | |
| 388 | ||
| 389 | if (steps_menu) | |
| 390 | return steps(builder, &stdout_writer); | |
| 381 | { | |
| 382 | var stdout_bw = std.fs.File.stdout().writer().buffered(&stdio_buffer); | |
| 383 | if (help_menu) return usage(builder, &stdout_bw); | |
| 384 | if (steps_menu) return steps(builder, &stdout_bw); | |
| 385 | } | |
| 391 | 386 | |
| 392 | 387 | var run: Run = .{ |
| 393 | 388 | .max_rss = max_rss, |
| ... | ... | @@ -699,7 +694,7 @@ fn runStepNames( |
| 699 | 694 | const ttyconf = run.ttyconf; |
| 700 | 695 | |
| 701 | 696 | if (run.summary != .none) { |
| 702 | var bw = std.debug.lockStdErr2(); | |
| 697 | var bw = std.debug.lockStdErr2(&stdio_buffer); | |
| 703 | 698 | defer std.debug.unlockStdErr(); |
| 704 | 699 | |
| 705 | 700 | const total_count = success_count + failure_count + pending_count + skipped_count; |
| ... | ... | @@ -1131,7 +1126,7 @@ fn workerMakeOneStep( |
| 1131 | 1126 | const show_stderr = s.result_stderr.len > 0; |
| 1132 | 1127 | |
| 1133 | 1128 | if (show_error_msgs or show_compile_errors or show_stderr) { |
| 1134 | var bw = std.debug.lockStdErr2(); | |
| 1129 | var bw = std.debug.lockStdErr2(&stdio_buffer); | |
| 1135 | 1130 | defer std.debug.unlockStdErr(); |
| 1136 | 1131 | |
| 1137 | 1132 | const gpa = b.allocator; |
| ... | ... | @@ -1256,7 +1251,7 @@ fn steps(builder: *std.Build, bw: *std.io.BufferedWriter) !void { |
| 1256 | 1251 | } |
| 1257 | 1252 | } |
| 1258 | 1253 | |
| 1259 | var stdout_buffer: [256]u8 = undefined; | |
| 1254 | var stdio_buffer: [256]u8 = undefined; | |
| 1260 | 1255 | |
| 1261 | 1256 | fn usage(b: *std.Build, bw: *std.io.BufferedWriter) !void { |
| 1262 | 1257 | try bw.print( |
lib/std/Build.zig+7-7| ... | ... | @@ -284,7 +284,7 @@ pub fn create( |
| 284 | 284 | .h_dir = undefined, |
| 285 | 285 | .dest_dir = graph.env_map.get("DESTDIR"), |
| 286 | 286 | .install_tls = .{ |
| 287 | .step = Step.init(.{ | |
| 287 | .step = .init(.{ | |
| 288 | 288 | .id = TopLevelStep.base_id, |
| 289 | 289 | .name = "install", |
| 290 | 290 | .owner = b, |
| ... | ... | @@ -292,7 +292,7 @@ pub fn create( |
| 292 | 292 | .description = "Copy build artifacts to prefix path", |
| 293 | 293 | }, |
| 294 | 294 | .uninstall_tls = .{ |
| 295 | .step = Step.init(.{ | |
| 295 | .step = .init(.{ | |
| 296 | 296 | .id = TopLevelStep.base_id, |
| 297 | 297 | .name = "uninstall", |
| 298 | 298 | .owner = b, |
| ... | ... | @@ -342,7 +342,7 @@ fn createChildOnly( |
| 342 | 342 | .graph = parent.graph, |
| 343 | 343 | .allocator = allocator, |
| 344 | 344 | .install_tls = .{ |
| 345 | .step = Step.init(.{ | |
| 345 | .step = .init(.{ | |
| 346 | 346 | .id = TopLevelStep.base_id, |
| 347 | 347 | .name = "install", |
| 348 | 348 | .owner = child, |
| ... | ... | @@ -350,7 +350,7 @@ fn createChildOnly( |
| 350 | 350 | .description = "Copy build artifacts to prefix path", |
| 351 | 351 | }, |
| 352 | 352 | .uninstall_tls = .{ |
| 353 | .step = Step.init(.{ | |
| 353 | .step = .init(.{ | |
| 354 | 354 | .id = TopLevelStep.base_id, |
| 355 | 355 | .name = "uninstall", |
| 356 | 356 | .owner = child, |
| ... | ... | @@ -1525,7 +1525,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1525 | 1525 | pub fn step(b: *Build, name: []const u8, description: []const u8) *Step { |
| 1526 | 1526 | const step_info = b.allocator.create(TopLevelStep) catch @panic("OOM"); |
| 1527 | 1527 | step_info.* = .{ |
| 1528 | .step = Step.init(.{ | |
| 1528 | .step = .init(.{ | |
| 1529 | 1529 | .id = TopLevelStep.base_id, |
| 1530 | 1530 | .name = name, |
| 1531 | 1531 | .owner = b, |
| ... | ... | @@ -1745,7 +1745,7 @@ pub fn addUserInputOption(b: *Build, name_raw: []const u8, value_raw: []const u8 |
| 1745 | 1745 | return true; |
| 1746 | 1746 | }, |
| 1747 | 1747 | .lazy_path, .lazy_path_list => { |
| 1748 | log.warn("the lazy path value type isn't added from the CLI, but somehow '{s}' is a .{}", .{ name, std.zig.fmtId(@tagName(gop.value_ptr.value)) }); | |
| 1748 | log.warn("the lazy path value type isn't added from the CLI, but somehow '{s}' is a .{f}", .{ name, std.zig.fmtId(@tagName(gop.value_ptr.value)) }); | |
| 1749 | 1749 | return true; |
| 1750 | 1750 | }, |
| 1751 | 1751 | } |
| ... | ... | @@ -2059,7 +2059,7 @@ pub fn runAllowFail( |
| 2059 | 2059 | try Step.handleVerbose2(b, null, child.env_map, argv); |
| 2060 | 2060 | try child.spawn(); |
| 2061 | 2061 | |
| 2062 | const stdout = child.stdout.?.reader().readAllAlloc(b.allocator, max_output_size) catch { | |
| 2062 | const stdout = child.stdout.?.readToEndAlloc(b.allocator, .limited(max_output_size)) catch { | |
| 2063 | 2063 | return error.ReadFailure; |
| 2064 | 2064 | }; |
| 2065 | 2065 | errdefer b.allocator.free(stdout); |
lib/std/Build/Cache.zig+2-2| ... | ... | @@ -333,7 +333,7 @@ pub const Manifest = struct { |
| 333 | 333 | pub const Diagnostic = union(enum) { |
| 334 | 334 | none, |
| 335 | 335 | manifest_create: fs.File.OpenError, |
| 336 | manifest_read: fs.File.ReadError, | |
| 336 | manifest_read: anyerror, | |
| 337 | 337 | manifest_lock: fs.File.LockError, |
| 338 | 338 | manifest_seek: fs.File.SeekError, |
| 339 | 339 | file_open: FileOp, |
| ... | ... | @@ -1062,7 +1062,7 @@ pub const Manifest = struct { |
| 1062 | 1062 | |
| 1063 | 1063 | fn addDepFileMaybePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void { |
| 1064 | 1064 | const gpa = self.cache.gpa; |
| 1065 | const dep_file_contents = try dir.readFileAlloc(gpa, dep_file_basename, manifest_file_size_max); | |
| 1065 | const dep_file_contents = try dir.readFileAlloc(dep_file_basename, gpa, .limited(manifest_file_size_max)); | |
| 1066 | 1066 | defer gpa.free(dep_file_contents); |
| 1067 | 1067 | |
| 1068 | 1068 | var error_buf: std.ArrayListUnmanaged(u8) = .empty; |
lib/std/Build/Cache/Directory.zig+3-5| ... | ... | @@ -57,15 +57,13 @@ pub fn closeAndFree(self: *Directory, gpa: Allocator) void { |
| 57 | 57 | |
| 58 | 58 | pub fn format( |
| 59 | 59 | self: Directory, |
| 60 | bw: *std.io.BufferedWriter, | |
| 60 | 61 | comptime fmt_string: []const u8, |
| 61 | options: fmt.FormatOptions, | |
| 62 | writer: anytype, | |
| 63 | 62 | ) !void { |
| 64 | _ = options; | |
| 65 | 63 | if (fmt_string.len != 0) fmt.invalidFmtError(fmt_string, self); |
| 66 | 64 | if (self.path) |p| { |
| 67 | try writer.writeAll(p); | |
| 68 | try writer.writeAll(fs.path.sep_str); | |
| 65 | try bw.writeAll(p); | |
| 66 | try bw.writeAll(fs.path.sep_str); | |
| 69 | 67 | } |
| 70 | 68 | } |
| 71 | 69 |
lib/std/Build/Cache/Path.zig+10-11| ... | ... | @@ -142,9 +142,8 @@ pub fn toStringZ(p: Path, allocator: Allocator) Allocator.Error![:0]u8 { |
| 142 | 142 | |
| 143 | 143 | pub fn format( |
| 144 | 144 | self: Path, |
| 145 | bw: *std.io.BufferedWriter, | |
| 145 | 146 | comptime fmt_string: []const u8, |
| 146 | options: std.fmt.FormatOptions, | |
| 147 | writer: anytype, | |
| 148 | 147 | ) !void { |
| 149 | 148 | if (fmt_string.len == 1) { |
| 150 | 149 | // Quote-escape the string. |
| ... | ... | @@ -155,33 +154,33 @@ pub fn format( |
| 155 | 154 | else => @compileError("unsupported format string: " ++ fmt_string), |
| 156 | 155 | }; |
| 157 | 156 | if (self.root_dir.path) |p| { |
| 158 | try stringEscape(p, f, options, writer); | |
| 159 | if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, f, options, writer); | |
| 157 | try stringEscape(p, bw, f); | |
| 158 | if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, bw, f); | |
| 160 | 159 | } |
| 161 | 160 | if (self.sub_path.len > 0) { |
| 162 | try stringEscape(self.sub_path, f, options, writer); | |
| 161 | try stringEscape(self.sub_path, bw, f); | |
| 163 | 162 | } |
| 164 | 163 | return; |
| 165 | 164 | } |
| 166 | 165 | if (fmt_string.len > 0) |
| 167 | 166 | std.fmt.invalidFmtError(fmt_string, self); |
| 168 | 167 | if (std.fs.path.isAbsolute(self.sub_path)) { |
| 169 | try writer.writeAll(self.sub_path); | |
| 168 | try bw.writeAll(self.sub_path); | |
| 170 | 169 | return; |
| 171 | 170 | } |
| 172 | 171 | if (self.root_dir.path) |p| { |
| 173 | try writer.writeAll(p); | |
| 172 | try bw.writeAll(p); | |
| 174 | 173 | if (self.sub_path.len > 0) { |
| 175 | try writer.writeAll(fs.path.sep_str); | |
| 176 | try writer.writeAll(self.sub_path); | |
| 174 | try bw.writeAll(fs.path.sep_str); | |
| 175 | try bw.writeAll(self.sub_path); | |
| 177 | 176 | } |
| 178 | 177 | return; |
| 179 | 178 | } |
| 180 | 179 | if (self.sub_path.len > 0) { |
| 181 | try writer.writeAll(self.sub_path); | |
| 180 | try bw.writeAll(self.sub_path); | |
| 182 | 181 | return; |
| 183 | 182 | } |
| 184 | try writer.writeByte('.'); | |
| 183 | try bw.writeByte('.'); | |
| 185 | 184 | } |
| 186 | 185 | |
| 187 | 186 | pub fn eql(self: Path, other: Path) bool { |
lib/std/Build/Fuzz/WebServer.zig+15-18| ... | ... | @@ -169,8 +169,8 @@ fn serveFile( |
| 169 | 169 | // The desired API is actually sendfile, which will require enhancing std.http.Server. |
| 170 | 170 | // We load the file with every request so that the user can make changes to the file |
| 171 | 171 | // and refresh the HTML page without restarting this server. |
| 172 | const file_contents = ws.zig_lib_directory.handle.readFileAlloc(gpa, name, 10 * 1024 * 1024) catch |err| { | |
| 173 | log.err("failed to read '{}{s}': {s}", .{ ws.zig_lib_directory, name, @errorName(err) }); | |
| 172 | const file_contents = ws.zig_lib_directory.handle.readFileAlloc(name, gpa, .limited(10 * 1024 * 1024)) catch |err| { | |
| 173 | log.err("failed to read '{f}{s}': {s}", .{ ws.zig_lib_directory, name, @errorName(err) }); | |
| 174 | 174 | return error.AlreadyReported; |
| 175 | 175 | }; |
| 176 | 176 | defer gpa.free(file_contents); |
| ... | ... | @@ -206,7 +206,7 @@ fn serveWasm( |
| 206 | 206 | }); |
| 207 | 207 | // std.http.Server does not have a sendfile API yet. |
| 208 | 208 | const bin_path = try wasm_base_path.join(arena, bin_name); |
| 209 | const file_contents = try bin_path.root_dir.handle.readFileAlloc(gpa, bin_path.sub_path, 10 * 1024 * 1024); | |
| 209 | const file_contents = try bin_path.root_dir.handle.readFileAlloc(bin_path.sub_path, gpa, .limited(10 * 1024 * 1024)); | |
| 210 | 210 | defer gpa.free(file_contents); |
| 211 | 211 | try request.respond(file_contents, .{ |
| 212 | 212 | .extra_headers = &.{ |
| ... | ... | @@ -251,10 +251,10 @@ fn buildWasmBinary( |
| 251 | 251 | "-fsingle-threaded", // |
| 252 | 252 | "--dep", "Walk", // |
| 253 | 253 | "--dep", "html_render", // |
| 254 | try std.fmt.allocPrint(arena, "-Mroot={}", .{main_src_path}), // | |
| 255 | try std.fmt.allocPrint(arena, "-MWalk={}", .{walk_src_path}), // | |
| 254 | try std.fmt.allocPrint(arena, "-Mroot={f}", .{main_src_path}), // | |
| 255 | try std.fmt.allocPrint(arena, "-MWalk={f}", .{walk_src_path}), // | |
| 256 | 256 | "--dep", "Walk", // |
| 257 | try std.fmt.allocPrint(arena, "-Mhtml_render={}", .{html_render_src_path}), // | |
| 257 | try std.fmt.allocPrint(arena, "-Mhtml_render={f}", .{html_render_src_path}), // | |
| 258 | 258 | "--listen=-", |
| 259 | 259 | }); |
| 260 | 260 | |
| ... | ... | @@ -280,13 +280,10 @@ fn buildWasmBinary( |
| 280 | 280 | const stdout = poller.fifo(.stdout); |
| 281 | 281 | |
| 282 | 282 | poll: while (true) { |
| 283 | while (stdout.readableLength() < @sizeOf(Header)) { | |
| 284 | if (!(try poller.poll())) break :poll; | |
| 285 | } | |
| 286 | const header = stdout.reader().readStruct(Header) catch unreachable; | |
| 287 | while (stdout.readableLength() < header.bytes_len) { | |
| 288 | if (!(try poller.poll())) break :poll; | |
| 289 | } | |
| 283 | while (stdout.readableLength() < @sizeOf(Header)) if (!try poller.poll()) break :poll; | |
| 284 | var header: Header = undefined; | |
| 285 | assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(Header)); | |
| 286 | while (stdout.readableLength() < header.bytes_len) if (!try poller.poll()) break :poll; | |
| 290 | 287 | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 291 | 288 | |
| 292 | 289 | switch (header.tag) { |
| ... | ... | @@ -527,7 +524,7 @@ fn serveSourcesTar(ws: *WebServer, request: *std.http.Server.Request) !void { |
| 527 | 524 | |
| 528 | 525 | for (deduped_paths) |joined_path| { |
| 529 | 526 | var file = joined_path.root_dir.handle.openFile(joined_path.sub_path, .{}) catch |err| { |
| 530 | log.err("failed to open {}: {s}", .{ joined_path, @errorName(err) }); | |
| 527 | log.err("failed to open {f}: {s}", .{ joined_path, @errorName(err) }); | |
| 531 | 528 | continue; |
| 532 | 529 | }; |
| 533 | 530 | defer file.close(); |
| ... | ... | @@ -605,7 +602,7 @@ fn prepareTables( |
| 605 | 602 | |
| 606 | 603 | const rebuilt_exe_path = run_step.rebuilt_executable.?; |
| 607 | 604 | var debug_info = std.debug.Info.load(gpa, rebuilt_exe_path, &gop.value_ptr.coverage) catch |err| { |
| 608 | log.err("step '{s}': failed to load debug information for '{}': {s}", .{ | |
| 605 | log.err("step '{s}': failed to load debug information for '{f}': {s}", .{ | |
| 609 | 606 | run_step.step.name, rebuilt_exe_path, @errorName(err), |
| 610 | 607 | }); |
| 611 | 608 | return error.AlreadyReported; |
| ... | ... | @@ -617,7 +614,7 @@ fn prepareTables( |
| 617 | 614 | .sub_path = "v/" ++ std.fmt.hex(coverage_id), |
| 618 | 615 | }; |
| 619 | 616 | var coverage_file = coverage_file_path.root_dir.handle.openFile(coverage_file_path.sub_path, .{}) catch |err| { |
| 620 | log.err("step '{s}': failed to load coverage file '{}': {s}", .{ | |
| 617 | log.err("step '{s}': failed to load coverage file '{f}': {s}", .{ | |
| 621 | 618 | run_step.step.name, coverage_file_path, @errorName(err), |
| 622 | 619 | }); |
| 623 | 620 | return error.AlreadyReported; |
| ... | ... | @@ -625,7 +622,7 @@ fn prepareTables( |
| 625 | 622 | defer coverage_file.close(); |
| 626 | 623 | |
| 627 | 624 | const file_size = coverage_file.getEndPos() catch |err| { |
| 628 | log.err("unable to check len of coverage file '{}': {s}", .{ coverage_file_path, @errorName(err) }); | |
| 625 | log.err("unable to check len of coverage file '{f}': {s}", .{ coverage_file_path, @errorName(err) }); | |
| 629 | 626 | return error.AlreadyReported; |
| 630 | 627 | }; |
| 631 | 628 | |
| ... | ... | @@ -637,7 +634,7 @@ fn prepareTables( |
| 637 | 634 | coverage_file.handle, |
| 638 | 635 | 0, |
| 639 | 636 | ) catch |err| { |
| 640 | log.err("failed to map coverage file '{}': {s}", .{ coverage_file_path, @errorName(err) }); | |
| 637 | log.err("failed to map coverage file '{f}': {s}", .{ coverage_file_path, @errorName(err) }); | |
| 641 | 638 | return error.AlreadyReported; |
| 642 | 639 | }; |
| 643 | 640 | gop.value_ptr.mapped_memory = mapped_memory; |
lib/std/Build/Step.zig+4-7| ... | ... | @@ -516,13 +516,10 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path { |
| 516 | 516 | const stdout = zp.poller.fifo(.stdout); |
| 517 | 517 | |
| 518 | 518 | poll: while (true) { |
| 519 | while (stdout.readableLength() < @sizeOf(Header)) { | |
| 520 | if (!(try zp.poller.poll())) break :poll; | |
| 521 | } | |
| 522 | const header = stdout.reader().readStruct(Header) catch unreachable; | |
| 523 | while (stdout.readableLength() < header.bytes_len) { | |
| 524 | if (!(try zp.poller.poll())) break :poll; | |
| 525 | } | |
| 519 | while (stdout.readableLength() < @sizeOf(Header)) if (!try zp.poller.poll()) break :poll; | |
| 520 | var header: Header = undefined; | |
| 521 | assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(Header)); | |
| 522 | while (stdout.readableLength() < header.bytes_len) if (!try zp.poller.poll()) break :poll; | |
| 526 | 523 | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 527 | 524 | |
| 528 | 525 | switch (header.tag) { |
lib/std/Build/Step/CheckFile.zig+2-2| ... | ... | @@ -28,7 +28,7 @@ pub fn create( |
| 28 | 28 | ) *CheckFile { |
| 29 | 29 | const check_file = owner.allocator.create(CheckFile) catch @panic("OOM"); |
| 30 | 30 | check_file.* = .{ |
| 31 | .step = Step.init(.{ | |
| 31 | .step = .init(.{ | |
| 32 | 32 | .id = base_id, |
| 33 | 33 | .name = "CheckFile", |
| 34 | 34 | .owner = owner, |
| ... | ... | @@ -53,7 +53,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 53 | 53 | try step.singleUnchangingWatchInput(check_file.source); |
| 54 | 54 | |
| 55 | 55 | const src_path = check_file.source.getPath2(b, step); |
| 56 | const contents = fs.cwd().readFileAlloc(b.allocator, src_path, check_file.max_bytes) catch |err| { | |
| 56 | const contents = fs.cwd().readFileAlloc(src_path, b.allocator, .limited(check_file.max_bytes)) catch |err| { | |
| 57 | 57 | return step.fail("unable to read '{s}': {s}", .{ |
| 58 | 58 | src_path, @errorName(err), |
| 59 | 59 | }); |
lib/std/Build/Step/CheckObject.zig+300-401| ... | ... | @@ -28,14 +28,14 @@ pub fn create( |
| 28 | 28 | const gpa = owner.allocator; |
| 29 | 29 | const check_object = gpa.create(CheckObject) catch @panic("OOM"); |
| 30 | 30 | check_object.* = .{ |
| 31 | .step = Step.init(.{ | |
| 31 | .step = .init(.{ | |
| 32 | 32 | .id = base_id, |
| 33 | 33 | .name = "CheckObject", |
| 34 | 34 | .owner = owner, |
| 35 | 35 | .makeFn = make, |
| 36 | 36 | }), |
| 37 | 37 | .source = source.dupe(owner), |
| 38 | .checks = std.ArrayList(Check).init(gpa), | |
| 38 | .checks = .init(gpa), | |
| 39 | 39 | .obj_format = obj_format, |
| 40 | 40 | }; |
| 41 | 41 | check_object.source.addStepDependencies(&check_object.step); |
| ... | ... | @@ -74,13 +74,13 @@ const Action = struct { |
| 74 | 74 | b: *std.Build, |
| 75 | 75 | step: *Step, |
| 76 | 76 | haystack: []const u8, |
| 77 | global_vars: anytype, | |
| 77 | global_vars: *std.StringHashMap(u64), | |
| 78 | 78 | ) !bool { |
| 79 | 79 | assert(act.tag == .extract); |
| 80 | 80 | const hay = mem.trim(u8, haystack, " "); |
| 81 | 81 | const phrase = mem.trim(u8, act.phrase.resolve(b, step), " "); |
| 82 | 82 | |
| 83 | var candidate_vars = std.ArrayList(struct { name: []const u8, value: u64 }).init(b.allocator); | |
| 83 | var candidate_vars: std.ArrayList(struct { name: []const u8, value: u64 }) = .init(b.allocator); | |
| 84 | 84 | var hay_it = mem.tokenizeScalar(u8, hay, ' '); |
| 85 | 85 | var needle_it = mem.tokenizeScalar(u8, phrase, ' '); |
| 86 | 86 | |
| ... | ... | @@ -153,11 +153,11 @@ const Action = struct { |
| 153 | 153 | /// Will return true if the `phrase` is correctly parsed into an RPN program and |
| 154 | 154 | /// its reduced, computed value compares using `op` with the expected value, either |
| 155 | 155 | /// a literal or another extracted variable. |
| 156 | fn computeCmp(act: Action, b: *std.Build, step: *Step, global_vars: anytype) !bool { | |
| 156 | fn computeCmp(act: Action, b: *std.Build, step: *Step, global_vars: std.StringHashMap(u64)) !bool { | |
| 157 | 157 | const gpa = step.owner.allocator; |
| 158 | 158 | const phrase = act.phrase.resolve(b, step); |
| 159 | var op_stack = std.ArrayList(enum { add, sub, mod, mul }).init(gpa); | |
| 160 | var values = std.ArrayList(u64).init(gpa); | |
| 159 | var op_stack: std.ArrayList(enum { add, sub, mod, mul }) = .init(gpa); | |
| 160 | var values: std.ArrayList(u64) = .init(gpa); | |
| 161 | 161 | |
| 162 | 162 | var it = mem.tokenizeScalar(u8, phrase, ' '); |
| 163 | 163 | while (it.next()) |next| { |
| ... | ... | @@ -230,17 +230,15 @@ const ComputeCompareExpected = struct { |
| 230 | 230 | }, |
| 231 | 231 | |
| 232 | 232 | pub fn format( |
| 233 | value: @This(), | |
| 233 | value: ComputeCompareExpected, | |
| 234 | bw: *std.io.BufferedWriter, | |
| 234 | 235 | comptime fmt: []const u8, |
| 235 | options: std.fmt.FormatOptions, | |
| 236 | writer: anytype, | |
| 237 | ) !void { | |
| 236 | ) anyerror!void { | |
| 238 | 237 | if (fmt.len != 0) std.fmt.invalidFmtError(fmt, value); |
| 239 | _ = options; | |
| 240 | try writer.print("{s} ", .{@tagName(value.op)}); | |
| 238 | try bw.print("{s} ", .{@tagName(value.op)}); | |
| 241 | 239 | switch (value.value) { |
| 242 | .variable => |name| try writer.writeAll(name), | |
| 243 | .literal => |x| try writer.print("{x}", .{x}), | |
| 240 | .variable => |name| try bw.writeAll(name), | |
| 241 | .literal => |x| try bw.print("{x}", .{x}), | |
| 244 | 242 | } |
| 245 | 243 | } |
| 246 | 244 | }; |
| ... | ... | @@ -566,15 +564,15 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 566 | 564 | |
| 567 | 565 | const src_path = check_object.source.getPath3(b, step); |
| 568 | 566 | const contents = src_path.root_dir.handle.readFileAllocOptions( |
| 569 | gpa, | |
| 570 | 567 | src_path.sub_path, |
| 571 | check_object.max_bytes, | |
| 568 | gpa, | |
| 569 | .limited(check_object.max_bytes), | |
| 572 | 570 | null, |
| 573 | 571 | .of(u64), |
| 574 | 572 | null, |
| 575 | ) catch |err| return step.fail("unable to read '{'}': {s}", .{ src_path, @errorName(err) }); | |
| 573 | ) catch |err| return step.fail("unable to read '{f'}': {s}", .{ src_path, @errorName(err) }); | |
| 576 | 574 | |
| 577 | var vars = std.StringHashMap(u64).init(gpa); | |
| 575 | var vars: std.StringHashMap(u64) = .init(gpa); | |
| 578 | 576 | for (check_object.checks.items) |chk| { |
| 579 | 577 | if (chk.kind == .compute_compare) { |
| 580 | 578 | assert(chk.actions.items.len == 1); |
| ... | ... | @@ -588,7 +586,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 588 | 586 | return step.fail( |
| 589 | 587 | \\ |
| 590 | 588 | \\========= comparison failed for action: =========== |
| 591 | \\{s} {} | |
| 589 | \\{s} {f} | |
| 592 | 590 | \\=================================================== |
| 593 | 591 | , .{ act.phrase.resolve(b, step), act.expected.? }); |
| 594 | 592 | } |
| ... | ... | @@ -621,15 +619,13 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 621 | 619 | |
| 622 | 620 | fn formatMessageString( |
| 623 | 621 | ctx: Ctx, |
| 622 | bw: *std.io.BufferedWriter, | |
| 624 | 623 | comptime unused_fmt_string: []const u8, |
| 625 | options: std.fmt.FormatOptions, | |
| 626 | writer: anytype, | |
| 627 | 624 | ) !void { |
| 628 | 625 | _ = unused_fmt_string; |
| 629 | _ = options; | |
| 630 | 626 | switch (ctx.kind) { |
| 631 | .dump_section => try writer.print("{s}", .{std.fmt.fmtSliceEscapeLower(ctx.msg)}), | |
| 632 | else => try writer.writeAll(ctx.msg), | |
| 627 | .dump_section => try bw.print("{f}", .{std.fmt.fmtSliceEscapeLower(ctx.msg)}), | |
| 628 | else => try bw.writeAll(ctx.msg), | |
| 633 | 629 | } |
| 634 | 630 | } |
| 635 | 631 | }.fmtMessageString; |
| ... | ... | @@ -644,11 +640,11 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 644 | 640 | return step.fail( |
| 645 | 641 | \\ |
| 646 | 642 | \\========= expected to find: ========================== |
| 647 | \\{s} | |
| 643 | \\{f} | |
| 648 | 644 | \\========= but parsed file does not contain it: ======= |
| 649 | \\{s} | |
| 645 | \\{f} | |
| 650 | 646 | \\========= file path: ================================= |
| 651 | \\{} | |
| 647 | \\{f} | |
| 652 | 648 | , .{ |
| 653 | 649 | fmtMessageString(chk.kind, act.phrase.resolve(b, step)), |
| 654 | 650 | fmtMessageString(chk.kind, output), |
| ... | ... | @@ -664,11 +660,11 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 664 | 660 | return step.fail( |
| 665 | 661 | \\ |
| 666 | 662 | \\========= expected to find: ========================== |
| 667 | \\*{s}* | |
| 663 | \\*{f}* | |
| 668 | 664 | \\========= but parsed file does not contain it: ======= |
| 669 | \\{s} | |
| 665 | \\{f} | |
| 670 | 666 | \\========= file path: ================================= |
| 671 | \\{} | |
| 667 | \\{f} | |
| 672 | 668 | , .{ |
| 673 | 669 | fmtMessageString(chk.kind, act.phrase.resolve(b, step)), |
| 674 | 670 | fmtMessageString(chk.kind, output), |
| ... | ... | @@ -683,11 +679,11 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 683 | 679 | return step.fail( |
| 684 | 680 | \\ |
| 685 | 681 | \\========= expected not to find: =================== |
| 686 | \\{s} | |
| 682 | \\{f} | |
| 687 | 683 | \\========= but parsed file does contain it: ======== |
| 688 | \\{s} | |
| 684 | \\{f} | |
| 689 | 685 | \\========= file path: ============================== |
| 690 | \\{} | |
| 686 | \\{f} | |
| 691 | 687 | , .{ |
| 692 | 688 | fmtMessageString(chk.kind, act.phrase.resolve(b, step)), |
| 693 | 689 | fmtMessageString(chk.kind, output), |
| ... | ... | @@ -703,13 +699,13 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 703 | 699 | return step.fail( |
| 704 | 700 | \\ |
| 705 | 701 | \\========= expected to find and extract: ============== |
| 706 | \\{s} | |
| 702 | \\{f} | |
| 707 | 703 | \\========= but parsed file does not contain it: ======= |
| 708 | \\{s} | |
| 704 | \\{f} | |
| 709 | 705 | \\========= file path: ============================== |
| 710 | \\{} | |
| 706 | \\{f} | |
| 711 | 707 | , .{ |
| 712 | act.phrase.resolve(b, step), | |
| 708 | fmtMessageString(chk.kind, act.phrase.resolve(b, step)), | |
| 713 | 709 | fmtMessageString(chk.kind, output), |
| 714 | 710 | src_path, |
| 715 | 711 | }); |
| ... | ... | @@ -762,14 +758,14 @@ const MachODumper = struct { |
| 762 | 758 | }, |
| 763 | 759 | .SYMTAB => { |
| 764 | 760 | const lc = cmd.cast(macho.symtab_command).?; |
| 765 | const symtab = @as([*]align(1) const macho.nlist_64, @ptrCast(ctx.data.ptr + lc.symoff))[0..lc.nsyms]; | |
| 761 | const symtab = @as([*]align(1) const macho.nlist_64, @ptrCast(ctx.data[lc.symoff..].ptr))[0..lc.nsyms]; | |
| 766 | 762 | const strtab = ctx.data[lc.stroff..][0..lc.strsize]; |
| 767 | 763 | try ctx.symtab.appendUnalignedSlice(ctx.gpa, symtab); |
| 768 | 764 | try ctx.strtab.appendSlice(ctx.gpa, strtab); |
| 769 | 765 | }, |
| 770 | 766 | .DYSYMTAB => { |
| 771 | 767 | const lc = cmd.cast(macho.dysymtab_command).?; |
| 772 | const indexes = @as([*]align(1) const u32, @ptrCast(ctx.data.ptr + lc.indirectsymoff))[0..lc.nindirectsyms]; | |
| 768 | const indexes = @as([*]align(1) const u32, @ptrCast(ctx.data[lc.indirectsymoff..].ptr))[0..lc.nindirectsyms]; | |
| 773 | 769 | try ctx.indsymtab.appendUnalignedSlice(ctx.gpa, indexes); |
| 774 | 770 | }, |
| 775 | 771 | .LOAD_DYLIB, |
| ... | ... | @@ -787,7 +783,7 @@ const MachODumper = struct { |
| 787 | 783 | |
| 788 | 784 | fn getString(ctx: ObjectContext, off: u32) [:0]const u8 { |
| 789 | 785 | assert(off < ctx.strtab.items.len); |
| 790 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(ctx.strtab.items.ptr + off)), 0); | |
| 786 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(ctx.strtab.items[off..].ptr)), 0); | |
| 791 | 787 | } |
| 792 | 788 | |
| 793 | 789 | fn getLoadCommandIterator(ctx: ObjectContext) macho.LoadCommandIterator { |
| ... | ... | @@ -1232,7 +1228,7 @@ const MachODumper = struct { |
| 1232 | 1228 | } |
| 1233 | 1229 | |
| 1234 | 1230 | fn dumpRebaseInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void { |
| 1235 | var rebases = std.ArrayList(u64).init(ctx.gpa); | |
| 1231 | var rebases: std.ArrayList(u64) = .init(ctx.gpa); | |
| 1236 | 1232 | defer rebases.deinit(); |
| 1237 | 1233 | try ctx.parseRebaseInfo(data, &rebases); |
| 1238 | 1234 | mem.sort(u64, rebases.items, {}, std.sort.asc(u64)); |
| ... | ... | @@ -1242,14 +1238,13 @@ const MachODumper = struct { |
| 1242 | 1238 | } |
| 1243 | 1239 | |
| 1244 | 1240 | fn parseRebaseInfo(ctx: ObjectContext, data: []const u8, rebases: *std.ArrayList(u64)) !void { |
| 1245 | var stream: std.io.FixedBufferStream = .{ .buffer = data }; | |
| 1246 | var creader = std.io.countingReader(stream.reader()); | |
| 1247 | const reader = creader.reader(); | |
| 1241 | var br: std.io.BufferedReader = undefined; | |
| 1242 | br.initFixed(data); | |
| 1248 | 1243 | |
| 1249 | 1244 | var seg_id: ?u8 = null; |
| 1250 | 1245 | var offset: u64 = 0; |
| 1251 | 1246 | while (true) { |
| 1252 | const byte = reader.readByte() catch break; | |
| 1247 | const byte = br.takeByte() catch break; | |
| 1253 | 1248 | const opc = byte & macho.REBASE_OPCODE_MASK; |
| 1254 | 1249 | const imm = byte & macho.REBASE_IMMEDIATE_MASK; |
| 1255 | 1250 | switch (opc) { |
| ... | ... | @@ -1257,17 +1252,17 @@ const MachODumper = struct { |
| 1257 | 1252 | macho.REBASE_OPCODE_SET_TYPE_IMM => {}, |
| 1258 | 1253 | macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => { |
| 1259 | 1254 | seg_id = imm; |
| 1260 | offset = try std.leb.readUleb128(u64, reader); | |
| 1255 | offset = try br.takeLeb128(u64); | |
| 1261 | 1256 | }, |
| 1262 | 1257 | macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED => { |
| 1263 | 1258 | offset += imm * @sizeOf(u64); |
| 1264 | 1259 | }, |
| 1265 | 1260 | macho.REBASE_OPCODE_ADD_ADDR_ULEB => { |
| 1266 | const addend = try std.leb.readUleb128(u64, reader); | |
| 1261 | const addend = try br.takeLeb128(u64); | |
| 1267 | 1262 | offset += addend; |
| 1268 | 1263 | }, |
| 1269 | 1264 | macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB => { |
| 1270 | const addend = try std.leb.readUleb128(u64, reader); | |
| 1265 | const addend = try br.takeLeb128(u64); | |
| 1271 | 1266 | const seg = ctx.segments.items[seg_id.?]; |
| 1272 | 1267 | const addr = seg.vmaddr + offset; |
| 1273 | 1268 | try rebases.append(addr); |
| ... | ... | @@ -1284,11 +1279,11 @@ const MachODumper = struct { |
| 1284 | 1279 | ntimes = imm; |
| 1285 | 1280 | }, |
| 1286 | 1281 | macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES => { |
| 1287 | ntimes = try std.leb.readUleb128(u64, reader); | |
| 1282 | ntimes = try br.takeLeb128(u64); | |
| 1288 | 1283 | }, |
| 1289 | 1284 | macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB => { |
| 1290 | ntimes = try std.leb.readUleb128(u64, reader); | |
| 1291 | skip = try std.leb.readUleb128(u64, reader); | |
| 1285 | ntimes = try br.takeLeb128(u64); | |
| 1286 | skip = try br.takeLeb128(u64); | |
| 1292 | 1287 | }, |
| 1293 | 1288 | else => unreachable, |
| 1294 | 1289 | } |
| ... | ... | @@ -1331,7 +1326,7 @@ const MachODumper = struct { |
| 1331 | 1326 | }; |
| 1332 | 1327 | |
| 1333 | 1328 | fn dumpBindInfo(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void { |
| 1334 | var bindings = std.ArrayList(Binding).init(ctx.gpa); | |
| 1329 | var bindings: std.ArrayList(Binding) = .init(ctx.gpa); | |
| 1335 | 1330 | defer { |
| 1336 | 1331 | for (bindings.items) |*b| { |
| 1337 | 1332 | b.deinit(ctx.gpa); |
| ... | ... | @@ -1354,9 +1349,8 @@ const MachODumper = struct { |
| 1354 | 1349 | } |
| 1355 | 1350 | |
| 1356 | 1351 | fn parseBindInfo(ctx: ObjectContext, data: []const u8, bindings: *std.ArrayList(Binding)) !void { |
| 1357 | var stream: std.io.FixedBufferStream = .{ .buffer = data }; | |
| 1358 | var creader = std.io.countingReader(stream.reader()); | |
| 1359 | const reader = creader.reader(); | |
| 1352 | var br: std.io.BufferedReader = undefined; | |
| 1353 | br.initFixed(data); | |
| 1360 | 1354 | |
| 1361 | 1355 | var seg_id: ?u8 = null; |
| 1362 | 1356 | var tag: Binding.Tag = .self; |
| ... | ... | @@ -1364,11 +1358,10 @@ const MachODumper = struct { |
| 1364 | 1358 | var offset: u64 = 0; |
| 1365 | 1359 | var addend: i64 = 0; |
| 1366 | 1360 | |
| 1367 | var name_buf = std.ArrayList(u8).init(ctx.gpa); | |
| 1361 | var name_buf: std.ArrayList(u8) = .init(ctx.gpa); | |
| 1368 | 1362 | defer name_buf.deinit(); |
| 1369 | 1363 | |
| 1370 | while (true) { | |
| 1371 | const byte = reader.readByte() catch break; | |
| 1364 | while (br.takeByte()) |byte| { | |
| 1372 | 1365 | const opc = byte & macho.BIND_OPCODE_MASK; |
| 1373 | 1366 | const imm = byte & macho.BIND_IMMEDIATE_MASK; |
| 1374 | 1367 | switch (opc) { |
| ... | ... | @@ -1389,7 +1382,7 @@ const MachODumper = struct { |
| 1389 | 1382 | }, |
| 1390 | 1383 | macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => { |
| 1391 | 1384 | seg_id = imm; |
| 1392 | offset = try std.leb.readUleb128(u64, reader); | |
| 1385 | offset = try br.takeLeb128(u64); | |
| 1393 | 1386 | }, |
| 1394 | 1387 | macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM => { |
| 1395 | 1388 | name_buf.clearRetainingCapacity(); |
| ... | ... | @@ -1398,10 +1391,10 @@ const MachODumper = struct { |
| 1398 | 1391 | try name_buf.append(0); |
| 1399 | 1392 | }, |
| 1400 | 1393 | macho.BIND_OPCODE_SET_ADDEND_SLEB => { |
| 1401 | addend = try std.leb.readIleb128(i64, reader); | |
| 1394 | addend = try br.takeLeb128(i64); | |
| 1402 | 1395 | }, |
| 1403 | 1396 | macho.BIND_OPCODE_ADD_ADDR_ULEB => { |
| 1404 | const x = try std.leb.readUleb128(u64, reader); | |
| 1397 | const x = try br.takeLeb128(u64); | |
| 1405 | 1398 | offset = @intCast(@as(i64, @intCast(offset)) + @as(i64, @bitCast(x))); |
| 1406 | 1399 | }, |
| 1407 | 1400 | macho.BIND_OPCODE_DO_BIND, |
| ... | ... | @@ -1416,14 +1409,14 @@ const MachODumper = struct { |
| 1416 | 1409 | switch (opc) { |
| 1417 | 1410 | macho.BIND_OPCODE_DO_BIND => {}, |
| 1418 | 1411 | macho.BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB => { |
| 1419 | add_addr = try std.leb.readUleb128(u64, reader); | |
| 1412 | add_addr = try br.takeLeb128(u64); | |
| 1420 | 1413 | }, |
| 1421 | 1414 | macho.BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED => { |
| 1422 | 1415 | add_addr = imm * @sizeOf(u64); |
| 1423 | 1416 | }, |
| 1424 | 1417 | macho.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB => { |
| 1425 | count = try std.leb.readUleb128(u64, reader); | |
| 1426 | skip = try std.leb.readUleb128(u64, reader); | |
| 1418 | count = try br.takeLeb128(u64); | |
| 1419 | skip = try br.takeLeb128(u64); | |
| 1427 | 1420 | }, |
| 1428 | 1421 | else => unreachable, |
| 1429 | 1422 | } |
| ... | ... | @@ -1444,7 +1437,7 @@ const MachODumper = struct { |
| 1444 | 1437 | }, |
| 1445 | 1438 | else => break, |
| 1446 | 1439 | } |
| 1447 | } | |
| 1440 | } else |_| {} | |
| 1448 | 1441 | } |
| 1449 | 1442 | |
| 1450 | 1443 | fn dumpExportsTrie(ctx: ObjectContext, data: []const u8, bw: *std.io.BufferedWriter) !void { |
| ... | ... | @@ -1453,9 +1446,10 @@ const MachODumper = struct { |
| 1453 | 1446 | var arena = std.heap.ArenaAllocator.init(ctx.gpa); |
| 1454 | 1447 | defer arena.deinit(); |
| 1455 | 1448 | |
| 1456 | var exports = std.ArrayList(Export).init(arena.allocator()); | |
| 1457 | var it = TrieIterator{ .data = data }; | |
| 1458 | try parseTrieNode(arena.allocator(), &it, "", &exports); | |
| 1449 | var exports: std.ArrayList(Export) = .init(arena.allocator()); | |
| 1450 | var br: std.io.BufferedReader = undefined; | |
| 1451 | br.initFixed(data); | |
| 1452 | try parseTrieNode(arena.allocator(), &br, "", &exports); | |
| 1459 | 1453 | |
| 1460 | 1454 | mem.sort(Export, exports.items, {}, Export.lessThan); |
| 1461 | 1455 | |
| ... | ... | @@ -1484,46 +1478,6 @@ const MachODumper = struct { |
| 1484 | 1478 | } |
| 1485 | 1479 | } |
| 1486 | 1480 | |
| 1487 | const TrieIterator = struct { | |
| 1488 | data: []const u8, | |
| 1489 | pos: usize = 0, | |
| 1490 | ||
| 1491 | fn getStream(it: *TrieIterator) std.io.FixedBufferStream { | |
| 1492 | return .{ .buffer = it.data[it.pos..] }; | |
| 1493 | } | |
| 1494 | ||
| 1495 | fn readUleb128(it: *TrieIterator) !u64 { | |
| 1496 | var stream = it.getStream(); | |
| 1497 | var creader = std.io.countingReader(stream.reader()); | |
| 1498 | const reader = creader.reader(); | |
| 1499 | const value = try std.leb.readUleb128(u64, reader); | |
| 1500 | it.pos += creader.bytes_read; | |
| 1501 | return value; | |
| 1502 | } | |
| 1503 | ||
| 1504 | fn readString(it: *TrieIterator) ![:0]const u8 { | |
| 1505 | var stream = it.getStream(); | |
| 1506 | const reader = stream.reader(); | |
| 1507 | ||
| 1508 | var count: usize = 0; | |
| 1509 | while (true) : (count += 1) { | |
| 1510 | const byte = try reader.readByte(); | |
| 1511 | if (byte == 0) break; | |
| 1512 | } | |
| 1513 | ||
| 1514 | const str = @as([*:0]const u8, @ptrCast(it.data.ptr + it.pos))[0..count :0]; | |
| 1515 | it.pos += count + 1; | |
| 1516 | return str; | |
| 1517 | } | |
| 1518 | ||
| 1519 | fn readByte(it: *TrieIterator) !u8 { | |
| 1520 | var stream = it.getStream(); | |
| 1521 | const value = try stream.reader().readByte(); | |
| 1522 | it.pos += 1; | |
| 1523 | return value; | |
| 1524 | } | |
| 1525 | }; | |
| 1526 | ||
| 1527 | 1481 | const Export = struct { |
| 1528 | 1482 | name: []const u8, |
| 1529 | 1483 | tag: enum { @"export", reexport, stub_resolver }, |
| ... | ... | @@ -1563,17 +1517,17 @@ const MachODumper = struct { |
| 1563 | 1517 | |
| 1564 | 1518 | fn parseTrieNode( |
| 1565 | 1519 | arena: Allocator, |
| 1566 | it: *TrieIterator, | |
| 1520 | br: *std.io.BufferedReader, | |
| 1567 | 1521 | prefix: []const u8, |
| 1568 | 1522 | exports: *std.ArrayList(Export), |
| 1569 | 1523 | ) !void { |
| 1570 | const size = try it.readUleb128(); | |
| 1524 | const size = try br.takeLeb128(u64); | |
| 1571 | 1525 | if (size > 0) { |
| 1572 | const flags = try it.readUleb128(); | |
| 1526 | const flags = try br.takeLeb128(u64); | |
| 1573 | 1527 | switch (flags) { |
| 1574 | 1528 | macho.EXPORT_SYMBOL_FLAGS_REEXPORT => { |
| 1575 | const ord = try it.readUleb128(); | |
| 1576 | const name = try arena.dupe(u8, try it.readString()); | |
| 1529 | const ord = try br.takeLeb128(u64); | |
| 1530 | const name = try br.takeDelimiterConclusive(0); | |
| 1577 | 1531 | try exports.append(.{ |
| 1578 | 1532 | .name = if (name.len > 0) name else prefix, |
| 1579 | 1533 | .tag = .reexport, |
| ... | ... | @@ -1581,8 +1535,8 @@ const MachODumper = struct { |
| 1581 | 1535 | }); |
| 1582 | 1536 | }, |
| 1583 | 1537 | macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER => { |
| 1584 | const stub_offset = try it.readUleb128(); | |
| 1585 | const resolver_offset = try it.readUleb128(); | |
| 1538 | const stub_offset = try br.takeLeb128(u64); | |
| 1539 | const resolver_offset = try br.takeLeb128(u64); | |
| 1586 | 1540 | try exports.append(.{ |
| 1587 | 1541 | .name = prefix, |
| 1588 | 1542 | .tag = .stub_resolver, |
| ... | ... | @@ -1593,7 +1547,7 @@ const MachODumper = struct { |
| 1593 | 1547 | }); |
| 1594 | 1548 | }, |
| 1595 | 1549 | else => { |
| 1596 | const vmoff = try it.readUleb128(); | |
| 1550 | const vmoff = try br.takeLeb128(u64); | |
| 1597 | 1551 | try exports.append(.{ |
| 1598 | 1552 | .name = prefix, |
| 1599 | 1553 | .tag = .@"export", |
| ... | ... | @@ -1612,15 +1566,15 @@ const MachODumper = struct { |
| 1612 | 1566 | } |
| 1613 | 1567 | } |
| 1614 | 1568 | |
| 1615 | const nedges = try it.readByte(); | |
| 1569 | const nedges = try br.takeByte(); | |
| 1616 | 1570 | for (0..nedges) |_| { |
| 1617 | const label = try it.readString(); | |
| 1618 | const off = try it.readUleb128(); | |
| 1571 | const label = try br.takeDelimiterConclusive(0); | |
| 1572 | const off = try br.takeLeb128(u64); | |
| 1619 | 1573 | const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label }); |
| 1620 | const curr = it.pos; | |
| 1621 | it.pos = off; | |
| 1622 | try parseTrieNode(arena, it, prefix_label, exports); | |
| 1623 | it.pos = curr; | |
| 1574 | const seek = br.seek; | |
| 1575 | br.seek = off; | |
| 1576 | try parseTrieNode(arena, br, prefix_label, exports); | |
| 1577 | br.seek = seek; | |
| 1624 | 1578 | } |
| 1625 | 1579 | } |
| 1626 | 1580 | |
| ... | ... | @@ -1640,8 +1594,10 @@ const MachODumper = struct { |
| 1640 | 1594 | var ctx = ObjectContext{ .gpa = gpa, .data = bytes, .header = hdr }; |
| 1641 | 1595 | try ctx.parse(); |
| 1642 | 1596 | |
| 1643 | var output: std.io.AllocatingWriter = undefined; | |
| 1644 | const bw = output.init(gpa); | |
| 1597 | var aw: std.io.AllocatingWriter = undefined; | |
| 1598 | aw.init(gpa); | |
| 1599 | defer aw.deinit(); | |
| 1600 | const bw = &aw.buffered_writer; | |
| 1645 | 1601 | |
| 1646 | 1602 | switch (check.kind) { |
| 1647 | 1603 | .headers => { |
| ... | ... | @@ -1717,7 +1673,7 @@ const MachODumper = struct { |
| 1717 | 1673 | }, |
| 1718 | 1674 | |
| 1719 | 1675 | .dump_section => { |
| 1720 | const name = mem.sliceTo(@as([*:0]const u8, @ptrCast(check.data.items.ptr + check.payload.dump_section)), 0); | |
| 1676 | const name = mem.sliceTo(@as([*:0]const u8, @ptrCast(check.data.items[check.payload.dump_section..].ptr)), 0); | |
| 1721 | 1677 | const sep_index = mem.indexOfScalar(u8, name, ',') orelse |
| 1722 | 1678 | return step.fail("invalid section name: {s}", .{name}); |
| 1723 | 1679 | const segname = name[0..sep_index]; |
| ... | ... | @@ -1730,7 +1686,7 @@ const MachODumper = struct { |
| 1730 | 1686 | else => return step.fail("invalid check kind for MachO file format: {s}", .{@tagName(check.kind)}), |
| 1731 | 1687 | } |
| 1732 | 1688 | |
| 1733 | return output.toOwnedSlice(); | |
| 1689 | return aw.toOwnedSlice(); | |
| 1734 | 1690 | } |
| 1735 | 1691 | }; |
| 1736 | 1692 | |
| ... | ... | @@ -1749,153 +1705,133 @@ const ElfDumper = struct { |
| 1749 | 1705 | |
| 1750 | 1706 | fn parseAndDumpArchive(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 1751 | 1707 | const gpa = step.owner.allocator; |
| 1752 | var stream: std.io.FixedBufferStream = .{ .buffer = bytes }; | |
| 1753 | const reader = stream.reader(); | |
| 1708 | var br: std.io.BufferedReader = undefined; | |
| 1709 | br.initFixed(bytes); | |
| 1754 | 1710 | |
| 1755 | const magic = try reader.readBytesNoEof(elf.ARMAG.len); | |
| 1756 | if (!mem.eql(u8, &magic, elf.ARMAG)) { | |
| 1757 | return error.InvalidArchiveMagicNumber; | |
| 1758 | } | |
| 1711 | if (!mem.eql(u8, try br.takeArray(elf.ARMAG.len), elf.ARMAG)) return error.InvalidArchiveMagicNumber; | |
| 1759 | 1712 | |
| 1760 | var ctx = ArchiveContext{ | |
| 1713 | var ctx: ArchiveContext = .{ | |
| 1761 | 1714 | .gpa = gpa, |
| 1762 | 1715 | .data = bytes, |
| 1763 | .strtab = &[0]u8{}, | |
| 1716 | .symtab = &.{}, | |
| 1717 | .strtab = &.{}, | |
| 1718 | .objects = .empty, | |
| 1764 | 1719 | }; |
| 1765 | defer { | |
| 1766 | for (ctx.objects.items) |*object| { | |
| 1767 | gpa.free(object.name); | |
| 1768 | } | |
| 1769 | ctx.objects.deinit(gpa); | |
| 1770 | } | |
| 1771 | ||
| 1772 | while (true) { | |
| 1773 | if (stream.pos >= ctx.data.len) break; | |
| 1774 | if (!mem.isAligned(stream.pos, 2)) stream.pos += 1; | |
| 1720 | defer ctx.deinit(); | |
| 1775 | 1721 | |
| 1776 | const hdr = try reader.readStruct(elf.ar_hdr); | |
| 1722 | while (br.seek < bytes.len) { | |
| 1723 | const hdr_seek = std.mem.alignForward(usize, br.seek, 2); | |
| 1724 | br.seek = hdr_seek; | |
| 1725 | const hdr = try br.takeStruct(elf.ar_hdr); | |
| 1777 | 1726 | |
| 1778 | 1727 | if (!mem.eql(u8, &hdr.ar_fmag, elf.ARFMAG)) return error.InvalidArchiveHeaderMagicNumber; |
| 1779 | 1728 | |
| 1780 | const size = try hdr.size(); | |
| 1781 | defer { | |
| 1782 | _ = stream.seekBy(size) catch {}; | |
| 1783 | } | |
| 1729 | const data = try br.take(try hdr.size()); | |
| 1784 | 1730 | |
| 1785 | 1731 | if (hdr.isSymtab()) { |
| 1786 | try ctx.parseSymtab(ctx.data[stream.pos..][0..size], .p32); | |
| 1732 | try ctx.parseSymtab(data, .p32); | |
| 1787 | 1733 | continue; |
| 1788 | 1734 | } |
| 1789 | 1735 | if (hdr.isSymtab64()) { |
| 1790 | try ctx.parseSymtab(ctx.data[stream.pos..][0..size], .p64); | |
| 1736 | try ctx.parseSymtab(data, .p64); | |
| 1791 | 1737 | continue; |
| 1792 | 1738 | } |
| 1793 | 1739 | if (hdr.isStrtab()) { |
| 1794 | ctx.strtab = ctx.data[stream.pos..][0..size]; | |
| 1740 | ctx.strtab = data; | |
| 1795 | 1741 | continue; |
| 1796 | 1742 | } |
| 1797 | 1743 | if (hdr.isSymdef() or hdr.isSymdefSorted()) continue; |
| 1798 | 1744 | |
| 1799 | const name = if (hdr.name()) |name| | |
| 1800 | try gpa.dupe(u8, name) | |
| 1801 | else if (try hdr.nameOffset()) |off| | |
| 1802 | try gpa.dupe(u8, ctx.getString(off)) | |
| 1803 | else | |
| 1804 | unreachable; | |
| 1805 | ||
| 1806 | try ctx.objects.append(gpa, .{ .name = name, .off = stream.pos, .len = size }); | |
| 1745 | const name = hdr.name() orelse ctx.getString((try hdr.nameOffset()).?); | |
| 1746 | try ctx.objects.putNoClobber(gpa, hdr_seek, .{ | |
| 1747 | .name = name, | |
| 1748 | .data = data, | |
| 1749 | }); | |
| 1807 | 1750 | } |
| 1808 | 1751 | |
| 1809 | var output: std.io.AllocatingWriter = undefined; | |
| 1810 | const writer = output.init(gpa); | |
| 1752 | var aw: std.io.AllocatingWriter = undefined; | |
| 1753 | aw.init(gpa); | |
| 1754 | defer aw.deinit(); | |
| 1755 | const bw = &aw.buffered_writer; | |
| 1811 | 1756 | |
| 1812 | 1757 | switch (check.kind) { |
| 1813 | .archive_symtab => if (ctx.symtab.items.len > 0) { | |
| 1814 | try ctx.dumpSymtab(writer); | |
| 1758 | .archive_symtab => if (ctx.symtab.len > 0) { | |
| 1759 | try ctx.dumpSymtab(bw); | |
| 1815 | 1760 | } else return step.fail("no archive symbol table found", .{}), |
| 1816 | 1761 | |
| 1817 | else => if (ctx.objects.items.len > 0) { | |
| 1818 | try ctx.dumpObjects(step, check, writer); | |
| 1762 | else => if (ctx.objects.count() > 0) { | |
| 1763 | try ctx.dumpObjects(step, check, bw); | |
| 1819 | 1764 | } else return step.fail("empty archive", .{}), |
| 1820 | 1765 | } |
| 1821 | 1766 | |
| 1822 | return output.toOwnedSlice(); | |
| 1767 | return aw.toOwnedSlice(); | |
| 1823 | 1768 | } |
| 1824 | 1769 | |
| 1825 | 1770 | const ArchiveContext = struct { |
| 1826 | 1771 | gpa: Allocator, |
| 1827 | 1772 | data: []const u8, |
| 1828 | symtab: std.ArrayListUnmanaged(ArSymtabEntry) = .empty, | |
| 1773 | symtab: []ArSymtabEntry, | |
| 1829 | 1774 | strtab: []const u8, |
| 1830 | objects: std.ArrayListUnmanaged(struct { name: []const u8, off: usize, len: usize }) = .empty, | |
| 1775 | objects: std.AutoArrayHashMapUnmanaged(usize, struct { name: []const u8, data: []const u8 }), | |
| 1831 | 1776 | |
| 1832 | fn parseSymtab(ctx: *ArchiveContext, raw: []const u8, ptr_width: enum { p32, p64 }) !void { | |
| 1833 | var stream: std.io.FixedBufferStream = .{ .buffer = raw }; | |
| 1834 | const reader = stream.reader(); | |
| 1777 | fn deinit(ctx: *ArchiveContext) void { | |
| 1778 | ctx.gpa.free(ctx.symtab); | |
| 1779 | ctx.objects.deinit(ctx.gpa); | |
| 1780 | } | |
| 1781 | ||
| 1782 | fn parseSymtab(ctx: *ArchiveContext, data: []const u8, ptr_width: enum { p32, p64 }) !void { | |
| 1783 | var br: std.io.BufferedReader = undefined; | |
| 1784 | br.initFixed(data); | |
| 1835 | 1785 | const num = switch (ptr_width) { |
| 1836 | .p32 => try reader.readInt(u32, .big), | |
| 1837 | .p64 => try reader.readInt(u64, .big), | |
| 1786 | .p32 => try br.takeInt(u32, .big), | |
| 1787 | .p64 => try br.takeInt(u64, .big), | |
| 1838 | 1788 | }; |
| 1839 | 1789 | const ptr_size: usize = switch (ptr_width) { |
| 1840 | 1790 | .p32 => @sizeOf(u32), |
| 1841 | 1791 | .p64 => @sizeOf(u64), |
| 1842 | 1792 | }; |
| 1843 | const strtab_off = (num + 1) * ptr_size; | |
| 1844 | const strtab_len = raw.len - strtab_off; | |
| 1845 | const strtab = raw[strtab_off..][0..strtab_len]; | |
| 1793 | try br.discard(num * ptr_size); | |
| 1794 | const strtab = try br.peekAll(0); | |
| 1846 | 1795 | |
| 1847 | try ctx.symtab.ensureTotalCapacityPrecise(ctx.gpa, num); | |
| 1796 | assert(ctx.symtab.len == 0); | |
| 1797 | ctx.symtab = try ctx.gpa.alloc(ArSymtabEntry, num); | |
| 1848 | 1798 | |
| 1849 | 1799 | var stroff: usize = 0; |
| 1850 | for (0..num) |_| { | |
| 1800 | for (ctx.symtab) |*entry| { | |
| 1851 | 1801 | const off = switch (ptr_width) { |
| 1852 | .p32 => try reader.readInt(u32, .big), | |
| 1853 | .p64 => try reader.readInt(u64, .big), | |
| 1802 | .p32 => try br.takeInt(u32, .big), | |
| 1803 | .p64 => try br.takeInt(u64, .big), | |
| 1854 | 1804 | }; |
| 1855 | const name = mem.sliceTo(@as([*:0]const u8, @ptrCast(strtab.ptr + stroff)), 0); | |
| 1805 | const name = mem.sliceTo(@as([*:0]const u8, @ptrCast(strtab[stroff..].ptr)), 0); | |
| 1856 | 1806 | stroff += name.len + 1; |
| 1857 | ctx.symtab.appendAssumeCapacity(.{ .off = off, .name = name }); | |
| 1807 | entry.* = .{ .off = off, .name = name }; | |
| 1858 | 1808 | } |
| 1859 | 1809 | } |
| 1860 | 1810 | |
| 1861 | 1811 | fn dumpSymtab(ctx: ArchiveContext, bw: *std.io.BufferedWriter) !void { |
| 1862 | var files = std.AutoHashMap(usize, []const u8).init(ctx.gpa); | |
| 1863 | defer files.deinit(); | |
| 1864 | try files.ensureUnusedCapacity(@intCast(ctx.objects.items.len)); | |
| 1865 | ||
| 1866 | for (ctx.objects.items) |object| { | |
| 1867 | files.putAssumeCapacityNoClobber(object.off - @sizeOf(elf.ar_hdr), object.name); | |
| 1868 | } | |
| 1869 | ||
| 1870 | var symbols = std.AutoArrayHashMap(usize, std.ArrayList([]const u8)).init(ctx.gpa); | |
| 1812 | var symbols: std.AutoArrayHashMap(usize, std.ArrayList([]const u8)) = .init(ctx.gpa); | |
| 1871 | 1813 | defer { |
| 1872 | for (symbols.values()) |*value| { | |
| 1873 | value.deinit(); | |
| 1874 | } | |
| 1814 | for (symbols.values()) |*value| value.deinit(); | |
| 1875 | 1815 | symbols.deinit(); |
| 1876 | 1816 | } |
| 1877 | 1817 | |
| 1878 | for (ctx.symtab.items) |entry| { | |
| 1818 | for (ctx.symtab) |entry| { | |
| 1879 | 1819 | const gop = try symbols.getOrPut(@intCast(entry.off)); |
| 1880 | if (!gop.found_existing) { | |
| 1881 | gop.value_ptr.* = std.ArrayList([]const u8).init(ctx.gpa); | |
| 1882 | } | |
| 1820 | if (!gop.found_existing) gop.value_ptr.* = .init(ctx.gpa); | |
| 1883 | 1821 | try gop.value_ptr.append(entry.name); |
| 1884 | 1822 | } |
| 1885 | 1823 | |
| 1886 | 1824 | try bw.print("{s}\n", .{archive_symtab_label}); |
| 1887 | 1825 | for (symbols.keys(), symbols.values()) |off, values| { |
| 1888 | try bw.print("in object {s}\n", .{files.get(off).?}); | |
| 1889 | for (values.items) |value| { | |
| 1890 | try bw.print("{s}\n", .{value}); | |
| 1891 | } | |
| 1826 | try bw.print("in object {s}\n", .{ctx.objects.get(off).?.name}); | |
| 1827 | for (values.items) |value| try bw.print("{s}\n", .{value}); | |
| 1892 | 1828 | } |
| 1893 | 1829 | } |
| 1894 | 1830 | |
| 1895 | 1831 | fn dumpObjects(ctx: ArchiveContext, step: *Step, check: Check, bw: *std.io.BufferedWriter) !void { |
| 1896 | for (ctx.objects.items) |object| { | |
| 1832 | for (ctx.objects.values()) |object| { | |
| 1897 | 1833 | try bw.print("object {s}\n", .{object.name}); |
| 1898 | const output = try parseAndDumpObject(step, check, ctx.data[object.off..][0..object.len]); | |
| 1834 | const output = try parseAndDumpObject(step, check, object.data); | |
| 1899 | 1835 | defer ctx.gpa.free(output); |
| 1900 | 1836 | try bw.print("{s}\n", .{output}); |
| 1901 | 1837 | } |
| ... | ... | @@ -1903,7 +1839,7 @@ const ElfDumper = struct { |
| 1903 | 1839 | |
| 1904 | 1840 | fn getString(ctx: ArchiveContext, off: u32) []const u8 { |
| 1905 | 1841 | assert(off < ctx.strtab.len); |
| 1906 | const name = mem.sliceTo(@as([*:'\n']const u8, @ptrCast(ctx.strtab.ptr + off)), 0); | |
| 1842 | const name = mem.sliceTo(@as([*:'\n']const u8, @ptrCast(ctx.strtab[off..].ptr)), 0); | |
| 1907 | 1843 | return name[0 .. name.len - 1]; |
| 1908 | 1844 | } |
| 1909 | 1845 | |
| ... | ... | @@ -1915,24 +1851,24 @@ const ElfDumper = struct { |
| 1915 | 1851 | |
| 1916 | 1852 | fn parseAndDumpObject(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 1917 | 1853 | const gpa = step.owner.allocator; |
| 1918 | var stream: std.io.FixedBufferStream = .{ .buffer = bytes }; | |
| 1919 | const reader = stream.reader(); | |
| 1854 | var br: std.io.BufferedReader = undefined; | |
| 1855 | br.initFixed(bytes); | |
| 1920 | 1856 | |
| 1921 | const hdr = try reader.readStruct(elf.Elf64_Ehdr); | |
| 1922 | if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) { | |
| 1923 | return error.InvalidMagicNumber; | |
| 1924 | } | |
| 1857 | const hdr = try br.takeStruct(elf.Elf64_Ehdr); | |
| 1858 | if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidMagicNumber; | |
| 1925 | 1859 | |
| 1926 | const shdrs = @as([*]align(1) const elf.Elf64_Shdr, @ptrCast(bytes.ptr + hdr.e_shoff))[0..hdr.e_shnum]; | |
| 1927 | const phdrs = @as([*]align(1) const elf.Elf64_Phdr, @ptrCast(bytes.ptr + hdr.e_phoff))[0..hdr.e_phnum]; | |
| 1860 | const shdrs = @as([*]align(1) const elf.Elf64_Shdr, @ptrCast(bytes[hdr.e_shoff..].ptr))[0..hdr.e_shnum]; | |
| 1861 | const phdrs = @as([*]align(1) const elf.Elf64_Phdr, @ptrCast(bytes[hdr.e_phoff..].ptr))[0..hdr.e_phnum]; | |
| 1928 | 1862 | |
| 1929 | var ctx = ObjectContext{ | |
| 1863 | var ctx: ObjectContext = .{ | |
| 1930 | 1864 | .gpa = gpa, |
| 1931 | 1865 | .data = bytes, |
| 1932 | 1866 | .hdr = hdr, |
| 1933 | 1867 | .shdrs = shdrs, |
| 1934 | 1868 | .phdrs = phdrs, |
| 1935 | 1869 | .shstrtab = undefined, |
| 1870 | .symtab = .{}, | |
| 1871 | .dysymtab = .{}, | |
| 1936 | 1872 | }; |
| 1937 | 1873 | ctx.shstrtab = ctx.getSectionContents(ctx.hdr.e_shstrndx); |
| 1938 | 1874 | |
| ... | ... | @@ -1963,8 +1899,10 @@ const ElfDumper = struct { |
| 1963 | 1899 | else => {}, |
| 1964 | 1900 | }; |
| 1965 | 1901 | |
| 1966 | var output: std.io.AllocatingWriter = undefined; | |
| 1967 | const bw = output.init(gpa); | |
| 1902 | var aw: std.io.AllocatingWriter = undefined; | |
| 1903 | aw.init(gpa); | |
| 1904 | defer aw.deinit(); | |
| 1905 | const bw = &aw.buffered_writer; | |
| 1968 | 1906 | |
| 1969 | 1907 | switch (check.kind) { |
| 1970 | 1908 | .headers => { |
| ... | ... | @@ -1986,7 +1924,7 @@ const ElfDumper = struct { |
| 1986 | 1924 | } else return step.fail("no .dynamic section found", .{}), |
| 1987 | 1925 | |
| 1988 | 1926 | .dump_section => { |
| 1989 | const name = mem.sliceTo(@as([*:0]const u8, @ptrCast(check.data.items.ptr + check.payload.dump_section)), 0); | |
| 1927 | const name = mem.sliceTo(@as([*:0]const u8, @ptrCast(check.data.items[check.payload.dump_section..].ptr)), 0); | |
| 1990 | 1928 | const shndx = ctx.getSectionByName(name) orelse return step.fail("no '{s}' section found", .{name}); |
| 1991 | 1929 | try ctx.dumpSection(shndx, bw); |
| 1992 | 1930 | }, |
| ... | ... | @@ -1994,18 +1932,18 @@ const ElfDumper = struct { |
| 1994 | 1932 | else => return step.fail("invalid check kind for ELF file format: {s}", .{@tagName(check.kind)}), |
| 1995 | 1933 | } |
| 1996 | 1934 | |
| 1997 | return output.toOwnedSlice(); | |
| 1935 | return aw.toOwnedSlice(); | |
| 1998 | 1936 | } |
| 1999 | 1937 | |
| 2000 | 1938 | const ObjectContext = struct { |
| 2001 | 1939 | gpa: Allocator, |
| 2002 | 1940 | data: []const u8, |
| 2003 | hdr: elf.Elf64_Ehdr, | |
| 1941 | hdr: *align(1) const elf.Elf64_Ehdr, | |
| 2004 | 1942 | shdrs: []align(1) const elf.Elf64_Shdr, |
| 2005 | 1943 | phdrs: []align(1) const elf.Elf64_Phdr, |
| 2006 | 1944 | shstrtab: []const u8, |
| 2007 | symtab: Symtab = .{}, | |
| 2008 | dysymtab: Symtab = .{}, | |
| 1945 | symtab: Symtab, | |
| 1946 | dysymtab: Symtab, | |
| 2009 | 1947 | |
| 2010 | 1948 | fn dumpHeader(ctx: ObjectContext, bw: *std.io.BufferedWriter) !void { |
| 2011 | 1949 | try bw.writeAll("header\n"); |
| ... | ... | @@ -2020,7 +1958,7 @@ const ElfDumper = struct { |
| 2020 | 1958 | |
| 2021 | 1959 | for (ctx.phdrs, 0..) |phdr, phndx| { |
| 2022 | 1960 | try bw.print("phdr {d}\n", .{phndx}); |
| 2023 | try bw.print("type {s}\n", .{fmtPhType(phdr.p_type)}); | |
| 1961 | try bw.print("type {f}\n", .{fmtPhType(phdr.p_type)}); | |
| 2024 | 1962 | try bw.print("vaddr {x}\n", .{phdr.p_vaddr}); |
| 2025 | 1963 | try bw.print("paddr {x}\n", .{phdr.p_paddr}); |
| 2026 | 1964 | try bw.print("offset {x}\n", .{phdr.p_offset}); |
| ... | ... | @@ -2060,7 +1998,7 @@ const ElfDumper = struct { |
| 2060 | 1998 | for (ctx.shdrs, 0..) |shdr, shndx| { |
| 2061 | 1999 | try bw.print("shdr {d}\n", .{shndx}); |
| 2062 | 2000 | try bw.print("name {s}\n", .{ctx.getSectionName(shndx)}); |
| 2063 | try bw.print("type {s}\n", .{fmtShType(shdr.sh_type)}); | |
| 2001 | try bw.print("type {f}\n", .{fmtShType(shdr.sh_type)}); | |
| 2064 | 2002 | try bw.print("addr {x}\n", .{shdr.sh_addr}); |
| 2065 | 2003 | try bw.print("offset {x}\n", .{shdr.sh_offset}); |
| 2066 | 2004 | try bw.print("size {x}\n", .{shdr.sh_size}); |
| ... | ... | @@ -2329,8 +2267,8 @@ const ElfDumper = struct { |
| 2329 | 2267 | }; |
| 2330 | 2268 | |
| 2331 | 2269 | fn getString(strtab: []const u8, off: u32) []const u8 { |
| 2332 | assert(off < strtab.len); | |
| 2333 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(strtab.ptr + off)), 0); | |
| 2270 | const str = strtab[off..]; | |
| 2271 | return str[0..std.mem.indexOfScalar(u8, str, 0).?]; | |
| 2334 | 2272 | } |
| 2335 | 2273 | |
| 2336 | 2274 | fn fmtShType(sh_type: u32) std.fmt.Formatter(formatShType) { |
| ... | ... | @@ -2339,12 +2277,10 @@ const ElfDumper = struct { |
| 2339 | 2277 | |
| 2340 | 2278 | fn formatShType( |
| 2341 | 2279 | sh_type: u32, |
| 2342 | comptime unused_fmt_string: []const u8, | |
| 2343 | options: std.fmt.FormatOptions, | |
| 2344 | 2280 | bw: *std.io.BufferedWriter, |
| 2281 | comptime unused_fmt_string: []const u8, | |
| 2345 | 2282 | ) !void { |
| 2346 | 2283 | _ = unused_fmt_string; |
| 2347 | _ = options; | |
| 2348 | 2284 | const name = switch (sh_type) { |
| 2349 | 2285 | elf.SHT_NULL => "NULL", |
| 2350 | 2286 | elf.SHT_PROGBITS => "PROGBITS", |
| ... | ... | @@ -2386,12 +2322,10 @@ const ElfDumper = struct { |
| 2386 | 2322 | |
| 2387 | 2323 | fn formatPhType( |
| 2388 | 2324 | ph_type: u32, |
| 2389 | comptime unused_fmt_string: []const u8, | |
| 2390 | options: std.fmt.FormatOptions, | |
| 2391 | 2325 | bw: *std.io.BufferedWriter, |
| 2326 | comptime unused_fmt_string: []const u8, | |
| 2392 | 2327 | ) !void { |
| 2393 | 2328 | _ = unused_fmt_string; |
| 2394 | _ = options; | |
| 2395 | 2329 | const p_type = switch (ph_type) { |
| 2396 | 2330 | elf.PT_NULL => "NULL", |
| 2397 | 2331 | elf.PT_LOAD => "LOAD", |
| ... | ... | @@ -2420,49 +2354,41 @@ const WasmDumper = struct { |
| 2420 | 2354 | |
| 2421 | 2355 | fn parseAndDump(step: *Step, check: Check, bytes: []const u8) ![]const u8 { |
| 2422 | 2356 | const gpa = step.owner.allocator; |
| 2423 | var fbs: std.io.FixedBufferStream = .{ .buffer = bytes }; | |
| 2424 | const reader = fbs.reader(); | |
| 2357 | var br: std.io.BufferedReader = undefined; | |
| 2358 | br.initFixed(bytes); | |
| 2425 | 2359 | |
| 2426 | const buf = try reader.readBytesNoEof(8); | |
| 2427 | if (!mem.eql(u8, buf[0..4], &std.wasm.magic)) { | |
| 2428 | return error.InvalidMagicByte; | |
| 2429 | } | |
| 2430 | if (!mem.eql(u8, buf[4..], &std.wasm.version)) { | |
| 2431 | return error.UnsupportedWasmVersion; | |
| 2432 | } | |
| 2360 | const buf = try br.takeArray(8); | |
| 2361 | if (!mem.eql(u8, buf[0..4], &std.wasm.magic)) return error.InvalidMagicByte; | |
| 2362 | if (!mem.eql(u8, buf[4..8], &std.wasm.version)) return error.UnsupportedWasmVersion; | |
| 2433 | 2363 | |
| 2434 | var output: std.io.AllocatingWriter = undefined; | |
| 2435 | const bw = output.init(gpa); | |
| 2436 | defer output.deinit(); | |
| 2437 | parseAndDumpInner(step, check, bytes, &fbs, bw) catch |err| switch (err) { | |
| 2364 | var aw: std.io.AllocatingWriter = undefined; | |
| 2365 | aw.init(gpa); | |
| 2366 | defer aw.deinit(); | |
| 2367 | const bw = &aw.buffered_writer; | |
| 2368 | ||
| 2369 | parseAndDumpInner(step, check, &br, bw) catch |err| switch (err) { | |
| 2438 | 2370 | error.EndOfStream => try bw.writeAll("\n<UnexpectedEndOfStream>"), |
| 2439 | 2371 | else => |e| return e, |
| 2440 | 2372 | }; |
| 2441 | return output.toOwnedSlice(); | |
| 2373 | return aw.toOwnedSlice(); | |
| 2442 | 2374 | } |
| 2443 | 2375 | |
| 2444 | 2376 | fn parseAndDumpInner( |
| 2445 | 2377 | step: *Step, |
| 2446 | 2378 | check: Check, |
| 2447 | bytes: []const u8, | |
| 2448 | fbs: *std.io.FixedBufferStream, | |
| 2379 | br: *std.io.BufferedReader, | |
| 2449 | 2380 | bw: *std.io.BufferedWriter, |
| 2450 | 2381 | ) !void { |
| 2451 | const reader = fbs.reader(); | |
| 2452 | ||
| 2382 | var section_br: std.io.BufferedReader = undefined; | |
| 2453 | 2383 | switch (check.kind) { |
| 2454 | .headers => { | |
| 2455 | while (reader.readByte()) |current_byte| { | |
| 2456 | const section = std.enums.fromInt(std.wasm.Section, current_byte) orelse { | |
| 2457 | return step.fail("Found invalid section id '{d}'", .{current_byte}); | |
| 2458 | }; | |
| 2459 | ||
| 2460 | const section_length = try std.leb.readUleb128(u32, reader); | |
| 2461 | try parseAndDumpSection(step, section, bytes[fbs.pos..][0..section_length], bw); | |
| 2462 | fbs.pos += section_length; | |
| 2463 | } else |_| {} // reached end of stream | |
| 2384 | .headers => while (br.takeEnum(std.wasm.Section, .little)) |section| { | |
| 2385 | section_br.initFixed(try br.take(try br.takeLeb128(u32))); | |
| 2386 | try parseAndDumpSection(step, section, &section_br, bw); | |
| 2387 | } else |err| switch (err) { | |
| 2388 | error.InvalidEnumTag => return step.fail("invalid section id", .{}), | |
| 2389 | error.EndOfStream => {}, | |
| 2390 | else => |e| return e, | |
| 2464 | 2391 | }, |
| 2465 | ||
| 2466 | 2392 | else => return step.fail("invalid check kind for Wasm file format: {s}", .{@tagName(check.kind)}), |
| 2467 | 2393 | } |
| 2468 | 2394 | } |
| ... | ... | @@ -2470,16 +2396,13 @@ const WasmDumper = struct { |
| 2470 | 2396 | fn parseAndDumpSection( |
| 2471 | 2397 | step: *Step, |
| 2472 | 2398 | section: std.wasm.Section, |
| 2473 | data: []const u8, | |
| 2399 | br: *std.io.BufferedReader, | |
| 2474 | 2400 | bw: *std.io.BufferedWriter, |
| 2475 | 2401 | ) !void { |
| 2476 | var fbs: std.io.FixedBufferStream = .{ .buffer = data }; | |
| 2477 | const reader = fbs.reader(); | |
| 2478 | ||
| 2479 | 2402 | try bw.print( |
| 2480 | 2403 | \\Section {s} |
| 2481 | 2404 | \\size {d} |
| 2482 | , .{ @tagName(section), data.len }); | |
| 2405 | , .{ @tagName(section), br.storageBuffer().len }); | |
| 2483 | 2406 | |
| 2484 | 2407 | switch (section) { |
| 2485 | 2408 | .type, |
| ... | ... | @@ -2493,74 +2416,65 @@ const WasmDumper = struct { |
| 2493 | 2416 | .code, |
| 2494 | 2417 | .data, |
| 2495 | 2418 | => { |
| 2496 | const entries = try std.leb.readUleb128(u32, reader); | |
| 2419 | const entries = try br.takeLeb128(u32); | |
| 2497 | 2420 | try bw.print("\nentries {d}\n", .{entries}); |
| 2498 | try parseSection(step, section, data[fbs.pos..], entries, bw); | |
| 2421 | try parseSection(step, section, br, entries, bw); | |
| 2499 | 2422 | }, |
| 2500 | 2423 | .custom => { |
| 2501 | const name_length = try std.leb.readUleb128(u32, reader); | |
| 2502 | const name = data[fbs.pos..][0..name_length]; | |
| 2503 | fbs.pos += name_length; | |
| 2424 | const name = try br.take(try br.takeLeb128(u32)); | |
| 2504 | 2425 | try bw.print("\nname {s}\n", .{name}); |
| 2505 | 2426 | |
| 2506 | 2427 | if (mem.eql(u8, name, "name")) { |
| 2507 | try parseDumpNames(step, reader, bw, data); | |
| 2428 | try parseDumpNames(step, br, bw); | |
| 2508 | 2429 | } else if (mem.eql(u8, name, "producers")) { |
| 2509 | try parseDumpProducers(reader, bw, data); | |
| 2430 | try parseDumpProducers(br, bw); | |
| 2510 | 2431 | } else if (mem.eql(u8, name, "target_features")) { |
| 2511 | try parseDumpFeatures(reader, bw, data); | |
| 2432 | try parseDumpFeatures(br, bw); | |
| 2512 | 2433 | } |
| 2513 | 2434 | // TODO: Implement parsing and dumping other custom sections (such as relocations) |
| 2514 | 2435 | }, |
| 2515 | 2436 | .start => { |
| 2516 | const start = try std.leb.readUleb128(u32, reader); | |
| 2437 | const start = try br.takeLeb128(u32); | |
| 2517 | 2438 | try bw.print("\nstart {d}\n", .{start}); |
| 2518 | 2439 | }, |
| 2519 | 2440 | .data_count => { |
| 2520 | const count = try std.leb.readUleb128(u32, reader); | |
| 2441 | const count = try br.takeLeb128(u32); | |
| 2521 | 2442 | try bw.print("\ncount {d}\n", .{count}); |
| 2522 | 2443 | }, |
| 2523 | 2444 | else => {}, // skip unknown sections |
| 2524 | 2445 | } |
| 2525 | 2446 | } |
| 2526 | 2447 | |
| 2527 | fn parseSection(step: *Step, section: std.wasm.Section, data: []const u8, entries: u32, bw: *std.io.BufferedWriter) !void { | |
| 2528 | var fbs: std.io.FixedBufferStream = .{ .buffer = data }; | |
| 2529 | const reader = fbs.reader(); | |
| 2530 | ||
| 2448 | fn parseSection(step: *Step, section: std.wasm.Section, br: *std.io.BufferedReader, entries: u32, bw: *std.io.BufferedWriter) !void { | |
| 2531 | 2449 | switch (section) { |
| 2532 | 2450 | .type => { |
| 2533 | 2451 | var i: u32 = 0; |
| 2534 | 2452 | while (i < entries) : (i += 1) { |
| 2535 | const func_type = try reader.readByte(); | |
| 2453 | const func_type = try br.takeByte(); | |
| 2536 | 2454 | if (func_type != std.wasm.function_type) { |
| 2537 | 2455 | return step.fail("expected function type, found byte '{d}'", .{func_type}); |
| 2538 | 2456 | } |
| 2539 | const params = try std.leb.readUleb128(u32, reader); | |
| 2457 | const params = try br.takeLeb128(u32); | |
| 2540 | 2458 | try bw.print("params {d}\n", .{params}); |
| 2541 | 2459 | var index: u32 = 0; |
| 2542 | 2460 | while (index < params) : (index += 1) { |
| 2543 | _ = try parseDumpType(step, std.wasm.Valtype, reader, bw); | |
| 2461 | _ = try parseDumpType(step, std.wasm.Valtype, br, bw); | |
| 2544 | 2462 | } else index = 0; |
| 2545 | const returns = try std.leb.readUleb128(u32, reader); | |
| 2463 | const returns = try br.takeLeb128(u32); | |
| 2546 | 2464 | try bw.print("returns {d}\n", .{returns}); |
| 2547 | 2465 | while (index < returns) : (index += 1) { |
| 2548 | _ = try parseDumpType(step, std.wasm.Valtype, reader, bw); | |
| 2466 | _ = try parseDumpType(step, std.wasm.Valtype, br, bw); | |
| 2549 | 2467 | } |
| 2550 | 2468 | } |
| 2551 | 2469 | }, |
| 2552 | 2470 | .import => { |
| 2553 | 2471 | var i: u32 = 0; |
| 2554 | 2472 | while (i < entries) : (i += 1) { |
| 2555 | const module_name_len = try std.leb.readUleb128(u32, reader); | |
| 2556 | const module_name = data[fbs.pos..][0..module_name_len]; | |
| 2557 | fbs.pos += module_name_len; | |
| 2558 | const name_len = try std.leb.readUleb128(u32, reader); | |
| 2559 | const name = data[fbs.pos..][0..name_len]; | |
| 2560 | fbs.pos += name_len; | |
| 2561 | ||
| 2562 | const kind = std.enums.fromInt(std.wasm.ExternalKind, try reader.readByte()) orelse { | |
| 2563 | return step.fail("invalid import kind", .{}); | |
| 2473 | const module_name = try br.take(try br.takeLeb128(u32)); | |
| 2474 | const name = try br.take(try br.takeLeb128(u32)); | |
| 2475 | const kind = br.takeEnum(std.wasm.ExternalKind, .little) catch |err| switch (err) { | |
| 2476 | error.InvalidEnumTag => return step.fail("invalid import kind", .{}), | |
| 2477 | else => |e| return e, | |
| 2564 | 2478 | }; |
| 2565 | 2479 | |
| 2566 | 2480 | try bw.print( |
| ... | ... | @@ -2570,19 +2484,15 @@ const WasmDumper = struct { |
| 2570 | 2484 | , .{ module_name, name, @tagName(kind) }); |
| 2571 | 2485 | try bw.writeByte('\n'); |
| 2572 | 2486 | switch (kind) { |
| 2573 | .function => { | |
| 2574 | try bw.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)}); | |
| 2575 | }, | |
| 2576 | .memory => { | |
| 2577 | try parseDumpLimits(reader, bw); | |
| 2578 | }, | |
| 2487 | .function => try bw.print("index {d}\n", .{try br.takeLeb128(u32)}), | |
| 2488 | .memory => try parseDumpLimits(br, bw), | |
| 2579 | 2489 | .global => { |
| 2580 | _ = try parseDumpType(step, std.wasm.Valtype, reader, bw); | |
| 2581 | try bw.print("mutable {}\n", .{0x01 == try std.leb.readUleb128(u32, reader)}); | |
| 2490 | _ = try parseDumpType(step, std.wasm.Valtype, br, bw); | |
| 2491 | try bw.print("mutable {}\n", .{0x01 == try br.takeLeb128(u32)}); | |
| 2582 | 2492 | }, |
| 2583 | 2493 | .table => { |
| 2584 | _ = try parseDumpType(step, std.wasm.RefType, reader, bw); | |
| 2585 | try parseDumpLimits(reader, bw); | |
| 2494 | _ = try parseDumpType(step, std.wasm.RefType, br, bw); | |
| 2495 | try parseDumpLimits(br, bw); | |
| 2586 | 2496 | }, |
| 2587 | 2497 | } |
| 2588 | 2498 | } |
| ... | ... | @@ -2590,41 +2500,39 @@ const WasmDumper = struct { |
| 2590 | 2500 | .function => { |
| 2591 | 2501 | var i: u32 = 0; |
| 2592 | 2502 | while (i < entries) : (i += 1) { |
| 2593 | try bw.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)}); | |
| 2503 | try bw.print("index {d}\n", .{try br.takeLeb128(u32)}); | |
| 2594 | 2504 | } |
| 2595 | 2505 | }, |
| 2596 | 2506 | .table => { |
| 2597 | 2507 | var i: u32 = 0; |
| 2598 | 2508 | while (i < entries) : (i += 1) { |
| 2599 | _ = try parseDumpType(step, std.wasm.RefType, reader, bw); | |
| 2600 | try parseDumpLimits(reader, bw); | |
| 2509 | _ = try parseDumpType(step, std.wasm.RefType, br, bw); | |
| 2510 | try parseDumpLimits(br, bw); | |
| 2601 | 2511 | } |
| 2602 | 2512 | }, |
| 2603 | 2513 | .memory => { |
| 2604 | 2514 | var i: u32 = 0; |
| 2605 | 2515 | while (i < entries) : (i += 1) { |
| 2606 | try parseDumpLimits(reader, bw); | |
| 2516 | try parseDumpLimits(br, bw); | |
| 2607 | 2517 | } |
| 2608 | 2518 | }, |
| 2609 | 2519 | .global => { |
| 2610 | 2520 | var i: u32 = 0; |
| 2611 | 2521 | while (i < entries) : (i += 1) { |
| 2612 | _ = try parseDumpType(step, std.wasm.Valtype, reader, bw); | |
| 2613 | try bw.print("mutable {}\n", .{0x01 == try std.leb.readUleb128(u1, reader)}); | |
| 2614 | try parseDumpInit(step, reader, bw); | |
| 2522 | _ = try parseDumpType(step, std.wasm.Valtype, br, bw); | |
| 2523 | try bw.print("mutable {}\n", .{0x01 == try br.takeLeb128(u1)}); | |
| 2524 | try parseDumpInit(step, br, bw); | |
| 2615 | 2525 | } |
| 2616 | 2526 | }, |
| 2617 | 2527 | .@"export" => { |
| 2618 | 2528 | var i: u32 = 0; |
| 2619 | 2529 | while (i < entries) : (i += 1) { |
| 2620 | const name_len = try std.leb.readUleb128(u32, reader); | |
| 2621 | const name = data[fbs.pos..][0..name_len]; | |
| 2622 | fbs.pos += name_len; | |
| 2623 | const kind_byte = try std.leb.readUleb128(u8, reader); | |
| 2624 | const kind = std.enums.fromInt(std.wasm.ExternalKind, kind_byte) orelse { | |
| 2625 | return step.fail("invalid export kind value '{d}'", .{kind_byte}); | |
| 2530 | const name = try br.take(try br.takeLeb128(u32)); | |
| 2531 | const kind = br.takeEnum(std.wasm.ExternalKind, .little) catch |err| switch (err) { | |
| 2532 | error.InvalidEnumTag => return step.fail("invalid export kind value", .{}), | |
| 2533 | else => |e| return e, | |
| 2626 | 2534 | }; |
| 2627 | const index = try std.leb.readUleb128(u32, reader); | |
| 2535 | const index = try br.takeLeb128(u32); | |
| 2628 | 2536 | try bw.print( |
| 2629 | 2537 | \\name {s} |
| 2630 | 2538 | \\kind {s} |
| ... | ... | @@ -2636,14 +2544,14 @@ const WasmDumper = struct { |
| 2636 | 2544 | .element => { |
| 2637 | 2545 | var i: u32 = 0; |
| 2638 | 2546 | while (i < entries) : (i += 1) { |
| 2639 | try bw.print("table index {d}\n", .{try std.leb.readUleb128(u32, reader)}); | |
| 2640 | try parseDumpInit(step, reader, bw); | |
| 2547 | try bw.print("table index {d}\n", .{try br.takeLeb128(u32)}); | |
| 2548 | try parseDumpInit(step, br, bw); | |
| 2641 | 2549 | |
| 2642 | const function_indexes = try std.leb.readUleb128(u32, reader); | |
| 2550 | const function_indexes = try br.takeLeb128(u32); | |
| 2643 | 2551 | var function_index: u32 = 0; |
| 2644 | 2552 | try bw.print("indexes {d}\n", .{function_indexes}); |
| 2645 | 2553 | while (function_index < function_indexes) : (function_index += 1) { |
| 2646 | try bw.print("index {d}\n", .{try std.leb.readUleb128(u32, reader)}); | |
| 2554 | try bw.print("index {d}\n", .{try br.takeLeb128(u32)}); | |
| 2647 | 2555 | } |
| 2648 | 2556 | } |
| 2649 | 2557 | }, |
| ... | ... | @@ -2651,101 +2559,95 @@ const WasmDumper = struct { |
| 2651 | 2559 | .data => { |
| 2652 | 2560 | var i: u32 = 0; |
| 2653 | 2561 | while (i < entries) : (i += 1) { |
| 2654 | const flags = try std.leb.readUleb128(u32, reader); | |
| 2655 | const index = if (flags & 0x02 != 0) | |
| 2656 | try std.leb.readUleb128(u32, reader) | |
| 2657 | else | |
| 2658 | 0; | |
| 2562 | const flags: packed struct(u32) { | |
| 2563 | passive: bool, | |
| 2564 | memidx: bool, | |
| 2565 | unused: u30, | |
| 2566 | } = @bitCast(try br.takeLeb128(u32)); | |
| 2567 | const index = if (flags.memidx) try br.takeLeb128(u32) else 0; | |
| 2659 | 2568 | try bw.print("memory index 0x{x}\n", .{index}); |
| 2660 | if (flags == 0) { | |
| 2661 | try parseDumpInit(step, reader, bw); | |
| 2662 | } | |
| 2663 | ||
| 2664 | const size = try std.leb.readUleb128(u32, reader); | |
| 2569 | if (!flags.passive) try parseDumpInit(step, br, bw); | |
| 2570 | const size = try br.takeLeb128(u32); | |
| 2665 | 2571 | try bw.print("size {d}\n", .{size}); |
| 2666 | try reader.skipBytes(size, .{}); // we do not care about the content of the segments | |
| 2572 | try br.discard(size); // we do not care about the content of the segments | |
| 2667 | 2573 | } |
| 2668 | 2574 | }, |
| 2669 | 2575 | else => unreachable, |
| 2670 | 2576 | } |
| 2671 | 2577 | } |
| 2672 | 2578 | |
| 2673 | fn parseDumpType(step: *Step, comptime E: type, reader: anytype, bw: *std.io.BufferedWriter) !E { | |
| 2674 | const byte = try reader.readByte(); | |
| 2675 | const tag = std.enums.fromInt(E, byte) orelse { | |
| 2676 | return step.fail("invalid wasm type value '{d}'", .{byte}); | |
| 2579 | fn parseDumpType(step: *Step, comptime E: type, br: *std.io.BufferedReader, bw: *std.io.BufferedWriter) !E { | |
| 2580 | const tag = br.takeEnum(E, .little) catch |err| switch (err) { | |
| 2581 | error.InvalidEnumTag => return step.fail("invalid wasm type value", .{}), | |
| 2582 | else => |e| return e, | |
| 2677 | 2583 | }; |
| 2678 | 2584 | try bw.print("type {s}\n", .{@tagName(tag)}); |
| 2679 | 2585 | return tag; |
| 2680 | 2586 | } |
| 2681 | 2587 | |
| 2682 | fn parseDumpLimits(reader: anytype, bw: *std.io.BufferedWriter) !void { | |
| 2683 | const flags = try std.leb.readUleb128(u8, reader); | |
| 2684 | const min = try std.leb.readUleb128(u32, reader); | |
| 2588 | fn parseDumpLimits(br: *std.io.BufferedReader, bw: *std.io.BufferedWriter) !void { | |
| 2589 | const flags = try br.takeLeb128(u8); | |
| 2590 | const min = try br.takeLeb128(u32); | |
| 2685 | 2591 | |
| 2686 | 2592 | try bw.print("min {x}\n", .{min}); |
| 2687 | if (flags != 0) { | |
| 2688 | try bw.print("max {x}\n", .{try std.leb.readUleb128(u32, reader)}); | |
| 2689 | } | |
| 2593 | if (flags != 0) try bw.print("max {x}\n", .{try br.takeLeb128(u32)}); | |
| 2690 | 2594 | } |
| 2691 | 2595 | |
| 2692 | fn parseDumpInit(step: *Step, reader: anytype, bw: *std.io.BufferedWriter) !void { | |
| 2693 | const byte = try reader.readByte(); | |
| 2694 | const opcode = std.enums.fromInt(std.wasm.Opcode, byte) orelse { | |
| 2695 | return step.fail("invalid wasm opcode '{d}'", .{byte}); | |
| 2596 | fn parseDumpInit(step: *Step, br: *std.io.BufferedReader, bw: *std.io.BufferedWriter) !void { | |
| 2597 | const opcode = br.takeEnum(std.wasm.Opcode, .little) catch |err| switch (err) { | |
| 2598 | error.InvalidEnumTag => return step.fail("invalid wasm opcode", .{}), | |
| 2599 | else => |e| return e, | |
| 2696 | 2600 | }; |
| 2697 | 2601 | switch (opcode) { |
| 2698 | .i32_const => try bw.print("i32.const {x}\n", .{try std.leb.readIleb128(i32, reader)}), | |
| 2699 | .i64_const => try bw.print("i64.const {x}\n", .{try std.leb.readIleb128(i64, reader)}), | |
| 2700 | .f32_const => try bw.print("f32.const {x}\n", .{@as(f32, @bitCast(try reader.readInt(u32, .little)))}), | |
| 2701 | .f64_const => try bw.print("f64.const {x}\n", .{@as(f64, @bitCast(try reader.readInt(u64, .little)))}), | |
| 2702 | .global_get => try bw.print("global.get {x}\n", .{try std.leb.readUleb128(u32, reader)}), | |
| 2602 | .i32_const => try bw.print("i32.const {x}\n", .{try br.takeLeb128(i32)}), | |
| 2603 | .i64_const => try bw.print("i64.const {x}\n", .{try br.takeLeb128(i64)}), | |
| 2604 | .f32_const => try bw.print("f32.const {x}\n", .{@as(f32, @bitCast(try br.takeInt(u32, .little)))}), | |
| 2605 | .f64_const => try bw.print("f64.const {x}\n", .{@as(f64, @bitCast(try br.takeInt(u64, .little)))}), | |
| 2606 | .global_get => try bw.print("global.get {x}\n", .{try br.takeLeb128(u32)}), | |
| 2703 | 2607 | else => unreachable, |
| 2704 | 2608 | } |
| 2705 | const end_opcode = try std.leb.readUleb128(u8, reader); | |
| 2609 | const end_opcode = try br.takeLeb128(u8); | |
| 2706 | 2610 | if (end_opcode != @intFromEnum(std.wasm.Opcode.end)) { |
| 2707 | 2611 | return step.fail("expected 'end' opcode in init expression", .{}); |
| 2708 | 2612 | } |
| 2709 | 2613 | } |
| 2710 | 2614 | |
| 2711 | 2615 | /// https://webassembly.github.io/spec/core/appendix/custom.html |
| 2712 | fn parseDumpNames(step: *Step, reader: anytype, bw: *std.io.BufferedWriter, data: []const u8) !void { | |
| 2713 | while (reader.context.pos < data.len) { | |
| 2714 | switch (try parseDumpType(step, std.wasm.NameSubsection, reader, bw)) { | |
| 2616 | fn parseDumpNames(step: *Step, br: *std.io.BufferedReader, bw: *std.io.BufferedWriter) !void { | |
| 2617 | var subsection_br: std.io.BufferedReader = undefined; | |
| 2618 | while (br.seek < br.storageBuffer().len) { | |
| 2619 | switch (try parseDumpType(step, std.wasm.NameSubsection, br, bw)) { | |
| 2715 | 2620 | // The module name subsection ... consists of a single name |
| 2716 | 2621 | // that is assigned to the module itself. |
| 2717 | 2622 | .module => { |
| 2718 | const size = try std.leb.readUleb128(u32, reader); | |
| 2719 | const name_len = try std.leb.readUleb128(u32, reader); | |
| 2720 | if (size != name_len + 1) return error.BadSubsectionSize; | |
| 2721 | if (reader.context.pos + name_len > data.len) return error.UnexpectedEndOfStream; | |
| 2722 | try bw.print("name {s}\n", .{data[reader.context.pos..][0..name_len]}); | |
| 2723 | reader.context.pos += name_len; | |
| 2623 | subsection_br.initFixed(try br.take(try br.takeLeb128(u32))); | |
| 2624 | const name = try subsection_br.take(try subsection_br.takeLeb128(u32)); | |
| 2625 | try bw.print( | |
| 2626 | \\name {s} | |
| 2627 | \\ | |
| 2628 | , .{name}); | |
| 2629 | if (subsection_br.seek != subsection_br.storageBuffer().len) return error.BadSubsectionSize; | |
| 2724 | 2630 | }, |
| 2725 | 2631 | |
| 2726 | 2632 | // The function name subsection ... consists of a name map |
| 2727 | 2633 | // assigning function names to function indices. |
| 2728 | 2634 | .function, .global, .data_segment => { |
| 2729 | const size = try std.leb.readUleb128(u32, reader); | |
| 2730 | const entries = try std.leb.readUleb128(u32, reader); | |
| 2635 | subsection_br.initFixed(try br.take(try br.takeLeb128(u32))); | |
| 2636 | const entries = try br.takeLeb128(u32); | |
| 2731 | 2637 | try bw.print( |
| 2732 | \\size {d} | |
| 2733 | 2638 | \\names {d} |
| 2734 | 2639 | \\ |
| 2735 | , .{ size, entries }); | |
| 2640 | , .{entries}); | |
| 2736 | 2641 | for (0..entries) |_| { |
| 2737 | const index = try std.leb.readUleb128(u32, reader); | |
| 2738 | const name_len = try std.leb.readUleb128(u32, reader); | |
| 2739 | if (reader.context.pos + name_len > data.len) return error.UnexpectedEndOfStream; | |
| 2740 | const name = data[reader.context.pos..][0..name_len]; | |
| 2741 | reader.context.pos += name.len; | |
| 2742 | ||
| 2642 | const index = try br.takeLeb128(u32); | |
| 2643 | const name = try br.take(try br.takeLeb128(u32)); | |
| 2743 | 2644 | try bw.print( |
| 2744 | 2645 | \\index {d} |
| 2745 | 2646 | \\name {s} |
| 2746 | 2647 | \\ |
| 2747 | 2648 | , .{ index, name }); |
| 2748 | 2649 | } |
| 2650 | if (subsection_br.seek != subsection_br.storageBuffer().len) return error.BadSubsectionSize; | |
| 2749 | 2651 | }, |
| 2750 | 2652 | |
| 2751 | 2653 | // The local name subsection ... consists of an indirect name |
| ... | ... | @@ -2760,52 +2662,49 @@ const WasmDumper = struct { |
| 2760 | 2662 | } |
| 2761 | 2663 | } |
| 2762 | 2664 | |
| 2763 | fn parseDumpProducers(reader: anytype, bw: *std.io.BufferedWriter, data: []const u8) !void { | |
| 2764 | const field_count = try std.leb.readUleb128(u32, reader); | |
| 2765 | try bw.print("fields {d}\n", .{field_count}); | |
| 2665 | fn parseDumpProducers(br: *std.io.BufferedReader, bw: *std.io.BufferedWriter) !void { | |
| 2666 | const field_count = try br.takeLeb128(u32); | |
| 2667 | try bw.print( | |
| 2668 | \\fields {d} | |
| 2669 | \\ | |
| 2670 | , .{field_count}); | |
| 2766 | 2671 | var current_field: u32 = 0; |
| 2767 | 2672 | while (current_field < field_count) : (current_field += 1) { |
| 2768 | const field_name_length = try std.leb.readUleb128(u32, reader); | |
| 2769 | const field_name = data[reader.context.pos..][0..field_name_length]; | |
| 2770 | reader.context.pos += field_name_length; | |
| 2771 | ||
| 2772 | const value_count = try std.leb.readUleb128(u32, reader); | |
| 2673 | const field_name = try br.take(try br.takeLeb128(u32)); | |
| 2674 | const value_count = try br.takeLeb128(u32); | |
| 2773 | 2675 | try bw.print( |
| 2774 | 2676 | \\field_name {s} |
| 2775 | 2677 | \\values {d} |
| 2678 | \\ | |
| 2776 | 2679 | , .{ field_name, value_count }); |
| 2777 | try bw.writeByte('\n'); | |
| 2778 | 2680 | var current_value: u32 = 0; |
| 2779 | 2681 | while (current_value < value_count) : (current_value += 1) { |
| 2780 | const value_length = try std.leb.readUleb128(u32, reader); | |
| 2781 | const value = data[reader.context.pos..][0..value_length]; | |
| 2782 | reader.context.pos += value_length; | |
| 2783 | ||
| 2784 | const version_length = try std.leb.readUleb128(u32, reader); | |
| 2785 | const version = data[reader.context.pos..][0..version_length]; | |
| 2786 | reader.context.pos += version_length; | |
| 2787 | ||
| 2682 | const value = try br.take(try br.takeLeb128(u32)); | |
| 2683 | const version = try br.take(try br.takeLeb128(u32)); | |
| 2788 | 2684 | try bw.print( |
| 2789 | 2685 | \\value_name {s} |
| 2790 | 2686 | \\version {s} |
| 2687 | \\ | |
| 2791 | 2688 | , .{ value, version }); |
| 2792 | try bw.writeByte('\n'); | |
| 2793 | 2689 | } |
| 2794 | 2690 | } |
| 2795 | 2691 | } |
| 2796 | 2692 | |
| 2797 | fn parseDumpFeatures(reader: anytype, bw: *std.io.BufferedWriter, data: []const u8) !void { | |
| 2798 | const feature_count = try std.leb.readUleb128(u32, reader); | |
| 2799 | try bw.print("features {d}\n", .{feature_count}); | |
| 2693 | fn parseDumpFeatures(br: *std.io.BufferedReader, bw: *std.io.BufferedWriter) !void { | |
| 2694 | const feature_count = try br.takeLeb128(u32); | |
| 2695 | try bw.print( | |
| 2696 | \\features {d} | |
| 2697 | \\ | |
| 2698 | , .{feature_count}); | |
| 2800 | 2699 | |
| 2801 | 2700 | var index: u32 = 0; |
| 2802 | 2701 | while (index < feature_count) : (index += 1) { |
| 2803 | const prefix_byte = try std.leb.readUleb128(u8, reader); | |
| 2804 | const name_length = try std.leb.readUleb128(u32, reader); | |
| 2805 | const feature_name = data[reader.context.pos..][0..name_length]; | |
| 2806 | reader.context.pos += name_length; | |
| 2807 | ||
| 2808 | try bw.print("{c} {s}\n", .{ prefix_byte, feature_name }); | |
| 2702 | const prefix_byte = try br.takeLeb128(u8); | |
| 2703 | const feature_name = try br.take(try br.takeLeb128(u32)); | |
| 2704 | try bw.print( | |
| 2705 | \\{c} {s} | |
| 2706 | \\ | |
| 2707 | , .{ prefix_byte, feature_name }); | |
| 2809 | 2708 | } |
| 2810 | 2709 | } |
| 2811 | 2710 | }; |
lib/std/Build/Step/Compile.zig+6-6| ... | ... | @@ -409,7 +409,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 409 | 409 | .linkage = options.linkage, |
| 410 | 410 | .kind = options.kind, |
| 411 | 411 | .name = name, |
| 412 | .step = Step.init(.{ | |
| 412 | .step = .init(.{ | |
| 413 | 413 | .id = base_id, |
| 414 | 414 | .name = step_name, |
| 415 | 415 | .owner = owner, |
| ... | ... | @@ -1542,7 +1542,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { |
| 1542 | 1542 | if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic) { |
| 1543 | 1543 | if (compile.version) |version| { |
| 1544 | 1544 | try zig_args.append("--version"); |
| 1545 | try zig_args.append(b.fmt("{}", .{version})); | |
| 1545 | try zig_args.append(b.fmt("{f}", .{version})); | |
| 1546 | 1546 | } |
| 1547 | 1547 | |
| 1548 | 1548 | if (compile.rootModuleTarget().os.tag.isDarwin()) { |
| ... | ... | @@ -1704,7 +1704,7 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { |
| 1704 | 1704 | const opt_zig_lib_dir = if (compile.zig_lib_dir) |dir| |
| 1705 | 1705 | dir.getPath2(b, step) |
| 1706 | 1706 | else if (b.graph.zig_lib_directory.path) |_| |
| 1707 | b.fmt("{}", .{b.graph.zig_lib_directory}) | |
| 1707 | b.fmt("{f}", .{b.graph.zig_lib_directory}) | |
| 1708 | 1708 | else |
| 1709 | 1709 | null; |
| 1710 | 1710 | |
| ... | ... | @@ -1830,7 +1830,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 1830 | 1830 | // Update generated files |
| 1831 | 1831 | if (maybe_output_dir) |output_dir| { |
| 1832 | 1832 | if (compile.emit_directory) |lp| { |
| 1833 | lp.path = b.fmt("{}", .{output_dir}); | |
| 1833 | lp.path = b.fmt("{f}", .{output_dir}); | |
| 1834 | 1834 | } |
| 1835 | 1835 | |
| 1836 | 1836 | // zig fmt: off |
| ... | ... | @@ -1970,13 +1970,13 @@ fn checkCompileErrors(compile: *Compile) !void { |
| 1970 | 1970 | |
| 1971 | 1971 | const actual_errors = ae: { |
| 1972 | 1972 | var aw: std.io.AllocatingWriter = undefined; |
| 1973 | const bw = aw.init(arena); | |
| 1973 | aw.init(arena); | |
| 1974 | 1974 | defer aw.deinit(); |
| 1975 | 1975 | try actual_eb.renderToWriter(.{ |
| 1976 | 1976 | .ttyconf = .no_color, |
| 1977 | 1977 | .include_reference_trace = false, |
| 1978 | 1978 | .include_source_line = false, |
| 1979 | }, bw); | |
| 1979 | }, &aw.buffered_writer); | |
| 1980 | 1980 | break :ae try aw.toOwnedSlice(); |
| 1981 | 1981 | }; |
| 1982 | 1982 |
lib/std/Build/Step/ConfigHeader.zig+89-137| ... | ... | @@ -87,7 +87,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader { |
| 87 | 87 | owner.fmt("configure {s} header to {s}", .{ @tagName(options.style), include_path }); |
| 88 | 88 | |
| 89 | 89 | config_header.* = .{ |
| 90 | .step = Step.init(.{ | |
| 90 | .step = .init(.{ | |
| 91 | 91 | .id = base_id, |
| 92 | 92 | .name = name, |
| 93 | 93 | .owner = owner, |
| ... | ... | @@ -95,7 +95,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader { |
| 95 | 95 | .first_ret_addr = options.first_ret_addr orelse @returnAddress(), |
| 96 | 96 | }), |
| 97 | 97 | .style = options.style, |
| 98 | .values = std.StringArrayHashMap(Value).init(owner.allocator), | |
| 98 | .values = .init(owner.allocator), | |
| 99 | 99 | |
| 100 | 100 | .max_bytes = options.max_bytes, |
| 101 | 101 | .include_path = include_path, |
| ... | ... | @@ -195,8 +195,10 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 195 | 195 | man.hash.addBytes(config_header.include_path); |
| 196 | 196 | man.hash.addOptionalBytes(config_header.include_guard_override); |
| 197 | 197 | |
| 198 | var output = std.ArrayList(u8).init(gpa); | |
| 199 | defer output.deinit(); | |
| 198 | var aw: std.io.AllocatingWriter = undefined; | |
| 199 | aw.init(gpa); | |
| 200 | defer aw.deinit(); | |
| 201 | const bw = &aw.buffered_writer; | |
| 200 | 202 | |
| 201 | 203 | const header_text = "This file was generated by ConfigHeader using the Zig Build System."; |
| 202 | 204 | const c_generated_line = "/* " ++ header_text ++ " */\n"; |
| ... | ... | @@ -204,40 +206,41 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 204 | 206 | |
| 205 | 207 | switch (config_header.style) { |
| 206 | 208 | .autoconf_undef, .autoconf, .autoconf_at => |file_source| { |
| 207 | try output.appendSlice(c_generated_line); | |
| 209 | try bw.writeAll(c_generated_line); | |
| 208 | 210 | const src_path = file_source.getPath2(b, step); |
| 209 | const contents = std.fs.cwd().readFileAlloc(arena, src_path, config_header.max_bytes) catch |err| { | |
| 211 | const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { | |
| 210 | 212 | return step.fail("unable to read autoconf input file '{s}': {s}", .{ |
| 211 | 213 | src_path, @errorName(err), |
| 212 | 214 | }); |
| 213 | 215 | }; |
| 214 | 216 | switch (config_header.style) { |
| 215 | .autoconf_undef, .autoconf => try render_autoconf_undef(step, contents, &output, config_header.values, src_path), | |
| 216 | .autoconf_at => try render_autoconf_at(step, contents, &output, config_header.values, src_path), | |
| 217 | .autoconf_undef, .autoconf => try render_autoconf_undef(step, contents, bw, config_header.values, src_path), | |
| 218 | .autoconf_at => try render_autoconf_at(step, contents, &aw, config_header.values, src_path), | |
| 217 | 219 | else => unreachable, |
| 218 | 220 | } |
| 219 | 221 | }, |
| 220 | 222 | .cmake => |file_source| { |
| 221 | try output.appendSlice(c_generated_line); | |
| 223 | try bw.writeAll(c_generated_line); | |
| 222 | 224 | const src_path = file_source.getPath2(b, step); |
| 223 | const contents = std.fs.cwd().readFileAlloc(arena, src_path, config_header.max_bytes) catch |err| { | |
| 225 | const contents = std.fs.cwd().readFileAlloc(src_path, arena, .limited(config_header.max_bytes)) catch |err| { | |
| 224 | 226 | return step.fail("unable to read cmake input file '{s}': {s}", .{ |
| 225 | 227 | src_path, @errorName(err), |
| 226 | 228 | }); |
| 227 | 229 | }; |
| 228 | try render_cmake(step, contents, &output, config_header.values, src_path); | |
| 230 | try render_cmake(step, contents, bw, config_header.values, src_path); | |
| 229 | 231 | }, |
| 230 | 232 | .blank => { |
| 231 | try output.appendSlice(c_generated_line); | |
| 232 | try render_blank(&output, config_header.values, config_header.include_path, config_header.include_guard_override); | |
| 233 | try bw.writeAll(c_generated_line); | |
| 234 | try render_blank(gpa, bw, config_header.values, config_header.include_path, config_header.include_guard_override); | |
| 233 | 235 | }, |
| 234 | 236 | .nasm => { |
| 235 | try output.appendSlice(asm_generated_line); | |
| 236 | try render_nasm(&output, config_header.values); | |
| 237 | try bw.writeAll(asm_generated_line); | |
| 238 | try render_nasm(bw, config_header.values); | |
| 237 | 239 | }, |
| 238 | 240 | } |
| 239 | 241 | |
| 240 | man.hash.addBytes(output.items); | |
| 242 | const output = aw.getWritten(); | |
| 243 | man.hash.addBytes(output); | |
| 241 | 244 | |
| 242 | 245 | if (try step.cacheHit(&man)) { |
| 243 | 246 | const digest = man.final(); |
| ... | ... | @@ -256,13 +259,13 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 256 | 259 | const sub_path_dirname = std.fs.path.dirname(sub_path).?; |
| 257 | 260 | |
| 258 | 261 | b.cache_root.handle.makePath(sub_path_dirname) catch |err| { |
| 259 | return step.fail("unable to make path '{}{s}': {s}", .{ | |
| 262 | return step.fail("unable to make path '{f}{s}': {s}", .{ | |
| 260 | 263 | b.cache_root, sub_path_dirname, @errorName(err), |
| 261 | 264 | }); |
| 262 | 265 | }; |
| 263 | 266 | |
| 264 | b.cache_root.handle.writeFile(.{ .sub_path = sub_path, .data = output.items }) catch |err| { | |
| 265 | return step.fail("unable to write file '{}{s}': {s}", .{ | |
| 267 | b.cache_root.handle.writeFile(.{ .sub_path = sub_path, .data = output }) catch |err| { | |
| 268 | return step.fail("unable to write file '{f}{s}': {s}", .{ | |
| 266 | 269 | b.cache_root, sub_path, @errorName(err), |
| 267 | 270 | }); |
| 268 | 271 | }; |
| ... | ... | @@ -274,7 +277,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 274 | 277 | fn render_autoconf_undef( |
| 275 | 278 | step: *Step, |
| 276 | 279 | contents: []const u8, |
| 277 | output: *std.ArrayList(u8), | |
| 280 | bw: *std.io.BufferedWriter, | |
| 278 | 281 | values: std.StringArrayHashMap(Value), |
| 279 | 282 | src_path: []const u8, |
| 280 | 283 | ) !void { |
| ... | ... | @@ -289,15 +292,15 @@ fn render_autoconf_undef( |
| 289 | 292 | var line_it = std.mem.splitScalar(u8, contents, '\n'); |
| 290 | 293 | while (line_it.next()) |line| : (line_index += 1) { |
| 291 | 294 | if (!std.mem.startsWith(u8, line, "#")) { |
| 292 | try output.appendSlice(line); | |
| 293 | try output.appendSlice("\n"); | |
| 295 | try bw.writeAll(line); | |
| 296 | try bw.writeByte('\n'); | |
| 294 | 297 | continue; |
| 295 | 298 | } |
| 296 | 299 | var it = std.mem.tokenizeAny(u8, line[1..], " \t\r"); |
| 297 | 300 | const undef = it.next().?; |
| 298 | 301 | if (!std.mem.eql(u8, undef, "undef")) { |
| 299 | try output.appendSlice(line); | |
| 300 | try output.appendSlice("\n"); | |
| 302 | try bw.writeAll(line); | |
| 303 | try bw.writeByte('\n'); | |
| 301 | 304 | continue; |
| 302 | 305 | } |
| 303 | 306 | const name = it.next().?; |
| ... | ... | @@ -309,7 +312,7 @@ fn render_autoconf_undef( |
| 309 | 312 | continue; |
| 310 | 313 | }; |
| 311 | 314 | is_used.set(index); |
| 312 | try renderValueC(output, name, values.values()[index]); | |
| 315 | try renderValueC(bw, name, values.values()[index]); | |
| 313 | 316 | } |
| 314 | 317 | |
| 315 | 318 | var unused_value_it = is_used.iterator(.{ .kind = .unset }); |
| ... | ... | @@ -326,12 +329,13 @@ fn render_autoconf_undef( |
| 326 | 329 | fn render_autoconf_at( |
| 327 | 330 | step: *Step, |
| 328 | 331 | contents: []const u8, |
| 329 | output: *std.ArrayList(u8), | |
| 332 | aw: *std.io.AllocatingWriter, | |
| 330 | 333 | values: std.StringArrayHashMap(Value), |
| 331 | 334 | src_path: []const u8, |
| 332 | 335 | ) !void { |
| 333 | 336 | const build = step.owner; |
| 334 | 337 | const allocator = build.allocator; |
| 338 | const bw = &aw.buffered_writer; | |
| 335 | 339 | |
| 336 | 340 | const used = allocator.alloc(bool, values.count()) catch @panic("OOM"); |
| 337 | 341 | for (used) |*u| u.* = false; |
| ... | ... | @@ -343,11 +347,11 @@ fn render_autoconf_at( |
| 343 | 347 | while (line_it.next()) |line| : (line_index += 1) { |
| 344 | 348 | const last_line = line_it.index == line_it.buffer.len; |
| 345 | 349 | |
| 346 | const old_len = output.items.len; | |
| 347 | expand_variables_autoconf_at(output, line, values, used) catch |err| switch (err) { | |
| 350 | const old_len = aw.getWritten().len; | |
| 351 | expand_variables_autoconf_at(bw, line, values, used) catch |err| switch (err) { | |
| 348 | 352 | error.MissingValue => { |
| 349 | const name = output.items[old_len..]; | |
| 350 | defer output.shrinkRetainingCapacity(old_len); | |
| 353 | const name = aw.getWritten()[old_len..]; | |
| 354 | defer aw.shrinkRetainingCapacity(old_len); | |
| 351 | 355 | try step.addError("{s}:{d}: error: unspecified config header value: '{s}'", .{ |
| 352 | 356 | src_path, line_index + 1, name, |
| 353 | 357 | }); |
| ... | ... | @@ -362,9 +366,7 @@ fn render_autoconf_at( |
| 362 | 366 | continue; |
| 363 | 367 | }, |
| 364 | 368 | }; |
| 365 | if (!last_line) { | |
| 366 | try output.append('\n'); | |
| 367 | } | |
| 369 | if (!last_line) try bw.writeByte('\n'); | |
| 368 | 370 | } |
| 369 | 371 | |
| 370 | 372 | for (values.unmanaged.entries.slice().items(.key), used) |name, u| { |
| ... | ... | @@ -374,15 +376,13 @@ fn render_autoconf_at( |
| 374 | 376 | } |
| 375 | 377 | } |
| 376 | 378 | |
| 377 | if (any_errors) { | |
| 378 | return error.MakeFailed; | |
| 379 | } | |
| 379 | if (any_errors) return error.MakeFailed; | |
| 380 | 380 | } |
| 381 | 381 | |
| 382 | 382 | fn render_cmake( |
| 383 | 383 | step: *Step, |
| 384 | 384 | contents: []const u8, |
| 385 | output: *std.ArrayList(u8), | |
| 385 | bw: *std.io.BufferedWriter, | |
| 386 | 386 | values: std.StringArrayHashMap(Value), |
| 387 | 387 | src_path: []const u8, |
| 388 | 388 | ) !void { |
| ... | ... | @@ -417,10 +417,8 @@ fn render_cmake( |
| 417 | 417 | defer allocator.free(line); |
| 418 | 418 | |
| 419 | 419 | if (!std.mem.startsWith(u8, line, "#")) { |
| 420 | try output.appendSlice(line); | |
| 421 | if (!last_line) { | |
| 422 | try output.appendSlice("\n"); | |
| 423 | } | |
| 420 | try bw.writeAll(line); | |
| 421 | if (!last_line) try bw.writeByte('\n'); | |
| 424 | 422 | continue; |
| 425 | 423 | } |
| 426 | 424 | var it = std.mem.tokenizeAny(u8, line[1..], " \t\r"); |
| ... | ... | @@ -428,10 +426,8 @@ fn render_cmake( |
| 428 | 426 | if (!std.mem.eql(u8, cmakedefine, "cmakedefine") and |
| 429 | 427 | !std.mem.eql(u8, cmakedefine, "cmakedefine01")) |
| 430 | 428 | { |
| 431 | try output.appendSlice(line); | |
| 432 | if (!last_line) { | |
| 433 | try output.appendSlice("\n"); | |
| 434 | } | |
| 429 | try bw.writeAll(line); | |
| 430 | if (!last_line) try bw.writeByte('\n'); | |
| 435 | 431 | continue; |
| 436 | 432 | } |
| 437 | 433 | |
| ... | ... | @@ -502,7 +498,7 @@ fn render_cmake( |
| 502 | 498 | value = Value{ .ident = it.rest() }; |
| 503 | 499 | } |
| 504 | 500 | |
| 505 | try renderValueC(output, name, value); | |
| 501 | try renderValueC(bw, name, value); | |
| 506 | 502 | } |
| 507 | 503 | |
| 508 | 504 | if (any_errors) { |
| ... | ... | @@ -511,13 +507,14 @@ fn render_cmake( |
| 511 | 507 | } |
| 512 | 508 | |
| 513 | 509 | fn render_blank( |
| 514 | output: *std.ArrayList(u8), | |
| 510 | gpa: std.mem.Allocator, | |
| 511 | bw: *std.io.BufferedWriter, | |
| 515 | 512 | defines: std.StringArrayHashMap(Value), |
| 516 | 513 | include_path: []const u8, |
| 517 | 514 | include_guard_override: ?[]const u8, |
| 518 | 515 | ) !void { |
| 519 | 516 | const include_guard_name = include_guard_override orelse blk: { |
| 520 | const name = try output.allocator.dupe(u8, include_path); | |
| 517 | const name = try gpa.dupe(u8, include_path); | |
| 521 | 518 | for (name) |*byte| { |
| 522 | 519 | switch (byte.*) { |
| 523 | 520 | 'a'...'z' => byte.* = byte.* - 'a' + 'A', |
| ... | ... | @@ -527,92 +524,53 @@ fn render_blank( |
| 527 | 524 | } |
| 528 | 525 | break :blk name; |
| 529 | 526 | }; |
| 527 | defer if (include_guard_override == null) gpa.free(include_guard_name); | |
| 530 | 528 | |
| 531 | try output.appendSlice("#ifndef "); | |
| 532 | try output.appendSlice(include_guard_name); | |
| 533 | try output.appendSlice("\n#define "); | |
| 534 | try output.appendSlice(include_guard_name); | |
| 535 | try output.appendSlice("\n"); | |
| 529 | try bw.print( | |
| 530 | \\#ifndef {[0]s} | |
| 531 | \\#define {[0]s} | |
| 532 | \\ | |
| 533 | , .{include_guard_name}); | |
| 536 | 534 | |
| 537 | 535 | const values = defines.values(); |
| 538 | for (defines.keys(), 0..) |name, i| { | |
| 539 | try renderValueC(output, name, values[i]); | |
| 540 | } | |
| 536 | for (defines.keys(), 0..) |name, i| try renderValueC(bw, name, values[i]); | |
| 541 | 537 | |
| 542 | try output.appendSlice("#endif /* "); | |
| 543 | try output.appendSlice(include_guard_name); | |
| 544 | try output.appendSlice(" */\n"); | |
| 538 | try bw.print( | |
| 539 | \\#endif /* {s} */ | |
| 540 | \\ | |
| 541 | , .{include_guard_name}); | |
| 545 | 542 | } |
| 546 | 543 | |
| 547 | fn render_nasm(output: *std.ArrayList(u8), defines: std.StringArrayHashMap(Value)) !void { | |
| 548 | const values = defines.values(); | |
| 549 | for (defines.keys(), 0..) |name, i| { | |
| 550 | try renderValueNasm(output, name, values[i]); | |
| 551 | } | |
| 544 | fn render_nasm(bw: *std.io.BufferedWriter, defines: std.StringArrayHashMap(Value)) !void { | |
| 545 | for (defines.keys(), defines.values()) |name, value| try renderValueNasm(bw, name, value); | |
| 552 | 546 | } |
| 553 | 547 | |
| 554 | fn renderValueC(output: *std.ArrayList(u8), name: []const u8, value: Value) !void { | |
| 548 | fn renderValueC(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !void { | |
| 555 | 549 | switch (value) { |
| 556 | .undef => { | |
| 557 | try output.appendSlice("/* #undef "); | |
| 558 | try output.appendSlice(name); | |
| 559 | try output.appendSlice(" */\n"); | |
| 560 | }, | |
| 561 | .defined => { | |
| 562 | try output.appendSlice("#define "); | |
| 563 | try output.appendSlice(name); | |
| 564 | try output.appendSlice("\n"); | |
| 565 | }, | |
| 566 | .boolean => |b| { | |
| 567 | try output.appendSlice("#define "); | |
| 568 | try output.appendSlice(name); | |
| 569 | try output.appendSlice(if (b) " 1\n" else " 0\n"); | |
| 570 | }, | |
| 571 | .int => |i| { | |
| 572 | try output.print("#define {s} {d}\n", .{ name, i }); | |
| 573 | }, | |
| 574 | .ident => |ident| { | |
| 575 | try output.print("#define {s} {s}\n", .{ name, ident }); | |
| 576 | }, | |
| 577 | .string => |string| { | |
| 578 | // TODO: use C-specific escaping instead of zig string literals | |
| 579 | try output.print("#define {s} \"{}\"\n", .{ name, std.zig.fmtEscapes(string) }); | |
| 580 | }, | |
| 550 | .undef => try bw.print("/* #undef {s} */\n", .{name}), | |
| 551 | .defined => try bw.print("#define {s}\n", .{name}), | |
| 552 | .boolean => |b| try bw.print("#define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }), | |
| 553 | .int => |i| try bw.print("#define {s} {d}\n", .{ name, i }), | |
| 554 | .ident => |ident| try bw.print("#define {s} {s}\n", .{ name, ident }), | |
| 555 | // TODO: use C-specific escaping instead of zig string literals | |
| 556 | .string => |string| try bw.print("#define {s} \"{f}\"\n", .{ name, std.zig.fmtEscapes(string) }), | |
| 581 | 557 | } |
| 582 | 558 | } |
| 583 | 559 | |
| 584 | fn renderValueNasm(output: *std.ArrayList(u8), name: []const u8, value: Value) !void { | |
| 560 | fn renderValueNasm(bw: *std.io.BufferedWriter, name: []const u8, value: Value) !void { | |
| 585 | 561 | switch (value) { |
| 586 | .undef => { | |
| 587 | try output.appendSlice("; %undef "); | |
| 588 | try output.appendSlice(name); | |
| 589 | try output.appendSlice("\n"); | |
| 590 | }, | |
| 591 | .defined => { | |
| 592 | try output.appendSlice("%define "); | |
| 593 | try output.appendSlice(name); | |
| 594 | try output.appendSlice("\n"); | |
| 595 | }, | |
| 596 | .boolean => |b| { | |
| 597 | try output.appendSlice("%define "); | |
| 598 | try output.appendSlice(name); | |
| 599 | try output.appendSlice(if (b) " 1\n" else " 0\n"); | |
| 600 | }, | |
| 601 | .int => |i| { | |
| 602 | try output.print("%define {s} {d}\n", .{ name, i }); | |
| 603 | }, | |
| 604 | .ident => |ident| { | |
| 605 | try output.print("%define {s} {s}\n", .{ name, ident }); | |
| 606 | }, | |
| 607 | .string => |string| { | |
| 608 | // TODO: use nasm-specific escaping instead of zig string literals | |
| 609 | try output.print("%define {s} \"{}\"\n", .{ name, std.zig.fmtEscapes(string) }); | |
| 610 | }, | |
| 562 | .undef => try bw.print("; %undef {s}\n", .{name}), | |
| 563 | .defined => try bw.print("%define {s}\n", .{name}), | |
| 564 | .boolean => |b| try bw.print("%define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }), | |
| 565 | .int => |i| try bw.print("%define {s} {d}\n", .{ name, i }), | |
| 566 | .ident => |ident| try bw.print("%define {s} {s}\n", .{ name, ident }), | |
| 567 | // TODO: use nasm-specific escaping instead of zig string literals | |
| 568 | .string => |string| try bw.print("%define {s} \"{f}\"\n", .{ name, std.zig.fmtEscapes(string) }), | |
| 611 | 569 | } |
| 612 | 570 | } |
| 613 | 571 | |
| 614 | 572 | fn expand_variables_autoconf_at( |
| 615 | output: *std.ArrayList(u8), | |
| 573 | bw: *std.io.BufferedWriter, | |
| 616 | 574 | contents: []const u8, |
| 617 | 575 | values: std.StringArrayHashMap(Value), |
| 618 | 576 | used: []bool, |
| ... | ... | @@ -637,23 +595,17 @@ fn expand_variables_autoconf_at( |
| 637 | 595 | const key = contents[curr + 1 .. close_pos]; |
| 638 | 596 | const index = values.getIndex(key) orelse { |
| 639 | 597 | // Report the missing key to the caller. |
| 640 | try output.appendSlice(key); | |
| 598 | try bw.writeAll(key); | |
| 641 | 599 | return error.MissingValue; |
| 642 | 600 | }; |
| 643 | 601 | const value = values.unmanaged.entries.slice().items(.value)[index]; |
| 644 | 602 | used[index] = true; |
| 645 | try output.appendSlice(contents[source_offset..curr]); | |
| 603 | try bw.writeAll(contents[source_offset..curr]); | |
| 646 | 604 | switch (value) { |
| 647 | 605 | .undef, .defined => {}, |
| 648 | .boolean => |b| { | |
| 649 | try output.append(if (b) '1' else '0'); | |
| 650 | }, | |
| 651 | .int => |i| { | |
| 652 | try output.writer().print("{d}", .{i}); | |
| 653 | }, | |
| 654 | .ident, .string => |s| { | |
| 655 | try output.appendSlice(s); | |
| 656 | }, | |
| 606 | .boolean => |b| try bw.writeByte(@as(u8, '0') + @intFromBool(b)), | |
| 607 | .int => |i| try bw.print("{d}", .{i}), | |
| 608 | .ident, .string => |s| try bw.writeAll(s), | |
| 657 | 609 | } |
| 658 | 610 | |
| 659 | 611 | curr = close_pos; |
| ... | ... | @@ -661,7 +613,7 @@ fn expand_variables_autoconf_at( |
| 661 | 613 | } |
| 662 | 614 | } |
| 663 | 615 | |
| 664 | try output.appendSlice(contents[source_offset..]); | |
| 616 | try bw.writeAll(contents[source_offset..]); | |
| 665 | 617 | } |
| 666 | 618 | |
| 667 | 619 | fn expand_variables_cmake( |
| ... | ... | @@ -669,7 +621,7 @@ fn expand_variables_cmake( |
| 669 | 621 | contents: []const u8, |
| 670 | 622 | values: std.StringArrayHashMap(Value), |
| 671 | 623 | ) ![]const u8 { |
| 672 | var result = std.ArrayList(u8).init(allocator); | |
| 624 | var result: std.ArrayList(u8) = .init(allocator); | |
| 673 | 625 | errdefer result.deinit(); |
| 674 | 626 | |
| 675 | 627 | const valid_varname_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/_.+-"; |
| ... | ... | @@ -681,7 +633,7 @@ fn expand_variables_cmake( |
| 681 | 633 | source: usize, |
| 682 | 634 | target: usize, |
| 683 | 635 | }; |
| 684 | var var_stack = std.ArrayList(Position).init(allocator); | |
| 636 | var var_stack: std.ArrayList(Position) = .init(allocator); | |
| 685 | 637 | defer var_stack.deinit(); |
| 686 | 638 | loop: while (curr < contents.len) : (curr += 1) { |
| 687 | 639 | switch (contents[curr]) { |
| ... | ... | @@ -801,7 +753,7 @@ fn testReplaceVariablesAutoconfAt( |
| 801 | 753 | expected: []const u8, |
| 802 | 754 | values: std.StringArrayHashMap(Value), |
| 803 | 755 | ) !void { |
| 804 | var output = std.ArrayList(u8).init(allocator); | |
| 756 | var output: std.ArrayList(u8) = .init(allocator); | |
| 805 | 757 | defer output.deinit(); |
| 806 | 758 | |
| 807 | 759 | const used = try allocator.alloc(bool, values.count()); |
| ... | ... | @@ -828,7 +780,7 @@ fn testReplaceVariablesCMake( |
| 828 | 780 | |
| 829 | 781 | test "expand_variables_autoconf_at simple cases" { |
| 830 | 782 | const allocator = std.testing.allocator; |
| 831 | var values = std.StringArrayHashMap(Value).init(allocator); | |
| 783 | var values: std.StringArrayHashMap(Value) = .init(allocator); | |
| 832 | 784 | defer values.deinit(); |
| 833 | 785 | |
| 834 | 786 | // empty strings are preserved |
| ... | ... | @@ -924,7 +876,7 @@ test "expand_variables_autoconf_at simple cases" { |
| 924 | 876 | |
| 925 | 877 | test "expand_variables_autoconf_at edge cases" { |
| 926 | 878 | const allocator = std.testing.allocator; |
| 927 | var values = std.StringArrayHashMap(Value).init(allocator); | |
| 879 | var values: std.StringArrayHashMap(Value) = .init(allocator); | |
| 928 | 880 | defer values.deinit(); |
| 929 | 881 | |
| 930 | 882 | // @-vars resolved only when they wrap valid characters, otherwise considered literals |
| ... | ... | @@ -940,7 +892,7 @@ test "expand_variables_autoconf_at edge cases" { |
| 940 | 892 | |
| 941 | 893 | test "expand_variables_cmake simple cases" { |
| 942 | 894 | const allocator = std.testing.allocator; |
| 943 | var values = std.StringArrayHashMap(Value).init(allocator); | |
| 895 | var values: std.StringArrayHashMap(Value) = .init(allocator); | |
| 944 | 896 | defer values.deinit(); |
| 945 | 897 | |
| 946 | 898 | try values.putNoClobber("undef", .undef); |
| ... | ... | @@ -1028,7 +980,7 @@ test "expand_variables_cmake simple cases" { |
| 1028 | 980 | |
| 1029 | 981 | test "expand_variables_cmake edge cases" { |
| 1030 | 982 | const allocator = std.testing.allocator; |
| 1031 | var values = std.StringArrayHashMap(Value).init(allocator); | |
| 983 | var values: std.StringArrayHashMap(Value) = .init(allocator); | |
| 1032 | 984 | defer values.deinit(); |
| 1033 | 985 | |
| 1034 | 986 | // special symbols |
| ... | ... | @@ -1089,7 +1041,7 @@ test "expand_variables_cmake edge cases" { |
| 1089 | 1041 | |
| 1090 | 1042 | test "expand_variables_cmake escaped characters" { |
| 1091 | 1043 | const allocator = std.testing.allocator; |
| 1092 | var values = std.StringArrayHashMap(Value).init(allocator); | |
| 1044 | var values: std.StringArrayHashMap(Value) = .init(allocator); | |
| 1093 | 1045 | defer values.deinit(); |
| 1094 | 1046 | |
| 1095 | 1047 | try values.putNoClobber("string", Value{ .string = "text" }); |
lib/std/Build/Step/Fail.zig+1-1| ... | ... | @@ -12,7 +12,7 @@ pub fn create(owner: *std.Build, error_msg: []const u8) *Fail { |
| 12 | 12 | const fail = owner.allocator.create(Fail) catch @panic("OOM"); |
| 13 | 13 | |
| 14 | 14 | fail.* = .{ |
| 15 | .step = Step.init(.{ | |
| 15 | .step = .init(.{ | |
| 16 | 16 | .id = base_id, |
| 17 | 17 | .name = "fail", |
| 18 | 18 | .owner = owner, |
lib/std/Build/Step/Fmt.zig+1-1| ... | ... | @@ -23,7 +23,7 @@ pub fn create(owner: *std.Build, options: Options) *Fmt { |
| 23 | 23 | const fmt = owner.allocator.create(Fmt) catch @panic("OOM"); |
| 24 | 24 | const name = if (options.check) "zig fmt --check" else "zig fmt"; |
| 25 | 25 | fmt.* = .{ |
| 26 | .step = Step.init(.{ | |
| 26 | .step = .init(.{ | |
| 27 | 27 | .id = base_id, |
| 28 | 28 | .name = name, |
| 29 | 29 | .owner = owner, |
lib/std/Build/Step/InstallArtifact.zig+2-2| ... | ... | @@ -63,7 +63,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins |
| 63 | 63 | .override => |o| o, |
| 64 | 64 | }; |
| 65 | 65 | install_artifact.* = .{ |
| 66 | .step = Step.init(.{ | |
| 66 | .step = .init(.{ | |
| 67 | 67 | .id = base_id, |
| 68 | 68 | .name = owner.fmt("install {s}", .{artifact.name}), |
| 69 | 69 | .owner = owner, |
| ... | ... | @@ -164,7 +164,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 164 | 164 | const full_h_prefix = b.getInstallPath(h_dir, dir.dest_rel_path); |
| 165 | 165 | |
| 166 | 166 | var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { |
| 167 | return step.fail("unable to open source directory '{}': {s}", .{ | |
| 167 | return step.fail("unable to open source directory '{f}': {s}", .{ | |
| 168 | 168 | src_dir_path, @errorName(err), |
| 169 | 169 | }); |
| 170 | 170 | }; |
lib/std/Build/Step/InstallDir.zig+2-2| ... | ... | @@ -43,7 +43,7 @@ pub const Options = struct { |
| 43 | 43 | pub fn create(owner: *std.Build, options: Options) *InstallDir { |
| 44 | 44 | const install_dir = owner.allocator.create(InstallDir) catch @panic("OOM"); |
| 45 | 45 | install_dir.* = .{ |
| 46 | .step = Step.init(.{ | |
| 46 | .step = .init(.{ | |
| 47 | 47 | .id = base_id, |
| 48 | 48 | .name = owner.fmt("install {s}/", .{options.source_dir.getDisplayName()}), |
| 49 | 49 | .owner = owner, |
| ... | ... | @@ -65,7 +65,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 65 | 65 | const src_dir_path = install_dir.options.source_dir.getPath3(b, step); |
| 66 | 66 | const need_derived_inputs = try step.addDirectoryWatchInput(install_dir.options.source_dir); |
| 67 | 67 | var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { |
| 68 | return step.fail("unable to open source directory '{}': {s}", .{ | |
| 68 | return step.fail("unable to open source directory '{f}': {s}", .{ | |
| 69 | 69 | src_dir_path, @errorName(err), |
| 70 | 70 | }); |
| 71 | 71 | }; |
lib/std/Build/Step/InstallFile.zig+1-1| ... | ... | @@ -21,7 +21,7 @@ pub fn create( |
| 21 | 21 | assert(dest_rel_path.len != 0); |
| 22 | 22 | const install_file = owner.allocator.create(InstallFile) catch @panic("OOM"); |
| 23 | 23 | install_file.* = .{ |
| 24 | .step = Step.init(.{ | |
| 24 | .step = .init(.{ | |
| 25 | 25 | .id = base_id, |
| 26 | 26 | .name = owner.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }), |
| 27 | 27 | .owner = owner, |
lib/std/Build/Step/ObjCopy.zig+2-2| ... | ... | @@ -111,8 +111,8 @@ pub fn create( |
| 111 | 111 | options: Options, |
| 112 | 112 | ) *ObjCopy { |
| 113 | 113 | const objcopy = owner.allocator.create(ObjCopy) catch @panic("OOM"); |
| 114 | objcopy.* = ObjCopy{ | |
| 115 | .step = Step.init(.{ | |
| 114 | objcopy.* = .{ | |
| 115 | .step = .init(.{ | |
| 116 | 116 | .id = base_id, |
| 117 | 117 | .name = owner.fmt("objcopy {s}", .{input_file.getDisplayName()}), |
| 118 | 118 | .owner = owner, |
lib/std/Build/Step/Options.zig+19-19| ... | ... | @@ -19,7 +19,7 @@ encountered_types: std.StringHashMapUnmanaged(void), |
| 19 | 19 | pub fn create(owner: *std.Build) *Options { |
| 20 | 20 | const options = owner.allocator.create(Options) catch @panic("OOM"); |
| 21 | 21 | options.* = .{ |
| 22 | .step = Step.init(.{ | |
| 22 | .step = .init(.{ | |
| 23 | 23 | .id = base_id, |
| 24 | 24 | .name = "options", |
| 25 | 25 | .owner = owner, |
| ... | ... | @@ -79,15 +79,15 @@ fn printType( |
| 79 | 79 | std.zig.fmtId(some), std.zig.fmtEscapes(value), |
| 80 | 80 | }); |
| 81 | 81 | } else { |
| 82 | try out.print(gpa, "\"{}\",", .{std.zig.fmtEscapes(value)}); | |
| 82 | try out.print(gpa, "\"{f}\",", .{std.zig.fmtEscapes(value)}); | |
| 83 | 83 | } |
| 84 | 84 | return out.appendSlice(gpa, "\n"); |
| 85 | 85 | }, |
| 86 | 86 | [:0]const u8 => { |
| 87 | 87 | if (name) |some| { |
| 88 | try out.print(gpa, "pub const {}: [:0]const u8 = \"{}\";", .{ std.zig.fmtId(some), std.zig.fmtEscapes(value) }); | |
| 88 | try out.print(gpa, "pub const {f}: [:0]const u8 = \"{f}\";", .{ std.zig.fmtId(some), std.zig.fmtEscapes(value) }); | |
| 89 | 89 | } else { |
| 90 | try out.print(gpa, "\"{}\",", .{std.zig.fmtEscapes(value)}); | |
| 90 | try out.print(gpa, "\"{f}\",", .{std.zig.fmtEscapes(value)}); | |
| 91 | 91 | } |
| 92 | 92 | return out.appendSlice(gpa, "\n"); |
| 93 | 93 | }, |
| ... | ... | @@ -97,7 +97,7 @@ fn printType( |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | 99 | if (value) |payload| { |
| 100 | try out.print(gpa, "\"{}\"", .{std.zig.fmtEscapes(payload)}); | |
| 100 | try out.print(gpa, "\"{f}\"", .{std.zig.fmtEscapes(payload)}); | |
| 101 | 101 | } else { |
| 102 | 102 | try out.appendSlice(gpa, "null"); |
| 103 | 103 | } |
| ... | ... | @@ -115,7 +115,7 @@ fn printType( |
| 115 | 115 | } |
| 116 | 116 | |
| 117 | 117 | if (value) |payload| { |
| 118 | try out.print(gpa, "\"{}\"", .{std.zig.fmtEscapes(payload)}); | |
| 118 | try out.print(gpa, "\"{f}\"", .{std.zig.fmtEscapes(payload)}); | |
| 119 | 119 | } else { |
| 120 | 120 | try out.appendSlice(gpa, "null"); |
| 121 | 121 | } |
| ... | ... | @@ -129,7 +129,7 @@ fn printType( |
| 129 | 129 | }, |
| 130 | 130 | std.SemanticVersion => { |
| 131 | 131 | if (name) |some| { |
| 132 | try out.print(gpa, "pub const {}: @import(\"std\").SemanticVersion = ", .{std.zig.fmtId(some)}); | |
| 132 | try out.print(gpa, "pub const {f}: @import(\"std\").SemanticVersion = ", .{std.zig.fmtId(some)}); | |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | 135 | try out.appendSlice(gpa, ".{\n"); |
| ... | ... | @@ -142,11 +142,11 @@ fn printType( |
| 142 | 142 | |
| 143 | 143 | if (value.pre) |some| { |
| 144 | 144 | try out.appendNTimes(gpa, ' ', indent); |
| 145 | try out.print(gpa, " .pre = \"{}\",\n", .{std.zig.fmtEscapes(some)}); | |
| 145 | try out.print(gpa, " .pre = \"{f}\",\n", .{std.zig.fmtEscapes(some)}); | |
| 146 | 146 | } |
| 147 | 147 | if (value.build) |some| { |
| 148 | 148 | try out.appendNTimes(gpa, ' ', indent); |
| 149 | try out.print(gpa, " .build = \"{}\",\n", .{std.zig.fmtEscapes(some)}); | |
| 149 | try out.print(gpa, " .build = \"{f}\",\n", .{std.zig.fmtEscapes(some)}); | |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | 152 | if (name != null) { |
| ... | ... | @@ -233,7 +233,7 @@ fn printType( |
| 233 | 233 | .null, |
| 234 | 234 | => { |
| 235 | 235 | if (name) |some| { |
| 236 | try out.print(gpa, "pub const {}: {s} = {any};\n", .{ std.zig.fmtId(some), @typeName(T), value }); | |
| 236 | try out.print(gpa, "pub const {f}: {s} = {any};\n", .{ std.zig.fmtId(some), @typeName(T), value }); | |
| 237 | 237 | } else { |
| 238 | 238 | try out.print(gpa, "{any},\n", .{value}); |
| 239 | 239 | } |
| ... | ... | @@ -243,7 +243,7 @@ fn printType( |
| 243 | 243 | try printEnum(options, out, T, info, indent); |
| 244 | 244 | |
| 245 | 245 | if (name) |some| { |
| 246 | try out.print(gpa, "pub const {}: {} = .{p_};\n", .{ | |
| 246 | try out.print(gpa, "pub const {f}: {f} = .{fp_};\n", .{ | |
| 247 | 247 | std.zig.fmtId(some), |
| 248 | 248 | std.zig.fmtId(@typeName(T)), |
| 249 | 249 | std.zig.fmtId(@tagName(value)), |
| ... | ... | @@ -255,7 +255,7 @@ fn printType( |
| 255 | 255 | try printStruct(options, out, T, info, indent); |
| 256 | 256 | |
| 257 | 257 | if (name) |some| { |
| 258 | try out.print(gpa, "pub const {}: {} = ", .{ | |
| 258 | try out.print(gpa, "pub const {f}: {f} = ", .{ | |
| 259 | 259 | std.zig.fmtId(some), |
| 260 | 260 | std.zig.fmtId(@typeName(T)), |
| 261 | 261 | }); |
| ... | ... | @@ -291,7 +291,7 @@ fn printEnum( |
| 291 | 291 | if (gop.found_existing) return; |
| 292 | 292 | |
| 293 | 293 | try out.appendNTimes(gpa, ' ', indent); |
| 294 | try out.print(gpa, "pub const {} = enum ({s}) {{\n", .{ std.zig.fmtId(@typeName(T)), @typeName(val.tag_type) }); | |
| 294 | try out.print(gpa, "pub const {f} = enum ({s}) {{\n", .{ std.zig.fmtId(@typeName(T)), @typeName(val.tag_type) }); | |
| 295 | 295 | |
| 296 | 296 | inline for (val.fields) |field| { |
| 297 | 297 | try out.appendNTimes(gpa, ' ', indent); |
| ... | ... | @@ -464,7 +464,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 464 | 464 | error.FileNotFound => { |
| 465 | 465 | const sub_dirname = fs.path.dirname(sub_path).?; |
| 466 | 466 | b.cache_root.handle.makePath(sub_dirname) catch |e| { |
| 467 | return step.fail("unable to make path '{}{s}': {s}", .{ | |
| 467 | return step.fail("unable to make path '{f}{s}': {s}", .{ | |
| 468 | 468 | b.cache_root, sub_dirname, @errorName(e), |
| 469 | 469 | }); |
| 470 | 470 | }; |
| ... | ... | @@ -476,13 +476,13 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 476 | 476 | const tmp_sub_path_dirname = fs.path.dirname(tmp_sub_path).?; |
| 477 | 477 | |
| 478 | 478 | b.cache_root.handle.makePath(tmp_sub_path_dirname) catch |err| { |
| 479 | return step.fail("unable to make temporary directory '{}{s}': {s}", .{ | |
| 479 | return step.fail("unable to make temporary directory '{f}{s}': {s}", .{ | |
| 480 | 480 | b.cache_root, tmp_sub_path_dirname, @errorName(err), |
| 481 | 481 | }); |
| 482 | 482 | }; |
| 483 | 483 | |
| 484 | 484 | b.cache_root.handle.writeFile(.{ .sub_path = tmp_sub_path, .data = options.contents.items }) catch |err| { |
| 485 | return step.fail("unable to write options to '{}{s}': {s}", .{ | |
| 485 | return step.fail("unable to write options to '{f}{s}': {s}", .{ | |
| 486 | 486 | b.cache_root, tmp_sub_path, @errorName(err), |
| 487 | 487 | }); |
| 488 | 488 | }; |
| ... | ... | @@ -491,7 +491,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 491 | 491 | error.PathAlreadyExists => { |
| 492 | 492 | // Other process beat us to it. Clean up the temp file. |
| 493 | 493 | b.cache_root.handle.deleteFile(tmp_sub_path) catch |e| { |
| 494 | try step.addError("warning: unable to delete temp file '{}{s}': {s}", .{ | |
| 494 | try step.addError("warning: unable to delete temp file '{f}{s}': {s}", .{ | |
| 495 | 495 | b.cache_root, tmp_sub_path, @errorName(e), |
| 496 | 496 | }); |
| 497 | 497 | }; |
| ... | ... | @@ -499,7 +499,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 499 | 499 | return; |
| 500 | 500 | }, |
| 501 | 501 | else => { |
| 502 | return step.fail("unable to rename options from '{}{s}' to '{}{s}': {s}", .{ | |
| 502 | return step.fail("unable to rename options from '{f}{s}' to '{f}{s}': {s}", .{ | |
| 503 | 503 | b.cache_root, tmp_sub_path, |
| 504 | 504 | b.cache_root, sub_path, |
| 505 | 505 | @errorName(err), |
| ... | ... | @@ -507,7 +507,7 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 507 | 507 | }, |
| 508 | 508 | }; |
| 509 | 509 | }, |
| 510 | else => |e| return step.fail("unable to access options file '{}{s}': {s}", .{ | |
| 510 | else => |e| return step.fail("unable to access options file '{f}{s}': {s}", .{ | |
| 511 | 511 | b.cache_root, sub_path, @errorName(e), |
| 512 | 512 | }), |
| 513 | 513 | } |
lib/std/Build/Step/RemoveDir.zig+1-1| ... | ... | @@ -12,7 +12,7 @@ doomed_path: LazyPath, |
| 12 | 12 | pub fn create(owner: *std.Build, doomed_path: LazyPath) *RemoveDir { |
| 13 | 13 | const remove_dir = owner.allocator.create(RemoveDir) catch @panic("OOM"); |
| 14 | 14 | remove_dir.* = .{ |
| 15 | .step = Step.init(.{ | |
| 15 | .step = .init(.{ | |
| 16 | 16 | .id = base_id, |
| 17 | 17 | .name = owner.fmt("RemoveDir {s}", .{doomed_path.getDisplayName()}), |
| 18 | 18 | .owner = owner, |
lib/std/Build/Step/Run.zig+23-30| ... | ... | @@ -169,7 +169,7 @@ pub const Output = struct { |
| 169 | 169 | pub fn create(owner: *std.Build, name: []const u8) *Run { |
| 170 | 170 | const run = owner.allocator.create(Run) catch @panic("OOM"); |
| 171 | 171 | run.* = .{ |
| 172 | .step = Step.init(.{ | |
| 172 | .step = .init(.{ | |
| 173 | 173 | .id = base_id, |
| 174 | 174 | .name = name, |
| 175 | 175 | .owner = owner, |
| ... | ... | @@ -832,7 +832,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 832 | 832 | else => unreachable, |
| 833 | 833 | }; |
| 834 | 834 | b.cache_root.handle.makePath(output_sub_dir_path) catch |err| { |
| 835 | return step.fail("unable to make path '{}{s}': {s}", .{ | |
| 835 | return step.fail("unable to make path '{f}{s}': {s}", .{ | |
| 836 | 836 | b.cache_root, output_sub_dir_path, @errorName(err), |
| 837 | 837 | }); |
| 838 | 838 | }; |
| ... | ... | @@ -864,7 +864,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 864 | 864 | else => unreachable, |
| 865 | 865 | }; |
| 866 | 866 | b.cache_root.handle.makePath(output_sub_dir_path) catch |err| { |
| 867 | return step.fail("unable to make path '{}{s}': {s}", .{ | |
| 867 | return step.fail("unable to make path '{f}{s}': {s}", .{ | |
| 868 | 868 | b.cache_root, output_sub_dir_path, @errorName(err), |
| 869 | 869 | }); |
| 870 | 870 | }; |
| ... | ... | @@ -903,21 +903,21 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 903 | 903 | b.cache_root.handle.rename(tmp_dir_path, o_sub_path) catch |err| { |
| 904 | 904 | if (err == error.PathAlreadyExists) { |
| 905 | 905 | b.cache_root.handle.deleteTree(o_sub_path) catch |del_err| { |
| 906 | return step.fail("unable to remove dir '{}'{s}: {s}", .{ | |
| 906 | return step.fail("unable to remove dir '{f}'{s}: {s}", .{ | |
| 907 | 907 | b.cache_root, |
| 908 | 908 | tmp_dir_path, |
| 909 | 909 | @errorName(del_err), |
| 910 | 910 | }); |
| 911 | 911 | }; |
| 912 | 912 | b.cache_root.handle.rename(tmp_dir_path, o_sub_path) catch |retry_err| { |
| 913 | return step.fail("unable to rename dir '{}{s}' to '{}{s}': {s}", .{ | |
| 913 | return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {s}", .{ | |
| 914 | 914 | b.cache_root, tmp_dir_path, |
| 915 | 915 | b.cache_root, o_sub_path, |
| 916 | 916 | @errorName(retry_err), |
| 917 | 917 | }); |
| 918 | 918 | }; |
| 919 | 919 | } else { |
| 920 | return step.fail("unable to rename dir '{}{s}' to '{}{s}': {s}", .{ | |
| 920 | return step.fail("unable to rename dir '{f}{s}' to '{f}{s}': {s}", .{ | |
| 921 | 921 | b.cache_root, tmp_dir_path, |
| 922 | 922 | b.cache_root, o_sub_path, |
| 923 | 923 | @errorName(err), |
| ... | ... | @@ -964,7 +964,7 @@ pub fn rerunInFuzzMode( |
| 964 | 964 | .artifact => |pa| { |
| 965 | 965 | const artifact = pa.artifact; |
| 966 | 966 | const file_path: []const u8 = p: { |
| 967 | if (artifact == run.producer.?) break :p b.fmt("{}", .{run.rebuilt_executable.?}); | |
| 967 | if (artifact == run.producer.?) break :p b.fmt("{f}", .{run.rebuilt_executable.?}); | |
| 968 | 968 | break :p artifact.installed_path orelse artifact.generated_bin.?.path.?; |
| 969 | 969 | }; |
| 970 | 970 | try argv_list.append(arena, b.fmt("{s}{s}", .{ |
| ... | ... | @@ -1013,20 +1013,16 @@ fn populateGeneratedPaths( |
| 1013 | 1013 | |
| 1014 | 1014 | fn formatTerm( |
| 1015 | 1015 | term: ?std.process.Child.Term, |
| 1016 | bw: *std.io.BufferedWriter, | |
| 1016 | 1017 | comptime fmt: []const u8, |
| 1017 | options: std.fmt.FormatOptions, | |
| 1018 | writer: anytype, | |
| 1019 | 1018 | ) !void { |
| 1020 | 1019 | _ = fmt; |
| 1021 | _ = options; | |
| 1022 | 1020 | if (term) |t| switch (t) { |
| 1023 | .Exited => |code| try writer.print("exited with code {}", .{code}), | |
| 1024 | .Signal => |sig| try writer.print("terminated with signal {}", .{sig}), | |
| 1025 | .Stopped => |sig| try writer.print("stopped with signal {}", .{sig}), | |
| 1026 | .Unknown => |code| try writer.print("terminated for unknown reason with code {}", .{code}), | |
| 1027 | } else { | |
| 1028 | try writer.writeAll("exited with any code"); | |
| 1029 | } | |
| 1021 | .Exited => |code| try bw.print("exited with code {}", .{code}), | |
| 1022 | .Signal => |sig| try bw.print("terminated with signal {}", .{sig}), | |
| 1023 | .Stopped => |sig| try bw.print("stopped with signal {}", .{sig}), | |
| 1024 | .Unknown => |code| try bw.print("terminated for unknown reason with code {}", .{code}), | |
| 1025 | } else try bw.writeAll("exited with any code"); | |
| 1030 | 1026 | } |
| 1031 | 1027 | fn fmtTerm(term: ?std.process.Child.Term) std.fmt.Formatter(formatTerm) { |
| 1032 | 1028 | return .{ .data = term }; |
| ... | ... | @@ -1262,12 +1258,12 @@ fn runCommand( |
| 1262 | 1258 | const sub_path = b.pathJoin(&output_components); |
| 1263 | 1259 | const sub_path_dirname = fs.path.dirname(sub_path).?; |
| 1264 | 1260 | b.cache_root.handle.makePath(sub_path_dirname) catch |err| { |
| 1265 | return step.fail("unable to make path '{}{s}': {s}", .{ | |
| 1261 | return step.fail("unable to make path '{f}{s}': {s}", .{ | |
| 1266 | 1262 | b.cache_root, sub_path_dirname, @errorName(err), |
| 1267 | 1263 | }); |
| 1268 | 1264 | }; |
| 1269 | 1265 | b.cache_root.handle.writeFile(.{ .sub_path = sub_path, .data = stream.bytes.? }) catch |err| { |
| 1270 | return step.fail("unable to write file '{}{s}': {s}", .{ | |
| 1266 | return step.fail("unable to write file '{f}{s}': {s}", .{ | |
| 1271 | 1267 | b.cache_root, sub_path, @errorName(err), |
| 1272 | 1268 | }); |
| 1273 | 1269 | }; |
| ... | ... | @@ -1346,7 +1342,7 @@ fn runCommand( |
| 1346 | 1342 | }, |
| 1347 | 1343 | .expect_term => |expected_term| { |
| 1348 | 1344 | if (!termMatches(expected_term, result.term)) { |
| 1349 | return step.fail("the following command {} (expected {}):\n{s}", .{ | |
| 1345 | return step.fail("the following command {f} (expected {f}):\n{s}", .{ | |
| 1350 | 1346 | fmtTerm(result.term), |
| 1351 | 1347 | fmtTerm(expected_term), |
| 1352 | 1348 | try Step.allocPrintCmd(arena, cwd, final_argv), |
| ... | ... | @@ -1366,7 +1362,7 @@ fn runCommand( |
| 1366 | 1362 | }; |
| 1367 | 1363 | const expected_term: std.process.Child.Term = .{ .Exited = 0 }; |
| 1368 | 1364 | if (!termMatches(expected_term, result.term)) { |
| 1369 | return step.fail("{s}the following command {} (expected {}):\n{s}", .{ | |
| 1365 | return step.fail("{s}the following command {f} (expected {f}):\n{s}", .{ | |
| 1370 | 1366 | prefix, |
| 1371 | 1367 | fmtTerm(result.term), |
| 1372 | 1368 | fmtTerm(expected_term), |
| ... | ... | @@ -1535,13 +1531,10 @@ fn evalZigTest( |
| 1535 | 1531 | defer if (sub_prog_node) |n| n.end(); |
| 1536 | 1532 | |
| 1537 | 1533 | const any_write_failed = first_write_failed or poll: while (true) { |
| 1538 | while (stdout.readableLength() < @sizeOf(Header)) { | |
| 1539 | if (!(try poller.poll())) break :poll false; | |
| 1540 | } | |
| 1541 | const header = stdout.reader().readStruct(Header) catch unreachable; | |
| 1542 | while (stdout.readableLength() < header.bytes_len) { | |
| 1543 | if (!(try poller.poll())) break :poll false; | |
| 1544 | } | |
| 1534 | while (stdout.readableLength() < @sizeOf(Header)) if (!try poller.poll()) break :poll false; | |
| 1535 | var header: Header = undefined; | |
| 1536 | assert(stdout.read(std.mem.asBytes(&header)) == @sizeOf(Header)); | |
| 1537 | while (stdout.readableLength() < header.bytes_len) if (!try poller.poll()) break :poll false; | |
| 1545 | 1538 | const body = stdout.readableSliceOfLen(header.bytes_len); |
| 1546 | 1539 | |
| 1547 | 1540 | switch (header.tag) { |
| ... | ... | @@ -1797,10 +1790,10 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult { |
| 1797 | 1790 | stdout_bytes = try poller.fifo(.stdout).toOwnedSlice(); |
| 1798 | 1791 | stderr_bytes = try poller.fifo(.stderr).toOwnedSlice(); |
| 1799 | 1792 | } else { |
| 1800 | stdout_bytes = try stdout.reader().readAllAlloc(arena, run.max_stdio_size); | |
| 1793 | stdout_bytes = try stdout.reader().readAlloc(arena, run.max_stdio_size); | |
| 1801 | 1794 | } |
| 1802 | 1795 | } else if (child.stderr) |stderr| { |
| 1803 | stderr_bytes = try stderr.reader().readAllAlloc(arena, run.max_stdio_size); | |
| 1796 | stderr_bytes = try stderr.reader().readAlloc(arena, run.max_stdio_size); | |
| 1804 | 1797 | } |
| 1805 | 1798 | |
| 1806 | 1799 | if (stderr_bytes) |bytes| if (bytes.len > 0) { |
lib/std/Build/Step/TranslateC.zig+1-1| ... | ... | @@ -31,7 +31,7 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC { |
| 31 | 31 | const translate_c = owner.allocator.create(TranslateC) catch @panic("OOM"); |
| 32 | 32 | const source = options.root_source_file.dupe(owner); |
| 33 | 33 | translate_c.* = .{ |
| 34 | .step = Step.init(.{ | |
| 34 | .step = .init(.{ | |
| 35 | 35 | .id = base_id, |
| 36 | 36 | .name = "translate-c", |
| 37 | 37 | .owner = owner, |
lib/std/Build/Step/UpdateSourceFiles.zig+4-4| ... | ... | @@ -27,7 +27,7 @@ pub const Contents = union(enum) { |
| 27 | 27 | pub fn create(owner: *std.Build) *UpdateSourceFiles { |
| 28 | 28 | const usf = owner.allocator.create(UpdateSourceFiles) catch @panic("OOM"); |
| 29 | 29 | usf.* = .{ |
| 30 | .step = Step.init(.{ | |
| 30 | .step = .init(.{ | |
| 31 | 31 | .id = base_id, |
| 32 | 32 | .name = "UpdateSourceFiles", |
| 33 | 33 | .owner = owner, |
| ... | ... | @@ -76,7 +76,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 76 | 76 | for (usf.output_source_files.items) |output_source_file| { |
| 77 | 77 | if (fs.path.dirname(output_source_file.sub_path)) |dirname| { |
| 78 | 78 | b.build_root.handle.makePath(dirname) catch |err| { |
| 79 | return step.fail("unable to make path '{}{s}': {s}", .{ | |
| 79 | return step.fail("unable to make path '{f}{s}': {s}", .{ | |
| 80 | 80 | b.build_root, dirname, @errorName(err), |
| 81 | 81 | }); |
| 82 | 82 | }; |
| ... | ... | @@ -84,7 +84,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 84 | 84 | switch (output_source_file.contents) { |
| 85 | 85 | .bytes => |bytes| { |
| 86 | 86 | b.build_root.handle.writeFile(.{ .sub_path = output_source_file.sub_path, .data = bytes }) catch |err| { |
| 87 | return step.fail("unable to write file '{}{s}': {s}", .{ | |
| 87 | return step.fail("unable to write file '{f}{s}': {s}", .{ | |
| 88 | 88 | b.build_root, output_source_file.sub_path, @errorName(err), |
| 89 | 89 | }); |
| 90 | 90 | }; |
| ... | ... | @@ -101,7 +101,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 101 | 101 | output_source_file.sub_path, |
| 102 | 102 | .{}, |
| 103 | 103 | ) catch |err| { |
| 104 | return step.fail("unable to update file from '{s}' to '{}{s}': {s}", .{ | |
| 104 | return step.fail("unable to update file from '{s}' to '{f}{s}': {s}", .{ | |
| 105 | 105 | source_path, b.build_root, output_source_file.sub_path, @errorName(err), |
| 106 | 106 | }); |
| 107 | 107 | }; |
lib/std/Build/Step/WriteFile.zig+8-8| ... | ... | @@ -67,7 +67,7 @@ pub const Contents = union(enum) { |
| 67 | 67 | pub fn create(owner: *std.Build) *WriteFile { |
| 68 | 68 | const write_file = owner.allocator.create(WriteFile) catch @panic("OOM"); |
| 69 | 69 | write_file.* = .{ |
| 70 | .step = Step.init(.{ | |
| 70 | .step = .init(.{ | |
| 71 | 71 | .id = base_id, |
| 72 | 72 | .name = "WriteFile", |
| 73 | 73 | .owner = owner, |
| ... | ... | @@ -217,7 +217,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 217 | 217 | const src_dir_path = dir.source.getPath3(b, step); |
| 218 | 218 | |
| 219 | 219 | var src_dir = src_dir_path.root_dir.handle.openDir(src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { |
| 220 | return step.fail("unable to open source directory '{}': {s}", .{ | |
| 220 | return step.fail("unable to open source directory '{f}': {s}", .{ | |
| 221 | 221 | src_dir_path, @errorName(err), |
| 222 | 222 | }); |
| 223 | 223 | }; |
| ... | ... | @@ -258,7 +258,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 258 | 258 | write_file.generated_directory.path = try b.cache_root.join(arena, &.{ "o", &digest }); |
| 259 | 259 | |
| 260 | 260 | var cache_dir = b.cache_root.handle.makeOpenPath(cache_path, .{}) catch |err| { |
| 261 | return step.fail("unable to make path '{}{s}': {s}", .{ | |
| 261 | return step.fail("unable to make path '{f}{s}': {s}", .{ | |
| 262 | 262 | b.cache_root, cache_path, @errorName(err), |
| 263 | 263 | }); |
| 264 | 264 | }; |
| ... | ... | @@ -269,7 +269,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 269 | 269 | for (write_file.files.items) |file| { |
| 270 | 270 | if (fs.path.dirname(file.sub_path)) |dirname| { |
| 271 | 271 | cache_dir.makePath(dirname) catch |err| { |
| 272 | return step.fail("unable to make path '{}{s}{c}{s}': {s}", .{ | |
| 272 | return step.fail("unable to make path '{f}{s}{c}{s}': {s}", .{ | |
| 273 | 273 | b.cache_root, cache_path, fs.path.sep, dirname, @errorName(err), |
| 274 | 274 | }); |
| 275 | 275 | }; |
| ... | ... | @@ -277,7 +277,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 277 | 277 | switch (file.contents) { |
| 278 | 278 | .bytes => |bytes| { |
| 279 | 279 | cache_dir.writeFile(.{ .sub_path = file.sub_path, .data = bytes }) catch |err| { |
| 280 | return step.fail("unable to write file '{}{s}{c}{s}': {s}", .{ | |
| 280 | return step.fail("unable to write file '{f}{s}{c}{s}': {s}", .{ | |
| 281 | 281 | b.cache_root, cache_path, fs.path.sep, file.sub_path, @errorName(err), |
| 282 | 282 | }); |
| 283 | 283 | }; |
| ... | ... | @@ -291,7 +291,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 291 | 291 | file.sub_path, |
| 292 | 292 | .{}, |
| 293 | 293 | ) catch |err| { |
| 294 | return step.fail("unable to update file from '{s}' to '{}{s}{c}{s}': {s}", .{ | |
| 294 | return step.fail("unable to update file from '{s}' to '{f}{s}{c}{s}': {s}", .{ | |
| 295 | 295 | source_path, |
| 296 | 296 | b.cache_root, |
| 297 | 297 | cache_path, |
| ... | ... | @@ -315,7 +315,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 315 | 315 | |
| 316 | 316 | if (dest_dirname.len != 0) { |
| 317 | 317 | cache_dir.makePath(dest_dirname) catch |err| { |
| 318 | return step.fail("unable to make path '{}{s}{c}{s}': {s}", .{ | |
| 318 | return step.fail("unable to make path '{f}{s}{c}{s}': {s}", .{ | |
| 319 | 319 | b.cache_root, cache_path, fs.path.sep, dest_dirname, @errorName(err), |
| 320 | 320 | }); |
| 321 | 321 | }; |
| ... | ... | @@ -338,7 +338,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 338 | 338 | dest_path, |
| 339 | 339 | .{}, |
| 340 | 340 | ) catch |err| { |
| 341 | return step.fail("unable to update file from '{}' to '{}{s}{c}{s}': {s}", .{ | |
| 341 | return step.fail("unable to update file from '{f}' to '{f}{s}{c}{s}': {s}", .{ | |
| 342 | 342 | src_entry_path, b.cache_root, cache_path, fs.path.sep, dest_path, @errorName(err), |
| 343 | 343 | }); |
| 344 | 344 | }; |
lib/std/Build/Watch.zig+2-2| ... | ... | @@ -211,7 +211,7 @@ const Os = switch (builtin.os.tag) { |
| 211 | 211 | .ADD = true, |
| 212 | 212 | .ONLYDIR = true, |
| 213 | 213 | }, fan_mask, path.root_dir.handle.fd, path.subPathOrDot()) catch |err| { |
| 214 | fatal("unable to watch {}: {s}", .{ path, @errorName(err) }); | |
| 214 | fatal("unable to watch {f}: {s}", .{ path, @errorName(err) }); | |
| 215 | 215 | }; |
| 216 | 216 | } |
| 217 | 217 | break :rs &dh_gop.value_ptr.reaction_set; |
| ... | ... | @@ -265,7 +265,7 @@ const Os = switch (builtin.os.tag) { |
| 265 | 265 | .ONLYDIR = true, |
| 266 | 266 | }, fan_mask, path.root_dir.handle.fd, path.subPathOrDot()) catch |err| switch (err) { |
| 267 | 267 | error.FileNotFound => {}, // Expected, harmless. |
| 268 | else => |e| std.log.warn("unable to unwatch '{}': {s}", .{ path, @errorName(e) }), | |
| 268 | else => |e| std.log.warn("unable to unwatch '{f}': {s}", .{ path, @errorName(e) }), | |
| 269 | 269 | }; |
| 270 | 270 | |
| 271 | 271 | w.dir_table.swapRemoveAt(i); |
lib/std/SemanticVersion.zig+4-6| ... | ... | @@ -152,15 +152,13 @@ fn parseNum(text: []const u8) error{ InvalidVersion, Overflow }!usize { |
| 152 | 152 | |
| 153 | 153 | pub fn format( |
| 154 | 154 | self: Version, |
| 155 | bw: *std.io.BufferedWriter, | |
| 155 | 156 | comptime fmt: []const u8, |
| 156 | options: std.fmt.FormatOptions, | |
| 157 | out_stream: anytype, | |
| 158 | 157 | ) !void { |
| 159 | _ = options; | |
| 160 | 158 | if (fmt.len != 0) std.fmt.invalidFmtError(fmt, self); |
| 161 | try std.fmt.format(out_stream, "{d}.{d}.{d}", .{ self.major, self.minor, self.patch }); | |
| 162 | if (self.pre) |pre| try std.fmt.format(out_stream, "-{s}", .{pre}); | |
| 163 | if (self.build) |build| try std.fmt.format(out_stream, "+{s}", .{build}); | |
| 159 | try bw.print("{d}.{d}.{d}", .{ self.major, self.minor, self.patch }); | |
| 160 | if (self.pre) |pre| try bw.print("-{s}", .{pre}); | |
| 161 | if (self.build) |build| try bw.print("+{s}", .{build}); | |
| 164 | 162 | } |
| 165 | 163 | |
| 166 | 164 | const expect = std.testing.expect; |
lib/std/Target/Query.zig+2-2| ... | ... | @@ -423,7 +423,7 @@ pub fn zigTriple(self: Query, gpa: Allocator) Allocator.Error![]u8 { |
| 423 | 423 | try formatVersion(v, gpa, &result); |
| 424 | 424 | }, |
| 425 | 425 | .windows => |v| { |
| 426 | try result.print(gpa, "{s}", .{v}); | |
| 426 | try result.print(gpa, "{d}", .{v}); | |
| 427 | 427 | }, |
| 428 | 428 | } |
| 429 | 429 | } |
| ... | ... | @@ -437,7 +437,7 @@ pub fn zigTriple(self: Query, gpa: Allocator) Allocator.Error![]u8 { |
| 437 | 437 | .windows => |v| { |
| 438 | 438 | // This is counting on a custom format() function defined on `WindowsVersion` |
| 439 | 439 | // to add a prefix '.' and make there be a total of three dots. |
| 440 | try result.print(gpa, "..{s}", .{v}); | |
| 440 | try result.print(gpa, "..{d}", .{v}); | |
| 441 | 441 | }, |
| 442 | 442 | } |
| 443 | 443 | } |
lib/std/fifo.zig+57-6| ... | ... | @@ -38,8 +38,6 @@ pub fn LinearFifo( |
| 38 | 38 | count: usize, |
| 39 | 39 | |
| 40 | 40 | const Self = @This(); |
| 41 | pub const Reader = std.io.Reader(*Self, error{}, readFn); | |
| 42 | pub const Writer = std.io.Writer(*Self, error{OutOfMemory}, appendWrite); | |
| 43 | 41 | |
| 44 | 42 | // Type of Self argument for slice operations. |
| 45 | 43 | // If buffer is inline (Static) then we need to ensure we haven't |
| ... | ... | @@ -236,8 +234,31 @@ pub fn LinearFifo( |
| 236 | 234 | return self.read(dest); |
| 237 | 235 | } |
| 238 | 236 | |
| 239 | pub fn reader(self: *Self) Reader { | |
| 240 | return .{ .context = self }; | |
| 237 | pub fn reader(self: *Self) std.io.Reader { | |
| 238 | return .{ | |
| 239 | .context = self, | |
| 240 | .vtable = &.{ | |
| 241 | .read = &reader_read, | |
| 242 | .readv = &reader_readv, | |
| 243 | }, | |
| 244 | }; | |
| 245 | } | |
| 246 | fn reader_read( | |
| 247 | ctx: ?*anyopaque, | |
| 248 | bw: *std.io.BufferedWriter, | |
| 249 | limit: std.io.Reader.Limit, | |
| 250 | ) anyerror!std.io.Reader.Status { | |
| 251 | const fifo: *Self = @alignCast(@ptrCast(ctx)); | |
| 252 | _ = fifo; | |
| 253 | _ = bw; | |
| 254 | _ = limit; | |
| 255 | @panic("TODO"); | |
| 256 | } | |
| 257 | fn reader_readv(ctx: ?*anyopaque, data: []const []u8) anyerror!std.io.Reader.Status { | |
| 258 | const fifo: *Self = @alignCast(@ptrCast(ctx)); | |
| 259 | _ = fifo; | |
| 260 | _ = data; | |
| 261 | @panic("TODO"); | |
| 241 | 262 | } |
| 242 | 263 | |
| 243 | 264 | /// Returns number of items available in fifo |
| ... | ... | @@ -326,8 +347,38 @@ pub fn LinearFifo( |
| 326 | 347 | return bytes.len; |
| 327 | 348 | } |
| 328 | 349 | |
| 329 | pub fn writer(self: *Self) Writer { | |
| 330 | return .{ .context = self }; | |
| 350 | pub fn writer(fifo: *Self) std.io.Writer { | |
| 351 | return .{ | |
| 352 | .context = fifo, | |
| 353 | .vtable = &.{ | |
| 354 | .writeSplat = writer_writeSplat, | |
| 355 | .writeFile = writer_writeFile, | |
| 356 | }, | |
| 357 | }; | |
| 358 | } | |
| 359 | fn writer_writeSplat(ctx: ?*anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 360 | const fifo: *Self = @alignCast(@ptrCast(ctx)); | |
| 361 | _ = fifo; | |
| 362 | _ = data; | |
| 363 | _ = splat; | |
| 364 | @panic("TODO"); | |
| 365 | } | |
| 366 | fn writer_writeFile( | |
| 367 | ctx: ?*anyopaque, | |
| 368 | file: std.fs.File, | |
| 369 | offset: std.io.Writer.Offset, | |
| 370 | limit: std.io.Writer.Limit, | |
| 371 | headers_and_trailers: []const []const u8, | |
| 372 | headers_len: usize, | |
| 373 | ) anyerror!usize { | |
| 374 | const fifo: *Self = @alignCast(@ptrCast(ctx)); | |
| 375 | _ = fifo; | |
| 376 | _ = file; | |
| 377 | _ = offset; | |
| 378 | _ = limit; | |
| 379 | _ = headers_and_trailers; | |
| 380 | _ = headers_len; | |
| 381 | @panic("TODO"); | |
| 331 | 382 | } |
| 332 | 383 | |
| 333 | 384 | /// Make `count` items available before the current read location |
lib/std/fmt.zig+5-8| ... | ... | @@ -451,12 +451,10 @@ fn SliceEscape(comptime case: Case) type { |
| 451 | 451 | return struct { |
| 452 | 452 | pub fn format( |
| 453 | 453 | bytes: []const u8, |
| 454 | bw: *std.io.BufferedWriter, | |
| 454 | 455 | comptime fmt: []const u8, |
| 455 | options: std.fmt.Options, | |
| 456 | writer: anytype, | |
| 457 | 456 | ) !void { |
| 458 | 457 | _ = fmt; |
| 459 | _ = options; | |
| 460 | 458 | var buf: [4]u8 = undefined; |
| 461 | 459 | |
| 462 | 460 | buf[0] = '\\'; |
| ... | ... | @@ -464,11 +462,11 @@ fn SliceEscape(comptime case: Case) type { |
| 464 | 462 | |
| 465 | 463 | for (bytes) |c| { |
| 466 | 464 | if (std.ascii.isPrint(c)) { |
| 467 | try writer.writeByte(c); | |
| 465 | try bw.writeByte(c); | |
| 468 | 466 | } else { |
| 469 | 467 | buf[2] = charset[c >> 4]; |
| 470 | 468 | buf[3] = charset[c & 15]; |
| 471 | try writer.writeAll(&buf); | |
| 469 | try bw.writeAll(&buf); | |
| 472 | 470 | } |
| 473 | 471 | } |
| 474 | 472 | } |
| ... | ... | @@ -535,11 +533,10 @@ pub fn Formatter(comptime formatFn: anytype) type { |
| 535 | 533 | data: Data, |
| 536 | 534 | pub fn format( |
| 537 | 535 | self: @This(), |
| 538 | comptime fmt: []const u8, | |
| 539 | options: std.fmt.Options, | |
| 540 | 536 | writer: *std.io.BufferedWriter, |
| 537 | comptime fmt: []const u8, | |
| 541 | 538 | ) anyerror!void { |
| 542 | try formatFn(self.data, fmt, options, writer); | |
| 539 | try formatFn(self.data, writer, fmt); | |
| 543 | 540 | } |
| 544 | 541 | }; |
| 545 | 542 | } |
lib/std/fs/Dir.zig+39-4| ... | ... | @@ -1979,10 +1979,45 @@ pub fn readFileAlloc( |
| 1979 | 1979 | /// * `error.FileTooBig` is returned. |
| 1980 | 1980 | limit: std.io.Reader.Limit, |
| 1981 | 1981 | ) (File.OpenError || File.ReadAllocError)![]u8 { |
| 1982 | var buffer: std.ArrayListUnmanaged(u8) = .empty; | |
| 1982 | return dir.readFileAllocOptions(file_path, gpa, limit, null, .of(u8), null); | |
| 1983 | } | |
| 1984 | ||
| 1985 | /// Reads all the bytes from the named file. On success, caller owns returned | |
| 1986 | /// buffer. | |
| 1987 | pub fn readFileAllocOptions( | |
| 1988 | dir: Dir, | |
| 1989 | /// On Windows, should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/). | |
| 1990 | /// On WASI, should be encoded as valid UTF-8. | |
| 1991 | /// On other platforms, an opaque sequence of bytes with no particular encoding. | |
| 1992 | file_path: []const u8, | |
| 1993 | /// Used to allocate the result. | |
| 1994 | gpa: mem.Allocator, | |
| 1995 | /// If exceeded: | |
| 1996 | /// * The array list's length is increased by exactly one byte past `limit`. | |
| 1997 | /// * The file seek position is advanced by exactly one byte past `limit`. | |
| 1998 | /// * `error.FileTooBig` is returned. | |
| 1999 | limit: std.io.Reader.Limit, | |
| 2000 | /// If specified, the initial buffer size is calculated using this value, | |
| 2001 | /// otherwise the effective file size is used instead. | |
| 2002 | size_hint: ?usize, | |
| 2003 | comptime alignment: std.mem.Alignment, | |
| 2004 | comptime optional_sentinel: ?u8, | |
| 2005 | ) (File.OpenError || File.ReadAllocError)!(if (optional_sentinel) |s| [:s]align(alignment.toByteUnits()) u8 else []align(alignment.toByteUnits()) u8) { | |
| 2006 | var buffer: std.ArrayListAlignedUnmanaged(u8, alignment) = .empty; | |
| 1983 | 2007 | defer buffer.deinit(gpa); |
| 1984 | try readFileIntoArrayList(dir, file_path, gpa, limit, null, &buffer); | |
| 1985 | return buffer.toOwnedSlice(gpa); | |
| 2008 | try readFileIntoArrayList( | |
| 2009 | dir, | |
| 2010 | file_path, | |
| 2011 | gpa, | |
| 2012 | limit, | |
| 2013 | if (size_hint) |sh| sh +| 1 else null, | |
| 2014 | alignment, | |
| 2015 | &buffer, | |
| 2016 | ); | |
| 2017 | return if (optional_sentinel) |sentinel| | |
| 2018 | buffer.toOwnedSliceSentinel(gpa, sentinel) | |
| 2019 | else | |
| 2020 | buffer.toOwnedSlice(gpa); | |
| 1986 | 2021 | } |
| 1987 | 2022 | |
| 1988 | 2023 | /// Reads all the bytes from the named file, appending them into the provided |
| ... | ... | @@ -2004,7 +2039,7 @@ pub fn readFileIntoArrayList( |
| 2004 | 2039 | /// otherwise the effective file size is used instead. |
| 2005 | 2040 | size_hint: ?usize, |
| 2006 | 2041 | comptime alignment: ?std.mem.Alignment, |
| 2007 | list: *std.ArrayListAligned(u8, alignment), | |
| 2042 | list: *std.ArrayListAlignedUnmanaged(u8, alignment), | |
| 2008 | 2043 | ) (File.OpenError || File.ReadAllocError)!void { |
| 2009 | 2044 | var file = try dir.openFile(file_path, .{}); |
| 2010 | 2045 | defer file.close(); |
lib/std/fs/File.zig+5-5| ... | ... | @@ -1169,7 +1169,7 @@ pub fn readIntoArrayList( |
| 1169 | 1169 | gpa: Allocator, |
| 1170 | 1170 | limit: std.io.Reader.Limit, |
| 1171 | 1171 | comptime alignment: ?std.mem.Alignment, |
| 1172 | list: *std.ArrayListAligned(u8, alignment), | |
| 1172 | list: *std.ArrayListAlignedUnmanaged(u8, alignment), | |
| 1173 | 1173 | ) ReadAllocError!void { |
| 1174 | 1174 | var remaining = limit; |
| 1175 | 1175 | while (true) { |
| ... | ... | @@ -1676,7 +1676,7 @@ fn streamReadVec(context: ?*anyopaque, data: []const []u8) anyerror!std.io.Reade |
| 1676 | 1676 | return .{ .len = @intCast(n), .end = n == 0 }; |
| 1677 | 1677 | } |
| 1678 | 1678 | |
| 1679 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 1679 | pub fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 1680 | 1680 | const handle = opaqueToHandle(context); |
| 1681 | 1681 | var splat_buffer: [256]u8 = undefined; |
| 1682 | 1682 | if (is_windows) { |
| ... | ... | @@ -1716,7 +1716,7 @@ fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) anye |
| 1716 | 1716 | return std.posix.writev(handle, iovecs[0..len]); |
| 1717 | 1717 | } |
| 1718 | 1718 | |
| 1719 | fn writeFile( | |
| 1719 | pub fn writeFile( | |
| 1720 | 1720 | context: ?*anyopaque, |
| 1721 | 1721 | in_file: std.fs.File, |
| 1722 | 1722 | in_offset: std.io.Writer.Offset, |
| ... | ... | @@ -1727,8 +1727,8 @@ fn writeFile( |
| 1727 | 1727 | const out_fd = opaqueToHandle(context); |
| 1728 | 1728 | const in_fd = in_file.handle; |
| 1729 | 1729 | const len_int = switch (in_limit) { |
| 1730 | .zero => return writeSplat(context, headers_and_trailers, 1), | |
| 1731 | .none => 0, | |
| 1730 | .nothing => return writeSplat(context, headers_and_trailers, 1), | |
| 1731 | .unlimited => 0, | |
| 1732 | 1732 | else => in_limit.toInt().?, |
| 1733 | 1733 | }; |
| 1734 | 1734 | if (native_os == .linux) sf: { |
lib/std/http/Server.zig+64-20| ... | ... | @@ -593,8 +593,46 @@ pub const Request = struct { |
| 593 | 593 | HttpHeadersOversize, |
| 594 | 594 | }; |
| 595 | 595 | |
| 596 | fn contentLengthReader_read( | |
| 597 | ctx: ?*anyopaque, | |
| 598 | bw: *std.io.BufferedWriter, | |
| 599 | limit: std.io.Reader.Limit, | |
| 600 | ) anyerror!std.io.Reader.Status { | |
| 601 | const request: *Request = @alignCast(@ptrCast(ctx)); | |
| 602 | _ = request; | |
| 603 | _ = bw; | |
| 604 | _ = limit; | |
| 605 | @panic("TODO"); | |
| 606 | } | |
| 607 | ||
| 608 | fn contentLengthReader_readv(ctx: ?*anyopaque, data: []const []u8) anyerror!std.io.Reader.Status { | |
| 609 | const request: *Request = @alignCast(@ptrCast(ctx)); | |
| 610 | _ = request; | |
| 611 | _ = data; | |
| 612 | @panic("TODO"); | |
| 613 | } | |
| 614 | ||
| 615 | fn chunkedReader_read( | |
| 616 | ctx: ?*anyopaque, | |
| 617 | bw: *std.io.BufferedWriter, | |
| 618 | limit: std.io.Reader.Limit, | |
| 619 | ) anyerror!std.io.Reader.Status { | |
| 620 | const request: *Request = @alignCast(@ptrCast(ctx)); | |
| 621 | _ = request; | |
| 622 | _ = bw; | |
| 623 | _ = limit; | |
| 624 | @panic("TODO"); | |
| 625 | } | |
| 626 | ||
| 627 | fn chunkedReader_readv(ctx: ?*anyopaque, data: []const []u8) anyerror!std.io.Reader.Status { | |
| 628 | const request: *Request = @alignCast(@ptrCast(ctx)); | |
| 629 | _ = request; | |
| 630 | _ = data; | |
| 631 | @panic("TODO"); | |
| 632 | } | |
| 633 | ||
| 596 | 634 | fn read_cl(context: *const anyopaque, buffer: []u8) ReadError!usize { |
| 597 | const request: *Request = @constCast(@alignCast(@ptrCast(context))); | |
| 635 | const request: *Request = @alignCast(@ptrCast(context)); | |
| 598 | 636 | const s = request.server; |
| 599 | 637 | |
| 600 | 638 | const remaining_content_length = &request.reader_state.remaining_content_length; |
| ... | ... | @@ -622,7 +660,7 @@ pub const Request = struct { |
| 622 | 660 | } |
| 623 | 661 | |
| 624 | 662 | fn read_chunked(context: *const anyopaque, buffer: []u8) ReadError!usize { |
| 625 | const request: *Request = @constCast(@alignCast(@ptrCast(context))); | |
| 663 | const request: *Request = @alignCast(@ptrCast(context)); | |
| 626 | 664 | const s = request.server; |
| 627 | 665 | |
| 628 | 666 | const cp = &request.reader_state.chunk_parser; |
| ... | ... | @@ -724,7 +762,7 @@ pub const Request = struct { |
| 724 | 762 | /// request's expect field to `null`. |
| 725 | 763 | /// |
| 726 | 764 | /// Asserts that this function is only called once. |
| 727 | pub fn reader(request: *Request) ReaderError!std.io.AnyReader { | |
| 765 | pub fn reader(request: *Request) ReaderError!std.io.Reader { | |
| 728 | 766 | const s = request.server; |
| 729 | 767 | assert(s.state == .received_head); |
| 730 | 768 | s.state = .receiving_body; |
| ... | ... | @@ -747,8 +785,11 @@ pub const Request = struct { |
| 747 | 785 | .chunked => { |
| 748 | 786 | request.reader_state = .{ .chunk_parser = http.ChunkParser.init }; |
| 749 | 787 | return .{ |
| 750 | .readFn = read_chunked, | |
| 751 | 788 | .context = request, |
| 789 | .vtable = &.{ | |
| 790 | .read = &chunkedReader_read, | |
| 791 | .readv = &chunkedReader_readv, | |
| 792 | }, | |
| 752 | 793 | }; |
| 753 | 794 | }, |
| 754 | 795 | .none => { |
| ... | ... | @@ -756,8 +797,11 @@ pub const Request = struct { |
| 756 | 797 | .remaining_content_length = request.head.content_length orelse 0, |
| 757 | 798 | }; |
| 758 | 799 | return .{ |
| 759 | .readFn = read_cl, | |
| 760 | 800 | .context = request, |
| 801 | .vtable = &.{ | |
| 802 | .read = &contentLengthReader_read, | |
| 803 | .readv = &contentLengthReader_readv, | |
| 804 | }, | |
| 761 | 805 | }; |
| 762 | 806 | }, |
| 763 | 807 | } |
| ... | ... | @@ -779,7 +823,7 @@ pub const Request = struct { |
| 779 | 823 | if (keep_alive and request.head.keep_alive) switch (s.state) { |
| 780 | 824 | .received_head => { |
| 781 | 825 | const r = request.reader() catch return false; |
| 782 | _ = r.discard() catch return false; | |
| 826 | _ = r.discardUntilEnd() catch return false; | |
| 783 | 827 | assert(s.state == .ready); |
| 784 | 828 | return true; |
| 785 | 829 | }, |
| ... | ... | @@ -868,30 +912,30 @@ pub const Response = struct { |
| 868 | 912 | } |
| 869 | 913 | } |
| 870 | 914 | |
| 871 | fn cl_writeSplat(context: *anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 915 | fn cl_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 872 | 916 | _ = splat; |
| 873 | 917 | return cl_write(context, data[0]); // TODO: try to send all the data |
| 874 | 918 | } |
| 875 | 919 | |
| 876 | 920 | fn cl_writeFile( |
| 877 | context: *anyopaque, | |
| 921 | context: ?*anyopaque, | |
| 878 | 922 | file: std.fs.File, |
| 879 | offset: u64, | |
| 880 | len: std.io.Writer.FileLen, | |
| 923 | offset: std.io.Writer.Offset, | |
| 924 | limit: std.io.Writer.Limit, | |
| 881 | 925 | headers_and_trailers: []const []const u8, |
| 882 | 926 | headers_len: usize, |
| 883 | 927 | ) anyerror!usize { |
| 884 | 928 | _ = context; |
| 885 | 929 | _ = file; |
| 886 | 930 | _ = offset; |
| 887 | _ = len; | |
| 931 | _ = limit; | |
| 888 | 932 | _ = headers_and_trailers; |
| 889 | 933 | _ = headers_len; |
| 890 | 934 | return error.Unimplemented; |
| 891 | 935 | } |
| 892 | 936 | |
| 893 | fn cl_write(context: *anyopaque, bytes: []const u8) anyerror!usize { | |
| 894 | const r: *Response = @constCast(@alignCast(@ptrCast(context))); | |
| 937 | fn cl_write(context: ?*anyopaque, bytes: []const u8) anyerror!usize { | |
| 938 | const r: *Response = @alignCast(@ptrCast(context)); | |
| 895 | 939 | |
| 896 | 940 | var trash: u64 = std.math.maxInt(u64); |
| 897 | 941 | const len = switch (r.transfer_encoding) { |
| ... | ... | @@ -935,30 +979,30 @@ pub const Response = struct { |
| 935 | 979 | return bytes.len; |
| 936 | 980 | } |
| 937 | 981 | |
| 938 | fn chunked_writeSplat(context: *anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 982 | fn chunked_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 939 | 983 | _ = splat; |
| 940 | 984 | return chunked_write(context, data[0]); // TODO: try to send all the data |
| 941 | 985 | } |
| 942 | 986 | |
| 943 | 987 | fn chunked_writeFile( |
| 944 | context: *anyopaque, | |
| 988 | context: ?*anyopaque, | |
| 945 | 989 | file: std.fs.File, |
| 946 | offset: u64, | |
| 947 | len: std.io.Writer.FileLen, | |
| 990 | offset: std.io.Writer.Offset, | |
| 991 | limit: std.io.Writer.Limit, | |
| 948 | 992 | headers_and_trailers: []const []const u8, |
| 949 | 993 | headers_len: usize, |
| 950 | 994 | ) anyerror!usize { |
| 951 | 995 | _ = context; |
| 952 | 996 | _ = file; |
| 953 | 997 | _ = offset; |
| 954 | _ = len; | |
| 998 | _ = limit; | |
| 955 | 999 | _ = headers_and_trailers; |
| 956 | 1000 | _ = headers_len; |
| 957 | 1001 | return error.Unimplemented; // TODO lower to a call to writeFile on the output |
| 958 | 1002 | } |
| 959 | 1003 | |
| 960 | fn chunked_write(context: *anyopaque, bytes: []const u8) anyerror!usize { | |
| 961 | const r: *Response = @constCast(@alignCast(@ptrCast(context))); | |
| 1004 | fn chunked_write(context: ?*anyopaque, bytes: []const u8) anyerror!usize { | |
| 1005 | const r: *Response = @alignCast(@ptrCast(context)); | |
| 962 | 1006 | assert(r.transfer_encoding == .chunked); |
| 963 | 1007 | |
| 964 | 1008 | if (r.elide_body) |
lib/std/http/WebSocket.zig+3-2| ... | ... | @@ -57,8 +57,8 @@ pub fn init( |
| 57 | 57 | |
| 58 | 58 | ws.* = .{ |
| 59 | 59 | .key = key, |
| 60 | .recv_fifo = std.fifo.LinearFifo(u8, .Slice).init(recv_buffer), | |
| 61 | .reader = try request.reader(), | |
| 60 | .recv_fifo = .init(recv_buffer), | |
| 61 | .reader = undefined, | |
| 62 | 62 | .response = request.respondStreaming(.{ |
| 63 | 63 | .send_buffer = send_buffer, |
| 64 | 64 | .respond_options = .{ |
| ... | ... | @@ -74,6 +74,7 @@ pub fn init( |
| 74 | 74 | .request = request, |
| 75 | 75 | .outstanding_len = 0, |
| 76 | 76 | }; |
| 77 | ws.reader.init(try request.reader(), &.{}); | |
| 77 | 78 | return true; |
| 78 | 79 | } |
| 79 | 80 |
lib/std/io/AllocatingWriter.zig+14-10| ... | ... | @@ -28,12 +28,12 @@ const vtable: std.io.Writer.VTable = .{ |
| 28 | 28 | |
| 29 | 29 | /// Sets the `AllocatingWriter` to an empty state. |
| 30 | 30 | pub fn init(aw: *AllocatingWriter, allocator: std.mem.Allocator) void { |
| 31 | initOwnedSlice(aw, allocator, &.{}); | |
| 31 | aw.initOwnedSlice(allocator, &.{}); | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | pub fn initCapacity(aw: *AllocatingWriter, allocator: std.mem.Allocator, capacity: usize) error{OutOfMemory}!void { |
| 35 | 35 | const initial_buffer = try allocator.alloc(u8, capacity); |
| 36 | initOwnedSlice(aw, allocator, initial_buffer); | |
| 36 | aw.initOwnedSlice(allocator, initial_buffer); | |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | pub fn initOwnedSlice(aw: *AllocatingWriter, allocator: std.mem.Allocator, slice: []u8) void { |
| ... | ... | @@ -119,11 +119,15 @@ pub fn getWritten(aw: *AllocatingWriter) []u8 { |
| 119 | 119 | return written; |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | pub fn clearRetainingCapacity(aw: *AllocatingWriter) void { | |
| 122 | pub fn shrinkRetainingCapacity(aw: *AllocatingWriter, new_len: usize) void { | |
| 123 | 123 | const bw = &aw.buffered_writer; |
| 124 | bw.buffer = aw.written.ptr[0 .. aw.written.len + bw.buffer.len]; | |
| 124 | bw.buffer = aw.written.ptr[new_len .. aw.written.len + bw.buffer.len]; | |
| 125 | 125 | bw.end = 0; |
| 126 | aw.written.len = 0; | |
| 126 | aw.written.len = new_len; | |
| 127 | } | |
| 128 | ||
| 129 | pub fn clearRetainingCapacity(aw: *AllocatingWriter) void { | |
| 130 | aw.shrinkRetainingCapacity(0); | |
| 127 | 131 | } |
| 128 | 132 | |
| 129 | 133 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) anyerror!usize { |
| ... | ... | @@ -161,7 +165,7 @@ fn writeFile( |
| 161 | 165 | context: ?*anyopaque, |
| 162 | 166 | file: std.fs.File, |
| 163 | 167 | offset: std.io.Writer.Offset, |
| 164 | len: std.io.Writer.FileLen, | |
| 168 | limit: std.io.Writer.Limit, | |
| 165 | 169 | headers_and_trailers_full: []const []const u8, |
| 166 | 170 | headers_len_full: usize, |
| 167 | 171 | ) anyerror!usize { |
| ... | ... | @@ -177,7 +181,7 @@ fn writeFile( |
| 177 | 181 | } else .{ headers_and_trailers_full, headers_len_full }; |
| 178 | 182 | const trailers = headers_and_trailers[headers_len..]; |
| 179 | 183 | const pos = offset.toInt() orelse @panic("TODO treat file as stream"); |
| 180 | if (len == .entire_file) { | |
| 184 | const limit_int = limit.toInt() orelse { | |
| 181 | 185 | var new_capacity: usize = list.capacity + std.atomic.cache_line; |
| 182 | 186 | for (headers_and_trailers) |bytes| new_capacity += bytes.len; |
| 183 | 187 | try list.ensureTotalCapacity(gpa, new_capacity); |
| ... | ... | @@ -193,12 +197,12 @@ fn writeFile( |
| 193 | 197 | } |
| 194 | 198 | list.items.len += n; |
| 195 | 199 | return list.items.len - start_len; |
| 196 | } | |
| 197 | var new_capacity: usize = list.capacity + len.int(); | |
| 200 | }; | |
| 201 | var new_capacity: usize = list.capacity + limit_int; | |
| 198 | 202 | for (headers_and_trailers) |bytes| new_capacity += bytes.len; |
| 199 | 203 | try list.ensureTotalCapacity(gpa, new_capacity); |
| 200 | 204 | for (headers_and_trailers[0..headers_len]) |bytes| list.appendSliceAssumeCapacity(bytes); |
| 201 | const dest = list.items.ptr[list.items.len..][0..len.int()]; | |
| 205 | const dest = list.items.ptr[list.items.len..][0..limit_int]; | |
| 202 | 206 | const n = try file.pread(dest, pos); |
| 203 | 207 | list.items.len += n; |
| 204 | 208 | if (n < dest.len) { |
lib/std/io/BufferedReader.zig+8-9| ... | ... | @@ -253,18 +253,17 @@ pub fn discardUpTo(br: *BufferedReader, n: usize) anyerror!usize { |
| 253 | 253 | const proposed_seek = br.seek + remaining; |
| 254 | 254 | if (proposed_seek <= storage.end) { |
| 255 | 255 | br.seek = proposed_seek; |
| 256 | return; | |
| 256 | return n; | |
| 257 | 257 | } |
| 258 | 258 | remaining -= (storage.end - br.seek); |
| 259 | 259 | storage.end = 0; |
| 260 | 260 | br.seek = 0; |
| 261 | const result = try br.unbuffered_reader.read(&storage, .none); | |
| 262 | result.write_err catch unreachable; | |
| 263 | try result.read_err; | |
| 261 | const result = try br.unbuffered_reader.read(storage, .unlimited); | |
| 264 | 262 | assert(result.len == storage.end); |
| 265 | 263 | if (remaining <= storage.end) continue; |
| 266 | 264 | if (result.end) return n - remaining; |
| 267 | 265 | } |
| 266 | return n; | |
| 268 | 267 | } |
| 269 | 268 | |
| 270 | 269 | /// Reads the stream until the end, ignoring all the data. |
| ... | ... | @@ -302,7 +301,7 @@ pub fn read(br: *BufferedReader, buffer: []u8) anyerror!void { |
| 302 | 301 | br.seek = 0; |
| 303 | 302 | var i: usize = in_buffer.len; |
| 304 | 303 | while (true) { |
| 305 | const status = try br.unbuffered_reader.read(storage, .none); | |
| 304 | const status = try br.unbuffered_reader.read(storage, .unlimited); | |
| 306 | 305 | const next_i = i + storage.end; |
| 307 | 306 | if (next_i >= buffer.len) { |
| 308 | 307 | const remaining = buffer[i..]; |
| ... | ... | @@ -389,7 +388,7 @@ pub fn peekDelimiterInclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 |
| 389 | 388 | /// * `peekDelimiterConclusive` |
| 390 | 389 | pub fn takeDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 { |
| 391 | 390 | const result = try peekDelimiterConclusive(br, delimiter); |
| 392 | toss(result.len); | |
| 391 | br.toss(result.len); | |
| 393 | 392 | return result; |
| 394 | 393 | } |
| 395 | 394 | |
| ... | ... | @@ -407,7 +406,7 @@ pub fn peekDelimiterConclusive(br: *BufferedReader, delimiter: u8) anyerror![]u8 |
| 407 | 406 | storage.end = i; |
| 408 | 407 | br.seek = 0; |
| 409 | 408 | while (i < storage.buffer.len) { |
| 410 | const status = try br.unbuffered_reader.read(storage, .none); | |
| 409 | const status = try br.unbuffered_reader.read(storage, .unlimited); | |
| 411 | 410 | if (std.mem.indexOfScalarPos(u8, storage.buffer[0..storage.end], i, delimiter)) |end| { |
| 412 | 411 | return storage.buffer[0 .. end + 1]; |
| 413 | 412 | } |
| ... | ... | @@ -505,7 +504,7 @@ pub fn fill(br: *BufferedReader, n: usize) anyerror!void { |
| 505 | 504 | storage.end = remainder.len; |
| 506 | 505 | br.seek = 0; |
| 507 | 506 | while (true) { |
| 508 | const status = try br.unbuffered_reader.read(storage, .none); | |
| 507 | const status = try br.unbuffered_reader.read(storage, .unlimited); | |
| 509 | 508 | if (n <= storage.end) return; |
| 510 | 509 | if (status.end) return error.EndOfStream; |
| 511 | 510 | } |
| ... | ... | @@ -589,7 +588,7 @@ fn takeMultipleOf7Leb128(br: *BufferedReader, comptime Result: type) anyerror!Re |
| 589 | 588 | const buffer: []const packed struct(u8) { bits: u7, more: bool } = @ptrCast(try br.peekAll(1)); |
| 590 | 589 | for (buffer, 1..) |byte, len| { |
| 591 | 590 | if (remaining_bits > 0) { |
| 592 | result = @shlExact(@as(UnsignedResult, byte.bits), result_info.bits - 7) | @shrExact(result, 7); | |
| 591 | result = @shlExact(@as(UnsignedResult, byte.bits), result_info.bits - 7) | if (result_info.bits > 7) @shrExact(result, 7) else 0; | |
| 593 | 592 | remaining_bits -= 7; |
| 594 | 593 | } else if (fits) fits = switch (result_info.signedness) { |
| 595 | 594 | .signed => @as(i7, @bitCast(byte.bits)) == @as(i7, @truncate(@as(Result, @bitCast(result)) >> (result_info.bits - 1))), |
lib/std/io/BufferedWriter.zig+50-47| ... | ... | @@ -503,7 +503,7 @@ pub const WriteFileOptions = struct { |
| 503 | 503 | offset: Writer.Offset = .none, |
| 504 | 504 | /// If the size of the source file is known, it is likely that passing the |
| 505 | 505 | /// size here will save one syscall. |
| 506 | limit: Writer.Limit = .none, | |
| 506 | limit: Writer.Limit = .unlimited, | |
| 507 | 507 | /// Headers and trailers must be passed together so that in case `len` is |
| 508 | 508 | /// zero, they can be forwarded directly to `Writer.VTable.writev`. |
| 509 | 509 | /// |
| ... | ... | @@ -518,55 +518,58 @@ pub const WriteFileOptions = struct { |
| 518 | 518 | pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOptions) anyerror!void { |
| 519 | 519 | const headers_and_trailers = options.headers_and_trailers; |
| 520 | 520 | const headers = headers_and_trailers[0..options.headers_len]; |
| 521 | if (options.limit == .zero) return writevAll(bw, headers_and_trailers); | |
| 522 | if (options.limit == .none) { | |
| 523 | // When reading the whole file, we cannot include the trailers in the | |
| 524 | // call that reads from the file handle, because we have no way to | |
| 525 | // determine whether a partial write is past the end of the file or | |
| 526 | // not. | |
| 527 | var i: usize = 0; | |
| 528 | var offset = options.offset; | |
| 529 | while (true) { | |
| 530 | var n = try writeFile(bw, file, offset, .entire_file, headers[i..], headers.len - i); | |
| 531 | while (i < headers.len and n >= headers[i].len) { | |
| 532 | n -= headers[i].len; | |
| 533 | i += 1; | |
| 534 | } | |
| 535 | if (i < headers.len) { | |
| 536 | headers[i] = headers[i][n..]; | |
| 537 | continue; | |
| 538 | } | |
| 539 | if (n == 0) break; | |
| 540 | offset += n; | |
| 541 | } | |
| 542 | } else { | |
| 543 | var len = options.limit.toInt().?; | |
| 544 | var i: usize = 0; | |
| 545 | var offset = options.offset; | |
| 546 | while (true) { | |
| 547 | var n = try writeFile(bw, file, offset, .init(len), headers_and_trailers[i..], headers.len - i); | |
| 548 | while (i < headers.len and n >= headers[i].len) { | |
| 549 | n -= headers[i].len; | |
| 550 | i += 1; | |
| 551 | } | |
| 552 | if (i < headers.len) { | |
| 553 | headers[i] = headers[i][n..]; | |
| 554 | continue; | |
| 521 | switch (options.limit) { | |
| 522 | .nothing => return writevAll(bw, headers_and_trailers), | |
| 523 | .unlimited => { | |
| 524 | // When reading the whole file, we cannot include the trailers in the | |
| 525 | // call that reads from the file handle, because we have no way to | |
| 526 | // determine whether a partial write is past the end of the file or | |
| 527 | // not. | |
| 528 | var i: usize = 0; | |
| 529 | var offset = options.offset; | |
| 530 | while (true) { | |
| 531 | var n = try writeFile(bw, file, offset, .unlimited, headers[i..], headers.len - i); | |
| 532 | while (i < headers.len and n >= headers[i].len) { | |
| 533 | n -= headers[i].len; | |
| 534 | i += 1; | |
| 535 | } | |
| 536 | if (i < headers.len) { | |
| 537 | headers[i] = headers[i][n..]; | |
| 538 | continue; | |
| 539 | } | |
| 540 | if (n == 0) break; | |
| 541 | offset = offset.advance(n); | |
| 555 | 542 | } |
| 556 | if (n >= len) { | |
| 557 | n -= len; | |
| 558 | if (i >= headers_and_trailers.len) return; | |
| 559 | while (n >= headers_and_trailers[i].len) { | |
| 560 | n -= headers_and_trailers[i].len; | |
| 543 | }, | |
| 544 | else => { | |
| 545 | var len = options.limit.toInt().?; | |
| 546 | var i: usize = 0; | |
| 547 | var offset = options.offset; | |
| 548 | while (true) { | |
| 549 | var n = try writeFile(bw, file, offset, .limited(len), headers_and_trailers[i..], headers.len - i); | |
| 550 | while (i < headers.len and n >= headers[i].len) { | |
| 551 | n -= headers[i].len; | |
| 561 | 552 | i += 1; |
| 553 | } | |
| 554 | if (i < headers.len) { | |
| 555 | headers[i] = headers[i][n..]; | |
| 556 | continue; | |
| 557 | } | |
| 558 | if (n >= len) { | |
| 559 | n -= len; | |
| 562 | 560 | if (i >= headers_and_trailers.len) return; |
| 561 | while (n >= headers_and_trailers[i].len) { | |
| 562 | n -= headers_and_trailers[i].len; | |
| 563 | i += 1; | |
| 564 | if (i >= headers_and_trailers.len) return; | |
| 565 | } | |
| 566 | headers_and_trailers[i] = headers_and_trailers[i][n..]; | |
| 567 | return writevAll(bw, headers_and_trailers[i..]); | |
| 563 | 568 | } |
| 564 | headers_and_trailers[i] = headers_and_trailers[i][n..]; | |
| 565 | return writevAll(bw, headers_and_trailers[i..]); | |
| 569 | offset = offset.advance(n); | |
| 570 | len -= n; | |
| 566 | 571 | } |
| 567 | offset += n; | |
| 568 | len -= n; | |
| 569 | } | |
| 572 | }, | |
| 570 | 573 | } |
| 571 | 574 | } |
| 572 | 575 | |
| ... | ... | @@ -717,9 +720,9 @@ pub fn printValue( |
| 717 | 720 | } |
| 718 | 721 | } |
| 719 | 722 | |
| 720 | try bw.writeByteCount('('); | |
| 723 | try bw.writeByte('('); | |
| 721 | 724 | try printValue(bw, actual_fmt, options, @intFromEnum(value), max_depth); |
| 722 | try bw.writeByteCount(')'); | |
| 725 | try bw.writeByte(')'); | |
| 723 | 726 | }, |
| 724 | 727 | .@"union" => |info| { |
| 725 | 728 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
lib/std/io/Reader.zig+15-12| ... | ... | @@ -48,12 +48,12 @@ pub const Status = packed struct(usize) { |
| 48 | 48 | }; |
| 49 | 49 | |
| 50 | 50 | pub const Limit = enum(usize) { |
| 51 | zero = 0, | |
| 52 | none = std.math.maxInt(usize), | |
| 51 | nothing = 0, | |
| 52 | unlimited = std.math.maxInt(usize), | |
| 53 | 53 | _, |
| 54 | 54 | |
| 55 | /// `std.math.maxInt(usize)` is interpreted to mean "no limit". | |
| 56 | pub fn init(n: usize) Limit { | |
| 55 | /// `std.math.maxInt(usize)` is interpreted to mean `.unlimited`. | |
| 56 | pub fn limited(n: usize) Limit { | |
| 57 | 57 | return @enumFromInt(n); |
| 58 | 58 | } |
| 59 | 59 | |
| ... | ... | @@ -66,7 +66,10 @@ pub const Limit = enum(usize) { |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | pub fn toInt(l: Limit) ?usize { |
| 69 | return if (l == .none) null else @intFromEnum(l); | |
| 69 | return switch (l) { | |
| 70 | else => @intFromEnum(l), | |
| 71 | .unlimited => null, | |
| 72 | }; | |
| 70 | 73 | } |
| 71 | 74 | |
| 72 | 75 | /// Reduces a slice to account for the limit, leaving room for one extra |
| ... | ... | @@ -84,7 +87,7 @@ pub const Limit = enum(usize) { |
| 84 | 87 | /// Return a new limit reduced by `amount` or return `null` indicating |
| 85 | 88 | /// limit would be exceeded. |
| 86 | 89 | pub fn subtract(l: Limit, amount: usize) ?Limit { |
| 87 | if (l == .none) return .{ .next = .none }; | |
| 90 | if (l == .unlimited) return .unlimited; | |
| 88 | 91 | if (amount > @intFromEnum(l)) return null; |
| 89 | 92 | return @enumFromInt(@intFromEnum(l) - amount); |
| 90 | 93 | } |
| ... | ... | @@ -103,7 +106,7 @@ pub fn readAll(r: Reader, w: *std.io.BufferedWriter) anyerror!usize { |
| 103 | 106 | const readFn = r.vtable.read; |
| 104 | 107 | var offset: usize = 0; |
| 105 | 108 | while (true) { |
| 106 | const status = try readFn(r.context, w, .none); | |
| 109 | const status = try readFn(r.context, w, .unlimited); | |
| 107 | 110 | offset += status.len; |
| 108 | 111 | if (status.end) return offset; |
| 109 | 112 | } |
| ... | ... | @@ -119,21 +122,21 @@ pub fn readAlloc(r: Reader, gpa: std.mem.Allocator, max_size: usize) anyerror![] |
| 119 | 122 | const readFn = r.vtable.read; |
| 120 | 123 | var aw: std.io.AllocatingWriter = undefined; |
| 121 | 124 | errdefer aw.deinit(); |
| 122 | const bw = aw.init(gpa); | |
| 125 | aw.init(gpa); | |
| 123 | 126 | var remaining = max_size; |
| 124 | 127 | while (remaining > 0) { |
| 125 | const status = try readFn(r.context, bw, .init(remaining)); | |
| 128 | const status = try readFn(r.context, &aw.buffered_writer, .limited(remaining)); | |
| 126 | 129 | if (status.end) break; |
| 127 | 130 | remaining -= status.len; |
| 128 | 131 | } |
| 129 | return aw.toOwnedSlice(gpa); | |
| 132 | return aw.toOwnedSlice(); | |
| 130 | 133 | } |
| 131 | 134 | |
| 132 | 135 | /// Reads the stream until the end, ignoring all the data. |
| 133 | 136 | /// Returns the number of bytes discarded. |
| 134 | 137 | pub fn discardUntilEnd(r: Reader) anyerror!usize { |
| 135 | var bw = std.io.null_writer.unbuffered(); | |
| 136 | return readAll(r, &bw); | |
| 138 | var bw = std.io.Writer.null.unbuffered(); | |
| 139 | return r.readAll(&bw); | |
| 137 | 140 | } |
| 138 | 141 | |
| 139 | 142 | test "readAlloc when the backing reader provides one byte at a time" { |
lib/std/io/Writer.zig+8-1| ... | ... | @@ -60,6 +60,13 @@ pub const Offset = enum(u64) { |
| 60 | 60 | pub fn toInt(o: Offset) ?u64 { |
| 61 | 61 | return if (o == .none) null else @intFromEnum(o); |
| 62 | 62 | } |
| 63 | ||
| 64 | pub fn advance(o: Offset, amount: u64) Offset { | |
| 65 | return switch (o) { | |
| 66 | .none => .none, | |
| 67 | else => .init(@intFromEnum(o) + amount), | |
| 68 | }; | |
| 69 | } | |
| 63 | 70 | }; |
| 64 | 71 | |
| 65 | 72 | pub fn writev(w: Writer, data: []const []const u8) anyerror!usize { |
| ... | ... | @@ -106,7 +113,7 @@ pub fn buffered(w: Writer, buffer: []u8) std.io.BufferedWriter { |
| 106 | 113 | } |
| 107 | 114 | |
| 108 | 115 | pub fn unbuffered(w: Writer) std.io.BufferedWriter { |
| 109 | return buffered(w, &.{}); | |
| 116 | return w.buffered(&.{}); | |
| 110 | 117 | } |
| 111 | 118 | |
| 112 | 119 | /// A `Writer` that discards all data. |
lib/std/net.zig+4-4| ... | ... | @@ -1853,7 +1853,7 @@ pub const Stream = struct { |
| 1853 | 1853 | }, |
| 1854 | 1854 | else => &.{ |
| 1855 | 1855 | .writeSplat = posix_writeSplat, |
| 1856 | .writeFile = std.fs.File.writer_writeFile, | |
| 1856 | .writeFile = std.fs.File.writeFile, | |
| 1857 | 1857 | }, |
| 1858 | 1858 | }, |
| 1859 | 1859 | }; |
| ... | ... | @@ -1960,7 +1960,7 @@ pub const Stream = struct { |
| 1960 | 1960 | return n; |
| 1961 | 1961 | } |
| 1962 | 1962 | |
| 1963 | fn posix_writeSplat(context: *anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 1963 | fn posix_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) anyerror!usize { | |
| 1964 | 1964 | const sock_fd = opaqueToHandle(context); |
| 1965 | 1965 | comptime assert(native_os != .windows); |
| 1966 | 1966 | var splat_buffer: [256]u8 = undefined; |
| ... | ... | @@ -2029,7 +2029,7 @@ pub const Stream = struct { |
| 2029 | 2029 | |
| 2030 | 2030 | const max_buffers_len = 8; |
| 2031 | 2031 | |
| 2032 | fn handleToOpaque(handle: Handle) *anyopaque { | |
| 2032 | fn handleToOpaque(handle: Handle) ?*anyopaque { | |
| 2033 | 2033 | return switch (@typeInfo(Handle)) { |
| 2034 | 2034 | .pointer => @ptrCast(handle), |
| 2035 | 2035 | .int => @ptrFromInt(@as(u32, @bitCast(handle))), |
| ... | ... | @@ -2037,7 +2037,7 @@ pub const Stream = struct { |
| 2037 | 2037 | }; |
| 2038 | 2038 | } |
| 2039 | 2039 | |
| 2040 | fn opaqueToHandle(userdata: *anyopaque) Handle { | |
| 2040 | fn opaqueToHandle(userdata: ?*anyopaque) Handle { | |
| 2041 | 2041 | return switch (@typeInfo(Handle)) { |
| 2042 | 2042 | .pointer => @ptrCast(userdata), |
| 2043 | 2043 | .int => @intCast(@intFromPtr(userdata)), |
lib/std/process/Child.zig+7-3| ... | ... | @@ -1004,13 +1004,17 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { |
| 1004 | 1004 | |
| 1005 | 1005 | fn writeIntFd(fd: i32, value: ErrInt) !void { |
| 1006 | 1006 | const file: File = .{ .handle = fd }; |
| 1007 | var bw = file.writer().unbuffered(); | |
| 1008 | bw.writeInt(u64, @intCast(value), .little) catch return error.SystemResources; | |
| 1007 | var buffer: [8]u8 = undefined; | |
| 1008 | std.mem.writeInt(u64, &buffer, @intCast(value), .little); | |
| 1009 | file.writeAll(&buffer) catch return error.SystemResorces; | |
| 1009 | 1010 | } |
| 1010 | 1011 | |
| 1011 | 1012 | fn readIntFd(fd: i32) !ErrInt { |
| 1012 | 1013 | const file: File = .{ .handle = fd }; |
| 1013 | return @intCast(file.reader().readInt(u64, .little) catch return error.SystemResources); | |
| 1014 | var buffer: [8]u8 = undefined; | |
| 1015 | const n = file.readAll(&buffer) catch return error.SystemResources; | |
| 1016 | if (n != buffer.len) return error.SystemResources; | |
| 1017 | return @intCast(std.mem.readInt(u64, &buffer, .little)); | |
| 1014 | 1018 | } |
| 1015 | 1019 | |
| 1016 | 1020 | const ErrInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8); |
lib/std/tar/Writer.zig+1-1| ... | ... | @@ -44,7 +44,7 @@ pub fn writeFile(self: *Self, sub_path: []const u8, file: std.fs.File) !void { |
| 44 | 44 | try header.setMtime(mtime); |
| 45 | 45 | try header.write(self.underlying_writer); |
| 46 | 46 | |
| 47 | try self.underlying_writer.writeFileAll(file, .{ .len = .init(stat.size) }); | |
| 47 | try self.underlying_writer.writeFileAll(file, .{ .limit = .limited(stat.size) }); | |
| 48 | 48 | try self.writePadding(stat.size); |
| 49 | 49 | } |
| 50 | 50 |
lib/std/zig.zig+6-9| ... | ... | @@ -414,9 +414,8 @@ test fmtId { |
| 414 | 414 | /// Print the string as a Zig identifier, escaping it with `@""` syntax if needed. |
| 415 | 415 | fn formatId( |
| 416 | 416 | bytes: []const u8, |
| 417 | bw: *std.io.BufferedWriter, | |
| 417 | 418 | comptime fmt: []const u8, |
| 418 | options: std.fmt.FormatOptions, | |
| 419 | writer: *std.io.BufferedWriter, | |
| 420 | 419 | ) !void { |
| 421 | 420 | const allow_primitive, const allow_underscore = comptime parse_fmt: { |
| 422 | 421 | var allow_primitive = false; |
| ... | ... | @@ -442,11 +441,11 @@ fn formatId( |
| 442 | 441 | (allow_primitive or !std.zig.isPrimitive(bytes)) and |
| 443 | 442 | (allow_underscore or !isUnderscore(bytes))) |
| 444 | 443 | { |
| 445 | return writer.writeAll(bytes); | |
| 444 | return bw.writeAll(bytes); | |
| 446 | 445 | } |
| 447 | try writer.writeAll("@\""); | |
| 448 | try stringEscape(bytes, "", options, writer); | |
| 449 | try writer.writeByte('"'); | |
| 446 | try bw.writeAll("@\""); | |
| 447 | try stringEscape(bytes, bw, ""); | |
| 448 | try bw.writeByte('"'); | |
| 450 | 449 | } |
| 451 | 450 | |
| 452 | 451 | /// Return a Formatter for Zig Escapes of a double quoted string. |
| ... | ... | @@ -473,11 +472,9 @@ test fmtEscapes { |
| 473 | 472 | /// Format `{'}` treats contents as a single-quoted string. |
| 474 | 473 | pub fn stringEscape( |
| 475 | 474 | bytes: []const u8, |
| 476 | comptime f: []const u8, | |
| 477 | options: std.fmt.FormatOptions, | |
| 478 | 475 | bw: *std.io.BufferedWriter, |
| 476 | comptime f: []const u8, | |
| 479 | 477 | ) !void { |
| 480 | _ = options; | |
| 481 | 478 | for (bytes) |byte| switch (byte) { |
| 482 | 479 | '\n' => try bw.writeAll("\\n"), |
| 483 | 480 | '\r' => try bw.writeAll("\\r"), |
lib/std/zig/ErrorBundle.zig+2-2| ... | ... | @@ -190,7 +190,7 @@ fn renderErrorMessageToWriter( |
| 190 | 190 | ) anyerror!void { |
| 191 | 191 | const ttyconf = options.ttyconf; |
| 192 | 192 | const err_msg = eb.getErrorMessage(err_msg_index); |
| 193 | const prefix_start = bw.bytes_written; | |
| 193 | const prefix_start = bw.count; | |
| 194 | 194 | if (err_msg.src_loc != .none) { |
| 195 | 195 | const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc)); |
| 196 | 196 | try bw.splatByteAll(' ', indent); |
| ... | ... | @@ -205,7 +205,7 @@ fn renderErrorMessageToWriter( |
| 205 | 205 | try bw.writeAll(": "); |
| 206 | 206 | // This is the length of the part before the error message: |
| 207 | 207 | // e.g. "file.zig:4:5: error: " |
| 208 | const prefix_len = bw.bytes_written - prefix_start; | |
| 208 | const prefix_len = bw.count - prefix_start; | |
| 209 | 209 | try ttyconf.setColor(bw, .reset); |
| 210 | 210 | try ttyconf.setColor(bw, .bold); |
| 211 | 211 | if (err_msg.count == 1) { |
test/src/Cases.zig+1-1| ... | ... | @@ -378,7 +378,7 @@ fn addFromDirInner( |
| 378 | 378 | current_file.* = filename; |
| 379 | 379 | |
| 380 | 380 | const max_file_size = 10 * 1024 * 1024; |
| 381 | const src = try iterable_dir.readFileAllocOptions(ctx.arena, filename, max_file_size, null, .@"1", 0); | |
| 381 | const src = try iterable_dir.readFileAllocOptions(filename, ctx.arena, .limited(max_file_size), null, .@"1", 0); | |
| 382 | 382 | |
| 383 | 383 | // Parse the manifest |
| 384 | 384 | var manifest = try TestManifest.parse(ctx.arena, src); |
test/standalone/run_output_caching/build.zig+2-2| ... | ... | @@ -75,7 +75,7 @@ const CheckOutputCaching = struct { |
| 75 | 75 | pub fn init(owner: *std.Build, expect_caching: bool, output_paths: []const std.Build.LazyPath) *CheckOutputCaching { |
| 76 | 76 | const check = owner.allocator.create(CheckOutputCaching) catch @panic("OOM"); |
| 77 | 77 | check.* = .{ |
| 78 | .step = std.Build.Step.init(.{ | |
| 78 | .step = .init(.{ | |
| 79 | 79 | .id = .custom, |
| 80 | 80 | .name = "check output caching", |
| 81 | 81 | .owner = owner, |
| ... | ... | @@ -112,7 +112,7 @@ const CheckPathEquality = struct { |
| 112 | 112 | pub fn init(owner: *std.Build, expected_equality: bool, output_paths: []const std.Build.LazyPath) *CheckPathEquality { |
| 113 | 113 | const check = owner.allocator.create(CheckPathEquality) catch @panic("OOM"); |
| 114 | 114 | check.* = .{ |
| 115 | .step = std.Build.Step.init(.{ | |
| 115 | .step = .init(.{ | |
| 116 | 116 | .id = .custom, |
| 117 | 117 | .name = "check output path equality", |
| 118 | 118 | .owner = owner, |
test/tests.zig+1-1| ... | ... | @@ -2711,7 +2711,7 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step) !void { |
| 2711 | 2711 | |
| 2712 | 2712 | run.addArg(b.graph.zig_exe); |
| 2713 | 2713 | run.addFileArg(b.path("test/incremental/").path(b, entry.path)); |
| 2714 | run.addArgs(&.{ "--zig-lib-dir", b.fmt("{}", .{b.graph.zig_lib_directory}) }); | |
| 2714 | run.addArgs(&.{ "--zig-lib-dir", b.fmt("{f}", .{b.graph.zig_lib_directory}) }); | |
| 2715 | 2715 | |
| 2716 | 2716 | run.addCheck(.{ .expect_term = .{ .Exited = 0 } }); |
| 2717 | 2717 |