diff options
Diffstat (limited to 'prb_string.h')
-rw-r--r-- | prb_string.h | 208 |
1 files changed, 182 insertions, 26 deletions
diff --git a/prb_string.h b/prb_string.h index 7df8246..344df11 100644 --- a/prb_string.h +++ b/prb_string.h @@ -1,40 +1,196 @@ -#ifndef PRB_STRING_H -#define PRB_STRING_H +void prb_memset(void *dest, i32 fill, u64 n) +{ + u8 *byte = dest; + while (n--) + *byte++ = fill; +} -/* NOTE(pryazha): I don't know wheter it's a good idea - * to keep regular and fixed-length strings together, but - * seems reasonable at the time. - */ +void prb_memmove(void *dest, const void *src, u64 size) +{ + u8 *byte_dest = dest; + const u8 *byte_src = src; + while (size--) + *byte_dest++ = *byte_src++; +} -/* NOTE(pryazha): Null-terminated strings */ +i32 prb_memeq(const void *p1, const void *p2, u64 size) +{ + const u8 *byte_p1 = p1; + const u8 *byte_p2 = p2; + while (size--) + if (*byte_p1++ != *byte_p2++) + return 0; + return 1; +} -void sys_vprintf(const char *fmt, va_list args); -void sys_printf(const char *fmt, ...); +i32 streq(const char *str1, const char *str2) +{ + if (!str1 || !str2) + return 0; + while (*str1++ == *str2++) + if (!*str1) + return 1; + return 0; +} -/* NOTE(pryazha): Fixed-length strings */ +// fixed length strings +#define str8lit(str) (str8_t){(u8 *)(str), sizeof(str) - 1} +#define str8exp(str) (i32)((str).len), ((str).ptr) -#define FLSLIT(s) fls((U8 *)(s), sizeof(s)-1) -#define FLSEXP(s) (int)((s).len), ((s).p) +#define MAX_FLS_BUFFER 1024 -FLS fls(U8 *p, U64 len); +typedef struct { + u8 *ptr; + u64 len; +} str8_t; -FLS flsfromcstr(const char *cstr); -char *flstocstr(Arena *a, FLS s); +typedef struct str8_node_t { + str8_t str; + struct str8_node_t *next; + struct str8_node_t *prev; +} str8_node_t; -FLS flsrange(U8 *start, U8 *end); -FLS flschopend(FLS s, U64 cnt); -FLS flschopstart(FLS s, U64 cnt); +typedef struct { + struct str8_node_t *first; + struct str8_node_t *last; + u64 len; + i32 cnt; +} str8_list_t; -FLS flspushfv(Arena *a, const char *fmt, va_list args); -FLS flspushf(Arena *a, const char *fmt, ...); +char *str8_to_cstr(arena_t *arena, str8_t str) +{ + u64 len = str.len + 1; + char *cstr = push_arena(arena, len); + prb_memmove(cstr, str.ptr, len); + cstr[str.len] = 0; + return cstr; +} -void flsprint(FLS s); +i32 str8eq(str8_t str1, str8_t str2) +{ + if (str1.len != str2.len) + return 0; + for (u64 i = 0; i < str1.len; ++i) + if (str1.ptr[i] != str2.ptr[i]) + return 0; + return 1; +} -FLSList *flslist(Arena *a); +u8 *str8ch(str8_t str, i32 c) +{ + for (u64 i = 0; i < str.len; ++i) + if (str.ptr[i] == c) + return str.ptr + i; + return 0; +} -void flslistpush(Arena *a, FLSList *l, FLS s, B32 front); -void flslistpushf(Arena *a, FLSList *l, B32 front, const char *fmt, ...); +u8 *str8rch(str8_t str, i32 c) +{ + for (u64 i = str.len - 1; i > 0; --i) + if (str.ptr[i] == c) + return str.ptr + i; + return 0; +} -void flslistprint(FLSList *l); +str8_t str8_range(u8 *start, u8 *end) +{ + assert(start); + assert(end); + assert(start < end); + str8_t result = {start, end - start}; + return result; +} -#endif /* PRB_STRING_H */ +str8_t str8_getdir(str8_t str) +{ + assert(str.len); + u8 *slash = str8rch(str, '/'); + if (!slash) + return str; + str8_t result = str8_range(str.ptr, slash); + return result; +} + +str8_t str8_pushfv(arena_t *arena, const char *format, va_list args) +{ + char tmp[MAX_FLS_BUFFER]; + i32 n = vsnprintf(tmp, MAX_FLS_BUFFER, format, args); + str8_t str = {0}; + if (n > 0) { + u8 *ptr = push_arena(arena, n); + prb_memmove(ptr, tmp, n); + str = (str8_t){ptr, n}; + str.ptr = ptr; + str.len = n; + } + return str; +} + +str8_t str8_pushf(arena_t *arena, const char *format, ...) +{ + va_list args; + va_start(args, format); + str8_t str = str8_pushfv(arena, format, args); + va_end(args); + return str; +} + +void str8_print(str8_t str) +{ + assert(str.ptr); + assert(str.len); + printf("%.*s", str8exp(str)); +} + +void str8_printf(const char *format, ...) +{ + + va_list args; + va_start(args, format); + arena_t temp = alloc_arena(MAX_FLS_BUFFER); + str8_t str = str8_pushfv(&temp, format, args); + va_end(args); + str8_print(str); + release_arena(&temp); +} + +void str8_list_push(arena_t *arena, str8_list_t *list, i32 front, str8_t str) +{ + str8_node_t *node = push_arena(arena, sizeof(str8_node_t)); + node->str = str; + if (front) + dllpushfront(list->first, list->last, node); + else + dllpushback(list->first, list->last, node); + list->len += str.len; + list->cnt++; +} + +void str8_list_pushf(arena_t *arena, str8_list_t *list, i32 front, const char *format, ...) +{ + va_list args; + va_start(args, format); + str8_t str = str8_pushfv(arena, format, args); + va_end(args); + str8_list_push(arena, list, front, str); +} + +/* TODO(pryazha): Check if that works :) */ +str8_t str8_list_join(arena_t *arena, str8_list_t *list) +{ + assert(arena); + assert(list); + str8_t str = {arena->memory + arena->used, 0}; + for (str8_node_t *node = list->first; node; node = node->next) { + u8 *ptr = push_arena(arena, node->str.len); + prb_memmove(ptr, node->str.ptr, node->str.len); + str.len += node->str.len; + } + return str; +} + +void str8_list_print(str8_list_t *list) +{ + for (str8_node_t *node = list->first; node; node = node->next) + str8_print(node->str); +} |