| ... | @@ -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 | } |
| 862 | | 862 | |
| 863 | /// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`. | 863 | /// Deprecated in favor of `resolveAlloc`. |
| 864 | pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 { | 864 | pub const resolve = resolveAlloc; |
| 865 | if (native_os == .windows) { | 865 | /// Deprecated in favor of `resolveAllocWindows`. |
| 866 | return resolveWindows(allocator, paths); | 866 | pub const resolveWindows = resolveAllocWindows; |
| 867 | } else { | 867 | /// Deprecated in favor of `resolveAllocPosix`. |
| 868 | return resolvePosix(allocator, paths); | 868 | pub const resolvePosix = resolveAllocPosix; |
| | 869 | |
| | 870 | /// On Windows, calls `resolveAllocWindows`; otherwise calls `resolveAllocPosix`. |
| | 871 | pub 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`. |
| | 879 | pub 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 | } |
| 871 | | 885 | |
| ... | @@ -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/13613 | 907 | /// This API may break in the future: https://github.com/ziglang/zig/issues/13613 |
| 894 | pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 { | 908 | pub fn resolveAllocWindows(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 { |
| 895 | // Avoid heap allocation when paths.len is <= @bitSizeOf(usize) * 2 | 909 | // 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 | } |
| 1095 | | 1109 | |
| | 1110 | pub 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 filesystem | 1117 | /// 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 path | 1126 | /// This function does not perform any syscalls. Executing this series of path |
| 1106 | /// lookups on an actual filesystem may produce different results due to | 1127 | /// lookups on an actual filesystem may produce different results due to |
| 1107 | /// symlinks. | 1128 | /// symlinks. |
| 1108 | pub fn resolvePosix(gpa: Allocator, paths: []const []const u8) Allocator.Error![]u8 { | 1129 | pub fn resolveAllocPosix(gpa: Allocator, paths: []const []const u8) Allocator.Error![]u8 { |
| 1109 | assert(paths.len > 0); | 1130 | assert(paths.len > 0); |
| 1110 | | 1131 | |
| 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 | } |
| 1180 | | 1201 | |
| 1181 | pub fn resolvePosix2(gpa: Allocator, al: *std.ArrayList(u8), paths: []const []const u8) Allocator.Error!void { | 1202 | pub 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 | } |
| 1201 | | 1222 | |
| 1202 | test resolveWindows { | 1223 | test 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 | } |
| 1289 | | 1310 | |
| 1290 | test resolvePosix { | 1311 | test 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 | } |
| 1307 | | 1328 | |
| 1308 | fn testResolveWindows(paths: []const []const u8, expected: []const u8) !void { | 1329 | fn 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 | } |
| 1313 | | 1334 | |
| 1314 | fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void { | 1335 | fn 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}), |
| 1661 | | 1682 | |
| 1662 | .relative => try resolveWindows(gpa, &.{ cwd, path }), | 1683 | .relative => try resolveAllocWindows(gpa, &.{ cwd, path }), |
| 1663 | | 1684 | |
| 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 path | 1696 | // 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 | /// |
| 1718 | pub fn relativePosix(allocator: Allocator, cwd: []const u8, from: []const u8, to: []const u8) Allocator.Error![]u8 { | 1739 | pub 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); |
| 1723 | | 1744 | |
| 1724 | var from_it = mem.tokenizeScalar(u8, resolved_from, '/'); | 1745 | var from_it = mem.tokenizeScalar(u8, resolved_from, '/'); |