diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2025-05-14 21:12:58 +0100 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2025-05-15 22:25:45 +0100 |
commit | 12de1e8db90bccd5a0eefd21075f07c7b7e3dfaa (patch) | |
tree | 0434141f2bfd24207a2864f613a1c2e3ee7181fc /lib/sv.c | |
parent | ba5c0a4579ece5d53c009a14d00e683e70b982f4 (diff) | |
download | oats-12de1e8db90bccd5a0eefd21075f07c7b7e3dfaa.tar.gz oats-12de1e8db90bccd5a0eefd21075f07c7b7e3dfaa.tar.bz2 oats-12de1e8db90bccd5a0eefd21075f07c7b7e3dfaa.zip |
Refactor for cleanliness
Move files into separate folders for ease of reading, include source
directory so we can use angle bracket includes, adjust build system to
make directories for objects
Diffstat (limited to 'lib/sv.c')
-rw-r--r-- | lib/sv.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/lib/sv.c b/lib/sv.c new file mode 100644 index 0000000..b2425b8 --- /dev/null +++ b/lib/sv.c @@ -0,0 +1,158 @@ +/* Copyright (C) 2025 Aryadev Chavali + + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License Version 2 for + * details. + + * You may distribute and modify this code under the terms of the GNU General + * Public License Version 2, which you should have received a copy of along with + * this program. If not, please go to <https://www.gnu.org/licenses/>. + + * Created: 2025-04-14 + * Description: String View implementation + */ + +#include <lib/sv.h> + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +sv_t sv_make(arena_t *allocator, const char *data, u64 size) +{ + sv_t s = {0}; + if (data) + s = sv_append(allocator, s, data, size); + else + { + s.data = arena_alloc(allocator, size); + s.size = size; + } + return s; +} + +sv_t sv_copy(arena_t *allocator, sv_t sv) +{ + return sv_make(allocator, sv.data, sv.size); +} + +sv_t sv_substr(sv_t sv, u64 index, u64 size) +{ + sv_t newsv = {0}; + if (index + size > sv.size) + return newsv; + newsv.data = sv.data + index; + newsv.size = size; + return newsv; +} + +sv_t sv_cut(sv_t sv, u64 index) +{ + return sv_substr(sv, index, sv.size < index ? 0 : sv.size - index); +} + +sv_t sv_chop(sv_t sv, u64 size) +{ + return sv_substr(sv, 0, size); +} + +sv_t sv_concat(arena_t *allocator, sv_t a, sv_t b) +{ + sv_t c = sv_make(allocator, a.data, a.size + b.size); + memcpy(c.data + a.size, b.data, b.size); + return c; +} + +sv_t sv_append(arena_t *allocator, sv_t sv, const char *data, u64 size) +{ + if (!allocator) + return (sv_t){0}; + + sv_t newsv = {0}; + newsv.size = sv.size + size; + newsv.data = arena_realloc(allocator, sv.data, sv.size, newsv.size); + if (data) + memcpy(newsv.data + sv.size, data, size); + return newsv; +} + +sv_t sv_prepend(arena_t *allocator, sv_t sv, const char *data, u64 size) +{ + if (!allocator) + return (sv_t){0}; + + // TODO: Can we make this cheaper to do? + sv_t newsv = sv_make(allocator, NULL, size + sv.size); + // Copy over `data` to the left side + memcpy(newsv.data, data, size); + // Copy old string to the right side + if (sv.data) + memcpy(newsv.data + size, sv.data, sv.size); + + return newsv; +} + +sv_t sv_fmt(arena_t *allocator, char *fmt, ...) +{ + if (!allocator) + return (sv_t){0}; + + va_list ap_1, ap_2; + va_start(ap_1, fmt); + + va_copy(ap_2, ap_1); + u64 size = vsnprintf(NULL, 0, fmt, ap_2); + va_end(ap_2); + + sv_t sv = sv_make(allocator, NULL, size); + vsprintf(sv.data, fmt, ap_1); + va_end(ap_1); + + return sv; +} + +i64 sv_find_substr(const sv_t sv, const sv_t substr) +{ + if (substr.size == 0) + return 0; + else if (sv.size < substr.size) + return -1; + else if (sv.size == substr.size) + return strncmp(sv.data, substr.data, sv.size) == 0 ? 0 : -1; + + for (u64 i = 0; i < (sv.size - substr.size); ++i) + if (strncmp(sv.data + i, substr.data, substr.size) == 0) + return i; + return -1; +} + +i64 sv_find_subcstr(const sv_t sv, const char *substr, u64 size) +{ + return sv_find_substr(sv, SV((char *)substr, size)); +} + +i64 sv_find_any(const sv_t sv, const char *bag) +{ + for (u64 i = 0; i < sv.size; ++i) + if (strchr(bag, sv.data[i])) + return i; + return -1; +} + +u64 sv_while(const sv_t sv, bool (*pred)(char)) +{ + u64 i; + for (i = 0; i < sv.size && pred(sv.data[i]); ++i) + continue; + return i; +} + +u64 sv_till(const sv_t sv, bool (*pred)(char)) +{ + u64 i; + for (i = 0; i < sv.size && !pred(sv.data[i]); ++i) + continue; + return i; +} |