From 0c347139b8188d500814b4176e5556721dd2bd51 Mon Sep 17 00:00:00 2001 From: Mosder Date: Fri, 21 Aug 2026 22:59:31 +0200 Subject: feat: implemented string slices --- src/string.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/string.c b/src/string.c index 02aa141..c26e3bd 100644 --- a/src/string.c +++ b/src/string.c @@ -1,113 +1,216 @@ #define MOS_FORCE_PREFIXES +#define _GNU_SOURCE #include "moslib/string.h" +#include +#include + +#include "moslib/ds/array.h" + MosStringSlice mos_ss_from_str(const char *str) { - return (MosStringSlice){0}; + return mos_ss_from_vars(str, strlen(str)); } MosStringSlice mos_ss_copy(MosStringSlice ss) { - return (MosStringSlice){0}; + return mos_ss_from_vars(ss.data, ss.len); } MosStringSlice mos_ss_from_arr(char *arr) { - return (MosStringSlice){0}; + return mos_ss_from_vars(arr, mos_arr_len(arr)); } MosStringSlice mos_ss_from_vars(const char *str, size_t len) { - return (MosStringSlice){0}; + return (MosStringSlice){.data = str, .len = len}; } void mos_ss_print(MosStringSlice ss) { + printf(MOS_SS_FMT, MOS_SS_ARGS(ss)); } int mos_ss_eq(MosStringSlice ss1, MosStringSlice ss2) { - return 0; + if (ss1.len != ss2.len) + return 0; + + return memcmp(ss1.data, ss2.data, ss1.len) == 0; } int mos_ss_eq_str(MosStringSlice ss, const char *str) { - return 0; + return mos_ss_eq(ss, mos_ss_from_str(str)); } MosStringSlice mos_ss_trim(MosStringSlice ss) { - return (MosStringSlice){0}; + return mos_ss_trim_right(mos_ss_trim_left(ss)); } MosStringSlice mos_ss_trim_left(MosStringSlice ss) { - return (MosStringSlice){0}; + size_t i = 0; + while (i < ss.len && isspace(ss.data[i])) { + i++; + } + + ss.data += i; + ss.len -= i; + return ss; } MosStringSlice mos_ss_trim_right(MosStringSlice ss) { - return (MosStringSlice){0}; + size_t i = ss.len; + while (i-- > 0 && isspace(ss.data[i])) + ; + + ss.len = i + 1; + return ss; } int mos_ss_starts_with(MosStringSlice ss, MosStringSlice prefix) { - return 0; + if (prefix.len > ss.len) + return 0; + + return memcmp(ss.data, prefix.data, prefix.len) == 0; } int mos_ss_ends_with(MosStringSlice ss, MosStringSlice suffix) { - return 0; + if (suffix.len > ss.len) + return 0; + + return memcmp(ss.data + ss.len - suffix.len, suffix.data, suffix.len) == 0; } int mos_ss_starts_with_str(MosStringSlice ss, const char *prefix) { - return 0; + return mos_ss_starts_with(ss, mos_ss_from_str(prefix)); } int mos_ss_ends_with_str(MosStringSlice ss, const char *suffix) { - return 0; + return mos_ss_ends_with(ss, mos_ss_from_str(suffix)); } size_t mos_ss_del_left(MosStringSlice *ss, size_t n) { - return 0; + if (n > ss->len) + n = ss->len; + + ss->data += n; + ss->len -= n; + return n; } size_t mos_ss_del_right(MosStringSlice *ss, size_t n) { - return 0; + if (n > ss->len) + n = ss->len; + + ss->len -= n; + return n; } int mos_ss_del_prefix(MosStringSlice *ss, MosStringSlice prefix) { - return 0; + if (!mos_ss_starts_with(*ss, prefix)) + return 0; + + mos_ss_del_left(ss, prefix.len); + return 1; } int mos_ss_del_suffix(MosStringSlice *ss, MosStringSlice suffix) { - return 0; + if (!mos_ss_ends_with(*ss, suffix)) + return 0; + + mos_ss_del_right(ss, suffix.len); + return 1; } int mos_ss_del_prefix_str(MosStringSlice *ss, char *prefix) { - return 0; + return mos_ss_del_prefix(ss, mos_ss_from_str(prefix)); } int mos_ss_del_suffix_str(MosStringSlice *ss, char *suffix) { - return 0; + return mos_ss_del_suffix(ss, mos_ss_from_str(suffix)); } MosStringSlice mos_ss_split(MosStringSlice *ss, char delim) { - return (MosStringSlice){0}; + size_t i = 0; + while (i < ss->len && ss->data[i] != delim) + i++; + + if (i >= ss->len) { + MosStringSlice res = mos_ss_copy(*ss); + ss->len = 0; + return res; + } + + MosStringSlice res = mos_ss_from_vars(ss->data, i); + ss->data += i + 1; + ss->len -= i + 1; + return res; } MosStringSlice mos_ss_split_str(MosStringSlice *ss, const char *delim) { - return (MosStringSlice){0}; + return mos_ss_split_ss(ss, mos_ss_from_str(delim)); } MosStringSlice mos_ss_split_ss(MosStringSlice *ss, MosStringSlice delim) { - return (MosStringSlice){0}; + if (delim.len == 0) + return MOS_SS_LIT(""); + + const char *found = memmem(ss->data, ss->len, delim.data, delim.len); + if (!found) { + MosStringSlice res = mos_ss_copy(*ss); + ss->len = 0; + return res; + } + + size_t i = found - ss->data; + MosStringSlice res = mos_ss_from_vars(ss->data, i); + ss->data += i + delim.len; + ss->len -= i + delim.len; + return res; } MosStringSlice mos_ss_split_left(MosStringSlice *ss, size_t n) { - return (MosStringSlice){0}; + if (n > ss->len) + n = ss->len; + + MosStringSlice left = mos_ss_from_vars(ss->data, n); + ss->data += n; + ss->len -= n; + return left; } MosStringSlice mos_ss_split_right(MosStringSlice *ss, size_t n) { - return (MosStringSlice){0}; + if (n > ss->len) + n = ss->len; + + MosStringSlice right = mos_ss_from_vars(ss->data + ss->len - n, n); + ss->len -= n; + return right; } MosStringSlice mos_ss_find(MosStringSlice ss, MosStringSlice target) { - return (MosStringSlice){0}; + if (target.len == 0) + return ss; + + const char *found = memmem(ss.data, ss.len, target.data, target.len); + if (!found) + return MOS_SS_LIT(""); + + return mos_ss_from_vars(found, ss.len - (found - ss.data)); } MosStringSlice mos_ss_find_str(MosStringSlice ss, const char *target) { - return (MosStringSlice){0}; + return mos_ss_find(ss, mos_ss_from_str(target)); } size_t mos_ss_utf8_len(MosStringSlice ss) { - return 0; + size_t utf8_len = ss.len; + for (size_t i = 0; i < ss.len; i++) { + char c = ss.data[i]; + if ((c & 0xC0) != 0xC0) + continue; + + if ((c & 0xE0) == 0xC0) + utf8_len -= 1; + else if ((c & 0xF0) == 0xE0) + utf8_len -= 2; + else if ((c & 0xF8) == 0xF0) + utf8_len -= 3; + } + return utf8_len; } -- cgit v1.2.3