authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-13 22:58:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-16 13:12:47-07:00
loga014c1a2876acf93a11cf4c1fdd255939ee0c6e0
tree2083018a6fda68add91a5faab9deaf9f1b9ffba0
parent79a7b7c0f033787215471beb9eab99264c1b7003

std.Build.Cache.DepTokenizer: slightly modernize


8 files changed, 380 insertions(+), 344 deletions(-)

lib/compiler/Maker/Step/Run.zig+26-10
...@@ -292,16 +292,32 @@ pub fn make(...@@ -292,16 +292,32 @@ pub fn make(
292 switch (arg.flags.tag) {292 switch (arg.flags.tag) {
293 .output_file => if (arg.flags.dep_file) {293 .output_file => if (arg.flags.dep_file) {
294 const generated_path = maker.generatedPath(arg.generated.value.?).*;294 const generated_path = maker.generatedPath(arg.generated.value.?).*;
295 const result = if (has_side_effects)295 if (has_side_effects) {
296 man.addDepFile(generated_path.root_dir.handle, generated_path.sub_path)296 var diagnostic: Cache.DepTokenizer.Token = undefined;
297 else297 man.addInputDepFile(generated_path, &diagnostic) catch |err| switch (err) {
298 man.addDepFilePost(generated_path.root_dir.handle, generated_path.sub_path);298 error.OutOfMemory, error.Canceled => |e| return e,
299 result catch |err| switch (err) {299 error.InvalidDepFile => return step.fail(maker, "failed adding dep file {f} to cache: {f}", .{
300 error.OutOfMemory, error.Canceled => |e| return e,300 generated_path, diagnostic,
301 else => |e| return step.fail(maker, "failed adding to cache the file {f}: {t}", .{301 }),
302 generated_path, e,302 else => |e| return step.fail(maker, "failed adding dep file {f} to cache: {t}", .{
303 }),303 generated_path, e,
304 };304 }),
305 };
306 } else {
307 var diagnostic: Cache.Manifest.AddDiscoveredDepFileDiagnostic = undefined;
308 man.addDiscoveredDepFile(generated_path, &diagnostic) catch |err| switch (err) {
309 error.OutOfMemory, error.Canceled => |e| return e,
310 error.InvalidDepFile => return step.fail(maker, "failed adding dep file {f} to cache: {f}", .{
311 generated_path, diagnostic.dep_tokenizer,
312 }),
313 error.FileSystemFailure => return step.fail(maker, "failed adding a path from dep file {f} to cache: {f}", .{
314 generated_path, diagnostic.add_discovered_path,
315 }),
316 else => |e| return step.fail(maker, "failed adding dep file {f} to cache: {t}", .{
317 generated_path, e,
318 }),
319 };
320 }
305 },321 },
306 .output_directory => continue,322 .output_directory => continue,
307 else => unreachable,323 else => unreachable,
lib/std/Build/Cache.zig+112-47
...@@ -759,6 +759,52 @@ pub const Manifest = struct {...@@ -759,6 +759,52 @@ pub const Manifest = struct {
759 _ = try addInputPath(m, opt_path orelse return, options);759 _ = try addInputPath(m, opt_path orelse return, options);
760 }760 }
761761
762 pub const AddInputDepFileError = error{
763 InvalidDepFile,
764 } || Allocator.Error || Io.File.OpenError || Io.File.Reader.Error;
765
766 pub fn addInputDepFile(m: *Manifest, path: Path, diagnostic: ?*DepTokenizer.Token) AddInputDepFileError!void {
767 assert(m.manifest_file == null);
768 assert(m.state == .input);
769
770 const cache = m.cache;
771 const gpa = cache.gpa;
772 const io = cache.io;
773
774 // TODO: change DepTokenizer to be streaming rather than operating on slice of bytes.
775 const prev_len = m.all_input_content.items.len;
776 defer m.all_input_content.items.len = prev_len;
777
778 const file = try path.root_dir.handle.openFile(io, path.sub_path, .{});
779 defer file.close(io);
780
781 var file_reader: Io.File.Reader = .init(file, io, &.{});
782 file_reader.interface.appendRemainingUnlimited(gpa, &m.all_input_content) catch |err| switch (err) {
783 error.OutOfMemory => |e| return e,
784 error.ReadFailed => return file_reader.err.?,
785 };
786
787 var aux: std.ArrayList(u8) = .empty;
788 defer aux.deinit(gpa);
789
790 var it: DepTokenizer = .{ .bytes = m.all_input_content.items[prev_len..] };
791 while (it.next()) |token| switch (token) {
792 .target, .target_must_resolve => {},
793 .prereq => |file_path| {
794 _ = try m.addInputPath(.initCwd(file_path), .{});
795 },
796 .prereq_must_resolve => {
797 aux.clearRetainingCapacity();
798 try token.resolve(gpa, &aux);
799 _ = try m.addInputPath(.initCwd(aux.items), .{});
800 },
801 else => |err| {
802 if (diagnostic) |d| d.* = err;
803 return error.InvalidDepFile;
804 },
805 };
806 }
807
762 pub const CheckResult = union(enum) {808 pub const CheckResult = union(enum) {
763 hit,809 hit,
764 incomplete_manifest,810 incomplete_manifest,
...@@ -1614,6 +1660,13 @@ pub const Manifest = struct {...@@ -1614,6 +1660,13 @@ pub const Manifest = struct {
1614 stat_dir: Io.Dir.StatError,1660 stat_dir: Io.Dir.StatError,
1615 read_file: Io.File.ReadPositionalError,1661 read_file: Io.File.ReadPositionalError,
1616 read_dir: Io.Dir.Reader.Error,1662 read_dir: Io.Dir.Reader.Error,
1663
1664 pub fn format(this: @This(), w: *Io.Writer) Io.Writer.Error!void {
1665 switch (this) {
1666 .none => return w.writeAll("none"),
1667 else => |err, tag| return w.print("{t}: {t}", .{ tag, err }),
1668 }
1669 }
1617 };1670 };
16181671
1619 pub const AddDiscoveredPathError = error{1672 pub const AddDiscoveredPathError = error{
...@@ -1726,6 +1779,59 @@ pub const Manifest = struct {...@@ -1726,6 +1779,59 @@ pub const Manifest = struct {
1726 }1779 }
1727 }1780 }
17281781
1782 pub const AddDiscoveredDepFileError = error{
1783 InvalidDepFile,
1784 } || AddDiscoveredPathError || Io.File.OpenError || Io.File.Reader.Error;
1785
1786 pub const AddDiscoveredDepFileDiagnostic = union(enum) {
1787 add_discovered_path: AddDiscoveredPathDiagnostic,
1788 dep_tokenizer: DepTokenizer.Token,
1789 };
1790
1791 pub fn addDiscoveredDepFile(
1792 m: *Manifest,
1793 path: Path,
1794 diagnostic: ?*AddDiscoveredDepFileDiagnostic,
1795 ) AddDiscoveredDepFileError!void {
1796 assert(m.manifest_file != null);
1797 transitionToMissDiscovered(m);
1798
1799 const cache = m.cache;
1800 const gpa = cache.gpa;
1801 const io = cache.io;
1802
1803 // TODO: change DepTokenizer to be streaming rather than operating on slice of bytes.
1804 const prev_len = m.all_input_content.items.len;
1805 defer m.all_input_content.items.len = prev_len;
1806
1807 const file = try path.root_dir.handle.openFile(io, path.sub_path, .{});
1808 defer file.close(io);
1809
1810 var file_reader: Io.File.Reader = .init(file, io, &.{});
1811 file_reader.interface.appendRemainingUnlimited(gpa, &m.all_input_content) catch |err| switch (err) {
1812 error.OutOfMemory => |e| return e,
1813 error.ReadFailed => return file_reader.err.?,
1814 };
1815
1816 var aux: std.ArrayList(u8) = .empty;
1817 defer aux.deinit(gpa);
1818
1819 var it: DepTokenizer = .{ .bytes = m.all_input_content.items[prev_len..] };
1820 while (it.next()) |token| switch (token) {
1821 .target, .target_must_resolve => {},
1822 .prereq => |p| try m.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(p) } }),
1823 .prereq_must_resolve => {
1824 aux.clearRetainingCapacity();
1825 try token.resolve(gpa, &aux);
1826 try m.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(aux.items) } });
1827 },
1828 else => |err| {
1829 if (diagnostic) |d| d.* = .{ .dep_tokenizer = err };
1830 return error.InvalidDepFile;
1831 },
1832 };
1833 }
1834
1729 fn populateFile(1835 fn populateFile(
1730 m: *Manifest,1836 m: *Manifest,
1731 file: *File,1837 file: *File,
...@@ -1810,53 +1916,6 @@ pub const Manifest = struct {...@@ -1810,53 +1916,6 @@ pub const Manifest = struct {
1810 }1916 }
1811 }1917 }
18121918
1813 pub fn addDepFile(self: *Manifest, dir: Io.Dir, dep_file_sub_path: []const u8) !void {
1814 assert(self.manifest_file == null);
1815 return self.addDepFileMaybePost(dir, dep_file_sub_path);
1816 }
1817
1818 pub fn addDepFilePost(self: *Manifest, dir: Io.Dir, dep_file_sub_path: []const u8) !void {
1819 assert(self.manifest_file != null);
1820 return self.addDepFileMaybePost(dir, dep_file_sub_path);
1821 }
1822
1823 fn addDepFileMaybePost(self: *Manifest, dir: Io.Dir, dep_file_sub_path: []const u8) !void {
1824 const gpa = self.cache.gpa;
1825 const io = self.cache.io;
1826 const dep_file_contents = try dir.readFileAlloc(io, dep_file_sub_path, gpa, .unlimited);
1827 defer gpa.free(dep_file_contents);
1828
1829 var error_buf: std.ArrayList(u8) = .empty;
1830 defer error_buf.deinit(gpa);
1831
1832 var resolve_buf: std.ArrayList(u8) = .empty;
1833 defer resolve_buf.deinit(gpa);
1834
1835 var it: DepTokenizer = .{ .bytes = dep_file_contents };
1836 while (it.next()) |token| switch (token) {
1837 // We don't care about targets, we only want the prereqs
1838 // Clang is invoked in single-source mode but other programs may not
1839 .target, .target_must_resolve => {},
1840 .prereq => |file_path| if (self.manifest_file == null) {
1841 _ = try self.addInputPath(.initCwd(file_path), .{});
1842 } else try self.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(file_path) } }),
1843 .prereq_must_resolve => {
1844 resolve_buf.clearRetainingCapacity();
1845 try token.resolve(gpa, &resolve_buf);
1846 if (self.manifest_file == null) {
1847 _ = try self.addInputPath(.initCwd(resolve_buf.items), .{});
1848 } else try self.addDiscoveredPath(.{
1849 .discovered_path = .{ .unresolved = .initCwd(resolve_buf.items) },
1850 });
1851 },
1852 else => |err| {
1853 try err.printError(gpa, &error_buf);
1854 log.err("failed parsing {s}: {s}", .{ dep_file_sub_path, error_buf.items });
1855 return error.InvalidDepFile;
1856 },
1857 };
1858 }
1859
1860 /// See also `hitDigestHex`.1919 /// See also `hitDigestHex`.
1861 pub fn hitDigest(m: *Manifest) BinDigest {1920 pub fn hitDigest(m: *Manifest) BinDigest {
1862 assert(m.manifest_file != null);1921 assert(m.manifest_file != null);
...@@ -2533,3 +2592,9 @@ test "Manifest with files added after initial hash" {...@@ -2533,3 +2592,9 @@ test "Manifest with files added after initial hash" {
2533 try testing.expect(!mem.eql(u8, &digest1, &digest3));2592 try testing.expect(!mem.eql(u8, &digest1, &digest3));
2534 }2593 }
2535}2594}
2595
2596test {
2597 _ = Path;
2598 _ = Directory;
2599 _ = DepTokenizer;
2600}
lib/std/Build/Cache/DepTokenizer.zig+188-250
...@@ -1,14 +1,15 @@...@@ -1,14 +1,15 @@
1const Tokenizer = @This();1const Tokenizer = @This();
22
3index: usize = 0,
4bytes: []const u8,
5state: State = .lhs,
6
7const std = @import("std");3const std = @import("std");
4const Io = std.Io;
8const testing = std.testing;5const testing = std.testing;
9const assert = std.debug.assert;6const assert = std.debug.assert;
10const Allocator = std.mem.Allocator;7const Allocator = std.mem.Allocator;
118
9index: usize = 0,
10bytes: []const u8,
11state: State = .lhs,
12
12pub fn next(self: *Tokenizer) ?Token {13pub fn next(self: *Tokenizer) ?Token {
13 var start = self.index;14 var start = self.index;
14 var must_resolve = false;15 var must_resolve = false;
...@@ -16,10 +17,7 @@ pub fn next(self: *Tokenizer) ?Token {...@@ -16,10 +17,7 @@ pub fn next(self: *Tokenizer) ?Token {
16 const char = self.bytes[self.index];17 const char = self.bytes[self.index];
17 switch (self.state) {18 switch (self.state) {
18 .lhs => switch (char) {19 .lhs => switch (char) {
19 '\t', '\n', '\r', ' ' => {20 '\t', '\n', '\r', ' ' => self.index += 1, // Ignore whitespace.
20 // silently ignore whitespace
21 self.index += 1;
22 },
23 else => {21 else => {
24 start = self.index;22 start = self.index;
25 self.state = .target;23 self.state = .target;
...@@ -79,7 +77,7 @@ pub fn next(self: *Tokenizer) ?Token {...@@ -79,7 +77,7 @@ pub fn next(self: *Tokenizer) ?Token {
79 self.index += 1;77 self.index += 1;
80 },78 },
81 else => {79 else => {
82 return errorIllegalChar(.expected_dollar_sign, self.index, char);80 return errorIllegalChar(.expected_dollar, self.index, char);
83 },81 },
84 },82 },
85 .target_colon => switch (char) {83 .target_colon => switch (char) {
...@@ -347,7 +345,7 @@ pub const Token = union(enum) {...@@ -347,7 +345,7 @@ pub const Token = union(enum) {
347345
348 invalid_target: IndexAndChar,346 invalid_target: IndexAndChar,
349 bad_target_escape: IndexAndChar,347 bad_target_escape: IndexAndChar,
350 expected_dollar_sign: IndexAndChar,348 expected_dollar: IndexAndChar,
351 continuation_eol: IndexAndChar,349 continuation_eol: IndexAndChar,
352 incomplete_escape: IndexAndChar,350 incomplete_escape: IndexAndChar,
353 expected_colon: IndexAndChar,351 expected_colon: IndexAndChar,
...@@ -429,48 +427,23 @@ pub const Token = union(enum) {...@@ -429,48 +427,23 @@ pub const Token = union(enum) {
429 }427 }
430 }428 }
431429
432 pub fn printError(self: Token, gpa: Allocator, list: *std.ArrayList(u8)) error{OutOfMemory}!void {430 pub fn format(token: Token, w: *Io.Writer) Io.Writer.Error!void {
433 switch (self) {431 switch (token) {
434 .target, .target_must_resolve, .prereq, .prereq_must_resolve => unreachable, // not an error432 .target, .target_must_resolve, .prereq, .prereq_must_resolve => return w.writeAll(@tagName(token)),
435 .incomplete_quoted_prerequisite,433 .incomplete_quoted_prerequisite, .incomplete_target => |info| return w.print("{t} {q} at position {d}", .{
436 .incomplete_target,434 token, info.bytes, info.index,
437 => |index_and_bytes| {435 }),
438 try list.print(gpa, "{s} '", .{self.errStr()});
439 if (self == .incomplete_target) {
440 const tmp = Token{ .target_must_resolve = index_and_bytes.bytes };
441 try tmp.resolve(gpa, list);
442 } else {
443 try printCharValues(gpa, list, index_and_bytes.bytes);
444 }
445 try list.print(gpa, "' at position {d}", .{index_and_bytes.index});
446 },
447 .invalid_target,436 .invalid_target,
448 .bad_target_escape,437 .bad_target_escape,
449 .expected_dollar_sign,438 .expected_dollar,
450 .continuation_eol,439 .continuation_eol,
451 .incomplete_escape,440 .incomplete_escape,
452 .expected_colon,441 .expected_colon,
453 => |index_and_char| {442 => |info| return w.print("illegal char '{f}' at position {d}: {t}", .{
454 try list.appendSlice(gpa, "illegal char ");443 std.zig.fmtChar(info.char), info.index, token,
455 try printUnderstandableChar(gpa, list, index_and_char.char);444 }),
456 try list.print(gpa, " at position {d}: {s}", .{ index_and_char.index, self.errStr() });
457 },
458 }445 }
459 }446 }
460
461 fn errStr(self: Token) []const u8 {
462 return switch (self) {
463 .target, .target_must_resolve, .prereq, .prereq_must_resolve => unreachable, // not an error
464 .incomplete_quoted_prerequisite => "incomplete quoted prerequisite",
465 .incomplete_target => "incomplete target",
466 .invalid_target => "invalid target",
467 .bad_target_escape => "bad target escape",
468 .expected_dollar_sign => "expecting '$'",
469 .continuation_eol => "continuation expecting end-of-line",
470 .incomplete_escape => "incomplete escape",
471 .expected_colon => "expecting ':'",
472 };
473 }
474};447};
475448
476test "empty file" {449test "empty file" {
...@@ -493,37 +466,37 @@ test "empty colon" {...@@ -493,37 +466,37 @@ test "empty colon" {
493}466}
494467
495test "empty target" {468test "empty target" {
496 try depTokenizer("foo.o:", "target = {foo.o}");469 try depTokenizer("foo.o:", "target = {\"foo.o\"}");
497 try depTokenizer(470 try depTokenizer(
498 \\foo.o:471 \\foo.o:
499 \\bar.o:472 \\bar.o:
500 \\abcd.o:473 \\abcd.o:
501 ,474 ,
502 \\target = {foo.o}475 \\target = {"foo.o"}
503 \\target = {bar.o}476 \\target = {"bar.o"}
504 \\target = {abcd.o}477 \\target = {"abcd.o"}
505 );478 );
506}479}
507480
508test "whitespace empty target" {481test "whitespace empty target" {
509 try depTokenizer("\nfoo.o:", "target = {foo.o}");482 try depTokenizer("\nfoo.o:", "target = {\"foo.o\"}");
510 try depTokenizer("\rfoo.o:", "target = {foo.o}");483 try depTokenizer("\rfoo.o:", "target = {\"foo.o\"}");
511 try depTokenizer("\r\nfoo.o:", "target = {foo.o}");484 try depTokenizer("\r\nfoo.o:", "target = {\"foo.o\"}");
512 try depTokenizer(" foo.o:", "target = {foo.o}");485 try depTokenizer(" foo.o:", "target = {\"foo.o\"}");
513}486}
514487
515test "escape empty target" {488test "escape empty target" {
516 try depTokenizer("\\ foo.o:", "target = { foo.o}");489 try depTokenizer("\\ foo.o:", "target = {\" foo.o\"}");
517 try depTokenizer("\\#foo.o:", "target = {#foo.o}");490 try depTokenizer("\\#foo.o:", "target = {\"#foo.o\"}");
518 try depTokenizer("\\\\foo.o:", "target = {\\foo.o}");491 try depTokenizer("\\\\foo.o:", "target = {\"\\\\foo.o\"}");
519 try depTokenizer("$$foo.o:", "target = {$foo.o}");492 try depTokenizer("$$foo.o:", "target = {\"$foo.o\"}");
520}493}
521494
522test "empty target linefeeds" {495test "empty target linefeeds" {
523 try depTokenizer("\n", "");496 try depTokenizer("\n", "");
524 try depTokenizer("\r\n", "");497 try depTokenizer("\r\n", "");
525498
526 const expect = "target = {foo.o}";499 const expect = "target = {\"foo.o\"}";
527 try depTokenizer(500 try depTokenizer(
528 \\foo.o:501 \\foo.o:
529 , expect);502 , expect);
...@@ -541,7 +514,7 @@ test "empty target linefeeds" {...@@ -541,7 +514,7 @@ test "empty target linefeeds" {
541}514}
542515
543test "empty target linefeeds + continuations" {516test "empty target linefeeds + continuations" {
544 const expect = "target = {foo.o}";517 const expect = "target = {\"foo.o\"}";
545 try depTokenizer(518 try depTokenizer(
546 \\foo.o:\519 \\foo.o:\
547 , expect);520 , expect);
...@@ -559,7 +532,7 @@ test "empty target linefeeds + continuations" {...@@ -559,7 +532,7 @@ test "empty target linefeeds + continuations" {
559}532}
560533
561test "empty target linefeeds + hspace + continuations" {534test "empty target linefeeds + hspace + continuations" {
562 const expect = "target = {foo.o}";535 const expect = "target = {\"foo.o\"}";
563 try depTokenizer(536 try depTokenizer(
564 \\foo.o: \537 \\foo.o: \
565 , expect);538 , expect);
...@@ -577,7 +550,7 @@ test "empty target linefeeds + hspace + continuations" {...@@ -577,7 +550,7 @@ test "empty target linefeeds + hspace + continuations" {
577}550}
578551
579test "empty target + hspace + colon" {552test "empty target + hspace + colon" {
580 const expect = "target = {foo.o}";553 const expect = "target = {\"foo.o\"}";
581554
582 try depTokenizer("foo.o :", expect);555 try depTokenizer("foo.o :", expect);
583 try depTokenizer("foo.o\t\t\t:", expect);556 try depTokenizer("foo.o\t\t\t:", expect);
...@@ -588,8 +561,8 @@ test "empty target + hspace + colon" {...@@ -588,8 +561,8 @@ test "empty target + hspace + colon" {
588561
589test "prereq" {562test "prereq" {
590 const expect =563 const expect =
591 \\target = {foo.o}564 \\target = {"foo.o"}
592 \\prereq = {foo.c}565 \\prereq = {"foo.c"}
593 ;566 ;
594 try depTokenizer("foo.o: foo.c", expect);567 try depTokenizer("foo.o: foo.c", expect);
595 try depTokenizer(568 try depTokenizer(
...@@ -608,9 +581,9 @@ test "prereq" {...@@ -608,9 +581,9 @@ test "prereq" {
608581
609test "prereq continuation" {582test "prereq continuation" {
610 const expect =583 const expect =
611 \\target = {foo.o}584 \\target = {"foo.o"}
612 \\prereq = {foo.h}585 \\prereq = {"foo.h"}
613 \\prereq = {bar.h}586 \\prereq = {"bar.h"}
614 ;587 ;
615 try depTokenizer(588 try depTokenizer(
616 \\foo.o: foo.h\589 \\foo.o: foo.h\
...@@ -624,19 +597,19 @@ test "prereq continuation" {...@@ -624,19 +597,19 @@ test "prereq continuation" {
624597
625test "prereq continuation (CRLF)" {598test "prereq continuation (CRLF)" {
626 const expect =599 const expect =
627 \\target = {foo.o}600 \\target = {"foo.o"}
628 \\prereq = {foo.h}601 \\prereq = {"foo.h"}
629 \\prereq = {bar.h}602 \\prereq = {"bar.h"}
630 ;603 ;
631 try depTokenizer("foo.o: foo.h\\\r\nbar.h", expect);604 try depTokenizer("foo.o: foo.h\\\r\nbar.h", expect);
632}605}
633606
634test "multiple prereqs" {607test "multiple prereqs" {
635 const expect =608 const expect =
636 \\target = {foo.o}609 \\target = {"foo.o"}
637 \\prereq = {foo.c}610 \\prereq = {"foo.c"}
638 \\prereq = {foo.h}611 \\prereq = {"foo.h"}
639 \\prereq = {bar.h}612 \\prereq = {"bar.h"}
640 ;613 ;
641 try depTokenizer("foo.o: foo.c foo.h bar.h", expect);614 try depTokenizer("foo.o: foo.c foo.h bar.h", expect);
642 try depTokenizer(615 try depTokenizer(
...@@ -680,19 +653,19 @@ test "multiple targets and prereqs" {...@@ -680,19 +653,19 @@ test "multiple targets and prereqs" {
680 \\ one.h two.h \653 \\ one.h two.h \
681 \\ three.h four.h654 \\ three.h four.h
682 ,655 ,
683 \\target = {foo.o}656 \\target = {"foo.o"}
684 \\prereq = {foo.c}657 \\prereq = {"foo.c"}
685 \\target = {bar.o}658 \\target = {"bar.o"}
686 \\prereq = {bar.c}659 \\prereq = {"bar.c"}
687 \\prereq = {a.h}660 \\prereq = {"a.h"}
688 \\prereq = {b.h}661 \\prereq = {"b.h"}
689 \\prereq = {c.h}662 \\prereq = {"c.h"}
690 \\target = {abc.o}663 \\target = {"abc.o"}
691 \\prereq = {abc.c}664 \\prereq = {"abc.c"}
692 \\prereq = {one.h}665 \\prereq = {"one.h"}
693 \\prereq = {two.h}666 \\prereq = {"two.h"}
694 \\prereq = {three.h}667 \\prereq = {"three.h"}
695 \\prereq = {four.h}668 \\prereq = {"four.h"}
696 );669 );
697 try depTokenizer(670 try depTokenizer(
698 \\ascii.o: ascii.c671 \\ascii.o: ascii.c
...@@ -702,21 +675,21 @@ test "multiple targets and prereqs" {...@@ -702,21 +675,21 @@ test "multiple targets and prereqs" {
702 \\ macho.c\675 \\ macho.c\
703 \\ a.h b.h c.h676 \\ a.h b.h c.h
704 ,677 ,
705 \\target = {ascii.o}678 \\target = {"ascii.o"}
706 \\prereq = {ascii.c}679 \\prereq = {"ascii.c"}
707 \\target = {base64.o}680 \\target = {"base64.o"}
708 \\prereq = {base64.c}681 \\prereq = {"base64.c"}
709 \\prereq = {stdio.h}682 \\prereq = {"stdio.h"}
710 \\target = {elf.o}683 \\target = {"elf.o"}
711 \\prereq = {elf.c}684 \\prereq = {"elf.c"}
712 \\prereq = {a.h}685 \\prereq = {"a.h"}
713 \\prereq = {b.h}686 \\prereq = {"b.h"}
714 \\prereq = {c.h}687 \\prereq = {"c.h"}
715 \\target = {macho.o}688 \\target = {"macho.o"}
716 \\prereq = {macho.c}689 \\prereq = {"macho.c"}
717 \\prereq = {a.h}690 \\prereq = {"a.h"}
718 \\prereq = {b.h}691 \\prereq = {"b.h"}
719 \\prereq = {c.h}692 \\prereq = {"c.h"}
720 );693 );
721 try depTokenizer(694 try depTokenizer(
722 \\a$$scii.o: ascii.c695 \\a$$scii.o: ascii.c
...@@ -726,20 +699,20 @@ test "multiple targets and prereqs" {...@@ -726,20 +699,20 @@ test "multiple targets and prereqs" {
726 \\ "macho!.c" \699 \\ "macho!.c" \
727 \\ a.h b.h c.h700 \\ a.h b.h c.h
728 ,701 ,
729 \\target = {a$scii.o}702 \\target = {"a$scii.o"}
730 \\prereq = {ascii.c}703 \\prereq = {"ascii.c"}
731 \\target = {\base64.o}704 \\target = {"\\base64.o"}
732 \\prereq = {\base64.c}705 \\prereq = {"\\base64.c"}
733 \\prereq = {s t#dio.h}706 \\prereq = {"s t#dio.h"}
734 \\target = {e\lf.o}707 \\target = {"e\\lf.o"}
735 \\prereq = {e\lf.c}708 \\prereq = {"e\\lf.c"}
736 \\prereq = {a.h$$}709 \\prereq = {"a.h$$"}
737 \\prereq = {$$b.h c.h$$}710 \\prereq = {"$$b.h c.h$$"}
738 \\target = {macho.o}711 \\target = {"macho.o"}
739 \\prereq = {macho!.c}712 \\prereq = {"macho!.c"}
740 \\prereq = {a.h}713 \\prereq = {"a.h"}
741 \\prereq = {b.h}714 \\prereq = {"b.h"}
742 \\prereq = {c.h}715 \\prereq = {"c.h"}
743 );716 );
744}717}
745718
...@@ -750,12 +723,12 @@ test "windows quoted prereqs" {...@@ -750,12 +723,12 @@ test "windows quoted prereqs" {
750 \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo1.h" \723 \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo1.h" \
751 \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo2.h"724 \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo2.h"
752 ,725 ,
753 \\target = {c:\foo.o}726 \\target = {"c:\\foo.o"}
754 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo.c}727 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\foo.c"}
755 \\target = {c:\foo2.o}728 \\target = {"c:\\foo2.o"}
756 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo2.c}729 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\foo2.c"}
757 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo1.h}730 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\foo1.h"}
758 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo2.h}731 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\foo2.h"}
759 );732 );
760}733}
761734
...@@ -779,23 +752,23 @@ test "windows mixed prereqs" {...@@ -779,23 +752,23 @@ test "windows mixed prereqs" {
779 \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h" \752 \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h" \
780 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h"753 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h"
781 ,754 ,
782 \\target = {cimport.o}755 \\target = {"cimport.o"}
783 \\prereq = {C:\msys64\home\anon\project\zig\master\zig-cache\o\qhvhbUo7GU5iKyQ5mpA8TcQpncCYaQu0wwvr3ybiSTj_Dtqi1Nmcb70kfODJ2Qlg\cimport.h}756 \\prereq = {"C:\\msys64\\home\\anon\\project\\zig\\master\\zig-cache\\o\\qhvhbUo7GU5iKyQ5mpA8TcQpncCYaQu0wwvr3ybiSTj_Dtqi1Nmcb70kfODJ2Qlg\\cimport.h"}
784 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\stdio.h}757 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\stdio.h"}
785 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt.h}758 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt.h"}
786 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime.h}759 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\vcruntime.h"}
787 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\sal.h}760 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\sal.h"}
788 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\concurrencysal.h}761 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\concurrencysal.h"}
789 \\prereq = {C:\msys64\opt\zig\lib\zig\include\vadefs.h}762 \\prereq = {"C:\\msys64\\opt\\zig\\lib\\zig\\include\\vadefs.h"}
790 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vadefs.h}763 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\vadefs.h"}
791 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstdio.h}764 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_wstdio.h"}
792 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_stdio_config.h}765 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_stdio_config.h"}
793 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\string.h}766 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\string.h"}
794 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memory.h}767 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_memory.h"}
795 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memcpy_s.h}768 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_memcpy_s.h"}
796 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\errno.h}769 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\errno.h"}
797 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h}770 \\prereq = {"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.21.27702\\lib\\x64\\\\..\\..\\include\\vcruntime_string.h"}
798 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h}771 \\prereq = {"C:\\Program Files (x86)\\Windows Kits\\10\\\\Include\\10.0.17763.0\\ucrt\\corecrt_wstring.h"}
799 );772 );
800}773}
801774
...@@ -810,14 +783,14 @@ test "windows funky targets" {...@@ -810,14 +783,14 @@ test "windows funky targets" {
810 \\C:\Users\anon\$$foo.o:783 \\C:\Users\anon\$$foo.o:
811 \\C:\Users\anon\\\ \ \ \ \ foo.o:784 \\C:\Users\anon\\\ \ \ \ \ foo.o:
812 ,785 ,
813 \\target = {C:\Users\anon\foo.o}786 \\target = {"C:\\Users\\anon\\foo.o"}
814 \\target = {C:\Users\anon\foo .o}787 \\target = {"C:\\Users\\anon\\foo .o"}
815 \\target = {C:\Users\anon\foo#.o}788 \\target = {"C:\\Users\\anon\\foo#.o"}
816 \\target = {C:\Users\anon\foo$.o}789 \\target = {"C:\\Users\\anon\\foo$.o"}
817 \\target = {C:\Users\anon\ foo.o}790 \\target = {"C:\\Users\\anon\\ foo.o"}
818 \\target = {C:\Users\anon\#foo.o}791 \\target = {"C:\\Users\\anon\\#foo.o"}
819 \\target = {C:\Users\anon\$foo.o}792 \\target = {"C:\\Users\\anon\\$foo.o"}
820 \\target = {C:\Users\anon\ foo.o}793 \\target = {"C:\\Users\\anon\\ foo.o"}
821 );794 );
822}795}
823796
...@@ -837,13 +810,13 @@ test "windows funky prereqs" {...@@ -837,13 +810,13 @@ test "windows funky prereqs" {
837 \\ somedir\\ \\ \c.c\810 \\ somedir\\ \\ \c.c\
838 \\811 \\
839 ,812 ,
840 \\target = {cimport.o}813 \\target = {"cimport.o"}
841 \\prereq = {trailingbackslash\}814 \\prereq = {"trailingbackslash\\"}
842 \\prereq = {C:\Users\John Smith\AppData\Local\zig\p\1220d14057af1a9d6dde4643293527bd5ee5099517d655251a066666a4320737ea7c\cimport.c}815 \\prereq = {"C:\\Users\\John Smith\\AppData\\Local\\zig\\p\\1220d14057af1a9d6dde4643293527bd5ee5099517d655251a066666a4320737ea7c\\cimport.c"}
843 \\prereq = {somedir\ a.c}816 \\prereq = {"somedir\\ a.c"}
844 \\prereq = {somedir/ a.c}817 \\prereq = {"somedir/ a.c"}
845 \\prereq = {somedir\ b.c}818 \\prereq = {"somedir\\ b.c"}
846 \\prereq = {somedir\ \ \c.c}819 \\prereq = {"somedir\\ \\ \\c.c"}
847 );820 );
848}821}
849822
...@@ -852,171 +825,171 @@ test "windows drive and forward slashes" {...@@ -852,171 +825,171 @@ test "windows drive and forward slashes" {
852 \\C:/msys64/what/zig-cache\tmp\48ac4d78dd531abd-cxa_thread_atexit.obj: \825 \\C:/msys64/what/zig-cache\tmp\48ac4d78dd531abd-cxa_thread_atexit.obj: \
853 \\ C:/msys64/opt/zig3/lib/zig/libc/mingw/crt/cxa_thread_atexit.c826 \\ C:/msys64/opt/zig3/lib/zig/libc/mingw/crt/cxa_thread_atexit.c
854 ,827 ,
855 \\target = {C:/msys64/what/zig-cache\tmp\48ac4d78dd531abd-cxa_thread_atexit.obj}828 \\target = {"C:/msys64/what/zig-cache\\tmp\\48ac4d78dd531abd-cxa_thread_atexit.obj"}
856 \\prereq = {C:/msys64/opt/zig3/lib/zig/libc/mingw/crt/cxa_thread_atexit.c}829 \\prereq = {"C:/msys64/opt/zig3/lib/zig/libc/mingw/crt/cxa_thread_atexit.c"}
857 );830 );
858}831}
859832
860test "error incomplete escape - reverse_solidus" {833test "error incomplete escape - reverse_solidus" {
861 try depTokenizer("\\",834 try depTokenizer("\\",
862 \\ERROR: illegal char '\' at position 0: incomplete escape835 \\ERROR: illegal char '\\' at position 0: incomplete_escape
863 );836 );
864 try depTokenizer("\t\\",837 try depTokenizer("\t\\",
865 \\ERROR: illegal char '\' at position 1: incomplete escape838 \\ERROR: illegal char '\\' at position 1: incomplete_escape
866 );839 );
867 try depTokenizer("\n\\",840 try depTokenizer("\n\\",
868 \\ERROR: illegal char '\' at position 1: incomplete escape841 \\ERROR: illegal char '\\' at position 1: incomplete_escape
869 );842 );
870 try depTokenizer("\r\\",843 try depTokenizer("\r\\",
871 \\ERROR: illegal char '\' at position 1: incomplete escape844 \\ERROR: illegal char '\\' at position 1: incomplete_escape
872 );845 );
873 try depTokenizer("\r\n\\",846 try depTokenizer("\r\n\\",
874 \\ERROR: illegal char '\' at position 2: incomplete escape847 \\ERROR: illegal char '\\' at position 2: incomplete_escape
875 );848 );
876 try depTokenizer(" \\",849 try depTokenizer(" \\",
877 \\ERROR: illegal char '\' at position 1: incomplete escape850 \\ERROR: illegal char '\\' at position 1: incomplete_escape
878 );851 );
879}852}
880853
881test "error incomplete escape - dollar_sign" {854test "error incomplete escape - dollar_sign" {
882 try depTokenizer("$",855 try depTokenizer("$",
883 \\ERROR: illegal char '$' at position 0: incomplete escape856 \\ERROR: illegal char '$' at position 0: incomplete_escape
884 );857 );
885 try depTokenizer("\t$",858 try depTokenizer("\t$",
886 \\ERROR: illegal char '$' at position 1: incomplete escape859 \\ERROR: illegal char '$' at position 1: incomplete_escape
887 );860 );
888 try depTokenizer("\n$",861 try depTokenizer("\n$",
889 \\ERROR: illegal char '$' at position 1: incomplete escape862 \\ERROR: illegal char '$' at position 1: incomplete_escape
890 );863 );
891 try depTokenizer("\r$",864 try depTokenizer("\r$",
892 \\ERROR: illegal char '$' at position 1: incomplete escape865 \\ERROR: illegal char '$' at position 1: incomplete_escape
893 );866 );
894 try depTokenizer("\r\n$",867 try depTokenizer("\r\n$",
895 \\ERROR: illegal char '$' at position 2: incomplete escape868 \\ERROR: illegal char '$' at position 2: incomplete_escape
896 );869 );
897 try depTokenizer(" $",870 try depTokenizer(" $",
898 \\ERROR: illegal char '$' at position 1: incomplete escape871 \\ERROR: illegal char '$' at position 1: incomplete_escape
899 );872 );
900}873}
901874
902test "error incomplete target" {875test "error incomplete target" {
903 try depTokenizer("foo.o",876 try depTokenizer("foo.o",
904 \\ERROR: incomplete target 'foo.o' at position 0877 \\ERROR: incomplete_target "foo.o" at position 0
905 );878 );
906 try depTokenizer("\tfoo.o",879 try depTokenizer("\tfoo.o",
907 \\ERROR: incomplete target 'foo.o' at position 1880 \\ERROR: incomplete_target "foo.o" at position 1
908 );881 );
909 try depTokenizer("\nfoo.o",882 try depTokenizer("\nfoo.o",
910 \\ERROR: incomplete target 'foo.o' at position 1883 \\ERROR: incomplete_target "foo.o" at position 1
911 );884 );
912 try depTokenizer("\rfoo.o",885 try depTokenizer("\rfoo.o",
913 \\ERROR: incomplete target 'foo.o' at position 1886 \\ERROR: incomplete_target "foo.o" at position 1
914 );887 );
915 try depTokenizer("\r\nfoo.o",888 try depTokenizer("\r\nfoo.o",
916 \\ERROR: incomplete target 'foo.o' at position 2889 \\ERROR: incomplete_target "foo.o" at position 2
917 );890 );
918 try depTokenizer(" foo.o",891 try depTokenizer(" foo.o",
919 \\ERROR: incomplete target 'foo.o' at position 1892 \\ERROR: incomplete_target "foo.o" at position 1
920 );893 );
921894
922 try depTokenizer("\\ foo.o",895 try depTokenizer("\\ foo.o",
923 \\ERROR: incomplete target ' foo.o' at position 0896 \\ERROR: incomplete_target "\\ foo.o" at position 0
924 );897 );
925 try depTokenizer("\\#foo.o",898 try depTokenizer("\\#foo.o",
926 \\ERROR: incomplete target '#foo.o' at position 0899 \\ERROR: incomplete_target "\\#foo.o" at position 0
927 );900 );
928 try depTokenizer("\\\\foo.o",901 try depTokenizer("\\\\foo.o",
929 \\ERROR: incomplete target '\foo.o' at position 0902 \\ERROR: incomplete_target "\\\\foo.o" at position 0
930 );903 );
931 try depTokenizer("$$foo.o",904 try depTokenizer("$$foo.o",
932 \\ERROR: incomplete target '$foo.o' at position 0905 \\ERROR: incomplete_target "$$foo.o" at position 0
933 );906 );
934}907}
935908
936test "error illegal char at position - bad target escape" {909test "error illegal char at position - bad target escape" {
937 try depTokenizer("\\\t",910 try depTokenizer("\\\t",
938 \\ERROR: illegal char \x09 at position 1: bad target escape911 \\ERROR: illegal char '\t' at position 1: bad_target_escape
939 );912 );
940 try depTokenizer("\\\n",913 try depTokenizer("\\\n",
941 \\ERROR: illegal char \x0A at position 1: bad target escape914 \\ERROR: illegal char '\n' at position 1: bad_target_escape
942 );915 );
943 try depTokenizer("\\\r",916 try depTokenizer("\\\r",
944 \\ERROR: illegal char \x0D at position 1: bad target escape917 \\ERROR: illegal char '\r' at position 1: bad_target_escape
945 );918 );
946 try depTokenizer("\\\r\n",919 try depTokenizer("\\\r\n",
947 \\ERROR: illegal char \x0D at position 1: bad target escape920 \\ERROR: illegal char '\r' at position 1: bad_target_escape
948 );921 );
949}922}
950923
951test "error illegal char at position - expecting dollar_sign" {924test "error illegal char at position - expecting dollar_sign" {
952 try depTokenizer("$\t",925 try depTokenizer("$\t",
953 \\ERROR: illegal char \x09 at position 1: expecting '$'926 \\ERROR: illegal char '\t' at position 1: expected_dollar
954 );927 );
955 try depTokenizer("$\n",928 try depTokenizer("$\n",
956 \\ERROR: illegal char \x0A at position 1: expecting '$'929 \\ERROR: illegal char '\n' at position 1: expected_dollar
957 );930 );
958 try depTokenizer("$\r",931 try depTokenizer("$\r",
959 \\ERROR: illegal char \x0D at position 1: expecting '$'932 \\ERROR: illegal char '\r' at position 1: expected_dollar
960 );933 );
961 try depTokenizer("$\r\n",934 try depTokenizer("$\r\n",
962 \\ERROR: illegal char \x0D at position 1: expecting '$'935 \\ERROR: illegal char '\r' at position 1: expected_dollar
963 );936 );
964}937}
965938
966test "error illegal char at position - invalid target" {939test "error illegal char at position - invalid target" {
967 try depTokenizer("foo\n.o",940 try depTokenizer("foo\n.o",
968 \\ERROR: illegal char \x0A at position 3: invalid target941 \\ERROR: illegal char '\n' at position 3: invalid_target
969 );942 );
970 try depTokenizer("foo\r.o",943 try depTokenizer("foo\r.o",
971 \\ERROR: illegal char \x0D at position 3: invalid target944 \\ERROR: illegal char '\r' at position 3: invalid_target
972 );945 );
973 try depTokenizer("foo\r\n.o",946 try depTokenizer("foo\r\n.o",
974 \\ERROR: illegal char \x0D at position 3: invalid target947 \\ERROR: illegal char '\r' at position 3: invalid_target
975 );948 );
976}949}
977950
978test "error target - continuation expecting end-of-line" {951test "error target - continuation expecting end-of-line" {
979 try depTokenizer("foo.o: \\\t",952 try depTokenizer("foo.o: \\\t",
980 \\target = {foo.o}953 \\target = {"foo.o"}
981 \\ERROR: illegal char \x09 at position 8: continuation expecting end-of-line954 \\ERROR: illegal char '\t' at position 8: continuation_eol
982 );955 );
983 try depTokenizer("foo.o: \\ ",956 try depTokenizer("foo.o: \\ ",
984 \\target = {foo.o}957 \\target = {"foo.o"}
985 \\ERROR: illegal char ' ' at position 8: continuation expecting end-of-line958 \\ERROR: illegal char ' ' at position 8: continuation_eol
986 );959 );
987 try depTokenizer("foo.o: \\x",960 try depTokenizer("foo.o: \\x",
988 \\target = {foo.o}961 \\target = {"foo.o"}
989 \\ERROR: illegal char 'x' at position 8: continuation expecting end-of-line962 \\ERROR: illegal char 'x' at position 8: continuation_eol
990 );963 );
991 try depTokenizer("foo.o: \\\x0dx",964 try depTokenizer("foo.o: \\\x0dx",
992 \\target = {foo.o}965 \\target = {"foo.o"}
993 \\ERROR: illegal char 'x' at position 9: continuation expecting end-of-line966 \\ERROR: illegal char 'x' at position 9: continuation_eol
994 );967 );
995}968}
996969
997test "error prereq - continuation expecting end-of-line" {970test "error prereq - continuation expecting end-of-line" {
998 try depTokenizer("foo.o: foo.h\\\x0dx",971 try depTokenizer("foo.o: foo.h\\\x0dx",
999 \\target = {foo.o}972 \\target = {"foo.o"}
1000 \\ERROR: illegal char 'x' at position 14: continuation expecting end-of-line973 \\ERROR: illegal char 'x' at position 14: continuation_eol
1001 );974 );
1002}975}
1003976
1004test "error illegal char at position - expecting colon" {977test "error illegal char at position - expecting colon" {
1005 try depTokenizer("foo\t.o:",978 try depTokenizer("foo\t.o:",
1006 \\target = {foo}979 \\target = {"foo"}
1007 \\ERROR: illegal char '.' at position 4: expecting ':'980 \\ERROR: illegal char '.' at position 4: expected_colon
1008 );981 );
1009 try depTokenizer("foo .o:",982 try depTokenizer("foo .o:",
1010 \\target = {foo}983 \\target = {"foo"}
1011 \\ERROR: illegal char '.' at position 4: expecting ':'984 \\ERROR: illegal char '.' at position 4: expected_colon
1012 );985 );
1013 try depTokenizer("foo \n.o:",986 try depTokenizer("foo \n.o:",
1014 \\target = {foo}987 \\target = {"foo"}
1015 \\ERROR: illegal char \x0A at position 4: expecting ':'988 \\ERROR: illegal char '\n' at position 4: expected_colon
1016 );989 );
1017 try depTokenizer("foo.o\t\n:",990 try depTokenizer("foo.o\t\n:",
1018 \\target = {foo.o}991 \\target = {"foo.o"}
1019 \\ERROR: illegal char \x0A at position 6: expecting ':'992 \\ERROR: illegal char '\n' at position 6: expected_colon
1020 );993 );
1021}994}
1022995
...@@ -1028,70 +1001,35 @@ fn depTokenizer(input: []const u8, expect: []const u8) !void {...@@ -1028,70 +1001,35 @@ fn depTokenizer(input: []const u8, expect: []const u8) !void {
10281001
1029 var it: Tokenizer = .{ .bytes = input };1002 var it: Tokenizer = .{ .bytes = input };
1030 var buffer: std.ArrayList(u8) = .empty;1003 var buffer: std.ArrayList(u8) = .empty;
1031 var resolve_buf: std.ArrayList(u8) = .empty;1004 var aux: std.ArrayList(u8) = .empty;
1032 var i: usize = 0;1005 var i: usize = 0;
1033 while (it.next()) |token| {1006 while (it.next()) |token| {
1034 if (i != 0) try buffer.appendSlice(arena, "\n");1007 if (i != 0) try buffer.appendSlice(arena, "\n");
1035 switch (token) {1008 switch (token) {
1036 .target, .prereq => |bytes| {1009 .target, .prereq => |bytes| {
1037 try buffer.appendSlice(arena, @tagName(token));1010 try buffer.print(arena, "{t} = {{{q}}}", .{ token, bytes });
1038 try buffer.appendSlice(arena, " = {");
1039 for (bytes) |b| {
1040 try buffer.append(arena, printable_char_tab[b]);
1041 }
1042 try buffer.appendSlice(arena, "}");
1043 },1011 },
1044 .target_must_resolve => {1012 .target_must_resolve => {
1045 try buffer.appendSlice(arena, "target = {");1013 try buffer.appendSlice(arena, "target = {");
1046 try token.resolve(arena, &resolve_buf);1014 aux.clearRetainingCapacity();
1047 for (resolve_buf.items) |b| {1015 try token.resolve(arena, &aux);
1048 try buffer.append(arena, printable_char_tab[b]);1016 try buffer.print(arena, "{q}", .{aux.items});
1049 }
1050 resolve_buf.items.len = 0;
1051 try buffer.appendSlice(arena, "}");1017 try buffer.appendSlice(arena, "}");
1052 },1018 },
1053 .prereq_must_resolve => {1019 .prereq_must_resolve => {
1054 try buffer.appendSlice(arena, "prereq = {");1020 try buffer.appendSlice(arena, "prereq = {");
1055 try token.resolve(arena, &resolve_buf);1021 aux.clearRetainingCapacity();
1056 for (resolve_buf.items) |b| {1022 try token.resolve(arena, &aux);
1057 try buffer.append(arena, printable_char_tab[b]);1023 try buffer.print(arena, "{q}", .{aux.items});
1058 }
1059 resolve_buf.items.len = 0;
1060 try buffer.appendSlice(arena, "}");1024 try buffer.appendSlice(arena, "}");
1061 },1025 },
1062 else => {1026 else => {
1063 try buffer.appendSlice(arena, "ERROR: ");1027 try buffer.print(arena, "ERROR: {f}", .{token});
1064 try token.printError(arena, &buffer);
1065 break;1028 break;
1066 },1029 },
1067 }1030 }
1068 i += 1;1031 i += 1;
1069 }1032 }
10701033
1071 if (std.mem.eql(u8, expect, buffer.items)) {
1072 try testing.expect(true);
1073 return;
1074 }
1075
1076 try testing.expectEqualStrings(expect, buffer.items);1034 try testing.expectEqualStrings(expect, buffer.items);
1077}1035}
1078
1079fn printCharValues(gpa: Allocator, list: *std.ArrayList(u8), bytes: []const u8) !void {
1080 for (bytes) |b| try list.append(gpa, printable_char_tab[b]);
1081}
1082
1083fn printUnderstandableChar(gpa: Allocator, list: *std.ArrayList(u8), char: u8) !void {
1084 if (std.ascii.isPrint(char)) {
1085 try list.print(gpa, "'{c}'", .{char});
1086 } else {
1087 try list.print(gpa, "\\x{X:0>2}", .{char});
1088 }
1089}
1090
1091// zig fmt: off
1092const printable_char_tab: [256]u8 = (
1093 "................................ !\"#$%&'()*+,-./0123456789:;<=>?" ++
1094 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~." ++
1095 "................................................................" ++
1096 "................................................................"
1097).*;
src/Compilation.zig+36-15
...@@ -5094,9 +5094,13 @@ pub fn translateC(...@@ -5094,9 +5094,13 @@ pub fn translateC(
5094 try @import("main.zig").translateC(gpa, arena, io, argv.items, environ_map, prog_node, comp.thread_limit, &stdout);5094 try @import("main.zig").translateC(gpa, arena, io, argv.items, environ_map, prog_node, comp.thread_limit, &stdout);
50955095
5096 if (out_dep_path) |dep_file_path| add_deps: {5096 if (out_dep_path) |dep_file_path| add_deps: {
5097 var diagnostic: Cache.Manifest.AddDiscoveredDepFileDiagnostic = undefined;
5097 const dep_basename = fs.path.basename(dep_file_path);5098 const dep_basename = fs.path.basename(dep_file_path);
5098 // Add the files depended on to the cache system, if a dep file was emitted5099 // Add the files depended on to the cache system, if a dep file was emitted
5099 man.addDepFilePost(cache_tmp_dir, dep_basename) catch |err| switch (err) {5100 man.addDiscoveredDepFile(.{
5101 .root_dir = .{ .handle = cache_tmp_dir, .path = tmp_sub_path },
5102 .sub_path = dep_basename,
5103 }, &diagnostic) catch |err| switch (err) {
5100 error.FileNotFound => break :add_deps,5104 error.FileNotFound => break :add_deps,
5101 else => |e| return e,5105 else => |e| return e,
5102 };5106 };
...@@ -5105,14 +5109,17 @@ pub fn translateC(...@@ -5105,14 +5109,17 @@ pub fn translateC(
5105 .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| {5109 .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| {
5106 try whole.cache_manifest_mutex.lock(io);5110 try whole.cache_manifest_mutex.lock(io);
5107 defer whole.cache_manifest_mutex.unlock(io);5111 defer whole.cache_manifest_mutex.unlock(io);
5108 try whole_cache_manifest.addDepFilePost(cache_tmp_dir, dep_basename);5112 try whole_cache_manifest.addDiscoveredDepFile(.{
5113 .root_dir = .{ .handle = cache_tmp_dir, .path = tmp_sub_path },
5114 .sub_path = dep_basename,
5115 }, &diagnostic);
5109 },5116 },
5110 .incremental, .none => {},5117 .incremental, .none => {},
5111 }5118 }
51125119
5113 // Just to save disk space, we delete the file because it is never needed again.5120 // Just to save disk space, we delete the file because it is never needed again.
5114 cache_tmp_dir.deleteFile(io, dep_basename) catch |err| {5121 cache_tmp_dir.deleteFile(io, dep_basename) catch |err| {
5115 log.warn("failed to delete '{s}': {t}", .{ dep_file_path, err });5122 log.warn("failed to delete dep file {q}: {t}", .{ dep_file_path, err });
5116 };5123 };
5117 }5124 }
51185125
...@@ -5527,7 +5534,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5527,7 +5534,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5527 const target = comp.getTarget();5534 const target = comp.getTarget();
5528 assert(target.ofmt != .c);5535 assert(target.ofmt != .c);
5529 const o_ext = target.ofmt.fileExt(target.cpu.arch);5536 const o_ext = target.ofmt.fileExt(target.cpu.arch);
5530 const digest = if (!comp.disable_c_depfile and try man.check(child_progress_node)) man.final() else blk: {5537 const digest = if (!comp.disable_c_depfile and .hit == try man.check(child_progress_node)) man.hitDigestHex() else miss: {
5531 var argv: std.array_list.Managed([]const u8) = .init(gpa);5538 var argv: std.array_list.Managed([]const u8) = .init(gpa);
5532 defer argv.deinit();5539 defer argv.deinit();
55335540
...@@ -5654,11 +5661,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5654,11 +5661,11 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5654 // Just to save disk space, we delete the files that are never needed again.5661 // Just to save disk space, we delete the files that are never needed again.
5655 defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(diag_file_path)) catch |err| switch (err) {5662 defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(diag_file_path)) catch |err| switch (err) {
5656 error.FileNotFound => {}, // the file wasn't created due to an error we reported5663 error.FileNotFound => {}, // the file wasn't created due to an error we reported
5657 else => log.warn("failed to delete '{s}': {s}", .{ diag_file_path, @errorName(err) }),5664 else => log.warn("failed to delete {q}: {t}", .{ diag_file_path, err }),
5658 };5665 };
5659 defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(dep_file_path)) catch |err| switch (err) {5666 defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(io, fs.path.basename(dep_file_path)) catch |err| switch (err) {
5660 error.FileNotFound => {}, // the file wasn't created due to an error we reported5667 error.FileNotFound => {}, // the file wasn't created due to an error we reported
5661 else => log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) }),5668 else => log.warn("failed to delete {q}: {t}", .{ dep_file_path, err }),
5662 };5669 };
5663 if (std.process.can_spawn) {5670 if (std.process.can_spawn) {
5664 if (comp.clang_passthrough_mode) {5671 if (comp.clang_passthrough_mode) {
...@@ -5747,8 +5754,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5747,8 +5754,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5747 const dep_basename = fs.path.basename(dep_file_path);5754 const dep_basename = fs.path.basename(dep_file_path);
57485755
5749 if (comp.file_system_inputs != null) {5756 if (comp.file_system_inputs != null) {
5757 // TODO instead of this rely on passing the manifest contents directly
5758
5750 // Use the same file size limit as the cache code does for dependency files.5759 // Use the same file size limit as the cache code does for dependency files.
5751 const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(io, dep_basename, gpa, .limited(Cache.manifest_file_size_max));5760 const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(io, dep_basename, gpa, .unlimited);
5752 defer gpa.free(dep_file_contents);5761 defer gpa.free(dep_file_contents);
57535762
5754 var str_buf: std.ArrayList(u8) = .empty;5763 var str_buf: std.ArrayList(u8) = .empty;
...@@ -5763,9 +5772,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5763,9 +5772,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5763 try token.resolve(gpa, &str_buf);5772 try token.resolve(gpa, &str_buf);
5764 break :p try .fromUnresolved(arena, comp.dirs, &.{str_buf.items});5773 break :p try .fromUnresolved(arena, comp.dirs, &.{str_buf.items});
5765 },5774 },
5766 else => |err| {5775 else => |err_token| {
5767 try err.printError(gpa, &str_buf);5776 log.err("failed parsing {s}: {f}", .{ dep_basename, err_token });
5768 log.err("failed parsing {s}: {s}", .{ dep_basename, str_buf.items });
5769 return error.InvalidDepFile;5777 return error.InvalidDepFile;
5770 },5778 },
5771 };5779 };
...@@ -5774,13 +5782,26 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5774,13 +5782,26 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5774 }5782 }
57755783
5776 // Add the files depended on to the cache system.5784 // Add the files depended on to the cache system.
5777 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);5785 var diagnostic: Cache.Manifest.AddDiscoveredDepFileDiagnostic = undefined;
5786 try man.addDiscoveredDepFile(.{
5787 .root_dir = .{
5788 .handle = zig_cache_tmp_dir,
5789 .path = "tmp",
5790 },
5791 .sub_path = dep_basename,
5792 }, &diagnostic);
5778 switch (comp.cache_use) {5793 switch (comp.cache_use) {
5779 .whole => |whole| {5794 .whole => |whole| {
5780 if (whole.cache_manifest) |whole_cache_manifest| {5795 if (whole.cache_manifest) |whole_cache_manifest| {
5781 try whole.cache_manifest_mutex.lock(io);5796 try whole.cache_manifest_mutex.lock(io);
5782 defer whole.cache_manifest_mutex.unlock(io);5797 defer whole.cache_manifest_mutex.unlock(io);
5783 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);5798 try whole_cache_manifest.addDiscoveredDepFile(.{
5799 .root_dir = .{
5800 .handle = zig_cache_tmp_dir,
5801 .path = "tmp",
5802 },
5803 .sub_path = dep_basename,
5804 }, &diagnostic);
5784 }5805 }
5785 },5806 },
5786 .incremental, .none => {},5807 .incremental, .none => {},
...@@ -5791,13 +5812,13 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr...@@ -5791,13 +5812,13 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
5791 if (comp.disable_c_depfile) _ = try man.check(child_progress_node);5812 if (comp.disable_c_depfile) _ = try man.check(child_progress_node);
57925813
5793 // Rename into place.5814 // Rename into place.
5794 const digest = man.final();5815 const digest = man.missDigestHex();
5795 const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest });5816 const o_sub_path = try fs.path.join(arena, &.{ "o", &digest });
5796 var o_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, o_sub_path, .{});5817 var o_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, o_sub_path, .{});
5797 defer o_dir.close(io);5818 defer o_dir.close(io);
5798 const tmp_basename = fs.path.basename(out_obj_path);5819 const tmp_basename = fs.path.basename(out_obj_path);
5799 try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename, io);5820 try Io.Dir.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename, io);
5800 break :blk digest;5821 break :miss digest;
5801 };5822 };
58025823
5803 if (man.have_exclusive_lock) {5824 if (man.have_exclusive_lock) {
src/libs/freebsd.zig+4-5
...@@ -465,9 +465,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -465,9 +465,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
465 .request_contents = true,465 .request_contents = true,
466 });466 });
467467
468 if (try man.check(prog_node)) {468 if (.hit == try man.check(prog_node)) {
469 const digest = man.final();469 const digest = man.hitDigestHex();
470
471 return queueSharedObjects(comp, .{470 return queueSharedObjects(comp, .{
472 .lock = man.toOwnedLock(),471 .lock = man.toOwnedLock(),
473 .dir_path = .{472 .dir_path = .{
...@@ -477,7 +476,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -477,7 +476,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
477 });476 });
478 }477 }
479478
480 const digest = man.final();479 const digest = man.missDigestHex();
481 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });480 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });
482481
483 var o_directory: Cache.Directory = .{482 var o_directory: Cache.Directory = .{
...@@ -486,7 +485,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -486,7 +485,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
486 };485 };
487 defer o_directory.handle.close(io);486 defer o_directory.handle.close(io);
488487
489 const abilists_contents = man.files.keys()[abilists_index].contents.?;488 const abilists_contents = abilists_index.contents(&man);
490 const metadata = try loadMetaData(gpa, abilists_contents);489 const metadata = try loadMetaData(gpa, abilists_contents);
491 defer metadata.destroy(gpa);490 defer metadata.destroy(gpa);
492491
src/libs/glibc.zig+5-6
...@@ -705,9 +705,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -705,9 +705,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
705 .request_contents = true,705 .request_contents = true,
706 });706 });
707707
708 if (try man.check(prog_node)) {708 if (.hit == try man.check(prog_node)) {
709 const digest = man.final();709 const digest = man.hitDigestHex();
710
711 return queueSharedObjects(comp, .{710 return queueSharedObjects(comp, .{
712 .lock = man.toOwnedLock(),711 .lock = man.toOwnedLock(),
713 .dir_path = .{712 .dir_path = .{
...@@ -717,8 +716,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -717,8 +716,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
717 });716 });
718 }717 }
719718
720 const digest = man.final();719 const digest = man.missDigestHex();
721 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });720 const o_sub_path = try path.join(arena, &.{ "o", &digest });
722721
723 var o_directory: Cache.Directory = .{722 var o_directory: Cache.Directory = .{
724 .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}),723 .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}),
...@@ -726,7 +725,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -726,7 +725,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
726 };725 };
727 defer o_directory.handle.close(io);726 defer o_directory.handle.close(io);
728727
729 const abilists_contents = man.files.keys()[abilists_index].contents.?;728 const abilists_contents = abilists_index.contents(&man);
730 const metadata = try loadMetaData(gpa, abilists_contents);729 const metadata = try loadMetaData(gpa, abilists_contents);
731 defer metadata.destroy(gpa);730 defer metadata.destroy(gpa);
732731
src/libs/netbsd.zig+5-6
...@@ -413,9 +413,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -413,9 +413,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
413 .request_contents = true,413 .request_contents = true,
414 });414 });
415415
416 if (try man.check(prog_node)) {416 if (.hit == try man.check(prog_node)) {
417 const digest = man.final();417 const digest = man.hitDigestHex();
418
419 return queueSharedObjects(comp, .{418 return queueSharedObjects(comp, .{
420 .lock = man.toOwnedLock(),419 .lock = man.toOwnedLock(),
421 .dir_path = .{420 .dir_path = .{
...@@ -425,8 +424,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -425,8 +424,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
425 });424 });
426 }425 }
427426
428 const digest = man.final();427 const digest = man.missDigestHex();
429 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });428 const o_sub_path = try path.join(arena, &.{ "o", &digest });
430429
431 var o_directory: Cache.Directory = .{430 var o_directory: Cache.Directory = .{
432 .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}),431 .handle = try comp.dirs.global_cache.handle.createDirPathOpen(io, o_sub_path, .{}),
...@@ -434,7 +433,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -434,7 +433,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
434 };433 };
435 defer o_directory.handle.close(io);434 defer o_directory.handle.close(io);
436435
437 const abilists_contents = man.files.keys()[abilists_index].contents.?;436 const abilists_contents = abilists_index.contents(&man);
438 const metadata = try loadMetaData(gpa, abilists_contents);437 const metadata = try loadMetaData(gpa, abilists_contents);
439 defer metadata.destroy(gpa);438 defer metadata.destroy(gpa);
440439
src/libs/openbsd.zig+4-5
...@@ -334,9 +334,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -334,9 +334,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
334 .request_contents = true,334 .request_contents = true,
335 });335 });
336336
337 if (try man.check(prog_node)) {337 if (.hit == try man.check(prog_node)) {
338 const digest = man.final();338 const digest = man.hitDigestHex();
339
340 return queueSharedObjects(comp, .{339 return queueSharedObjects(comp, .{
341 .lock = man.toOwnedLock(),340 .lock = man.toOwnedLock(),
342 .dir_path = .{341 .dir_path = .{
...@@ -346,7 +345,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -346,7 +345,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
346 });345 });
347 }346 }
348347
349 const digest = man.final();348 const digest = man.missDigestHex();
350 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });349 const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest });
351350
352 var o_directory: Cache.Directory = .{351 var o_directory: Cache.Directory = .{
...@@ -355,7 +354,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -355,7 +354,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
355 };354 };
356 defer o_directory.handle.close(io);355 defer o_directory.handle.close(io);
357356
358 const abilists_contents = man.files.keys()[abilists_index].contents.?;357 const abilists_contents = abilists_index.contents(&man);
359 const metadata = try loadMetaData(gpa, abilists_contents);358 const metadata = try loadMetaData(gpa, abilists_contents);
360 defer metadata.destroy(gpa);359 defer metadata.destroy(gpa);
361360