summaryrefslogtreecommitdiff
path: root/src/str.c
blob: e14591d6c46366ce47fc73873320daf9e51146fa (plain)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// SPDX-FileCopyrightText: 2024 Lizzy Fleckenstein <lizzy@vlhl.dev>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

#include <stdlib.h>
#include <string.h>
#include "str.h"

bool str_eq(str s1, str s2)
{
	if (s1.len != s2.len)
		return false;

	return memcmp(s1.data, s2.data, s1.len) == 0;
}


int str_cmp(str s1, str s2)
{
	size_t min_len = s1.len < s2.len ? s1.len : s2.len;
	int cmp = memcmp(s1.data, s2.data, min_len);

	if (cmp == 0)
		return (int) s1.len - (int) s2.len;
	else
		return cmp;
}

static bool match_char(char c, str tokens)
{
	for (size_t t = 0; t < tokens.len; t++)
		if (c == tokens.data[t])
			return true;

	return false;
}

size_t str_find(str s, str tokens)
{
	for (size_t i = 0; i < s.len; i++)
		if (match_char(s.data[i], tokens))
			return i;

	return s.len;
}

str str_walk(str *s, str sep)
{
	if (s->len == 0)
		return NILS;

	size_t x = str_find(*s, sep);
	size_t o = x + (x < s->len);

	*s = str_advance(*s, o);

	if (x == 0)
		return str_walk(s, sep);
	else
		return (str) { x, s->data - o };
}

str str_eat(str s, str tokens)
{
	while (s.len > 0 && match_char(s.data[0], tokens))
		s = str_advance(s, 1);
	return s;
}

str str_advance(str s, size_t x)
{
	s.len -= x;
	s.data += x;
	return s;
}

bool str_start(str s, str start)
{
	if (s.len < start.len)
		return false;
	s.len = start.len;
	return str_cmp(s, start) == 0;
}

str str_intro(char *c)
{
	return (str) { strlen(c), c };
}

str str_clone(str s)
{
	str c = { s.len, malloc(s.len) };
	memcpy(c.data, s.data, s.len);
	return c;
}