Generalize join.

This commit is contained in:
Andrea Orru 2017-05-28 15:54:53 +02:00
parent 2dfb1ebee2
commit 6a87aa4d2e
2 changed files with 41 additions and 29 deletions

View File

@ -1,4 +1,5 @@
const assert = @import("debug.zig").assert;
const debug = @import("debug.zig");
const assert = debug.assert;
const math = @import("math.zig");
const os = @import("os/index.zig");
const io = @import("io.zig");
@ -285,6 +286,44 @@ const SplitIterator = struct {
}
};
/// Naively combines a series of strings with a separator.
/// Allocates memory for the result, which must be freed by the caller.
pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 {
comptime assert(strings.len >= 1);
var total_strings_len: usize = strings.len; // 1 slash per string
{
comptime var string_i = 0;
inline while (string_i < strings.len) : (string_i += 1) {
const arg = ([]const u8)(strings[string_i]);
total_strings_len += arg.len;
}
}
const buf = %return allocator.alloc(u8, total_strings_len);
%defer allocator.free(buf);
var buf_index: usize = 0;
comptime var string_i = 0;
inline while (true) {
const arg = ([]const u8)(strings[string_i]);
string_i += 1;
copy(u8, buf[buf_index..], arg);
buf_index += arg.len;
if (string_i >= strings.len) break;
if (buf[buf_index - 1] != sep) {
buf[buf_index] = sep;
buf_index += 1;
}
}
return buf[0..buf_index];
}
test "mem.join" {
assert(eql(u8, %%join(&debug.global_allocator, ',', "a", "b", "c"), "a,b,c"));
assert(eql(u8, %%join(&debug.global_allocator, ',', "a"), "a"));
}
test "testStringEquality" {
assert(eql(u8, "abcd", "abcd"));
assert(!eql(u8, "abcdef", "abZdef"));

View File

@ -21,34 +21,7 @@ pub const delimiter = switch (builtin.os) {
/// Naively combines a series of paths with the native path seperator.
/// Allocates memory for the result, which must be freed by the caller.
pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 {
comptime assert(paths.len >= 2);
var total_paths_len: usize = paths.len; // 1 slash per path
{
comptime var path_i = 0;
inline while (path_i < paths.len) : (path_i += 1) {
const arg = ([]const u8)(paths[path_i]);
total_paths_len += arg.len;
}
}
const buf = %return allocator.alloc(u8, total_paths_len);
%defer allocator.free(buf);
var buf_index: usize = 0;
comptime var path_i = 0;
inline while (true) {
const arg = ([]const u8)(paths[path_i]);
path_i += 1;
mem.copy(u8, buf[buf_index..], arg);
buf_index += arg.len;
if (path_i >= paths.len) break;
if (buf[buf_index - 1] != sep) {
buf[buf_index] = sep;
buf_index += 1;
}
}
return buf[0..buf_index];
mem.join(allocator, sep, paths)
}
test "os.path.join" {