authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2025-10-03 14:25:12-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2025-10-03 16:29:09-07:00
log894a99171491c9b054ae93b10ca3dc6fa6d8c125
tree7f6c87c201d7f96d8d9d7800f53c6e78a5d050aa
parent98dd8856ef901b99f198d992146abd0545adb5b2

Add depth function to `Walker.Entry`

This enables depth-related use cases without any dependency on the Walker's internal stack which doesn't always pertain to the actual depth of the current entry (i.e. recursing into a directory immediately affects the stack).

3 files changed, 28 insertions(+), 20 deletions(-)

lib/std/fs/Dir.zig+9-4
......@@ -732,16 +732,14 @@ pub const SelectiveWalker = struct {
732732 });
733733 }
734734
735 pub fn depth(self: *SelectiveWalker) usize {
736 return self.stack.items.len;
737 }
738
739735 pub fn deinit(self: *SelectiveWalker) void {
740736 self.name_buffer.deinit(self.allocator);
741737 self.stack.deinit(self.allocator);
742738 }
743739
744740 /// Leaves the current directory, continuing walking one level up.
741 /// If the current entry is a directory entry, then the "current directory"
742 /// will pertain to that entry if `enter` is called before `leave`.
745743 pub fn leave(self: *SelectiveWalker) void {
746744 var item = self.stack.pop().?;
747745 if (self.stack.items.len != 0) {
......@@ -789,6 +787,13 @@ pub const Walker = struct {
789787 basename: [:0]const u8,
790788 path: [:0]const u8,
791789 kind: Dir.Entry.Kind,
790
791 /// Returns the depth of the entry relative to the initial directory.
792 /// Returns 1 for a direct child of the initial directory, 2 for an entry
793 /// within a direct child of the initial directory, etc.
794 pub fn depth(self: Walker.Entry) usize {
795 return mem.countScalar(u8, self.path, fs.path.sep) + 1;
796 }
792797 };
793798
794799 const StackItem = struct {
lib/std/fs/test.zig+18-15
......@@ -1765,14 +1765,14 @@ test "walker" {
17651765
17661766 // iteration order of walker is undefined, so need lookup maps to check against
17671767
1768 const expected_paths = std.StaticStringMap(void).initComptime(.{
1769 .{"dir1"},
1770 .{"dir2"},
1771 .{"dir3"},
1772 .{"dir4"},
1773 .{"dir3" ++ fs.path.sep_str ++ "sub1"},
1774 .{"dir3" ++ fs.path.sep_str ++ "sub2"},
1775 .{"dir3" ++ fs.path.sep_str ++ "sub2" ++ fs.path.sep_str ++ "subsub1"},
1768 const expected_paths = std.StaticStringMap(usize).initComptime(.{
1769 .{ "dir1", 1 },
1770 .{ "dir2", 1 },
1771 .{ "dir3", 1 },
1772 .{ "dir4", 1 },
1773 .{ "dir3" ++ fs.path.sep_str ++ "sub1", 2 },
1774 .{ "dir3" ++ fs.path.sep_str ++ "sub2", 2 },
1775 .{ "dir3" ++ fs.path.sep_str ++ "sub2" ++ fs.path.sep_str ++ "subsub1", 3 },
17761776 });
17771777
17781778 const expected_basenames = std.StaticStringMap(void).initComptime(.{
......@@ -1802,6 +1802,10 @@ test "walker" {
18021802 std.debug.print("found unexpected path: {f}\n", .{std.ascii.hexEscape(entry.path, .lower)});
18031803 return err;
18041804 };
1805 testing.expectEqual(expected_paths.get(entry.path).?, entry.depth()) catch |err| {
1806 std.debug.print("path reported unexpected depth: {f}\n", .{std.ascii.hexEscape(entry.path, .lower)});
1807 return err;
1808 };
18051809 // make sure that the entry.dir is the containing dir
18061810 var entry_dir = try entry.dir.openDir(entry.basename, .{});
18071811 defer entry_dir.close();
......@@ -1851,6 +1855,10 @@ test "selective walker, skip entries that start with ." {
18511855 var num_walked: usize = 0;
18521856 while (try walker.next()) |entry| {
18531857 if (entry.basename[0] == '.') continue;
1858 if (entry.kind == .directory) {
1859 try walker.enter(entry);
1860 }
1861
18541862 testing.expect(expected_basenames.has(entry.basename)) catch |err| {
18551863 std.debug.print("found unexpected basename: {f}\n", .{std.ascii.hexEscape(entry.basename, .lower)});
18561864 return err;
......@@ -1859,16 +1867,11 @@ test "selective walker, skip entries that start with ." {
18591867 std.debug.print("found unexpected path: {f}\n", .{std.ascii.hexEscape(entry.path, .lower)});
18601868 return err;
18611869 };
1862
1863 testing.expectEqual(expected_paths.get(entry.path).?, walker.depth()) catch |err| {
1864 std.debug.print("path reported unexpected depth: {f}, {d}, expected {d}\n", .{ std.ascii.hexEscape(entry.path, .lower), walker.depth(), expected_paths.get(entry.path).? });
1870 testing.expectEqual(expected_paths.get(entry.path).?, entry.depth()) catch |err| {
1871 std.debug.print("path reported unexpected depth: {f}\n", .{std.ascii.hexEscape(entry.path, .lower)});
18651872 return err;
18661873 };
18671874
1868 if (entry.kind == .directory) {
1869 try walker.enter(entry);
1870 }
1871
18721875 // make sure that the entry.dir is the containing dir
18731876 var entry_dir = try entry.dir.openDir(entry.basename, .{});
18741877 defer entry_dir.close();
tools/update_mingw.zig+1-1
......@@ -117,7 +117,7 @@ pub fn main() !void {
117117 while (try walker.next()) |entry| {
118118 switch (entry.kind) {
119119 .directory => {
120 switch (walker.depth()) {
120 switch (entry.depth()) {
121121 1 => if (def_dirs.has(entry.basename)) {
122122 try walker.enter(entry);
123123 continue;