summaryrefslogtreecommitdiff
path: root/stage3/string.c
blob: 2f95b99204f717b15e5996b99e54f9b7f6561f65 (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
#include "string.h"
#include "memory.h"
#include "heap.h"

isize str_cmp(str s1, str s2)
{
	if (s1.len != s2.len)
		return (isize) s1.len - (isize) s2.len;

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

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

	return false;
}

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

	return s.len;
}

usize str_parse_num(str s, u8 base, u64 *x)
{
	*x = 0;

	for (usize i = 0; i < s.len; i++) {
		u8 c = s.data[i];

		u64 d;
		if (c >= '0' && c <= '9')
			d = c - '0';
		else if (c >= 'a' && c <= 'z')
			d = c - 'a';
		else if (c >= 'A' && c <= 'z')
			d = c - 'A';
		else
			return i;

		if (d >= base)
			return i;

		*x = *x * base + d;
	}

    return s.len;
}

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

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

	s->len -= o;
	s->data += o;

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