From 4126fa433baedc37c90f6984db5beb73d45ad3a6 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Tue, 28 Mar 2023 06:45:10 +0200 Subject: Barbarian strings --- gen_cmake.c | 39 +++++----------------- include/kit.inl.h | 88 +++++++++++++++++++++++++++++++++++++++---------- source/kit/string_ref.h | 18 ++++++++++ 3 files changed, 98 insertions(+), 47 deletions(-) diff --git a/gen_cmake.c b/gen_cmake.c index 4ed98de..a08ffb9 100644 --- a/gen_cmake.c +++ b/gen_cmake.c @@ -14,30 +14,6 @@ typedef struct { int have_cmakelists; } gen_result_t; -/* FIXME - * Barbarian strings!!! - */ -char const *sz_(str_t const s) { - static char buf[1000]; - int n = s.size; - if (n > 999) - n = 999; - memcpy(buf, s.values, n); - buf[n] = '\0'; - return buf; -} - -int make_sz(string_t *const s) { - ptrdiff_t const n = s->size; - DA_RESIZE(*s, n + 1); - if (s->size != n + 1) { - printf("Error: Bad alloc.\n"); - return 0; - } - s->values[n] = '\0'; - return 1; -} - int is_header(str_t const file) { return file.size > 2 && file.values[file.size - 2] == '.' && file.values[file.size - 1] == 'h'; @@ -70,7 +46,10 @@ gen_result_t gen_cmakelists_for(str_t const target, string_t cmakelists_path = path_join(folder, SZ("CMakeLists.txt"), ALLOC); - if (!make_sz(&cmakelists_path)) { + DA_APPEND(cmakelists_path, '\0'); + + if (cmakelists_path.size == 0 || + cmakelists_path.values[cmakelists_path.size - 1] != '\0') { result.status = KIT_ERROR_BAD_ALLOC; result.have_cmakelists = 0; DA_DESTROY(cmakelists_path); @@ -112,12 +91,12 @@ gen_result_t gen_cmakelists_for(str_t const target, if (!have_headers) fprintf(out, "target_sources(\n %*s\n PUBLIC", - (int) target.size, sz_(target)); + (int) target.size, BS(target)); fprintf( out, "\n $", - (int) item.size, sz_(item)); + (int) item.size, BS(item)); have_headers = 1; } @@ -137,7 +116,7 @@ gen_result_t gen_cmakelists_for(str_t const target, if (!have_headers && !have_sources) fprintf(out, "target_sources(\n %*s\n PRIVATE", - (int) target.size, sz_(target)); + (int) target.size, BS(target)); else if (!have_sources) fprintf(out, "\n PRIVATE"); @@ -146,7 +125,7 @@ gen_result_t gen_cmakelists_for(str_t const target, line_length = 5; } - fprintf(out, " %*s", (int) item.size, sz_(item)); + fprintf(out, " %*s", (int) item.size, BS(item)); line_length += 1 + item.size; have_sources = 1; @@ -178,7 +157,7 @@ gen_result_t gen_cmakelists_for(str_t const target, fprintf(out, "\n"); fprintf(out, "add_subdirectory(%*s)\n", (int) item.size, - sz_(item)); + BS(item)); have_folders = 1; } diff --git a/include/kit.inl.h b/include/kit.inl.h index 873e0bf..4c50c24 100644 --- a/include/kit.inl.h +++ b/include/kit.inl.h @@ -298,6 +298,8 @@ typedef KIT_DA(char) kit_string_t; #ifndef KIT_STRING_REF_H #define KIT_STRING_REF_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -322,6 +324,19 @@ static kit_str_t kit_str(ptrdiff_t const size, return s; } +/* Make a barbarian string for C standard library functions. + * Not thread safe. + */ +static char const *kit_make_bs(kit_str_t const s) { + static char buf[4096]; + ptrdiff_t n = s.size; + if (n > 4095) + n = 4095; + memcpy(buf, s.values, n); + buf[n] = '\0'; + return buf; +} + #ifdef __GNUC__ # pragma GCC pop_options # pragma GCC diagnostic pop @@ -330,6 +345,8 @@ static kit_str_t kit_str(ptrdiff_t const size, #define KIT_SZ(static_str_) \ kit_str(sizeof(static_str_) - 1, (static_str_)) +#define KIT_WRAP_BS(string_) kit_str(strlen(string_), (string_)) + #define KIT_WRAP_STR(string_) \ kit_str((string_).size, (string_).values) @@ -340,6 +357,8 @@ static kit_str_t kit_str(ptrdiff_t const size, # define str_t kit_str_t # define SZ KIT_SZ +# define BS kit_make_bs +# define WRAP_BS KIT_WRAP_BS # define WRAP_STR KIT_WRAP_STR #endif @@ -379,8 +398,6 @@ typedef enum { KIT_PATH_FOLDER } kit_path_type_t; -enum { KIT_FILE_SIZE_ERROR = -1 }; - kit_string_t kit_path_norm(kit_str_t path, kit_allocator_t alloc); kit_string_t kit_path_join(kit_str_t left, kit_str_t right, @@ -388,6 +405,8 @@ kit_string_t kit_path_join(kit_str_t left, kit_str_t right, kit_string_t kit_path_user(kit_allocator_t alloc); +kit_string_t kit_path_cache(kit_allocator_t alloc); + kit_str_t kit_path_index(kit_str_t path, ptrdiff_t index); kit_str_t kit_path_take(kit_str_t path, ptrdiff_t count); @@ -429,6 +448,7 @@ void kit_path_list_destroy(kit_path_list_t list); # define path_norm kit_path_norm # define path_join kit_path_join # define path_user kit_path_user +# define path_cache kit_path_cache # define path_index kit_path_index # define path_take kit_path_take # define file_create_folder kit_file_create_folder @@ -676,6 +696,23 @@ static int is_delim(char const c) { return c == '/' || c == '\\'; } +static kit_string_t kit_get_env_(char *const name, + kit_allocator_t const alloc) { + char *const val = getenv(name); + ptrdiff_t const size = val != NULL ? (ptrdiff_t) strlen(val) : 0; + + string_t result; + DA_INIT(result, size, alloc); + assert(result.size == size); + + if (result.size == size && size > 0) + memcpy(result.values, val, result.size); + else + DA_RESIZE(result, 0); + + return result; +} + kit_string_t kit_path_norm(kit_str_t const path, kit_allocator_t const alloc) { str_t const parent = SZ(".."); @@ -763,26 +800,43 @@ kit_string_t kit_path_join(kit_str_t const left, } kit_string_t kit_path_user(kit_allocator_t const alloc) { - char *home = getenv(KIT_ENV_HOME); - ptrdiff_t const size = home != NULL ? (ptrdiff_t) strlen(home) : 0; - - string_t user; - DA_INIT(user, size, alloc); - assert(user.size == size); - - if (user.size == size) - memcpy(user.values, home, user.size); - else { + kit_string_t user = kit_get_env_(KIT_ENV_HOME, alloc); + if (user.size == 0) { DA_RESIZE(user, 1); - assert(user.size == 1); - if (user.size == 1) user.values[0] = '.'; } - return user; } +kit_string_t kit_path_cache(kit_allocator_t alloc) { + kit_string_t cache, user; + +#if defined(_WIN32) && !defined(__CYGWIN__) + cache = kit_get_env_("LOCALAPPDATA", alloc); + if (cache.size != 0) + return cache; + DA_DESTROY(cache); +#endif + + cache = kit_get_env_("XDG_CACHE_HOME", alloc); + if (cache.size != 0) + return cache; + DA_DESTROY(cache); + + user = kit_path_user(alloc); + cache = +#ifdef __APPLE__ + kit_path_join(WRAP_STR(user), SZ("Library" PATH_DELIM "Caches"), + alloc); +#else + kit_path_join(WRAP_STR(user), SZ(".cache"), alloc); +#endif + DA_DESTROY(user); + + return cache; +} + kit_str_t kit_path_index(kit_str_t const path, ptrdiff_t const index) { str_t s = { .size = 0, .values = NULL }; @@ -864,7 +918,7 @@ static void win32_prepare_path_(WCHAR *const buf, WCHAR buf[PATH_BUF_SIZE]; \ win32_prepare_path_(buf, path) #else -static void unix_prepare_path_(char *const buf, +static void unix_prepare_path_(char *const buf, kit_str_t const path) { assert(path.size == 0 || path.values != NULL); assert(path.size + 1 < PATH_BUF_SIZE); @@ -1020,7 +1074,7 @@ kit_file_info_t kit_file_info(kit_str_t const path) { result.time_modified_sec = (int64_t) info.st_mtim.tv_sec; result.time_modified_nsec = (int32_t) info.st_mtim.tv_nsec; # endif - result.status = KIT_OK; + result.status = KIT_OK; return result; } #endif diff --git a/source/kit/string_ref.h b/source/kit/string_ref.h index 1497bb0..6c89292 100644 --- a/source/kit/string_ref.h +++ b/source/kit/string_ref.h @@ -2,6 +2,7 @@ #define KIT_STRING_REF_H #include "array_ref.h" +#include #ifdef __cplusplus extern "C" { @@ -27,6 +28,19 @@ static kit_str_t kit_str(ptrdiff_t const size, return s; } +/* Make a barbarian string for C standard library functions. + * Not thread safe. + */ +static char const *kit_make_bs(kit_str_t const s) { + static char buf[4096]; + ptrdiff_t n = s.size; + if (n > 4095) + n = 4095; + memcpy(buf, s.values, n); + buf[n] = '\0'; + return buf; +} + #ifdef __GNUC__ # pragma GCC pop_options # pragma GCC diagnostic pop @@ -35,6 +49,8 @@ static kit_str_t kit_str(ptrdiff_t const size, #define KIT_SZ(static_str_) \ kit_str(sizeof(static_str_) - 1, (static_str_)) +#define KIT_WRAP_BS(string_) kit_str(strlen(string_), (string_)) + #define KIT_WRAP_STR(string_) \ kit_str((string_).size, (string_).values) @@ -45,6 +61,8 @@ static kit_str_t kit_str(ptrdiff_t const size, # define str_t kit_str_t # define SZ KIT_SZ +# define BS kit_make_bs +# define WRAP_BS KIT_WRAP_BS # define WRAP_STR KIT_WRAP_STR #endif -- cgit v1.2.3