dup.ha (1514B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use types; 5 6 // Duplicates a string. Aborts on allocation failure. 7 export fn dup(s: const str) str = { 8 const in = &s: *types::string; 9 const id = match (in.data) { 10 case null => 11 return ""; // Empty string 12 case let b: *[*]u8 => 13 yield b; 14 }; 15 let buf: []u8 = alloc(id[..in.length], in.length); 16 let out = types::string { 17 data = buf: *[*]u8, 18 length = in.length, 19 capacity = in.length, 20 }; 21 return *(&out: *str); 22 }; 23 24 // Creates a copy of a []str slice with all the strings duplicated. The result 25 // must be freed using [[freeall]]. 26 export fn dupall(strs: []str) []str = { 27 let newsl: []str = alloc([], len(strs)); 28 for (let s .. strs) { 29 static append(newsl, dup(s)); 30 }; 31 return newsl; 32 }; 33 34 // Frees all the strings in a slice and the slice itself. Inverse of [[dupall]]. 35 export fn freeall(s: []str) void = { 36 for (let i = 0z; i < len(s); i += 1) { 37 free(s[i]); 38 }; 39 free(s); 40 }; 41 42 @test fn dup() void = { 43 let s = dup(""); 44 defer free(s); 45 assert(s == ""); 46 47 let s = dup("hello"); 48 defer free(s); 49 assert(s == "hello"); 50 }; 51 52 @test fn dupall() void = { 53 const payload: []str = []; 54 55 let s = dupall(payload); 56 defer freeall(s); 57 assert(len(s) == len(payload)); 58 for (let i = 0z; i < len(s); i += 1) { 59 assert(s[i] == payload[i]); 60 }; 61 62 const payload: []str = ["a", "aaa"]; 63 64 let s = dupall(payload); 65 defer freeall(s); 66 assert(len(s) == len(payload)); 67 for (let i = 0z; i < len(s); i += 1) { 68 assert(s[i] == payload[i]); 69 }; 70 };