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