authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-03 15:48:00-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-04 17:42:21-07:00
logc3f2f93dbfec9060054c0cbafd7fbbdc63a249b3
tree105a7bce461d9e01691896f28669a58760709251
parent0342d5890d80f81178e2f725092b34157825f7a7

std.fs.path: rename resolve functions to resolveAlloc

introduce resolveAppend variants

1 files changed, 42 insertions(+), 21 deletions(-)

lib/std/fs/path.zig+42-21
......@@ -860,12 +860,26 @@ fn testCompareDiskDesignators(expected_result: bool, kind: DiskDesignatorKind, p
860860 try std.testing.expectEqual(expected_result, compareDiskDesignators(u16, kind, wtf16_buf1[0..w1_len], wtf16_buf2[0..w2_len]));
861861}
862862
863/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.
864pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
865 if (native_os == .windows) {
866 return resolveWindows(allocator, paths);
867 } else {
868 return resolvePosix(allocator, paths);
863/// Deprecated in favor of `resolveAlloc`.
864pub const resolve = resolveAlloc;
865/// Deprecated in favor of `resolveAllocWindows`.
866pub const resolveWindows = resolveAllocWindows;
867/// Deprecated in favor of `resolveAllocPosix`.
868pub const resolvePosix = resolveAllocPosix;
869
870/// On Windows, calls `resolveAllocWindows`; otherwise calls `resolveAllocPosix`.
871pub fn resolveAlloc(gpa: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
872 switch (native_os) {
873 .windows => return resolveAllocWindows(gpa, paths),
874 else => return resolveAllocPosix(gpa, paths),
875 }
876}
877
878/// On Windows, calls `resolveAppendWindows`; otherwise calls `resolveAppendPosix`.
879pub fn resolveAppend(gpa: Allocator, al: *std.ArrayList(u8), paths: []const []const u8) Allocator.Error!void {
880 switch (native_os) {
881 .windows => return resolveAppendWindows(gpa, al, paths),
882 else => return resolveAppendPosix(gpa, al, paths),
869883 }
870884}
871885
......@@ -891,7 +905,7 @@ pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error!
891905/// Note: all usage of this function should be audited due to the existence of symlinks.
892906/// Without performing actual syscalls, resolving `..` could be incorrect.
893907/// This API may break in the future: https://github.com/ziglang/zig/issues/13613
894pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
908pub fn resolveAllocWindows(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
895909 // Avoid heap allocation when paths.len is <= @bitSizeOf(usize) * 2
896910 // (we use `* 3` because stackFallback uses 1 usize as a length)
897911 var buf: [3]usize = undefined;
......@@ -1093,6 +1107,13 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator
10931107 return result.toOwnedSlice(allocator);
10941108}
10951109
1110pub fn resolveAppendWindows(gpa: Allocator, al: *std.ArrayList(u8), paths: []const []const u8) Allocator.Error!void {
1111 _ = gpa;
1112 _ = al;
1113 _ = paths;
1114 @panic("TODO");
1115}
1116
10961117/// Simulates a series of relative directory changes on a virtual filesystem
10971118/// that has no symlinks.
10981119///
......@@ -1105,7 +1126,7 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator
11051126/// This function does not perform any syscalls. Executing this series of path
11061127/// lookups on an actual filesystem may produce different results due to
11071128/// symlinks.
1108pub fn resolvePosix(gpa: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
1129pub fn resolveAllocPosix(gpa: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
11091130 assert(paths.len > 0);
11101131
11111132 var result: std.ArrayList(u8) = .empty;
......@@ -1178,7 +1199,7 @@ pub fn resolvePosix(gpa: Allocator, paths: []const []const u8) Allocator.Error![
11781199 }
11791200}
11801201
1181pub fn resolvePosix2(gpa: Allocator, al: *std.ArrayList(u8), paths: []const []const u8) Allocator.Error!void {
1202pub fn resolveAppendPosix(gpa: Allocator, al: *std.ArrayList(u8), paths: []const []const u8) Allocator.Error!void {
11821203 _ = gpa;
11831204 _ = al;
11841205 _ = paths;
......@@ -1199,7 +1220,7 @@ test resolve {
11991220 try testResolvePosix(&[_][]const u8{""}, ".");
12001221}
12011222
1202test resolveWindows {
1223test resolveAllocWindows {
12031224 try testResolveWindows(
12041225 &[_][]const u8{ "Z:\\", "/usr/local", "lib\\zig\\std\\array_list.zig" },
12051226 "Z:\\usr\\local\\lib\\zig\\std\\array_list.zig",
......@@ -1287,7 +1308,7 @@ test resolveWindows {
12871308 try testResolveWindows(&[_][]const u8{ "C:\\", "\\??\\C:\\foo", "bar" }, "C:\\??\\C:\\foo\\bar");
12881309}
12891310
1290test resolvePosix {
1311test resolveAllocPosix {
12911312 try testResolvePosix(&.{ "/a/b", "c" }, "/a/b/c");
12921313 try testResolvePosix(&.{ "/a/b", "c", "//d", "e///" }, "/d/e");
12931314 try testResolvePosix(&.{ "/a/b/c", "..", "../" }, "/a");
......@@ -1306,13 +1327,13 @@ test resolvePosix {
13061327}
13071328
13081329fn testResolveWindows(paths: []const []const u8, expected: []const u8) !void {
1309 const actual = try resolveWindows(testing.allocator, paths);
1330 const actual = try resolveAllocWindows(testing.allocator, paths);
13101331 defer testing.allocator.free(actual);
13111332 try testing.expectEqualStrings(expected, actual);
13121333}
13131334
13141335fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void {
1315 const actual = try resolvePosix(testing.allocator, paths);
1336 const actual = try resolveAllocPosix(testing.allocator, paths);
13161337 defer testing.allocator.free(actual);
13171338 try testing.expectEqualStrings(expected, actual);
13181339}
......@@ -1657,9 +1678,9 @@ fn windowsResolveAgainstCwd(
16571678 .unc_absolute,
16581679 .root_local_device,
16591680 .local_device,
1660 => try resolveWindows(gpa, &.{path}),
1681 => try resolveAllocWindows(gpa, &.{path}),
16611682
1662 .relative => try resolveWindows(gpa, &.{ cwd, path }),
1683 .relative => try resolveAllocWindows(gpa, &.{ cwd, path }),
16631684
16641685 .rooted => blk: {
16651686 const parsed_cwd = parsePathWindows(u8, cwd);
......@@ -1667,13 +1688,13 @@ fn windowsResolveAgainstCwd(
16671688 .drive_absolute => {
16681689 var drive_buf = "_:\\".*;
16691690 drive_buf[0] = cwd[0];
1670 break :blk try resolveWindows(gpa, &.{ &drive_buf, path });
1691 break :blk try resolveAllocWindows(gpa, &.{ &drive_buf, path });
16711692 },
16721693 .unc_absolute => {
1673 break :blk try resolveWindows(gpa, &.{ parsed_cwd.root, path });
1694 break :blk try resolveAllocWindows(gpa, &.{ parsed_cwd.root, path });
16741695 },
16751696 // Effectively a malformed CWD, give up and just return a normalized path
1676 else => break :blk try resolveWindows(gpa, &.{path}),
1697 else => break :blk try resolveAllocWindows(gpa, &.{path}),
16771698 }
16781699 },
16791700 .drive_relative => blk: {
......@@ -1702,7 +1723,7 @@ fn windowsResolveAgainstCwd(
17021723 break :drive_cwd drive_buf;
17031724 };
17041725 defer temp_allocator.free(drive_cwd);
1705 break :blk try resolveWindows(gpa, &.{ drive_cwd, path });
1726 break :blk try resolveAllocWindows(gpa, &.{ drive_cwd, path });
17061727 },
17071728 };
17081729}
......@@ -1716,9 +1737,9 @@ fn windowsResolveAgainstCwd(
17161737/// on each), a zero-length string is returned.
17171738///
17181739pub fn relativePosix(allocator: Allocator, cwd: []const u8, from: []const u8, to: []const u8) Allocator.Error![]u8 {
1719 const resolved_from = try resolvePosix(allocator, &[_][]const u8{ cwd, from });
1740 const resolved_from = try resolveAllocPosix(allocator, &[_][]const u8{ cwd, from });
17201741 defer allocator.free(resolved_from);
1721 const resolved_to = try resolvePosix(allocator, &[_][]const u8{ cwd, to });
1742 const resolved_to = try resolveAllocPosix(allocator, &[_][]const u8{ cwd, to });
17221743 defer allocator.free(resolved_to);
17231744
17241745 var from_it = mem.tokenizeScalar(u8, resolved_from, '/');