s8_fmtspec, remove %S for tcc bounds check, optional stbsp

This commit is contained in:
Krzosa Karol
2026-03-07 19:50:45 +01:00
parent 3566408199
commit 534e24719d
9 changed files with 1996 additions and 1992 deletions

View File

@@ -5,5 +5,5 @@ if [ ! -d build ]; then
fi fi
cd build cd build
# clang ../src/testing/testing_main.c -o testing_main -I../src/ -ldl -lm -lbacktrace -g -Wall -Wextra -Wno-missing-braces -Wno-missing-field-initializers -Wno-single-bit-bitfield-constant-conversion -fdiagnostics-absolute-paths -Wno-writable-strings -Wno-unsequenced # clang ../src/testing/testing_main.c -o testing_main -I../src/ -ldl -lm -lbacktrace -g -Wall -Wextra -Wno-missing-braces -Wno-missing-field-initializers -Wno-single-bit-bitfield-constant-conversion -fdiagnostics-absolute-paths -Wno-writable-strings -Wno-unsequenced
tcc $(realpath ../src/testing/testing_main.c) -o testing_main -I$(realpath ../src/) -ldl -lm -Wall -Wextra tcc $(realpath ../src/testing/testing_main.c) -o testing_main -I$(realpath ../src/) -b -g -ldl -lm -Wall -Wextra
./testing_main ./testing_main

View File

