diff options
Diffstat (limited to 'str.h')
-rw-r--r-- | str.h | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/str.h b/str.h new file mode 100644 index 0000000..22a0d31 --- /dev/null +++ b/str.h @@ -0,0 +1,102 @@ +#ifndef STR_H +#define STR_H + +#include <string.h> +#include <stddef.h> + +#include "typ.h" +#include "arena.h" + +typedef struct { + char *s; + isize n; +} Str; + +#define S(s) (Str){s,sizeof(s)-1} + +/* allocating */ + +Str str_dup(Str a, Arena *m) { + char *s = new_arr(m, char, a.n); + memcpy(s, a.s, a.n); + a.s = s; + return a; +} + +static inline void str_cat(Str *a, Str b, Arena *m) { + a->s = resize(m, a->s, a->n, a->n + b.n); + memcpy(&a->s[a->n], b.s, b.n); + a->n += b.n; +} + +/* conversions */ + +static inline char *str_to_cstr(Str s, Arena *a) { + char *r = new_arr(a, char, s.n + 1); + memcpy(r, s.s, s.n); + r[s.n] = 0; + return r; +} + +static inline Str str_from_cstr(const char *s) { + return (Str) { (char*)s, strlen(s) }; +} + +/* pure functions */ + +static inline int str_eql(Str a, Str b) { + return a.n == b.n && !memcmp(a.s, b.s, b.n); +} + +static inline int str_starts(Str a, Str b) { + return a.n >= b.n && !memcmp(a.s, b.s, b.n); +} + +static inline int str_ends(Str a, Str b) { + return a.n >= b.n && !memcmp(&a.s[a.n - b.n], b.s, b.n); +} + +static inline void str_catc(Str *a, char b, Arena *m) { + a->s = resize(m, a->s, a->n, a->n + 1); + a->s[a->n++] = b; +} + +static inline Str str_skip(Str a, isize n) { + return (Str) { a.s + n, a.n - n }; +} + +static inline int is_space(char c) { + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} + +static inline Str str_trim_left(Str a) { + while (a.n > 0 && is_space(a.s[0])) a.s++, a.n--; + return a; +} + +static inline Str str_trim_right(Str a) { + while (a.n > 0 && is_space(a.s[a.n - 1])) a.n--; + return a; +} + +static inline Str str_trim(Str a) { + return str_trim_left(str_trim_right(a)); +} + +typedef struct { + Str head, tail; +} Cut; + +static inline Cut str_cut(Str s, char c) { + char *p = memchr(s.s, c, s.n); + if (!p) { + return (Cut) { s, { &s.s[s.n], 0 } }; + } else { + return (Cut) { + { s.s, p - s.s }, + { p + 1, &s.s[s.n] - (p + 1) } + }; + } +} + +#endif |