hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };