diff options
Diffstat (limited to 'str.c')
-rw-r--r-- | str.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/str.c b/str.c new file mode 100644 index 0000000..10d64e1 --- /dev/null +++ b/str.c @@ -0,0 +1,60 @@ +#include <stdlib.h> +#include <string.h> +#include "str.h" +#include "err.h" + +/* strings */ + +void str_init(str_t *b, size_t n) { + b->buf = calloc(1, n); + if (!b->buf) { + efatal("str_init"); + } + b->cap = n; + b->sz = 0; +} + +/* does NOT change sz! just makes room */ +void str_grow(str_t *b, size_t n) { + size_t sz = b->sz + n; + size_t c = b->cap; + if (sz > c) { + while (sz > c) c <<= 1; + char *p = realloc(b->buf, c); + if (!p) efatal("str_grow"); + b->buf = p; + b->cap = c; + } +} + +void str_cat(str_t *b, strv_t s) { + str_grow(b, s.n); + memcpy(&b->buf[b->sz], s.s, s.n); + b->sz += s.n; +} + +void str_catc(str_t *b, char c) { + str_grow(b, 1); + b->buf[b->sz++] = c; +} + +void str_free(str_t *b) { + free(b->buf); +} + +/* string views */ + +strv_t strv(const char *s) { + return (strv_t) { s, strlen(s) }; +} + +int strv_split(strv_t *src, int chr, strv_t *dest) { + char *c = memchr(src->s, chr, src->n); + *dest = (strv_t) { + src->s, + c ? c - src->s : src->n + }; + src->s = c ? c + 1 : &src->s[src->n]; + src->n -= dest->n + !!c; + return dest->n > 0; +} |