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
|
#include "util/str.h"
static bool match_char(char c, str tokens)
{
for (size_t t = 0; t < tokens.len; t++)
if (c == tokens.ptr[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.ptr[i], tokens))
return i;
return s.len;
}
str str_walk(str *s, str sep)
{
if (s->len == 0)
return (str) {};
size_t x = str_find(*s, sep);
size_t o = x + (x < s->len);
*s = str_advance(*s, o);
return (str) { x, s->ptr - o };
}
str str_eat(str s, str tokens)
{
while (s.len > 0 && match_char(s.ptr[0], tokens))
s = str_advance(s, 1);
return s;
}
str str_advance(str s, size_t x)
{
s.len -= x;
s.ptr += x;
return s;
}
bool str_start(str s, str start)
{
if (s.len < start.len)
return false;
s.len = start.len;
return array_eq(s, start);
}
str str_intro(char *s)
{
return (str) { strlen(s), s };
}
#include <stdio.h>
#define PARSE_NUM(parse, ...) \
NULTERM(s, buf) \
char *end; \
auto v = parse(buf, &end); \
if (end != buf+s.len) \
return false; \
*x = v; \
return true;
bool str_parse_int(str s, long *x)
{
#define strtol_(start, endp) strtol(start, endp, 0)
PARSE_NUM(strtol_)
#undef strtol_
}
bool str_parse_double(str s, double *x)
{
PARSE_NUM(strtod)
}
bool str_split(str s, str sep, str *a, str *b)
{
size_t x = str_find(s, sep);
if (x == s.len)
return false;
*a = (str) { x, s.ptr };
*b = str_advance(s, x+1);
return true;
}
|