File: dup.ha

package info (click to toggle)
hare 0.26.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,352 kB
  • sloc: asm: 1,374; makefile: 123; sh: 117; lisp: 101
file content (73 lines) | stat: -rw-r--r-- 1,609 bytes parent folder | download
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]);
	};
};