mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 15:13:08 +00:00
Skip empty strings in std.fs.path.join function
This commit is contained in:
parent
a8e8927c49
commit
eb010ce65d
@ -43,17 +43,32 @@ pub fn isSep(byte: u8) bool {
|
||||
fn joinSepMaybeZ(allocator: *Allocator, separator: u8, sepPredicate: fn (u8) bool, paths: []const []const u8, zero: bool) ![]u8 {
|
||||
if (paths.len == 0) return if (zero) try allocator.dupe(u8, &[1]u8{0}) else &[0]u8{};
|
||||
|
||||
// Find first non-empty path index.
|
||||
const first_path_index = blk: {
|
||||
for (paths) |path, index| {
|
||||
if (path.len == 0) continue else break :blk index;
|
||||
}
|
||||
|
||||
// All paths provided were empty, so return early.
|
||||
return if (zero) try allocator.dupe(u8, &[1]u8{0}) else &[0]u8{};
|
||||
};
|
||||
|
||||
// Calculate length needed for resulting joined path buffer.
|
||||
const total_len = blk: {
|
||||
var sum: usize = paths[0].len;
|
||||
var i: usize = 1;
|
||||
var sum: usize = paths[first_path_index].len;
|
||||
var prev_path = paths[first_path_index];
|
||||
assert(prev_path.len > 0);
|
||||
var i: usize = first_path_index + 1;
|
||||
while (i < paths.len) : (i += 1) {
|
||||
const prev_path = paths[i - 1];
|
||||
const this_path = paths[i];
|
||||
const prev_sep = (prev_path.len != 0 and sepPredicate(prev_path[prev_path.len - 1]));
|
||||
const this_sep = (this_path.len != 0 and sepPredicate(this_path[0]));
|
||||
if (this_path.len == 0) continue;
|
||||
const prev_sep = sepPredicate(prev_path[prev_path.len - 1]);
|
||||
const this_sep = sepPredicate(this_path[0]);
|
||||
sum += @boolToInt(!prev_sep and !this_sep);
|
||||
sum += if (prev_sep and this_sep) this_path.len - 1 else this_path.len;
|
||||
prev_path = this_path;
|
||||
}
|
||||
|
||||
if (zero) sum += 1;
|
||||
break :blk sum;
|
||||
};
|
||||
@ -61,14 +76,16 @@ fn joinSepMaybeZ(allocator: *Allocator, separator: u8, sepPredicate: fn (u8) boo
|
||||
const buf = try allocator.alloc(u8, total_len);
|
||||
errdefer allocator.free(buf);
|
||||
|
||||
mem.copy(u8, buf, paths[0]);
|
||||
var buf_index: usize = paths[0].len;
|
||||
var i: usize = 1;
|
||||
mem.copy(u8, buf, paths[first_path_index]);
|
||||
var buf_index: usize = paths[first_path_index].len;
|
||||
var prev_path = paths[first_path_index];
|
||||
assert(prev_path.len > 0);
|
||||
var i: usize = first_path_index + 1;
|
||||
while (i < paths.len) : (i += 1) {
|
||||
const prev_path = paths[i - 1];
|
||||
const this_path = paths[i];
|
||||
const prev_sep = (prev_path.len != 0 and sepPredicate(prev_path[prev_path.len - 1]));
|
||||
const this_sep = (this_path.len != 0 and sepPredicate(this_path[0]));
|
||||
if (this_path.len == 0) continue;
|
||||
const prev_sep = sepPredicate(prev_path[prev_path.len - 1]);
|
||||
const this_sep = sepPredicate(this_path[0]);
|
||||
if (!prev_sep and !this_sep) {
|
||||
buf[buf_index] = separator;
|
||||
buf_index += 1;
|
||||
@ -76,6 +93,7 @@ fn joinSepMaybeZ(allocator: *Allocator, separator: u8, sepPredicate: fn (u8) boo
|
||||
const adjusted_path = if (prev_sep and this_sep) this_path[1..] else this_path;
|
||||
mem.copy(u8, buf[buf_index..], adjusted_path);
|
||||
buf_index += adjusted_path.len;
|
||||
prev_path = this_path;
|
||||
}
|
||||
|
||||
if (zero) buf[buf.len - 1] = 0;
|
||||
@ -148,6 +166,10 @@ test "join" {
|
||||
try testJoinMaybeZWindows(&[_][]const u8{ "c:\\", "a", "b/", "c" }, "c:\\a\\b/c", zero);
|
||||
try testJoinMaybeZWindows(&[_][]const u8{ "c:\\a/", "b\\", "/c" }, "c:\\a/b\\c", zero);
|
||||
|
||||
try testJoinMaybeZWindows(&[_][]const u8{ "", "c:\\", "", "", "a", "b\\", "c", "" }, "c:\\a\\b\\c", zero);
|
||||
try testJoinMaybeZWindows(&[_][]const u8{ "c:\\a/", "", "b\\", "", "/c" }, "c:\\a/b\\c", zero);
|
||||
try testJoinMaybeZWindows(&[_][]const u8{ "", "" }, "", zero);
|
||||
|
||||
try testJoinMaybeZPosix(&[_][]const u8{}, "", zero);
|
||||
try testJoinMaybeZPosix(&[_][]const u8{ "/a/b", "c" }, "/a/b/c", zero);
|
||||
try testJoinMaybeZPosix(&[_][]const u8{ "/a/b/", "c" }, "/a/b/c", zero);
|
||||
@ -163,6 +185,10 @@ test "join" {
|
||||
|
||||
try testJoinMaybeZPosix(&[_][]const u8{ "a", "/c" }, "a/c", zero);
|
||||
try testJoinMaybeZPosix(&[_][]const u8{ "a/", "/c" }, "a/c", zero);
|
||||
|
||||
try testJoinMaybeZPosix(&[_][]const u8{ "", "/", "a", "", "b/", "c", "" }, "/a/b/c", zero);
|
||||
try testJoinMaybeZPosix(&[_][]const u8{ "/a/", "", "", "b/", "c" }, "/a/b/c", zero);
|
||||
try testJoinMaybeZPosix(&[_][]const u8{ "", "" }, "", zero);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user