175 lines
5.2 KiB
C
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;
|
|
};
|