summaryrefslogtreecommitdiff
path: root/src/util/str.c
blob: 97945bc13d4e959e63b6bf89033ebf534a138659 (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
#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;
}