Files
codebase/src/core/core_string.h
2025-11-18 08:40:36 +01:00

175 lines
5.2 KiB
C

#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("<INVALID>")
#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;
};