authorgravatar for tssund93@gmail.comTravis <tssund93@gmail.com> 2020-11-10 17:15:08-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-11 11:15:34-08:00
logcc2981edfc4c0e36d3ce6d564f7a36caae9b61b7
treec64b16c3b3e139c08c3cd1ee39640b4e779ba6fb
parent1295525a7afe76d0ac384b3f74927ac22b27ec09

update path.join to recognize any separators that isSep does


1 files changed, 22 insertions(+), 17 deletions(-)

lib/std/fs/path.zig+22-17
......@@ -39,7 +39,7 @@ pub fn isSep(byte: u8) bool {
3939
4040/// This is different from mem.join in that the separator will not be repeated if
4141/// it is found at the end or beginning of a pair of consecutive paths.
42fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u8 {
42fn joinSep(allocator: *Allocator, separator: u8, sepPredicate: fn (u8) bool, paths: []const []const u8) ![]u8 {
4343 if (paths.len == 0) return &[0]u8{};
4444
4545 const total_len = blk: {
......@@ -48,8 +48,8 @@ fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u
4848 while (i < paths.len) : (i += 1) {
4949 const prev_path = paths[i - 1];
5050 const this_path = paths[i];
51 const prev_sep = (prev_path.len != 0 and prev_path[prev_path.len - 1] == separator);
52 const this_sep = (this_path.len != 0 and this_path[0] == separator);
51 const prev_sep = (prev_path.len != 0 and sepPredicate(prev_path[prev_path.len - 1]));
52 const this_sep = (this_path.len != 0 and sepPredicate(this_path[0]));
5353 sum += @boolToInt(!prev_sep and !this_sep);
5454 sum += if (prev_sep and this_sep) this_path.len - 1 else this_path.len;
5555 }
......@@ -65,8 +65,8 @@ fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u
6565 while (i < paths.len) : (i += 1) {
6666 const prev_path = paths[i - 1];
6767 const this_path = paths[i];
68 const prev_sep = (prev_path.len != 0 and prev_path[prev_path.len - 1] == separator);
69 const this_sep = (this_path.len != 0 and this_path[0] == separator);
68 const prev_sep = (prev_path.len != 0 and sepPredicate(prev_path[prev_path.len - 1]));
69 const this_sep = (this_path.len != 0 and sepPredicate(this_path[0]));
7070 if (!prev_sep and !this_sep) {
7171 buf[buf_index] = separator;
7272 buf_index += 1;
......@@ -80,28 +80,30 @@ fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u
8080 return buf;
8181}
8282
83pub const join = if (builtin.os.tag == .windows) joinWindows else joinPosix;
84
85/// Naively combines a series of paths with the native path seperator.
86/// Allocates memory for the result, which must be freed by the caller.
87pub fn joinWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
88 return joinSep(allocator, sep_windows, paths);
89}
90
9183/// Naively combines a series of paths with the native path seperator.
9284/// Allocates memory for the result, which must be freed by the caller.
93pub fn joinPosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
94 return joinSep(allocator, sep_posix, paths);
85pub fn join(allocator: *Allocator, paths: []const []const u8) ![]u8 {
86 return joinSep(allocator, sep, isSep, paths);
9587}
9688
9789fn testJoinWindows(paths: []const []const u8, expected: []const u8) void {
98 const actual = joinWindows(testing.allocator, paths) catch @panic("fail");
90 const windowsIsSep = struct {
91 fn isSep(byte: u8) bool {
92 return byte == '/' or byte == '\\';
93 }
94 }.isSep;
95 const actual = joinSep(testing.allocator, sep_windows, windowsIsSep, paths) catch @panic("fail");
9996 defer testing.allocator.free(actual);
10097 testing.expectEqualSlices(u8, expected, actual);
10198}
10299
103100fn testJoinPosix(paths: []const []const u8, expected: []const u8) void {
104 const actual = joinPosix(testing.allocator, paths) catch @panic("fail");
101 const posixIsSep = struct {
102 fn isSep(byte: u8) bool {
103 return byte == '/';
104 }
105 }.isSep;
106 const actual = joinSep(testing.allocator, sep_posix, posixIsSep, paths) catch @panic("fail");
105107 defer testing.allocator.free(actual);
106108 testing.expectEqualSlices(u8, expected, actual);
107109}
......@@ -119,6 +121,9 @@ test "join" {
119121 "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std\\io.zig",
120122 );
121123
124 testJoinWindows(&[_][]const u8{ "c:\\", "a", "b/", "c" }, "c:\\a\\b/c");
125 testJoinWindows(&[_][]const u8{ "c:\\a/", "b\\", "/c" }, "c:\\a/b\\c");
126
122127 testJoinPosix(&[_][]const u8{ "/a/b", "c" }, "/a/b/c");
123128 testJoinPosix(&[_][]const u8{ "/a/b/", "c" }, "/a/b/c");
124129