From 649c2c09680dbd7de3e245e2b5fcd710201ba6ab Mon Sep 17 00:00:00 2001 From: Timerix Date: Mon, 8 Jun 2026 00:21:42 +0500 Subject: [PATCH] removed RESULT_ERROR_FMT, see RESULT_ERROR_HEAP for reason --- include/tlibc/errors.h | 22 ++++++++++++++++------ project.config | 40 ++++++++++++++++++++++++---------------- src/filesystem/dir.c | 4 ++-- src/filesystem/file.c | 15 ++++++++------- src/term.c | 9 ++++++--- src/time.c | 3 ++- 6 files changed, 58 insertions(+), 35 deletions(-) diff --git a/include/tlibc/errors.h b/include/tlibc/errors.h index 40d49df..aff633a 100755 --- a/include/tlibc/errors.h +++ b/include/tlibc/errors.h @@ -85,14 +85,24 @@ typedef struct Result_ { ErrorCodePage_name(CODE_PAGE), CODE), \ .u = 0 \ } -#define RESULT_ERROR_CODE_FMT(CODE_PAGE, CODE, FORMAT, ARGS...) \ - RESULT_ERROR_CODE(CODE_PAGE, CODE, str_from_cstr(sprintf_malloc(FORMAT ,##ARGS)), true) + +#define RESULT_ERROR_CODE_HEAP(CODE_PAGE, CODE, CHAR_PTR_HEAP) \ + RESULT_ERROR_CODE(CODE_PAGE, CODE, str_from_cstr(CHAR_PTR_HEAP), true) + #define RESULT_ERROR(MSG, IS_MSG_ON_HEAP) \ RESULT_ERROR_CODE(NONE, 0, MSG, IS_MSG_ON_HEAP); -#define RESULT_ERROR_LITERAL(MSG) \ - RESULT_ERROR(STR((MSG)), false) -#define RESULT_ERROR_FMT(FORMAT, ARGS...) \ - RESULT_ERROR_CODE_FMT(NONE, 0, FORMAT ,##ARGS) + +#define RESULT_ERROR_LITERAL(CHAR_LITERAL) \ + RESULT_ERROR(STR((CHAR_LITERAL)), false) + +/// WARNING: make sure CHAR_PTR_HEAP is a variable +/// Anti-Example: +/// Defer(free(key)); +/// Return RESULT_ERROR_HEAP(sprintf_malloc("key not found: %s", key)) +/// SEGFAULT!!!! +/// key was destroyed by Return before sprintf_malloc was called +#define RESULT_ERROR_HEAP(CHAR_PTR_HEAP) \ + RESULT_ERROR(str_from_cstr(CHAR_PTR_HEAP), true) #define RESULT_ERROR_ERRNO() \ RESULT_ERROR_CODE(LIBC_ERRNO, errno, str_from_cstr(strerror_malloc(errno)), true) diff --git a/project.config b/project.config index a84ab45..8eea3aa 100644 --- a/project.config +++ b/project.config @@ -1,12 +1,12 @@ #!/usr/bin/env bash -CBUILD_VERSION=2.3.0 +CBUILD_VERSION=2.3.5 PROJECT="tlibc" CMP_C="gcc" CMP_CPP="g++" -STD_C="c11" +STD_C="c99" STD_CPP="c++11" -WARN_C="-Wall -Wextra +WARN_COMMON="-Wall -Wextra -Wduplicated-branches -Wduplicated-cond -Wformat=2 @@ -15,8 +15,10 @@ WARN_C="-Wall -Wextra -Werror=return-type -Werror=pointer-arith -Werror=init-self + -Wno-maybe-uninitialized" +WARN_C="$WARN_COMMON -Werror=incompatible-pointer-types" -WARN_CPP="$WARN_C" +WARN_CPP="$WARN_COMMON" SRC_C="$(find src -name '*.c')" SRC_CPP="$(find src -name '*.cpp')" @@ -36,20 +38,23 @@ OUTDIR="bin" STATIC_LIB_FILE="$PROJECT.a" INCLUDE="-Iinclude" +DEFINES="" # OS-specific options case "$OS" in WINDOWS) EXEC_FILE="$PROJECT.exe" SHARED_LIB_FILE="$PROJECT.dll" - INCLUDE="$INCLUDE " LINKER_LIBS="-luuid" + INCLUDE="$INCLUDE " + DEFINES="$DEFINES " ;; LINUX) EXEC_FILE="$PROJECT" SHARED_LIB_FILE="$PROJECT.so" - INCLUDE="$INCLUDE " LINKER_LIBS="" + INCLUDE="$INCLUDE " + DEFINES="$DEFINES " ;; *) error "operating system $OS has no configuration variants" @@ -66,7 +71,9 @@ case "$TASK" in # -fprofile-use enables compiler to use profiling info files to optimize executable # -fprofile-prefix-path sets path where profiling info about objects are be saved # -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code - C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections" + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use + -fprofile-prefix-path=$(realpath $OBJDIR)/objects + -fdata-sections -ffunction-sections -Wl,--gc-sections $DEFINES" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" PRE_TASK_SCRIPT="" @@ -75,7 +82,7 @@ case "$TASK" in ;; # creates executable with debug info and no optimizations build_exec_dbg) - C_ARGS="-O0 -g3" + C_ARGS="-O0 -g3 $DEFINES" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" PRE_TASK_SCRIPT="" @@ -84,7 +91,7 @@ case "$TASK" in ;; # creates shared library build_shared_lib) - C_ARGS="-O2 -fpic -flto -shared" + C_ARGS="-O2 -fpic -flto -shared $DEFINES" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE" PRE_TASK_SCRIPT="" @@ -93,7 +100,7 @@ case "$TASK" in ;; # creates shared library with debug symbols and no optimizations build_shared_lib_dbg) - C_ARGS="-O0 -g3 -fpic -shared" + C_ARGS="-O0 -g3 -fpic -shared $DEFINES" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE" PRE_TASK_SCRIPT="" @@ -102,7 +109,7 @@ case "$TASK" in ;; # creates static library build_static_lib) - C_ARGS="-O2 -fpic -fdata-sections -ffunction-sections" + C_ARGS="-O2 -fpic -fdata-sections -ffunction-sections $DEFINES" CPP_ARGS="$C_ARGS" PRE_TASK_SCRIPT="" TASK_SCRIPT="@cbuild/default_tasks/build_static_lib.sh" @@ -110,7 +117,7 @@ case "$TASK" in ;; # creates static library with debug symbols and no optimizations build_static_lib_dbg) - C_ARGS="-O0 -g3" + C_ARGS="-O0 -g3 $DEFINES" CPP_ARGS="$C_ARGS" PRE_TASK_SCRIPT="" TASK_SCRIPT="@cbuild/default_tasks/build_static_lib.sh" @@ -134,7 +141,8 @@ case "$TASK" in # -pg adds code to executable, that generates file containing function call info (gmon.out) # -fprofile-generate generates executable with profiling code # -fprofile-prefix-path sets path where profiling info about objects will be saved - C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects" + C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate + -fprofile-prefix-path=$(realpath $OBJDIR)/objects $DEFINES" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" @@ -150,7 +158,7 @@ case "$TASK" in # https://github.com/msys2/MINGW-packages/issues/8503#issuecomment-1365475205 C_ARGS="-O0 -g -pg -no-pie -fno-omit-frame-pointer -fno-inline-functions -fno-inline-functions-called-once - -fno-optimize-sibling-calls -fopenmp" + -fno-optimize-sibling-calls -fopenmp $DEFINES" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" @@ -164,7 +172,7 @@ case "$TASK" in callgrind) OUTDIR="$OUTDIR/callgrind" # -pg adds code to executable, that generates file containing function call info (gmon.out) - C_ARGS="-O2 -flto=auto -fuse-linker-plugin" + C_ARGS="-O2 -flto=auto -fuse-linker-plugin $DEFINES" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" @@ -174,7 +182,7 @@ case "$TASK" in # compiles executable with sanitizers and executes it to find errors and warnings sanitize) OUTDIR="$OUTDIR/sanitize" - C_ARGS="-O0 -g3 -fsanitize=undefined,address" + C_ARGS="-O0 -g3 -fsanitize=undefined,address $DEFINES" CPP_ARGS="$C_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS" PRE_TASK_SCRIPT="@cbuild/default_tasks/build_exec.sh" diff --git a/src/filesystem/dir.c b/src/filesystem/dir.c index e710365..fe31b32 100644 --- a/src/filesystem/dir.c +++ b/src/filesystem/dir.c @@ -40,11 +40,11 @@ Result(bool) dir_create(cstr path){ #endif { char* errno_s = strerror_malloc(errno); - ResultVar(void) err = RESULT_ERROR_FMT( + char* err = sprintf_malloc( "Can't create dicectory '%s': %s", path, errno_s); free(errno_s); - Return err; + Return RESULT_ERROR_HEAP(err); } Return RESULT_VALUE(i, true); diff --git a/src/filesystem/file.c b/src/filesystem/file.c index 67b9ff2..b8cf435 100644 --- a/src/filesystem/file.c +++ b/src/filesystem/file.c @@ -26,11 +26,11 @@ Result(FILE*) file_open(cstr file_name, cstr fopen_mode){ FILE* f = fopen(file_name, fopen_mode); if(f == NULL){ char* errno_s = strerror_malloc(errno); - ResultVar(void) err = RESULT_ERROR_FMT( + char* err = sprintf_malloc( "Can't open (%s) file '%s': %s", fopen_mode, file_name, errno_s); free(errno_s); - return err; + return RESULT_ERROR_HEAP(err); } return RESULT_VALUE(p, f); } @@ -43,11 +43,11 @@ Result(FILE*) file_openOrCreateReadWrite(cstr file_name){ f = fopen(file_name, fopen_mode); if(f == NULL){ char* errno_s = strerror_malloc(errno); - ResultVar(void) err = RESULT_ERROR_FMT( + char* err = sprintf_malloc( "Can't open (%s) file '%s': %s", fopen_mode, file_name, errno_s); free(errno_s); - return err; + return RESULT_ERROR_HEAP(err); } } return RESULT_VALUE(p, f); @@ -66,11 +66,11 @@ Result(i64) file_tellPos(FILE* f){ Result(void) file_seek(FILE* f, i64 offset, SeekOrigin origin){ if(IFWIN(_fseeki64, fseeko64)(f, offset, (int)origin) != 0){ char* errno_s = strerror_malloc(errno); - ResultVar(void) err = RESULT_ERROR_FMT( + char* err = sprintf_malloc( "Can't seek (offset: "FMT_i64", origin: %i) in file: %s", offset, origin, errno_s); free(errno_s); - return err; + return RESULT_ERROR_HEAP(err); } return RESULT_VOID; } @@ -129,9 +129,10 @@ Result(void) file_readStructsExactly(FILE* f, void* dst, u64 struct_size, u64 ex return RESULT_ERROR_ERRNO(); } if(r != exact_count){ - return RESULT_ERROR_FMT( + char* err = sprintf_malloc( "read "FMT_u64" structures out of "FMT_u64, r, exact_count); + return RESULT_ERROR_HEAP(err); } return RESULT_VOID; } diff --git a/src/term.c b/src/term.c index 746b022..3f432b8 100644 --- a/src/term.c +++ b/src/term.c @@ -1,16 +1,19 @@ #include "tlibc/term.h" #if defined(_WIN64) || defined(_WIN32) #include - #define try_win_bool(EXPR) if(!(EXPR)) { Return RESULT_ERROR_FMT(#EXPR " failed with WindowsError %lu", GetLastError()); } + #define try_win_bool(EXPR) if(!(EXPR)) { \ + char* err97774 = sprintf_malloc(#EXPR " failed with WindowsError %lu", GetLastError()); \ + Return RESULT_ERROR_HEAP(err97774); \ + } #else #include #include #include #define try_zero_errno(EXPR) if((EXPR) != 0) { \ char* errno_s = strerror_malloc(errno); \ - ResultVar(void) err = RESULT_ERROR_FMT(#EXPR " failed with errno: %s", strerror(errno)); \ + char* err97775 = sprintf_malloc(#EXPR " failed with errno: %s", errno_s); \ free(errno_s); \ - Return err; \ + Return RESULT_ERROR_HEAP(err97775); \ } #endif diff --git a/src/time.c b/src/time.c index 0659ac7..b397cbf 100644 --- a/src/time.c +++ b/src/time.c @@ -79,7 +79,8 @@ Result(void) DateTime_parse(cstr src, DateTime* dt){ &dt->d.year, &dt->d.month, &dt->d.month_day, &dt->t.hour, &dt->t.min, &sec_f); if(r != 6){ - return RESULT_ERROR_FMT("attepmted to parse DateTime, got %i fields out of 6", r); + char* err = sprintf_malloc("attepmted to parse DateTime, got %i fields out of 6", r); + return RESULT_ERROR_HEAP(err); } dt->t.sec = (i32)sec_f; dt->t.nsec = (sec_f - (i32)sec_f) * 1e9;