authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-28 23:22:56-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2017-05-28 23:22:56-04:00
log16f16b9c17383a9a075ba3067d6b0ef8c8c0df11
tree2094816b8d3aa507938acf5af20e0d34fc3b0f2f
parent2dfb1ebee2bc215271e5416b723d746af319621b
parent8d6ecfeffec6156c065b1881e2a74a2774d63592

Merge pull request #380 from AndreaOrru/master

Generalize join for use outside std/os/path

2 files changed, 41 insertions(+), 29 deletions(-)

std/mem.zig+40-1
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const assert = @import("debug.zig").assert;1const debug = @import("debug.zig");
2const assert = debug.assert;
2const math = @import("math.zig");3const math = @import("math.zig");
3const os = @import("os/index.zig");4const os = @import("os/index.zig");
4const io = @import("io.zig");5const io = @import("io.zig");
...@@ -285,6 +286,44 @@ const SplitIterator = struct {...@@ -285,6 +286,44 @@ const SplitIterator = struct {
285 }286 }
286};287};
287288
289/// Naively combines a series of strings with a separator.
290/// Allocates memory for the result, which must be freed by the caller.
291pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 {
292 comptime assert(strings.len >= 1);
293 var total_strings_len: usize = strings.len; // 1 sep per string
294 {
295 comptime var string_i = 0;
296 inline while (string_i < strings.len) : (string_i += 1) {
297 const arg = ([]const u8)(strings[string_i]);
298 total_strings_len += arg.len;
299 }
300 }
301
302 const buf = %return allocator.alloc(u8, total_strings_len);
303 %defer allocator.free(buf);
304
305 var buf_index: usize = 0;
306 comptime var string_i = 0;
307 inline while (true) {
308 const arg = ([]const u8)(strings[string_i]);
309 string_i += 1;
310 copy(u8, buf[buf_index..], arg);
311 buf_index += arg.len;
312 if (string_i >= strings.len) break;
313 if (buf[buf_index - 1] != sep) {
314 buf[buf_index] = sep;
315 buf_index += 1;
316 }
317 }
318
319 return buf[0..buf_index];
320}
321
322test "mem.join" {
323 assert(eql(u8, %%join(&debug.global_allocator, ',', "a", "b", "c"), "a,b,c"));
324 assert(eql(u8, %%join(&debug.global_allocator, ',', "a"), "a"));
325}
326
288test "testStringEquality" {327test "testStringEquality" {
289 assert(eql(u8, "abcd", "abcd"));328 assert(eql(u8, "abcd", "abcd"));
290 assert(!eql(u8, "abcdef", "abZdef"));329 assert(!eql(u8, "abcdef", "abZdef"));
std/os/path.zig+1-28
...@@ -21,34 +21,7 @@ pub const delimiter = switch (builtin.os) {...@@ -21,34 +21,7 @@ pub const delimiter = switch (builtin.os) {
21/// Naively combines a series of paths with the native path seperator.21/// Naively combines a series of paths with the native path seperator.
22/// Allocates memory for the result, which must be freed by the caller.22/// Allocates memory for the result, which must be freed by the caller.
23pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 {23pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 {
24 comptime assert(paths.len >= 2);24 mem.join(allocator, sep, paths)
25 var total_paths_len: usize = paths.len; // 1 slash per path
26 {
27 comptime var path_i = 0;
28 inline while (path_i < paths.len) : (path_i += 1) {
29 const arg = ([]const u8)(paths[path_i]);
30 total_paths_len += arg.len;
31 }
32 }
33
34 const buf = %return allocator.alloc(u8, total_paths_len);
35 %defer allocator.free(buf);
36
37 var buf_index: usize = 0;
38 comptime var path_i = 0;
39 inline while (true) {
40 const arg = ([]const u8)(paths[path_i]);
41 path_i += 1;
42 mem.copy(u8, buf[buf_index..], arg);
43 buf_index += arg.len;
44 if (path_i >= paths.len) break;
45 if (buf[buf_index - 1] != sep) {
46 buf[buf_index] = sep;
47 buf_index += 1;
48 }
49 }
50
51 return buf[0..buf_index];
52}25}
5326
54test "os.path.join" {27test "os.path.join" {