@@ -435,9 +435,9 @@ fn void parser_panicf(b32 print_only_file, lex_t *token, const char *str, ...) {
S8_FMT(scratch.arena, str, str8); S8_FMT(scratch.arena, str, str8);
if (print_only_file) { if (print_only_file) {
fatalf("%s: error: %S", token->file, str8); fatalf("%s: error: %.*s", token->file, s8_fmtspec(str8));
} else { } else {
fatalf("%s(%d): error: %S", token->file, token->line, str8); fatalf("%s(%d): error: %.*s", token->file, token->line, s8_fmtspec(str8));
} }
@@ -447,13 +447,13 @@ fn void parser_panicf(b32 print_only_file, lex_t *token, const char *str, ...) {
fn lex_t *parser_expect(parser_t *par, lex_kind_t kind) { fn lex_t *parser_expect(parser_t *par, lex_kind_t kind) {
lex_t *token = parser_match(par, kind); lex_t *token = parser_match(par, kind);
if (!token) parser_panicf(par->print_only_file, par->at, "expected token kind: %S, got instead: %S", lex_kind_to_s8(kind), lex_kind_to_s8(par->at->kind)); if (!token) parser_panicf(par->print_only_file, par->at, "expected token kind: %s, got instead: %s", lex_kind_to_s8(kind).str, lex_kind_to_s8(par->at->kind).str);
return token; return token;
} }
fn lex_t *parser_expecti(parser_t *par, s8_t ident) { fn lex_t *parser_expecti(parser_t *par, s8_t ident) {
lex_t *token = parser_matchi(par, ident); lex_t *token = parser_matchi(par, ident);
if (!token) parser_panicf(par->print_only_file, par->at, "expected identifier: '%S'", ident); if (!token) parser_panicf(par->print_only_file, par->at, "expected identifier: '%.*s'", s8_fmtspec(ident));
return token; return token;
} }

View File

@@ -21,18 +21,18 @@ fn void default_log_proc(log_level_t level, s8_t file_and_line, s8_t string) {
switch(level) { switch(level) {
case log_level_debug: case log_level_debug:
case log_level_info: { case log_level_info: {
os_console_log(s8_printf(scratch.arena, "%S\n", string).str); os_console_log(s8_printf(scratch.arena, "%.*s\n", s8_fmtspec(string)).str);
} break; } break;
case log_level_warning: { case log_level_warning: {
os_console_log(s8_printf(scratch.arena, "%S%s%S\n", file_and_line, colon, string).str); os_console_log(s8_printf(scratch.arena, "%.*s%s%.*s\n", s8_fmtspec(file_and_line), colon, s8_fmtspec(string)).str);
if (tcx->log.break_on_warning) debug_break(); if (tcx->log.break_on_warning) debug_break();
} break; } break;
case log_level_error: { case log_level_error: {
os_console_log(s8_printf(scratch.arena, "%S%s%S\n", file_and_line, colon, string).str); os_console_log(s8_printf(scratch.arena, "%.*s%s%.*s\n", s8_fmtspec(file_and_line), colon, s8_fmtspec(string)).str);
if (tcx->log.break_on_error) debug_break(); if (tcx->log.break_on_error) debug_break();
} break; } break;
case log_level_fatal: { case log_level_fatal: {
os_error_box(s8_printf(scratch.arena, "%S%s%S\n", file_and_line, colon, string).str); os_error_box(s8_printf(scratch.arena, "%.*s%s%.*s\n", s8_fmtspec(file_and_line), colon, s8_fmtspec(string)).str);
if (tcx->log.break_on_fatal) debug_break(); if (tcx->log.break_on_fatal) debug_break();
} break; } break;
default_is_invalid; default_is_invalid;

View File

@@ -3,8 +3,6 @@
#include "core_platform.h" #include "core_platform.h"
#include "stb_sprintf.h" #include "stb_sprintf.h"
#define s8_vsnprintf stbsp_vsnprintf
fn i32 str_len(char *str) { fn i32 str_len(char *str) {
i32 i = 0; i32 i = 0;
while (str[i]) i += 1; while (str[i]) i += 1;

View File

@@ -161,10 +161,16 @@ void *sbin_read_data(stream_t *stream, i64 size);
s8_t result = s8_vfmt(ma, str, args1); \ s8_t result = s8_vfmt(ma, str, args1); \
va_end(args1) va_end(args1)
#if PLATFORM_TCC
#define s8_vsnprintf vsnprintf
#else
#define s8_vsnprintf stbsp_vsnprintf
#endif
#define STR_FMT(buff, str) \ #define STR_FMT(buff, str) \
va_list args1; \ va_list args1; \
va_start(args1, str); \ va_start(args1, str); \
i32 len = stbsp_vsnprintf(buff, sizeof(buff), str, args1); \ i32 len = s8_vsnprintf(buff, sizeof(buff), str, args1); \
va_end(args1) va_end(args1)
typedef struct fuzzy_pair_t fuzzy_pair_t; typedef struct fuzzy_pair_t fuzzy_pair_t;

View File

@@ -196,7 +196,7 @@ fn void ti__serial_data_ex(sb8_t *sb, void *p, type_t *type) {
if (type == &type__s8_t) { if (type == &type__s8_t) {
s8_t n = *(s8_t *)p; s8_t n = *(s8_t *)p;
sb8_printf(sb, "\"%S\"", n); sb8_printf(sb, "\"%.*s\"", s8_fmtspec(n));
return; return;
} }
@@ -234,7 +234,7 @@ fn void ti__serial_data_ex(sb8_t *sb, void *p, type_t *type) {
type_member_t *mem = type->members + i; type_member_t *mem = type->members + i;
void *mem_p = ti_extract_member(p, mem); void *mem_p = ti_extract_member(p, mem);
sb8_indent(sb); sb8_indent(sb);
sb8_printf(sb, "%S: ", mem->name); sb8_printf(sb, "%.*s: ", s8_fmtspec(mem->name));
ti__serial_data_ex(sb, mem_p, mem->type); ti__serial_data_ex(sb, mem_p, mem->type);
sb8_printf(sb, ","); sb8_printf(sb, ",");
} }
@@ -377,7 +377,7 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t *
lex_t *token = parser_expect(par, lex_kind_ident); lex_t *token = parser_expect(par, lex_kind_ident);
i64 value = ti_enum_name_to_value(token->string, type); i64 value = ti_enum_name_to_value(token->string, type);
if (value == -1) { if (value == -1) {
fatalf("invalid enum value: %S", token->string); fatalf("invalid enum value: %.*s", s8_fmtspec(token->string));
} }
ti_enum_write_value(p, value, type); ti_enum_write_value(p, value, type);
@@ -396,7 +396,7 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t *
u8 *mem_p = p8 + mem->offset; u8 *mem_p = p8 + mem->offset;
ti__deserial_data_ex(arena, par, mem_p, mem->type); ti__deserial_data_ex(arena, par, mem_p, mem->type);
} else { } else {
debugf("deserial - skipping field: %S", ident->string); debugf("deserial - skipping field: %.*s", s8_fmtspec(ident->string));
parser_eat_until(par, lex_kind_comma); parser_eat_until(par, lex_kind_comma);
} }
@@ -412,7 +412,7 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t *
lex_t *ident = parser_expect(par, lex_kind_ident); lex_t *ident = parser_expect(par, lex_kind_ident);
parser_expect(par, lex_kind_colon); parser_expect(par, lex_kind_colon);
expect (s8_are_equal(ident->string, mem->name)) fatalf("expected identifier: %S, got instead %S", mem->name, ident->string); expect (s8_are_equal(ident->string, mem->name)) fatalf("expected identifier: %.*s, got instead %.*s", s8_fmtspec(mem->name), s8_fmtspec(ident->string));
ti__deserial_data_ex(arena, par, memp, mem->type); ti__deserial_data_ex(arena, par, memp, mem->type);
parser_expect(par, lex_kind_comma); parser_expect(par, lex_kind_comma);
@@ -457,10 +457,10 @@ fn s8_t ti_serial_type(ma_arena_t *arena, type_t *type) {
return type->name; return type->name;
} else if (type->kind == type_kind_pointer) { } else if (type->kind == type_kind_pointer) {
s8_t name = ti_serial_type(arena, type->base); s8_t name = ti_serial_type(arena, type->base);
return s8_printf(arena, "%S*", name); return s8_printf(arena, "%.*s*", s8_fmtspec(name));
} else if (type->kind == type_kind_array) { } else if (type->kind == type_kind_array) {
s8_t name = ti_serial_type(arena, type->base); s8_t name = ti_serial_type(arena, type->base);
return s8_printf(arena, "%S[%d]", name, type->count); return s8_printf(arena, "%.*s[%d]", s8_fmtspec(name), type->count);
} else_is_invalid; } else_is_invalid;
return s8_invalid; return s8_invalid;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -173,7 +173,7 @@ fn void os_advance(os_iter_t *it) {
it->name = s8_from_s16(it->arena, s16_make(data->cFileName, str16_len(data->cFileName))); it->name = s8_from_s16(it->arena, s16_make(data->cFileName, str16_len(data->cFileName)));
char *separator = it->path.str[it->path.len - 1] == '/' ? "" : "/"; char *separator = it->path.str[it->path.len - 1] == '/' ? "" : "/";
it->rel = s8_printf(it->arena, "%S%s%S", it->path, separator, it->name); it->rel = s8_printf(it->arena, "%.*s%s%.*s", s8_fmtspec(it->path), separator, s8_fmtspec(it->name));
it->abs = os_abs(it->arena, it->rel); it->abs = os_abs(it->arena, it->rel);
it->is_valid = true; it->is_valid = true;
s8_normalize_path_unsafe(it->rel); s8_normalize_path_unsafe(it->rel);
@@ -196,7 +196,7 @@ fn os_iter_t *os_iter(ma_arena_t *arena, s8_t path) {
it->is_valid = true; it->is_valid = true;
ma_temp_t scratch = ma_begin_scratch1(arena); ma_temp_t scratch = ma_begin_scratch1(arena);
s8_t mod_path = s8_printf(scratch.arena, "%S\\*", path); s8_t mod_path = s8_printf(scratch.arena, "%.*s\\*", s8_fmtspec(path));
s16_t mod_path16 = s16_from_s8(scratch.arena, mod_path); s16_t mod_path16 = s16_from_s8(scratch.arena, mod_path);
it->w32->handle = FindFirstFileW(mod_path16.str, &it->w32->data); it->w32->handle = FindFirstFileW(mod_path16.str, &it->w32->data);
@@ -257,7 +257,7 @@ fn s8_t os_exe_dir(ma_arena_t *arena) {
ma_temp_t scratch = ma_begin_scratch1(arena); ma_temp_t scratch = ma_begin_scratch1(arena);
s8_t exe = os_exe(scratch.arena); s8_t exe = os_exe(scratch.arena);
s8_t path = s8_chop_last_slash(exe); s8_t path = s8_chop_last_slash(exe);
s8_t result = s8_printf(arena, "%S", path); s8_t result = s8_printf(arena, "%.*s", s8_fmtspec(path));
ma_end_scratch(scratch); ma_end_scratch(scratch);
return result; return result;
} }
@@ -301,7 +301,7 @@ fn s8_t os_cwd(ma_arena_t *arena) {
assert(wsize <= buffer_size); assert(wsize <= buffer_size);
s8_t path = s8_from_s16(scratch.arena, s16_make(buffer, wsize)); s8_t path = s8_from_s16(scratch.arena, s16_make(buffer, wsize));
s8_normalize_path_unsafe(path); s8_normalize_path_unsafe(path);
s8_t result = s8_printf(arena, "%S", path); s8_t result = s8_printf(arena, "%.*s", s8_fmtspec(path));
ma_end_scratch(scratch); ma_end_scratch(scratch);
return result; return result;
} }
@@ -398,10 +398,10 @@ fn s8_t os_appdata(ma_arena_t *arena, s8_t name) {
ma_temp_t scratch = ma_begin_scratch1(arena); ma_temp_t scratch = ma_begin_scratch1(arena);
s8_t tmp = s8_from_s16(scratch.arena, appdata_path); s8_t tmp = s8_from_s16(scratch.arena, appdata_path);
s8_normalize_path_unsafe(tmp); s8_normalize_path_unsafe(tmp);
s8_t path = s8_printf(arena, "%S/%S", tmp, name); s8_t path = s8_printf(arena, "%.*s/%.*s", s8_fmtspec(tmp), s8_fmtspec(name));
os_mkdir_t mkdir_status = os_mkdir(path); os_mkdir_t mkdir_status = os_mkdir(path);
if (mkdir_status != os_mkdir_success && mkdir_status != os_mkdir_file_exists) { if (mkdir_status != os_mkdir_success && mkdir_status != os_mkdir_file_exists) {
debugf("%s.os_mkdir failed with status: %d, for: %S", __FUNCTION__, mkdir_status, path); debugf("%s.os_mkdir failed with status: %d, for: %.*s", __FUNCTION__, mkdir_status, s8_fmtspec(path));
path = s8_null; path = s8_null;
} }
@@ -611,7 +611,7 @@ fn void os_advance(os_iter_t *it) {
it->name = s8_copy(it->arena, s8_from_char(file->d_name)); it->name = s8_copy(it->arena, s8_from_char(file->d_name));
const char *separator = it->path.str[it->path.len - 1] == '/' ? "" : "/"; const char *separator = it->path.str[it->path.len - 1] == '/' ? "" : "/";
it->rel = s8_printf(it->arena, "%S%s%s", it->path, separator, file->d_name); it->rel = s8_printf(it->arena, "%.*s%s%s", s8_fmtspec(it->path), separator, file->d_name);
it->abs = os_abs(it->arena, it->rel); it->abs = os_abs(it->arena, it->rel);
it->is_valid = true; it->is_valid = true;
return; return;

View File

@@ -10,7 +10,6 @@ fn void os_test(void) {
os_date_t local_time = os_local_time(); os_date_t local_time = os_local_time();
os_date_t universal_time = os_universal_time(); os_date_t universal_time = os_universal_time();
unused(universal_time); unused(local_time); unused(universal_time); unused(local_time);
// debugf("OS local_time = %S | universal_time = %S", os_format_date(&tcx->temp, local_time), os_format_date(&tcx->temp, universal_time));
s8_t exe_dir = os_exe_dir(&tcx->temp); s8_t exe_dir = os_exe_dir(&tcx->temp);
assert(exe_dir.str[exe_dir.len - 1] != '/'); assert(exe_dir.str[exe_dir.len - 1] != '/');
@@ -84,12 +83,12 @@ fn void test_s8(void) {
sb8_t *sb = &(sb8_t){arena}; sb8_t *sb = &(sb8_t){arena};
s8_t memes = s8("memes"); s8_t memes = s8("memes");
sb8_printf(sb, "%S", memes); sb8_printf(sb, "%.*s", s8_fmtspec(memes));
assert(sb->first == sb->last); assert(sb->first == sb->last);
assert(sb->first->len == 5); assert(sb->first->len == 5);
assert(s8_are_equal(sb->first->string, memes)); assert(s8_are_equal(sb->first->string, memes));
sb8_printf(sb, "%S", s8("things are going fine")); sb8_printf(sb, "%s", "things are going fine");
s8_t string = sb8_merge(temp.arena, sb); s8_t string = sb8_merge(temp.arena, sb);
assert(s8_are_equal(string, s8("memesthings are going fine"))); assert(s8_are_equal(string, s8("memesthings are going fine")));
@@ -158,7 +157,7 @@ fn void test_s8(void) {
} }
{ {
s8_t s = s8_printf(arena, "%d%Sv%s", 32, s8("|"), ">"); s8_t s = s8_printf(arena, "%d%sv%s", 32, "|", ">");
assert(s8_are_equal(s, s8("32|v>"))); assert(s8_are_equal(s, s8("32|v>")));
} }
@@ -174,6 +173,7 @@ fn void test_s8(void) {
int main() { int main() {
os_core_init(); os_core_init();
test_s8(); test_s8();
os_test(); os_test();
debugf("Testing OK"); debugf("Testing OK");