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...@@ -860,12 +860,26 @@ fn testCompareDiskDesignators(expected_result: bool, kind: DiskDesignatorKind, p
860 try std.testing.expectEqual(expected_result, compareDiskDesignators(u16, kind, wtf16_buf1[0..w1_len], wtf16_buf2[0..w2_len]));860 try std.testing.expectEqual(expected_result, compareDiskDesignators(u16, kind, wtf16_buf1[0..w1_len], wtf16_buf2[0..w2_len]));
861}861}
862862
863/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.863/// Deprecated in favor of `resolveAlloc`.
864pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 {864pub const resolve = resolveAlloc;
865 if (native_os == .windows) {865/// Deprecated in favor of `resolveAllocWindows`.
866 return resolveWindows(allocator, paths);866pub const resolveWindows = resolveAllocWindows;
867 } else {867/// Deprecated in favor of `resolveAllocPosix`.
868 return resolvePosix(allocator, paths);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),
869 }883 }
870}884}
871885
...@@ -891,7 +905,7 @@ pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error!...@@ -891,7 +905,7 @@ pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error!
891/// Note: all usage of this function should be audited due to the existence of symlinks.905/// Note: all usage of this function should be audited due to the existence of symlinks.
892/// Without performing actual syscalls, resolving `..` could be incorrect.906/// Without performing actual syscalls, resolving `..` could be incorrect.
893/// This API may break in the future: https://github.com/ziglang/zig/issues/13613907/// 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 {
895 // Avoid heap allocation when paths.len is <= @bitSizeOf(usize) * 2909 // Avoid heap allocation when paths.len is <= @bitSizeOf(usize) * 2
896 // (we use `* 3` because stackFallback uses 1 usize as a length)910 // (we use `* 3` because stackFallback uses 1 usize as a length)
897 var buf: [3]usize = undefined;911 var buf: [3]usize = undefined;
...@@ -1093,6 +1107,13 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator...@@ -1093,6 +1107,13 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator
1093 return result.toOwnedSlice(allocator);1107 return result.toOwnedSlice(allocator);
1094}1108}
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
1096/// Simulates a series of relative directory changes on a virtual filesystem1117/// Simulates a series of relative directory changes on a virtual filesystem
1097/// that has no symlinks.1118/// that has no symlinks.
1098///1119///
...@@ -1105,7 +1126,7 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator...@@ -1105,7 +1126,7 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator
1105/// This function does not perform any syscalls. Executing this series of path1126/// This function does not perform any syscalls. Executing this series of path
1106/// lookups on an actual filesystem may produce different results due to1127/// lookups on an actual filesystem may produce different results due to
1107/// symlinks.1128/// 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 {
1109 assert(paths.len > 0);1130 assert(paths.len > 0);
11101131
1111 var result: std.ArrayList(u8) = .empty;1132 var result: std.ArrayList(u8) = .empty;
...@@ -1178,7 +1199,7 @@ pub fn resolvePosix(gpa: Allocator, paths: []const []const u8) Allocator.Error![...@@ -1178,7 +1199,7 @@ pub fn resolvePosix(gpa: Allocator, paths: []const []const u8) Allocator.Error![
1178 }1199 }
1179}1200}
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 {
1182 _ = gpa;1203 _ = gpa;
1183 _ = al;1204 _ = al;
1184 _ = paths;1205 _ = paths;
...@@ -1199,7 +1220,7 @@ test resolve {...@@ -1199,7 +1220,7 @@ test resolve {
1199 try testResolvePosix(&[_][]const u8{""}, ".");1220 try testResolvePosix(&[_][]const u8{""}, ".");
1200}1221}
12011222
1202test resolveWindows {1223test resolveAllocWindows {
1203 try testResolveWindows(1224 try testResolveWindows(
1204 &[_][]const u8{ "Z:\\", "/usr/local", "lib\\zig\\std\\array_list.zig" },1225 &[_][]const u8{ "Z:\\", "/usr/local", "lib\\zig\\std\\array_list.zig" },
1205 "Z:\\usr\\local\\lib\\zig\\std\\array_list.zig",1226 "Z:\\usr\\local\\lib\\zig\\std\\array_list.zig",
...@@ -1287,7 +1308,7 @@ test resolveWindows {...@@ -1287,7 +1308,7 @@ test resolveWindows {
1287 try testResolveWindows(&[_][]const u8{ "C:\\", "\\??\\C:\\foo", "bar" }, "C:\\??\\C:\\foo\\bar");1308 try testResolveWindows(&[_][]const u8{ "C:\\", "\\??\\C:\\foo", "bar" }, "C:\\??\\C:\\foo\\bar");
1288}1309}
12891310
1290test resolvePosix {1311test resolveAllocPosix {
1291 try testResolvePosix(&.{ "/a/b", "c" }, "/a/b/c");1312 try testResolvePosix(&.{ "/a/b", "c" }, "/a/b/c");
1292 try testResolvePosix(&.{ "/a/b", "c", "//d", "e///" }, "/d/e");1313 try testResolvePosix(&.{ "/a/b", "c", "//d", "e///" }, "/d/e");
1293 try testResolvePosix(&.{ "/a/b/c", "..", "../" }, "/a");1314 try testResolvePosix(&.{ "/a/b/c", "..", "../" }, "/a");
...@@ -1306,13 +1327,13 @@ test resolvePosix {...@@ -1306,13 +1327,13 @@ test resolvePosix {
1306}1327}
13071328
1308fn testResolveWindows(paths: []const []const u8, expected: []const u8) !void {1329fn 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);
1310 defer testing.allocator.free(actual);1331 defer testing.allocator.free(actual);
1311 try testing.expectEqualStrings(expected, actual);1332 try testing.expectEqualStrings(expected, actual);
1312}1333}
13131334
1314fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void {1335fn 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);
1316 defer testing.allocator.free(actual);1337 defer testing.allocator.free(actual);
1317 try testing.expectEqualStrings(expected, actual);1338 try testing.expectEqualStrings(expected, actual);
1318}1339}
...@@ -1657,9 +1678,9 @@ fn windowsResolveAgainstCwd(...@@ -1657,9 +1678,9 @@ fn windowsResolveAgainstCwd(
1657 .unc_absolute,1678 .unc_absolute,
1658 .root_local_device,1679 .root_local_device,
1659 .local_device,1680 .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
1664 .rooted => blk: {1685 .rooted => blk: {
1665 const parsed_cwd = parsePathWindows(u8, cwd);1686 const parsed_cwd = parsePathWindows(u8, cwd);
...@@ -1667,13 +1688,13 @@ fn windowsResolveAgainstCwd(...@@ -1667,13 +1688,13 @@ fn windowsResolveAgainstCwd(
1667 .drive_absolute => {1688 .drive_absolute => {
1668 var drive_buf = "_:\\".*;1689 var drive_buf = "_:\\".*;
1669 drive_buf[0] = cwd[0];1690 drive_buf[0] = cwd[0];
1670 break :blk try resolveWindows(gpa, &.{ &drive_buf, path });1691 break :blk try resolveAllocWindows(gpa, &.{ &drive_buf, path });
1671 },1692 },
1672 .unc_absolute => {1693 .unc_absolute => {
1673 break :blk try resolveWindows(gpa, &.{ parsed_cwd.root, path });1694 break :blk try resolveAllocWindows(gpa, &.{ parsed_cwd.root, path });
1674 },1695 },
1675 // Effectively a malformed CWD, give up and just return a normalized path1696 // 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}),
1677 }1698 }
1678 },1699 },
1679 .drive_relative => blk: {1700 .drive_relative => blk: {
...@@ -1702,7 +1723,7 @@ fn windowsResolveAgainstCwd(...@@ -1702,7 +1723,7 @@ fn windowsResolveAgainstCwd(
1702 break :drive_cwd drive_buf;1723 break :drive_cwd drive_buf;
1703 };1724 };
1704 defer temp_allocator.free(drive_cwd);1725 defer temp_allocator.free(drive_cwd);
1705 break :blk try resolveWindows(gpa, &.{ drive_cwd, path });1726 break :blk try resolveAllocWindows(gpa, &.{ drive_cwd, path });
1706 },1727 },
1707 };1728 };
1708}1729}
...@@ -1716,9 +1737,9 @@ fn windowsResolveAgainstCwd(...@@ -1716,9 +1737,9 @@ fn windowsResolveAgainstCwd(
1716/// on each), a zero-length string is returned.1737/// on each), a zero-length string is returned.
1717///1738///
1718pub fn relativePosix(allocator: Allocator, cwd: []const u8, from: []const u8, to: []const u8) Allocator.Error![]u8 {1739pub 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 });
1720 defer allocator.free(resolved_from);1741 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 });
1722 defer allocator.free(resolved_to);1743 defer allocator.free(resolved_to);
17231744
1724 var from_it = mem.tokenizeScalar(u8, resolved_from, '/');1745 var from_it = mem.tokenizeScalar(u8, resolved_from, '/');