summaryrefslogtreecommitdiff
path: root/src/str.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/str.c')
-rw-r--r--src/str.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/str.c b/src/str.c
new file mode 100644
index 0000000..4f6d5c7
--- /dev/null
+++ b/src/str.c
@@ -0,0 +1,83 @@
+// SPDX-FileCopyrightText: 2024 Lizzy Fleckenstein <lizzy@vlhl.dev>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+#include <stdlib.h>
+#include <string.h>
+#include "str.h"
+
+int str_cmp(str s1, str s2)
+{
+ if (s1.len != s2.len)
+ return (int) s1.len - (int) s2.len;
+
+ return memcmp(s1.data, s2.data, s1.len);
+}
+
+static bool match_char(char c, str tokens)
+{
+ for (size_t t = 0; t < tokens.len; t++)
+ if (c == tokens.data[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.data[i], tokens))
+ return i;
+
+ return s.len;
+}
+
+str str_walk(str *s, str sep)
+{
+ if (s->len == 0)
+ return NILS;
+
+ size_t x = str_find(*s, sep);
+ size_t o = x + (x < s->len);
+
+ *s = str_advance(*s, o);
+
+ if (x == 0)
+ return str_walk(s, sep);
+ else
+ return (str) { x, s->data - o };
+}
+
+str str_eat(str s, str tokens)
+{
+ while (s.len > 0 && match_char(s.data[0], tokens))
+ s = str_advance(s, 1);
+ return s;
+}
+
+str str_advance(str s, size_t x)
+{
+ s.len -= x;
+ s.data += x;
+ return s;
+}
+
+bool str_start(str s, str start)
+{
+ if (s.len < start.len)
+ return false;
+ s.len = start.len;
+ return str_cmp(s, start) == 0;
+}
+
+str str_intro(char *c)
+{
+ return (str) { strlen(c), c };
+}
+
+str str_clone(str s)
+{
+ str c = { s.len, malloc(s.len) };
+ memcpy(c.data, s.data, s.len);
+ return c;
+}