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