summary refs log tree commit diff
path: root/str.h
diff options
context:
space:
mode:
Diffstat (limited to 'str.h')
-rw-r--r--str.h102
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