#pragma once #include "core_basic.h" #include "core_arena.h" typedef struct s8_t s8_t; struct s8_t { char *str; int64_t len; }; typedef struct sb8_node_t sb8_node_t; struct sb8_node_t { sb8_node_t *next; union { struct { char *str; int64_t len; }; s8_t string; }; }; typedef struct sb8_t sb8_t; struct sb8_t { ma_arena_t *arena; sb8_node_t *first; sb8_node_t *last; // WARNING: remember to update typeinfo after editing this i32 indent; }; typedef i32 s8_seek_t; enum { s8_seek_none = 0, s8_seek_ignore_case = 1, s8_seek_match_find_last = 2, }; typedef i32 s8_split_t; enum { s8_split_none = 0, s8_split_ignore_case = 1, s8_split_inclusive = 2, s8_split_cleanup = 4, }; enum { s8_ignore_case = 1 }; // // char and char string operations fn i32 str_len(char *str); fn b32 str_eq(char *a, char *b); fn char char_to_lower_case(char a); fn char char_to_upper_case(char a); fn b32 char_is_whitespace(char w); fn b32 char_is_alphabetic(char a); fn b32 char_is_ident(char a); fn b32 char_is_digit(char a); fn b32 char_is_alphanumeric(char a); fn u64 u64_from_hexchar(char c); fn u64 u64_from_s8(s8_t s, u64 base); fn f64 f64_from_s8(s8_t string); // // string8 constructors #define s8_make(str,len) (s8_t){str, len} #define s8_null (s8_t){0} #define s8_invalid s8("") #define s8(string) (s8_t){(char *)string, sizeof(string) - 1} #define s8_const(string) { string, sizeof(string) - 1 } #define s8_struct(DATA) (s8_t){.str = (char *)&(DATA), .len = sizeof(DATA)} #define s8_array(DATA) (s8_t){.str = (char *)(DATA), .len = lengthof(DATA)} #define s8_array_lit(DATA) {.str = (char *)(DATA), .len = lengthof(DATA)} fn s8_t s8_from_range(char *begin, char *end); fn s8_t s8_from_char(char *string); fn s8_t s8_copy(ma_arena_t *ma, s8_t string); // // conditional fn b32 s8_are_equal_ex(s8_t a, s8_t b, b32 ignore_case); fn b32 s8_are_equal(s8_t a, s8_t b); fn b32 s8_ends_with_ex(s8_t a, s8_t end, b32 ignore_case); fn b32 s8_starts_with_ex(s8_t a, s8_t start, b32 ignore_case); fn b32 s8_ends_with(s8_t a, s8_t end); fn b32 s8_starts_with(s8_t a, s8_t start); fn b32 s8_is_pointer_inside(s8_t string, char *p);// @todo: maybe more general? // // search fn b32 s8_seek(s8_t string, s8_t find, s8_seek_t flags, int64_t *index_out); fn int64_t s8_find(s8_t string, s8_t find, s8_seek_t flag); fn sb8_t s8_split(ma_arena_t *ma, s8_t string, s8_t find, s8_split_t flags); // // string view transforms fn s8_t s8_slice(s8_t string, int64_t first_index, int64_t one_past_last_index); fn s8_t s8_get_postfix(s8_t string, int64_t len); fn s8_t s8_get_prefix(s8_t string, int64_t len); fn s8_t s8_chop(s8_t string, int64_t len); fn s8_t s8_skip(s8_t string, int64_t len); fn s8_t s8_chop_last_slash(s8_t s); fn s8_t s8_chop_last_period(s8_t s); fn s8_t s8_skip_to_last_slash(s8_t s); fn s8_t s8_skip_to_last_period(s8_t s); fn s8_t s8_get_name_no_ext(s8_t s); fn s8_t s8_trim(s8_t string); fn s8_t s8_trim_end(s8_t string); fn s8_t s8_cut_start(s8_t *in, i64 size); fn s8_t s8_cut_end(s8_t *in, i64 size); // // formatting fn void s8_normalize_path_unsafe(s8_t s); fn s8_t s8_normalize_path(ma_arena_t *ma, s8_t s); fn s8_t s8_to_lower_case(ma_arena_t *ma, s8_t s); fn s8_t s8_to_upper_case(ma_arena_t *ma, s8_t s); fn s8_t s8_vfmt(ma_arena_t *ma, const char *str, va_list args1); fn s8_t s8_printf(ma_arena_t *ma, const char *str, ...); // // string builder #define sb8(ARENA) &(sb8_t){.arena = arena} #define sb8_serial_begin(ARENA) &(sb8_t){.arena = ARENA} #define sb8_serial_end(ARENA, SB) sb8_merge(ARENA, SB) fn s8_t sb8_printf(sb8_t *sb, const char *str, ...); fn sb8_node_t *sb8_append(sb8_t *list, s8_t string); fn sb8_node_t *sb8_create_node(ma_arena_t *ma, s8_t str); fn s8_t sb8_merge(ma_arena_t *arena, sb8_t *sb); fn void sb8_indent(sb8_t *sb); fn s8_t sb8_stmtf(sb8_t *sb, const char *str, ...); fn int64_t sb8_char_size(sb8_t *sb); #if 0 sb8_t *sbin_write_begin(ma_arena_t *arena); s8_t sbin_write_end(sb8_t *sb); void *sbin_write_data(sb8_t *sb, void *p, i64 size); void *sbin_write_size(sb8_t *sb, i64 size); void *sbin_write_u64(sb8_t *sb, u64 value); void *sbin_write_u32(sb8_t *sb, u32 value); void *sbin_write_u16(sb8_t *sb, u16 value); void *sbin_write_u8(sb8_t *sb, u8 value); s8_t *sbin_write_s8(sb8_t *sb, s8_t string); char *sbin_write_str(sb8_t *sb, char *string); stream_t sbin_read_begin(void *p, i64 size); void sbin_read_end(stream_t *stream); void *sbin_read_data(stream_t *stream, i64 size); #endif // // other #define s8_fmtspec(string) (int)(string).len, (string).str #define S8_CODE(...) s8(#__VA_ARGS__) #define S8_FILE s8(__FILE__) #define S8_FILE_AND_LINE s8(FILE_AND_LINE) #define S8_FMT(ma, str, result) \ va_list args1; \ va_start(args1, str); \ s8_t result = s8_vfmt(ma, str, args1); \ va_end(args1) #define STR_FMT(buff, str) \ va_list args1; \ va_start(args1, str); \ i32 len = stbsp_vsnprintf(buff, sizeof(buff), str, args1); \ va_end(args1) typedef struct fuzzy_pair_t fuzzy_pair_t; struct fuzzy_pair_t { i64 index; i64 rating; };