string16
This commit is contained in:
@@ -350,9 +350,9 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int n
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
s8_t dir = os_exe_dir(scratch.arena);
|
||||
for (os_iter_t *it = os_iter(scratch.arena, dir); it->is_valid; os_advance(it)) {
|
||||
b32 is_dll = s8_ends_with(it->name, s8_lit(".dll"), false);
|
||||
b32 is_pdb = s8_ends_with(it->name, s8_lit(".pdb"), false);
|
||||
b32 is_rdi = s8_ends_with(it->name, s8_lit(".rdi"), false);
|
||||
b32 is_dll = s8_ends_with(it->name, s8_lit(".dll"));
|
||||
b32 is_pdb = s8_ends_with(it->name, s8_lit(".pdb"));
|
||||
b32 is_rdi = s8_ends_with(it->name, s8_lit(".rdi"));
|
||||
b32 is_temp = s8_find(it->name, s8_lit("_temp_"), s8_seek_none) != -1;
|
||||
if (is_temp && (is_dll || is_pdb || is_rdi)) {
|
||||
b32 ok = os_delete(it->abs);
|
||||
|
||||
@@ -30,7 +30,7 @@ fn void os_error_box(char *str) {
|
||||
|
||||
fn void os_console_log(char *str) {
|
||||
s8_t string = s8_from_char(str);
|
||||
if (s8_ends_with(string, s8_lit("\n"), false)) {
|
||||
if (s8_ends_with(string, s8_lit("\n"))) {
|
||||
string = s8_chop(string, 1);
|
||||
}
|
||||
wasm_write_to_console((isize)string.str, (i32)string.len);
|
||||
|
||||
@@ -45,13 +45,6 @@ fn b32 char_is_alphanumeric(char a) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn i64 wstr_len(wchar_t *string) {
|
||||
i64 len = 0;
|
||||
while (*string++ != 0)
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
fn s8_t s8_from_range(char *begin, char *end) {
|
||||
assert(end >= begin);
|
||||
intptr_t size = (intptr_t)end - (intptr_t)begin;
|
||||
@@ -66,21 +59,6 @@ fn s8_t s8_from_char(char *string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_from_s8(ma_arena_t *ma, s8_t string) {
|
||||
u16 *buffer = ma_push_array(ma, u16, string.len + 1);
|
||||
i64 len = wstr_from_str(buffer, string.len + 1, string.str, string.len);
|
||||
assert(len <= string.len); // @todo: verify
|
||||
return (s16_t){buffer, len};
|
||||
}
|
||||
|
||||
fn s8_t s8_from_s16(ma_arena_t *ma, s16_t string) {
|
||||
i64 buffer_size = (string.len + 1) * 2;
|
||||
char *buffer = ma_push_array(ma, char, buffer_size);
|
||||
i64 len = str_from_wstr(buffer, buffer_size, string.str, string.len);
|
||||
assert(len < buffer_size);
|
||||
return (s8_t){buffer, len};
|
||||
}
|
||||
|
||||
fn s8_t s8_copy(ma_arena_t *ma, s8_t string) {
|
||||
char *copy = (char *)ma_push_size(ma, sizeof(char) * (string.len + 1));
|
||||
memory_copy(copy, string.str, string.len);
|
||||
@@ -89,7 +67,7 @@ fn s8_t s8_copy(ma_arena_t *ma, s8_t string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
s8_t s8_copy_char(ma_arena_t *ma, char *s) {
|
||||
fn s8_t s8_copy_char(ma_arena_t *ma, char *s) {
|
||||
int64_t len = str_len(s);
|
||||
char *copy = (char *)ma_push_size(ma, sizeof(char) * (len + 1));
|
||||
memory_copy(copy, s, len);
|
||||
@@ -143,18 +121,26 @@ fn s8_t s8_skip(s8_t string, int64_t len) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 s8_ends_with(s8_t a, s8_t end, b32 ignore_case) {
|
||||
fn b32 s8_ends_with_ex(s8_t a, s8_t end, b32 ignore_case) {
|
||||
s8_t a_end = s8_get_postfix(a, end.len);
|
||||
b32 result = s8_are_equal_ex(end, a_end, ignore_case);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 s8_starts_with(s8_t a, s8_t start, b32 ignore_case) {
|
||||
fn b32 s8_starts_with_ex(s8_t a, s8_t start, b32 ignore_case) {
|
||||
s8_t a_start = s8_get_prefix(a, start.len);
|
||||
b32 result = s8_are_equal_ex(start, a_start, ignore_case);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 s8_ends_with(s8_t a, s8_t end) {
|
||||
return s8_ends_with_ex(a, end, false);
|
||||
}
|
||||
|
||||
fn b32 s8_starts_with(s8_t a, s8_t start) {
|
||||
return s8_starts_with_ex(a, start, false);
|
||||
}
|
||||
|
||||
fn void s8_normalize_path_unsafe(s8_t s) {
|
||||
for (int64_t i = 0; i < s.len; i++) {
|
||||
if (s.str[i] == '\\')
|
||||
@@ -297,34 +283,35 @@ fn int64_t s8_find(s8_t string, s8_t find, s8_seek_t flag) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s8_t s8_chop_last_slash(s8_t s) {
|
||||
fn s8_t s8_chop_last_char(s8_t s, s8_t ch) {
|
||||
s8_t result = s;
|
||||
s8_seek(s, s8_lit("/"), s8_seek_match_find_last, &result.len);
|
||||
s8_seek(s, ch, s8_seek_match_find_last, &result.len);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s8_t s8_chop_last_slash(s8_t s) {
|
||||
return s8_chop_last_char(s, s8_lit("/"));
|
||||
}
|
||||
|
||||
fn s8_t s8_chop_last_period(s8_t s) {
|
||||
return s8_chop_last_char(s, s8_lit("."));
|
||||
}
|
||||
|
||||
fn s8_t s8_skip_to_last_char(s8_t s, s8_t ch) {
|
||||
int64_t pos;
|
||||
s8_t result = s;
|
||||
s8_seek(s, s8_lit("."), s8_seek_match_find_last, &result.len);
|
||||
if (s8_seek(s, ch, s8_seek_match_find_last, &pos)) {
|
||||
result = s8_skip(result, pos + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s8_t s8_skip_to_last_slash(s8_t s) {
|
||||
int64_t pos;
|
||||
s8_t result = s;
|
||||
if (s8_seek(s, s8_lit("/"), s8_seek_match_find_last, &pos)) {
|
||||
result = s8_skip(result, pos + 1);
|
||||
}
|
||||
return result;
|
||||
return s8_skip_to_last_char(s, s8_lit("/"));
|
||||
}
|
||||
|
||||
fn s8_t s8_skip_to_last_period(s8_t s) {
|
||||
int64_t pos;
|
||||
s8_t result = s;
|
||||
if (s8_seek(s, s8_lit("."), s8_seek_match_find_last, &pos)) {
|
||||
result = s8_skip(result, pos + 1);
|
||||
}
|
||||
return result;
|
||||
return s8_skip_to_last_char(s, s8_lit("."));
|
||||
}
|
||||
|
||||
fn s8_t s8_get_name_no_ext(s8_t s) {
|
||||
@@ -333,10 +320,7 @@ fn s8_t s8_get_name_no_ext(s8_t s) {
|
||||
|
||||
fn s8_t s8_normalize_path(ma_arena_t *ma, s8_t s) {
|
||||
s8_t copy = s8_copy(ma, s);
|
||||
for (int64_t i = 0; i < copy.len; i++) {
|
||||
if (copy.str[i] == '\\')
|
||||
copy.str[i] = '/';
|
||||
}
|
||||
s8_normalize_path_unsafe(copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -489,9 +473,9 @@ fn f64 f64_from_s8(s8_t string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
gb_read_only i64 fuzzy_closer_word_begin = 5;
|
||||
gb_read_only i64 fuzzy_consecutive_multiplier = 3;
|
||||
fn i64 fuzzy_rate_string(s8_t string, s8_t with) {
|
||||
gb_read_only i64 s8_fuzzy_closer_word_begin = 5;
|
||||
gb_read_only i64 s8_fuzzy_consecutive_multiplier = 3;
|
||||
fn i64 s8_fuzzy_rate_string(s8_t string, s8_t with) {
|
||||
if (with.len == 0) return 0;
|
||||
|
||||
i64 points = 0;
|
||||
@@ -499,26 +483,26 @@ fn i64 fuzzy_rate_string(s8_t string, s8_t with) {
|
||||
i64 with_i = 0;
|
||||
for (i64 i = 0; i < string.len; i++) {
|
||||
if (string.str[i] == with.str[with_i]) {
|
||||
i64 closer_begin = CLAMP_BOT((i64)0, fuzzy_closer_word_begin - i);
|
||||
i64 closer_begin = CLAMP_BOT((i64)0, s8_fuzzy_closer_word_begin - i);
|
||||
points += closer_begin;
|
||||
consecutive++;
|
||||
with_i += 1;
|
||||
} else {
|
||||
points += consecutive * fuzzy_consecutive_multiplier;
|
||||
points += consecutive * s8_fuzzy_consecutive_multiplier;
|
||||
consecutive = 0;
|
||||
with_i = 0;
|
||||
}
|
||||
|
||||
if (with_i >= with.len) with_i = 0;
|
||||
}
|
||||
points += consecutive * fuzzy_consecutive_multiplier;
|
||||
points += consecutive * s8_fuzzy_consecutive_multiplier;
|
||||
return points;
|
||||
}
|
||||
|
||||
fn fuzzy_pair_t *fuzzy_rate_array(ma_arena_t *arena, s8_t needle, s8_t *array, i32 len) {
|
||||
fn fuzzy_pair_t *s8_fuzzy_rate_array(ma_arena_t *arena, s8_t needle, s8_t *array, i32 len) {
|
||||
fuzzy_pair_t *pairs = ma_push_array(arena, fuzzy_pair_t, len);
|
||||
for (i32 i = 0; i < len; i += 1) {
|
||||
pairs[i].rating = fuzzy_rate_string(array[i], needle);
|
||||
pairs[i].rating = s8_fuzzy_rate_string(array[i], needle);
|
||||
pairs[i].index = i;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,18 +4,6 @@ struct s8_t {
|
||||
int64_t len;
|
||||
};
|
||||
|
||||
typedef struct s16_t s16_t;
|
||||
struct s16_t {
|
||||
u16 *str;
|
||||
i64 len;
|
||||
};
|
||||
|
||||
typedef struct s32_t s32_t;
|
||||
struct s32_t {
|
||||
u32 *str;
|
||||
i64 len;
|
||||
};
|
||||
|
||||
typedef struct sb8_node_t sb8_node_t;
|
||||
struct sb8_node_t {
|
||||
sb8_node_t *next;
|
||||
@@ -54,7 +42,6 @@ enum { s8_ignore_case = 1 };
|
||||
//
|
||||
// char and char string operations
|
||||
fn i32 str_len(char *str);
|
||||
fn i64 wstr_len(wchar_t *string);
|
||||
fn b32 str_eq(char *a, char *b);
|
||||
fn char char_to_lower_case(char a);
|
||||
fn char char_to_upper_case(char a);
|
||||
@@ -81,15 +68,15 @@ fn f64 f64_from_s8(s8_t string);
|
||||
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);
|
||||
fn s16_t s16_from_s8(ma_arena_t *ma, s8_t string);
|
||||
fn s8_t s8_from_s16(ma_arena_t *ma, s16_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(s8_t a, s8_t end, b32 ignore_case);
|
||||
fn b32 s8_starts_with(s8_t a, s8_t start, b32 ignore_case);
|
||||
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?
|
||||
|
||||
//
|
||||
@@ -162,7 +149,6 @@ void *sbin_read_data(stream_t *stream, i64 size);
|
||||
#define S8_CODE(...) s8_lit(#__VA_ARGS__)
|
||||
#define S8_FILE s8_lit(__FILE__)
|
||||
#define S8_FILE_AND_LINE s8_lit(FILE_AND_LINE)
|
||||
#define s16(str,len) (s16_t){str, len}
|
||||
|
||||
#define S8_FMT(ma, str, result) \
|
||||
va_list args1; \
|
||||
|
||||
@@ -0,0 +1,594 @@
|
||||
fn i64 wstr_len(wchar_t *string) {
|
||||
i64 len = 0;
|
||||
while (*string++ != 0)
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
fn u16 u16_to_lower_case(u16 a) {
|
||||
if (a >= 'A' && a <= 'Z') a += 32;
|
||||
return a;
|
||||
}
|
||||
|
||||
fn u16 u16_to_upper_case(u16 a) {
|
||||
if (a >= 'a' && a <= 'z') a -= 32;
|
||||
return a;
|
||||
}
|
||||
|
||||
fn b32 u16_is_whitespace(u16 w) {
|
||||
b32 result = w == '\n' || w == ' ' || w == '\t' || w == '\v' || w == '\r';
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 u16_is_alphabetic(u16 a) {
|
||||
b32 result = (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z');
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 u16_is_ident(u16 a) {
|
||||
b32 result = (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z') || a == '_';
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 u16_is_digit(u16 a) {
|
||||
b32 result = a >= '0' && a <= '9';
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 u16_is_alphanumeric(u16 a) {
|
||||
b32 result = u16_is_digit(a) || u16_is_alphabetic(a);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_from_range(u16 *begin, u16 *end) {
|
||||
assert(end >= begin);
|
||||
intptr_t size = (intptr_t)end - (intptr_t)begin;
|
||||
s16_t result = {begin, size / 2};
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_from_u16(u16 *string) {
|
||||
s16_t result;
|
||||
result.str = string;
|
||||
result.len = wstr_len(string);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_from_wstr(wchar_t *string) {
|
||||
return s16_from_u16((u16 *)string);
|
||||
}
|
||||
|
||||
fn s16_t s16_copy(ma_arena_t *ma, s16_t string) {
|
||||
i64 byte_size = sizeof(u16) * string.len;
|
||||
u16 *copy = (u16 *)ma_push_size(ma, byte_size + sizeof(u16));
|
||||
memory_copy(copy, string.str, byte_size);
|
||||
copy[string.len] = 0;
|
||||
s16_t result = s16(copy, string.len);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_copy_u16(ma_arena_t *ma, u16 *s) {
|
||||
return s16_copy(ma, s16(s, wstr_len(s)));
|
||||
}
|
||||
|
||||
fn s16_t s16_copy_wstr(ma_arena_t *ma, wchar_t *s) {
|
||||
return s16_copy(ma, s16(s, wstr_len(s)));
|
||||
}
|
||||
|
||||
fn b32 s16_are_equal_ex(s16_t a, s16_t b, b32 ignore_case) {
|
||||
if (a.len != b.len) return false;
|
||||
for (i64 i = 0; i < a.len; i++) {
|
||||
u16 A = a.str[i];
|
||||
u16 B = b.str[i];
|
||||
if (ignore_case) {
|
||||
A = u16_to_lower_case(A);
|
||||
B = u16_to_lower_case(B);
|
||||
}
|
||||
if (A != B)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn b32 s16_are_equal(s16_t a, s16_t b) {
|
||||
return s16_are_equal_ex(a, b, false);
|
||||
}
|
||||
|
||||
fn s16_t s16_from_s8(ma_arena_t *ma, s8_t string) {
|
||||
u16 *buffer = ma_push_array(ma, u16, string.len + 1);
|
||||
i64 len = wstr_from_str(buffer, string.len + 1, string.str, string.len);
|
||||
assert(len <= string.len); // @todo: verify
|
||||
return (s16_t){buffer, len};
|
||||
}
|
||||
|
||||
fn s8_t s8_from_s16(ma_arena_t *ma, s16_t string) {
|
||||
i64 buffer_size = (string.len + 1) * 2;
|
||||
char *buffer = ma_push_array(ma, char, buffer_size);
|
||||
i64 len = str_from_wstr(buffer, buffer_size, string.str, string.len);
|
||||
assert(len < buffer_size);
|
||||
return (s8_t){buffer, len};
|
||||
}
|
||||
|
||||
fn s16_t s16_get_postfix(s16_t string, i64 len) {
|
||||
len = CLAMP_TOP(len, string.len);
|
||||
i64 remain_len = string.len - len;
|
||||
s16_t result = s16(string.str + remain_len, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_get_prefix(s16_t string, i64 len) {
|
||||
len = CLAMP_TOP(len, string.len);
|
||||
s16_t result = s16(string.str, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_chop(s16_t string, i64 len) {
|
||||
len = CLAMP_TOP(len, string.len);
|
||||
s16_t result = s16(string.str, string.len - len);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_skip(s16_t string, i64 len) {
|
||||
len = CLAMP_TOP(len, string.len);
|
||||
i64 remain = string.len - len;
|
||||
s16_t result = s16(string.str + len, remain);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 s16_ends_with_ex(s16_t a, s16_t end, b32 ignore_case) {
|
||||
s16_t a_end = s16_get_postfix(a, end.len);
|
||||
b32 result = s16_are_equal_ex(end, a_end, ignore_case);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 s16_starts_with_ex(s16_t a, s16_t start, b32 ignore_case) {
|
||||
s16_t a_start = s16_get_prefix(a, start.len);
|
||||
b32 result = s16_are_equal_ex(start, a_start, ignore_case);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 s16_ends_with(s16_t a, s16_t end) {
|
||||
return s16_ends_with_ex(a, end, false);
|
||||
}
|
||||
|
||||
fn b32 s16_starts_with(s16_t a, s16_t start) {
|
||||
return s16_ends_with_ex(a, start, false);
|
||||
}
|
||||
|
||||
fn void s16_normalize_path_unsafe(s16_t s) {
|
||||
for (i64 i = 0; i < s.len; i++) {
|
||||
if (s.str[i] == '\\')
|
||||
s.str[i] = '/';
|
||||
}
|
||||
}
|
||||
|
||||
fn s16_t s16_normalize_path(ma_arena_t *ma, s16_t s) {
|
||||
s16_t copy = s16_copy(ma, s);
|
||||
s16_normalize_path_unsafe(copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
fn b32 s16_is_pointer_inside(s16_t string, u16 *p) {
|
||||
uintptr_t pointer = (uintptr_t)p;
|
||||
uintptr_t start = (uintptr_t)string.str;
|
||||
uintptr_t stop = start + (uintptr_t)string.len * sizeof(u16);
|
||||
b32 result = pointer >= start && pointer < stop;
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_cut_start(s16_t *in, i64 size) {
|
||||
s16_t result = s16_get_prefix(*in, size);
|
||||
*in = s16_skip(*in, result.len);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_cut_end(s16_t *in, i64 size) {
|
||||
s16_t result = s16_get_postfix(*in, size);
|
||||
*in = s16_chop(*in, result.len);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_slice(s16_t string, i64 first_index, i64 one_past_last_index) {
|
||||
if (one_past_last_index < 0) one_past_last_index = string.len + one_past_last_index + 1;
|
||||
if (first_index < 0) first_index = string.len + first_index;
|
||||
assert(first_index < one_past_last_index);
|
||||
assert(string.len > 0);
|
||||
s16_t result = string;
|
||||
if (string.len > 0) {
|
||||
if (one_past_last_index > first_index) {
|
||||
first_index = CLAMP_TOP(first_index, string.len - 1);
|
||||
one_past_last_index = CLAMP_TOP(one_past_last_index, string.len);
|
||||
result.str += first_index;
|
||||
result.len = one_past_last_index - first_index;
|
||||
}
|
||||
else {
|
||||
result.len = 0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_trim(s16_t string) {
|
||||
if (string.len == 0)
|
||||
return string;
|
||||
|
||||
i64 whitespace_begin = 0;
|
||||
for (; whitespace_begin < string.len; whitespace_begin++) {
|
||||
if (!u16_is_whitespace(string.str[whitespace_begin])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i64 whitespace_end = string.len;
|
||||
for (; whitespace_end != whitespace_begin; whitespace_end--) {
|
||||
if (!u16_is_whitespace(string.str[whitespace_end - 1])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (whitespace_begin == whitespace_end) {
|
||||
string.len = 0;
|
||||
}
|
||||
else {
|
||||
string = s16_slice(string, whitespace_begin, whitespace_end);
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
fn s16_t s16_trim_end(s16_t string) {
|
||||
i64 whitespace_end = string.len;
|
||||
for (; whitespace_end != 0; whitespace_end--) {
|
||||
if (!u16_is_whitespace(string.str[whitespace_end - 1])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
s16_t result = s16_get_prefix(string, whitespace_end);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn b32 s16_seek(s16_t string, s16_t find, s16_seek_t flags, int64_t *index_out) {
|
||||
b32 ignore_case = flags & s16_seek_ignore_case ? true : false;
|
||||
b32 result = false;
|
||||
if (flags & s16_seek_match_find_last) {
|
||||
for (int64_t i = string.len; i != 0; i--) {
|
||||
int64_t index = i - 1;
|
||||
s16_t substring = s16_slice(string, index, index + find.len);
|
||||
if (s16_are_equal_ex(substring, find, ignore_case)) {
|
||||
if (index_out)
|
||||
*index_out = index;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int64_t i = 0; i < string.len; i++) {
|
||||
s16_t substring = s16_slice(string, i, i + find.len);
|
||||
if (s16_are_equal_ex(substring, find, ignore_case)) {
|
||||
if (index_out)
|
||||
*index_out = i;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn int64_t s16_find(s16_t string, s16_t find, s16_seek_t flag) {
|
||||
int64_t result = -1;
|
||||
s16_seek(string, find, flag, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_chop_last_char(s16_t s, s16_t ch) {
|
||||
s16_t result = s;
|
||||
s16_seek(s, ch, s16_seek_match_find_last, &result.len);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_chop_last_slash(s16_t s) {
|
||||
return s16_chop_last_char(s, s16_lit("/"));
|
||||
}
|
||||
|
||||
fn s16_t s16_chop_last_period(s16_t s) {
|
||||
return s16_chop_last_char(s, s16_lit("."));
|
||||
}
|
||||
|
||||
fn s16_t s16_skip_to_last_char(s16_t s, s16_t ch) {
|
||||
int64_t pos;
|
||||
s16_t result = s;
|
||||
if (s16_seek(s, ch, s16_seek_match_find_last, &pos)) {
|
||||
result = s16_skip(result, pos + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t s16_skip_to_last_slash(s16_t s) {
|
||||
return s16_skip_to_last_char(s, s16_lit("/"));
|
||||
}
|
||||
|
||||
fn s16_t s16_skip_to_last_period(s16_t s) {
|
||||
return s16_skip_to_last_char(s, s16_lit("."));
|
||||
}
|
||||
|
||||
fn s16_t s16_get_name_no_ext(s16_t s) {
|
||||
return s16_skip_to_last_slash(s16_chop_last_period(s));
|
||||
}
|
||||
|
||||
fn s16_t s16_to_lower_case(ma_arena_t *ma, s16_t s) {
|
||||
s16_t copy = s16_copy(ma, s);
|
||||
for (int64_t i = 0; i < copy.len; i++) {
|
||||
copy.str[i] = u16_to_lower_case(copy.str[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
fn s16_t s16_to_upper_case(ma_arena_t *ma, s16_t s) {
|
||||
s16_t copy = s16_copy(ma, s);
|
||||
for (int64_t i = 0; i < copy.len; i++) {
|
||||
copy.str[i] = u16_to_upper_case(copy.str[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
fn s16_t s16_printf(ma_arena_t *ma, const char *str, ...) {
|
||||
ma_temp_t scratch = ma_begin_scratch1(ma);
|
||||
S8_FMT(scratch.arena, str, result);
|
||||
s16_t result16 = s16_from_s8(ma, result);
|
||||
ma_end_scratch(scratch);
|
||||
return result16;
|
||||
}
|
||||
|
||||
fn u64 u64_from_s16(s16_t s, u64 base) {
|
||||
assert(base >= 2 && base <= 16);
|
||||
u64 acc = 0;
|
||||
for (i64 i = 0; i < s.len; i++) {
|
||||
u64 num = u64_from_hexchar((char)s.str[i]);
|
||||
assert(num < base);
|
||||
acc *= base;
|
||||
acc += num;
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
fn f64 f64_from_s16(s16_t string) {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
s8_t num_string = s8_from_s16(scratch.arena, string);
|
||||
f64 result = os_parse_float(num_string.str);
|
||||
ma_end_scratch(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
gb_read_only i64 s16_fuzzy_closer_word_begin = 5;
|
||||
gb_read_only i64 s16_fuzzy_consecutive_multiplier = 3;
|
||||
fn i64 s16_fuzzy_rate(s16_t string, s16_t with) {
|
||||
if (with.len == 0) return 0;
|
||||
|
||||
i64 points = 0;
|
||||
i64 consecutive = 0;
|
||||
i64 with_i = 0;
|
||||
for (i64 i = 0; i < string.len; i++) {
|
||||
if (string.str[i] == with.str[with_i]) {
|
||||
i64 closer_begin = CLAMP_BOT((i64)0, s16_fuzzy_closer_word_begin - i);
|
||||
points += closer_begin;
|
||||
consecutive++;
|
||||
with_i += 1;
|
||||
} else {
|
||||
points += consecutive * s16_fuzzy_consecutive_multiplier;
|
||||
consecutive = 0;
|
||||
with_i = 0;
|
||||
}
|
||||
|
||||
if (with_i >= with.len) with_i = 0;
|
||||
}
|
||||
points += consecutive * s16_fuzzy_consecutive_multiplier;
|
||||
return points;
|
||||
}
|
||||
|
||||
fn fuzzy_pair_t *s16_fuzzy_rate_array(ma_arena_t *arena, s16_t needle, s16_t *array, i32 len) {
|
||||
fuzzy_pair_t *pairs = ma_push_array(arena, fuzzy_pair_t, len);
|
||||
for (i32 i = 0; i < len; i += 1) {
|
||||
pairs[i].rating = s16_fuzzy_rate(array[i], needle);
|
||||
pairs[i].index = i;
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < len - 1; i++) {
|
||||
for (i32 j = 0; j < len - 1; j++) {
|
||||
if (pairs[j].rating < pairs[j + 1].rating) {
|
||||
SWAP(fuzzy_pair_t, pairs[j], pairs[j + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pairs;
|
||||
}
|
||||
|
||||
fn sb16_node_t *sb16_create_node(ma_arena_t *ma, s16_t str) {
|
||||
sb16_node_t *node = ma_push_type(ma, sb16_node_t);
|
||||
node->string = str;
|
||||
return node;
|
||||
}
|
||||
|
||||
fn sb16_node_t *sb16_append(sb16_t *list, s16_t string) {
|
||||
assert(list->arena != NULL);
|
||||
sb16_node_t *node = sb16_create_node(list->arena, string);
|
||||
SLLQ_APPEND(list->first, list->last, node);
|
||||
return node;
|
||||
}
|
||||
|
||||
fn s16_t sb16_printf(sb16_t *sb, const char *str, ...) {
|
||||
ma_temp_t scratch = ma_begin_scratch1(sb->arena);
|
||||
S8_FMT(scratch.arena, str, result);
|
||||
s16_t result16 = s16_from_s8(sb->arena, result);
|
||||
sb16_append(sb, result16);
|
||||
ma_end_scratch(scratch);
|
||||
return result16;
|
||||
}
|
||||
|
||||
fn void sb16_indent(sb16_t *sb) {
|
||||
sb16_printf(sb, "\n%.*s", sb->indent*4, " ");
|
||||
}
|
||||
|
||||
fn s16_t sb16_stmtf(sb16_t *sb, const char *str, ...) {
|
||||
ma_temp_t scratch = ma_begin_scratch1(sb->arena);
|
||||
S8_FMT(scratch.arena, str, result);
|
||||
s16_t result16 = s16_from_s8(sb->arena, result);
|
||||
sb16_indent(sb);
|
||||
sb16_append(sb, result16);
|
||||
ma_end_scratch(scratch);
|
||||
return result16;
|
||||
}
|
||||
|
||||
fn int64_t sb16_char_size(sb16_t *sb) {
|
||||
int64_t result = 0;
|
||||
for (sb16_node_t *it = sb->first; it; it = it->next) {
|
||||
result += it->len;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fn s16_t sb16_merge(ma_arena_t *arena, sb16_t *sb) {
|
||||
int64_t size = sb16_char_size(sb) + 1;
|
||||
i64 byte_size = size * sizeof(u16);
|
||||
u16 *str = ma_push_size(arena, byte_size);
|
||||
s16_t result = {str, 0};
|
||||
for (sb16_node_t *it = sb->first; it; it = it->next) {
|
||||
memory_copy(result.str + result.len, it->str, it->len * sizeof(u16));
|
||||
result.len += it->len;
|
||||
}
|
||||
result.str[result.len] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
fn sb16_t s16_split(ma_arena_t *ma, s16_t string, s16_t find, s16_split_t flags) {
|
||||
sb16_t result = (sb16_t){ma};
|
||||
int64_t index = 0;
|
||||
|
||||
s16_seek_t find_flag = flags & s16_split_ignore_case ? s16_seek_ignore_case : s16_seek_none;
|
||||
while (s16_seek(string, find, find_flag, &index)) {
|
||||
s16_t before_match = s16(string.str, index);
|
||||
sb16_append(&result, before_match);
|
||||
if (flags & s16_split_inclusive) {
|
||||
s16_t match = s16(string.str + index, find.len);
|
||||
sb16_append(&result, match);
|
||||
}
|
||||
string = s16_skip(string, index + find.len);
|
||||
}
|
||||
if (string.len) sb16_append(&result, string);
|
||||
return result;
|
||||
}
|
||||
|
||||
fn_test void test_string16(void) {
|
||||
ma_temp_t scratch = ma_begin_scratch();
|
||||
|
||||
// string16 lit basic tests
|
||||
{
|
||||
s16_t a = s16_lit("memes");
|
||||
s16_t b = s16_lit("not memes");
|
||||
s16_t c = s16_lit("MEMES");
|
||||
assert(a.len == 5);
|
||||
assert(a.str[0] == L'm');
|
||||
assert(a.str[4] == L's');
|
||||
assert(s16_are_equal(a, b) == false);
|
||||
assert(s16_are_equal(a, a) == true);
|
||||
assert(s16_are_equal_ex(a, c, true) == true);
|
||||
assert(sizeof(wchar_t) == sizeof(u16));
|
||||
}
|
||||
|
||||
{
|
||||
assert(u16_to_upper_case('a') == L'A');
|
||||
assert(u16_to_upper_case('a') == 'A');
|
||||
assert(u16_to_upper_case(L'a') == 'A');
|
||||
assert(u16_is_digit('3'));
|
||||
}
|
||||
|
||||
{
|
||||
s16_t a = s16_from_wstr(L"memes");
|
||||
assert(a.len == 5);
|
||||
assert(s16_are_equal(a, s16_lit("memes")) == true);
|
||||
|
||||
s16_t b = s16_copy(scratch.arena, a);
|
||||
assert(a.str != b.str);
|
||||
assert(b.len == a.len);
|
||||
assert(s16_are_equal(a, b));
|
||||
|
||||
s16_t c = s16_from_range(a.str, a.str + a.len);
|
||||
assert(s16_are_equal(a, c));
|
||||
}
|
||||
|
||||
{
|
||||
s16_t a = s16_lit("thing itself");
|
||||
assert(s16_starts_with_ex(a, s16_lit("thing"), false));
|
||||
assert(!s16_starts_with_ex(a, s16_lit("thing itself and"), false));
|
||||
assert(!s16_starts_with_ex(a, s16_lit("thing itself "), false));
|
||||
assert(s16_starts_with_ex(a, s16_lit("THING"), true));
|
||||
assert(!s16_starts_with_ex(a, s16_lit("a"), false));
|
||||
|
||||
assert(s16_ends_with_ex(a, s16_lit("itself"), false));
|
||||
assert(s16_ends_with_ex(a, s16_lit("thing itself"), false));
|
||||
assert(!s16_ends_with_ex(a, s16_lit("thing itselfa"), false));
|
||||
|
||||
s16_t b = s16_lit("memes");
|
||||
assert(s16_is_pointer_inside(b, b.str));
|
||||
assert(s16_is_pointer_inside(b, b.str + 4));
|
||||
assert(!s16_is_pointer_inside(b, b.str + 5));
|
||||
}
|
||||
|
||||
{
|
||||
s16_t a = s16_lit("C:\\Program Files\\Memes");
|
||||
s16_normalize_path_unsafe(a);
|
||||
assert(a.str[2] == '/');
|
||||
}
|
||||
|
||||
{
|
||||
s16_t a = s16_lit(" thing ");
|
||||
s16_t b = s16_trim(a);
|
||||
assert(s16_are_equal(b, s16_lit("thing")));
|
||||
}
|
||||
|
||||
{
|
||||
s16_t a = s16_printf(scratch.arena, "%d", 432);
|
||||
assert(s16_are_equal(a, s16_lit("432")));
|
||||
assert(f64_from_s16(s16_lit("432.0")) == 432.0);
|
||||
assert(u64_from_s16(s16_lit("432"), 10) == 432);
|
||||
}
|
||||
|
||||
{
|
||||
sb16_t *list = sb16_serial_begin(scratch.arena);
|
||||
sb16_printf(list, "%d ", 987);
|
||||
sb16_printf(list, "ter ");
|
||||
sb16_printf(list, "|");
|
||||
s16_t string = sb16_serial_end(scratch.arena, list);
|
||||
assert(s16_are_equal(string, s16_lit("987 ter |")));
|
||||
}
|
||||
|
||||
{
|
||||
s16_t a = s16_lit("A|B|dek|mek|vek|");
|
||||
sb16_t b = s16_split(scratch.arena, a, s16_lit("|"), s16_split_none);
|
||||
assert(s16_are_equal(b.first->string, s16_lit("A")));
|
||||
assert(s16_are_equal(b.first->next->string, s16_lit("B")));
|
||||
assert(s16_are_equal(b.first->next->next->string, s16_lit("dek")));
|
||||
assert(s16_are_equal(b.first->next->next->next->string, s16_lit("mek")));
|
||||
assert(s16_are_equal(b.first->next->next->next->next->string, s16_lit("vek")));
|
||||
assert(b.first->next->next->next->next->next == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
s16_t a = s16_to_upper_case(scratch.arena, s16_lit("thing Meme"));
|
||||
assert(s16_are_equal(a, s16_lit("THING MEME")));
|
||||
|
||||
a = s16_to_lower_case(scratch.arena, s16_lit("THING Meme"));
|
||||
assert(s16_are_equal(a, s16_lit("thing meme")));
|
||||
}
|
||||
|
||||
{
|
||||
s16_t a = s16_lit("C:/thing/itself");
|
||||
assert(s16_are_equal(s16_chop_last_slash(a), s16_lit("C:/thing")));
|
||||
}
|
||||
|
||||
ma_end_scratch(scratch);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
typedef struct s16_t s16_t;
|
||||
struct s16_t {
|
||||
u16 *str;
|
||||
i64 len;
|
||||
};
|
||||
|
||||
typedef struct sb16_node_t sb16_node_t;
|
||||
struct sb16_node_t {
|
||||
sb16_node_t *next;
|
||||
union {
|
||||
struct { u16 *str; int64_t len; };
|
||||
s16_t string;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct sb16_t sb16_t;
|
||||
struct sb16_t {
|
||||
ma_arena_t *arena;
|
||||
sb16_node_t *first;
|
||||
sb16_node_t *last;
|
||||
|
||||
// WARNING: remember to update typeinfo after editing this
|
||||
i32 indent;
|
||||
};
|
||||
|
||||
typedef i32 s16_seek_t;
|
||||
enum {
|
||||
s16_seek_none = 0,
|
||||
s16_seek_ignore_case = 1,
|
||||
s16_seek_match_find_last = 2,
|
||||
};
|
||||
|
||||
typedef i32 s16_split_t;
|
||||
enum {
|
||||
s16_split_none = 0,
|
||||
s16_split_ignore_case = 1,
|
||||
s16_split_inclusive = 2,
|
||||
};
|
||||
|
||||
enum { s16_ignore_case = 1 };
|
||||
|
||||
|
||||
typedef struct s32_t s32_t;
|
||||
struct s32_t {
|
||||
u32 *str;
|
||||
i64 len;
|
||||
};
|
||||
|
||||
#define s16(str,len) (s16_t){str, len}
|
||||
#define s16_lit(str) (s16_t){L##str, sizeof(L##str) / sizeof(u16) - 1}
|
||||
#define s16_invalid s16_lit("<INVALID>")
|
||||
|
||||
#define sb16(ARENA) &(sb16_t){.arena = arena}
|
||||
#define sb16_serial_begin(ARENA) &(sb16_t){.arena = ARENA}
|
||||
#define sb16_serial_end(ARENA, SB) sb16_merge(ARENA, SB)
|
||||
|
||||
fn i64 wstr_len(wchar_t *string);
|
||||
fn u16 u16_to_lower_case(u16 a);
|
||||
fn u16 u16_to_upper_case(u16 a);
|
||||
fn b32 u16_is_whitespace(u16 w);
|
||||
fn b32 u16_is_alphabetic(u16 a);
|
||||
fn b32 u16_is_ident(u16 a);
|
||||
fn b32 u16_is_digit(u16 a);
|
||||
fn b32 u16_is_alphanumeric(u16 a);
|
||||
fn s16_t s16_from_range(u16 *begin, u16 *end);
|
||||
fn s16_t s16_from_u16(u16 *string);
|
||||
fn s16_t s16_from_wstr(wchar_t *string);
|
||||
fn s16_t s16_copy(ma_arena_t *ma, s16_t string);
|
||||
fn s16_t s16_copy_u16(ma_arena_t *ma, u16 *s);
|
||||
fn s16_t s16_copy_wstr(ma_arena_t *ma, wchar_t *s);
|
||||
fn b32 s16_are_equal_ex(s16_t a, s16_t b, b32 ignore_case);
|
||||
fn b32 s16_are_equal(s16_t a, s16_t b);
|
||||
fn s16_t s16_from_s8(ma_arena_t *ma, s8_t string);
|
||||
fn s8_t s8_from_s16(ma_arena_t *ma, s16_t string);
|
||||
fn s16_t s16_get_postfix(s16_t string, i64 len);
|
||||
fn s16_t s16_get_prefix(s16_t string, i64 len);
|
||||
fn s16_t s16_chop(s16_t string, i64 len);
|
||||
fn s16_t s16_skip(s16_t string, i64 len);
|
||||
fn b32 s16_ends_with_ex(s16_t a, s16_t end, b32 ignore_case);
|
||||
fn b32 s16_starts_with_ex(s16_t a, s16_t start, b32 ignore_case);
|
||||
fn b32 s16_ends_with(s16_t a, s16_t end);
|
||||
fn b32 s16_starts_with(s16_t a, s16_t start);
|
||||
fn void s16_normalize_path_unsafe(s16_t s);
|
||||
fn s16_t s16_normalize_path(ma_arena_t *ma, s16_t s);
|
||||
fn b32 s16_is_pointer_inside(s16_t string, u16 *p);
|
||||
fn s16_t s16_cut_start(s16_t *in, i64 size);
|
||||
fn s16_t s16_cut_end(s16_t *in, i64 size);
|
||||
fn s16_t s16_slice(s16_t string, i64 first_index, i64 one_past_last_index);
|
||||
fn s16_t s16_trim(s16_t string);
|
||||
fn s16_t s16_trim_end(s16_t string);
|
||||
fn b32 s16_seek(s16_t string, s16_t find, s16_seek_t flags, int64_t *index_out);
|
||||
fn int64_t s16_find(s16_t string, s16_t find, s16_seek_t flag);
|
||||
fn s16_t s16_chop_last_char(s16_t s, s16_t ch);
|
||||
fn s16_t s16_chop_last_slash(s16_t s);
|
||||
fn s16_t s16_chop_last_period(s16_t s);
|
||||
fn s16_t s16_skip_to_last_char(s16_t s, s16_t ch);
|
||||
fn s16_t s16_skip_to_last_slash(s16_t s);
|
||||
fn s16_t s16_skip_to_last_period(s16_t s);
|
||||
fn s16_t s16_get_name_no_ext(s16_t s);
|
||||
fn s16_t s16_to_lower_case(ma_arena_t *ma, s16_t s);
|
||||
fn s16_t s16_to_upper_case(ma_arena_t *ma, s16_t s);
|
||||
fn s16_t s16_printf(ma_arena_t *ma, const char *str, ...);
|
||||
fn u64 u64_from_s16(s16_t s, u64 base);
|
||||
fn f64 f64_from_s16(s16_t string);
|
||||
fn i64 s16_fuzzy_rate(s16_t string, s16_t with);
|
||||
fn fuzzy_pair_t *s16_fuzzy_rate_array(ma_arena_t *arena, s16_t needle, s16_t *array, i32 len);
|
||||
fn sb16_node_t *sb16_create_node(ma_arena_t *ma, s16_t str);
|
||||
fn sb16_node_t *sb16_append(sb16_t *list, s16_t string);
|
||||
fn s16_t sb16_printf(sb16_t *sb, const char *str, ...);
|
||||
fn void sb16_indent(sb16_t *sb);
|
||||
fn s16_t sb16_stmtf(sb16_t *sb, const char *str, ...);
|
||||
fn int64_t sb16_char_size(sb16_t *sb);
|
||||
fn s16_t sb16_merge(ma_arena_t *arena, sb16_t *sb);
|
||||
fn sb16_t s16_split(ma_arena_t *ma, s16_t string, s16_t find, s16_split_t flags);
|
||||
@@ -48,7 +48,7 @@ fn mt_file_t *mt_find_file_exact(mt_files_t *root, s8_t path) {
|
||||
|
||||
fn mt_file_t *mt_find_file(mt_files_t *root, s8_t name) {
|
||||
for (mt_file_t *it = root->first; it; it = it->next) {
|
||||
if (s8_ends_with(name, it->path, false)) return it;
|
||||
if (s8_ends_with(name, it->path)) return it;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
fn void run_tests(void) {
|
||||
test_string16();
|
||||
test_hash_table();
|
||||
test_intern_table();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ gb_read_only mt_tweak_t tweak_table[] = {
|
||||
|
||||
};
|
||||
void run_all_tests(void) {
|
||||
test_string16();
|
||||
test_hash_table();
|
||||
test_intern_table();
|
||||
ui_test_text_replace();
|
||||
|
||||
@@ -55,12 +55,12 @@ fn void mt_ui_stacks(ma_arena_t *arena, sb8_t *c, sb8_t *h) {
|
||||
// create `stack` and `node` columns
|
||||
for (ast_t *it = table->first; it; it = it->next) {
|
||||
s8_t type = mtts(it, "type");
|
||||
if (s8_ends_with(type, s8_lit("_t"), false)) {
|
||||
if (s8_ends_with(type, s8_lit("_t"))) {
|
||||
type = s8_chop(type, 2);
|
||||
}
|
||||
|
||||
s8_t ui_type = type;
|
||||
if (!s8_starts_with(ui_type, s8_lit("ui_"), false)) {
|
||||
if (!s8_starts_with(ui_type, s8_lit("ui_"))) {
|
||||
ui_type = s8_printf(arena, "ui_%S", ui_type);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ fn void mt_ui_stacks(ma_arena_t *arena, sb8_t *c, sb8_t *h) {
|
||||
|
||||
sb8_stmtf(c, "fn void ui_box_fill_with_colors(ui_box_t *box) {");
|
||||
for (ast_t *it = table->first; it; it = it->next) {
|
||||
if (!s8_ends_with(mtts(it, "name"), s8_lit("_color"), false)) {
|
||||
if (!s8_ends_with(mtts(it, "name"), s8_lit("_color"))) {
|
||||
continue;
|
||||
}
|
||||
mt_stmtf(c, it, "box->@name = ui_top_@name();");
|
||||
|
||||
@@ -7,6 +7,7 @@ gb_read_only mt_tweak_t tweak_table[] = {
|
||||
|
||||
};
|
||||
void run_all_tests(void) {
|
||||
test_string16();
|
||||
test_hash_table();
|
||||
test_intern_table();
|
||||
ui_test_text_replace();
|
||||
|
||||
Reference in New Issue
Block a user