aboutsummaryrefslogtreecommitdiff
path: root/src/base/string/split.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/string/split.c')
-rw-r--r--src/base/string/split.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/base/string/split.c b/src/base/string/split.c
new file mode 100644
index 0000000..2aa68b4
--- /dev/null
+++ b/src/base/string/split.c
@@ -0,0 +1,39 @@
+#include "internal.h"
+
+// split will split the string by the given token.
+// returns a stretchy buffer of strings that result from the partition.
+// it is the caller's responsibility to clean the memory.
+string*
+str·split(string s, const byte* tok)
+{
+ string* fields = nil;
+ vlong start = 0;
+
+ vlong sL = str·len(s);
+ vlong tokL = strlen(tok);
+ if (sL == 0 || tokL == 0) return nil;
+
+ buffit(fields, 5);
+
+ for (vlong i = 0; i < sL - tokL; i++) {
+ if ((tokL == 1 && s[i] == tokL) || !memcmp(s + i, tok, tokL)) {
+ bufpush(fields, str·makelen(s + start, i - start));
+ if (fields[buflen(fields) - 1] == nil) goto cleanup;
+
+ start = i + tokL;
+ i += tokL - 1;
+ }
+ }
+
+ bufpush(fields, str·makelen(s + start, sL - start));
+
+ return fields;
+
+cleanup:
+ for (vlong i = 0; i < buflen(fields); i++) {
+ str·free(fields[i]);
+ }
+ buffree(fields);
+ return nil;
+}
+