authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-03 17:57:25-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-04 17:42:22-07:00
log1bfbbe8b80c9155591766e302ffbc93c180b348a
tree44eb8251820c307c9adfe8178f8676b42f728c86
parentc3f2f93dbfec9060054c0cbafd7fbbdc63a249b3

std.fs.path: rename relative functions to relativeAlloc

introduce relativeAppend variants

1 files changed, 107 insertions(+), 25 deletions(-)

lib/std/fs/path.zig+107-25
...@@ -867,6 +867,13 @@ pub const resolveWindows = resolveAllocWindows;...@@ -867,6 +867,13 @@ pub const resolveWindows = resolveAllocWindows;
867/// Deprecated in favor of `resolveAllocPosix`.867/// Deprecated in favor of `resolveAllocPosix`.
868pub const resolvePosix = resolveAllocPosix;868pub const resolvePosix = resolveAllocPosix;
869869
870/// Deprecated in favor of `relativeAlloc`.
871pub const relative = relativeAlloc;
872/// Deprecated in favor of `relativeAllocPosix`.
873pub const relativePosix = relativeAllocPosix;
874/// Deprecated in favor of `relativeAllocWindows`.
875pub const relativeWindows = relativeAllocWindows;
876
870/// On Windows, calls `resolveAllocWindows`; otherwise calls `resolveAllocPosix`.877/// On Windows, calls `resolveAllocWindows`; otherwise calls `resolveAllocPosix`.
871pub fn resolveAlloc(gpa: Allocator, paths: []const []const u8) Allocator.Error![]u8 {878pub fn resolveAlloc(gpa: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
872 switch (native_os) {879 switch (native_os) {
...@@ -1536,7 +1543,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) !void {...@@ -1536,7 +1543,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) !void {
1536///1543///
1537/// See `relativePosix` and `relativeWindows` for operating system specific1544/// See `relativePosix` and `relativeWindows` for operating system specific
1538/// details and for how `environ_map` is used.1545/// details and for how `environ_map` is used.
1539pub fn relative(1546pub fn relativeAlloc(
1540 gpa: Allocator,1547 gpa: Allocator,
1541 cwd: []const u8,1548 cwd: []const u8,
1542 environ_map: ?*const std.process.Environ.Map,1549 environ_map: ?*const std.process.Environ.Map,
...@@ -1544,9 +1551,36 @@ pub fn relative(...@@ -1544,9 +1551,36 @@ pub fn relative(
1544 to: []const u8,1551 to: []const u8,
1545) Allocator.Error![]u8 {1552) Allocator.Error![]u8 {
1546 if (native_os == .windows) {1553 if (native_os == .windows) {
1547 return relativeWindows(gpa, cwd, environ_map, from, to);1554 return relativeAllocWindows(gpa, cwd, environ_map, from, to);
1555 } else {
1556 return relativeAllocPosix(gpa, cwd, from, to);
1557 }
1558}
1559
1560/// Appends the non-absolute path from `from` to `to` to the provided array
1561/// list.
1562///
1563/// Other than modifying the provided array list, this is a pure function; the
1564/// result solely depends on the input parameters and no file system operations
1565/// are performed.
1566///
1567/// If `from` and `to` each resolve to the same path (after calling
1568/// `resolveAppend` on each), a zero-length string is returned.
1569///
1570/// See `relativeAppendPosix` and `relativeAppendWindows` for operating system
1571/// specific details and for how `environ_map` is used.
1572pub fn relativeAppend(
1573 gpa: Allocator,
1574 al: *std.ArrayList(u8),
1575 cwd: []const u8,
1576 environ_map: ?*const std.process.Environ.Map,
1577 from: []const u8,
1578 to: []const u8,
1579) Allocator.Error!void {
1580 if (native_os == .windows) {
1581 return relativeAppendWindows(gpa, al, cwd, environ_map, from, to);
1548 } else {1582 } else {
1549 return relativePosix(gpa, cwd, from, to);1583 return relativeAppendPosix(gpa, al, cwd, from, to);
1550 }1584 }
1551}1585}
15521586
...@@ -1567,7 +1601,7 @@ pub fn relative(...@@ -1567,7 +1601,7 @@ pub fn relative(
1567/// shell concept, so there's no guarantee that it'll be set or that it'll even1601/// shell concept, so there's no guarantee that it'll be set or that it'll even
1568/// be accurate. This is the only reason for the `environ_map` parameter. `null` is1602/// be accurate. This is the only reason for the `environ_map` parameter. `null` is
1569/// treated equivalent to the environment variable missing.1603/// treated equivalent to the environment variable missing.
1570pub fn relativeWindows(1604pub fn relativeAllocWindows(
1571 gpa: Allocator,1605 gpa: Allocator,
1572 cwd: []const u8,1606 cwd: []const u8,
1573 environ_map: ?*const std.process.Environ.Map,1607 environ_map: ?*const std.process.Environ.Map,
...@@ -1663,6 +1697,23 @@ pub fn relativeWindows(...@@ -1663,6 +1697,23 @@ pub fn relativeWindows(
1663 return [_]u8{};1697 return [_]u8{};
1664}1698}
16651699
1700pub fn relativeAppendWindows(
1701 gpa: Allocator,
1702 al: *std.ArrayList(u8),
1703 cwd: []const u8,
1704 environ_map: ?*const std.process.Environ.Map,
1705 from: []const u8,
1706 to: []const u8,
1707) Allocator.Error!void {
1708 _ = gpa;
1709 _ = al;
1710 _ = cwd;
1711 _ = environ_map;
1712 _ = from;
1713 _ = to;
1714 @panic("TODO");
1715}
1716
1666fn windowsResolveAgainstCwd(1717fn windowsResolveAgainstCwd(
1667 gpa: Allocator,1718 gpa: Allocator,
1668 cwd: []const u8,1719 cwd: []const u8,
...@@ -1728,36 +1779,66 @@ fn windowsResolveAgainstCwd(...@@ -1728,36 +1779,66 @@ fn windowsResolveAgainstCwd(
1728 };1779 };
1729}1780}
17301781
1731/// Returns the non-absolute path from `from` to `to` according to Windows rules.1782/// Returns the non-absolute path from `from` to `to` according to POSIX rules.
1732///1783///
1733/// Other than memory allocation, this is a pure function; the result solely1784/// Other than memory allocation, this is a pure function; the result solely
1734/// depends on the input parameters.1785/// depends on the input parameters.
1735///1786///
1736/// If `from` and `to` each resolve to the same path (after calling `resolve`1787/// If `from` and `to` each resolve to the same path (after calling `resolve`
1737/// on each), a zero-length string is returned.1788/// on each), a zero-length string is returned.
1789pub fn relativeAllocPosix(gpa: Allocator, cwd: []const u8, from: []const u8, to: []const u8) Allocator.Error![]u8 {
1790 var buffer: std.ArrayList(u8) = .empty;
1791 defer buffer.deinit(gpa);
1792 try relativeAppendPosix(gpa, &buffer, cwd, from, to);
1793 try buffer.shrinkToLen(gpa);
1794 return buffer.toOwnedSliceAssert();
1795}
1796
1797/// Appends the non-absolute path from `from` to `to` according to POSIX rules
1798/// to the provided array list.
1799///
1800/// Other than modifying the provided array list, this is a pure function; the
1801/// result solely depends on the input parameters and it does no file system
1802/// operations.
1738///1803///
1739pub fn relativePosix(allocator: Allocator, cwd: []const u8, from: []const u8, to: []const u8) Allocator.Error![]u8 {1804/// If `from` and `to` each resolve to the same path (after calling
1740 const resolved_from = try resolveAllocPosix(allocator, &[_][]const u8{ cwd, from });1805/// `resolveAppend` on each), nothing is appended to the array list.
1741 defer allocator.free(resolved_from);1806pub fn relativeAppendPosix(
1742 const resolved_to = try resolveAllocPosix(allocator, &[_][]const u8{ cwd, to });1807 gpa: Allocator,
1743 defer allocator.free(resolved_to);1808 al: *std.ArrayList(u8),
17441809 cwd: []const u8,
1745 var from_it = mem.tokenizeScalar(u8, resolved_from, '/');1810 from: []const u8,
1746 var to_it = mem.tokenizeScalar(u8, resolved_to, '/');1811 to: []const u8,
1812) Allocator.Error!void {
1813 const orig_len = al.items.len;
1814 errdefer al.items.len = orig_len;
1815
1816 const resolved_from_start = al.items.len;
1817 try resolveAppendPosix(gpa, al, &.{ cwd, from });
1818 const resolved_from_end = al.items.len;
1819
1820 const resolved_to_start = al.items.len;
1821 try resolveAppendPosix(gpa, al, &.{ cwd, to });
1822 const resolved_to_end = al.items.len;
1823
1824 var from_it = mem.tokenizeScalar(u8, al.items[resolved_from_start..resolved_from_end], '/');
1825 var to_it = mem.tokenizeScalar(u8, al.items[resolved_to_start..resolved_to_end], '/');
1747 while (true) {1826 while (true) {
1748 const from_component = from_it.next() orelse return allocator.dupe(u8, to_it.rest());1827 const from_component = from_it.next() orelse {
1828 const result = to_it.rest();
1829 @memmove(al.items[orig_len..][0..result.len], result);
1830 al.shrinkRetainingCapacity(orig_len + result.len);
1831 return;
1832 };
1749 const to_rest = to_it.rest();1833 const to_rest = to_it.rest();
1750 if (to_it.next()) |to_component| {1834 if (to_it.next()) |to_component| {
1751 if (mem.eql(u8, from_component, to_component))1835 if (mem.eql(u8, from_component, to_component))
1752 continue;1836 continue;
1753 }1837 }
1754 var up_count: usize = 1;1838 var up_count: usize = 1;
1755 while (from_it.next()) |_| {1839 while (from_it.next()) |_| up_count += 1;
1756 up_count += 1;
1757 }
1758 const up_index_end = up_count * "../".len;1840 const up_index_end = up_count * "../".len;
1759 const result = try allocator.alloc(u8, up_index_end + to_rest.len);1841 const result = al.items[orig_len..];
1760 errdefer allocator.free(result);
17611842
1762 var result_index: usize = 0;1843 var result_index: usize = 0;
1763 while (result_index < up_index_end) {1844 while (result_index < up_index_end) {
...@@ -1765,15 +1846,16 @@ pub fn relativePosix(allocator: Allocator, cwd: []const u8, from: []const u8, to...@@ -1765,15 +1846,16 @@ pub fn relativePosix(allocator: Allocator, cwd: []const u8, from: []const u8, to
1765 result_index += 3;1846 result_index += 3;
1766 }1847 }
1767 if (to_rest.len == 0) {1848 if (to_rest.len == 0) {
1768 // shave off the trailing slash1849 // Shave off the trailing slash.
1769 return allocator.realloc(result, result_index - 1);1850 al.shrinkRetainingCapacity(orig_len + result_index - 1);
1851 return;
1770 }1852 }
17711853 @memmove(result[result_index..][0..to_rest.len], to_rest);
1772 @memcpy(result[result_index..][0..to_rest.len], to_rest);1854 al.shrinkRetainingCapacity(orig_len + result_index + to_rest.len);
1773 return result;1855 return;
1774 }1856 }
17751857
1776 return [_]u8{};1858 al.shrinkRetainingCapacity(orig_len);
1777}1859}
17781860
1779test relative {1861test relative {