diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | build.c | 247 | ||||
-rw-r--r-- | gen_cmake.c | 2 | ||||
-rw-r--r-- | gen_inl.c | 49 | ||||
-rw-r--r-- | include/kit.inl.h | 333 | ||||
-rw-r--r-- | source/kit/file.h | 18 |
6 files changed, 328 insertions, 322 deletions
@@ -2,3 +2,4 @@ *.swp gen_inl gen_cmake +build_c @@ -0,0 +1,247 @@ +#if 0 +gcc -fsanitize=address,undefined,leak build.c -o build_c && ./build_c +exit +#endif + +/********************************************************************* + * * + * KIT Library * + * * + *********************************************************************/ + +// Just paste the Kit library code here. + +#include "include/kit.inl.h" + +/********************************************************************* + * * + * BUILD_C * + * * + * Experimental pure C build system. * + * Work in progress. * + * * + *********************************************************************/ + +#include <stdio.h> + +#define DL PATH_DELIM + +enum { MAX_STR = 4096, MAX_DEPENDENCIES = 100, MAX_UNITS = 400 }; + +typedef DA(ptrdiff_t) index_array_t; + +typedef enum { UNIT_NONE, UNIT_HEADER, UNIT_SOURCE } unit_type_t; + +typedef struct { + string_t path; + unit_type_t type; + index_array_t dependencies; +} unit_t; + +typedef DA(unit_t) unit_array_t; + +unit_array_t units; + +kit_allocator_t ALLOC; + +int is_header(str_t file) { + ptrdiff_t const n = file.size; + return n > 2 && file.values[n - 2] == '.' && + file.values[n - 1] == 'h'; +} + +int is_source(str_t file) { + ptrdiff_t const n = file.size; + return n > 2 && file.values[n - 2] == '.' && + file.values[n - 1] == 'c'; +} + +unit_type_t unit_type(str_t file) { + if (is_header(file)) + return UNIT_HEADER; + if (is_source(file)) + return UNIT_SOURCE; + return UNIT_NONE; +} + +void enum_sources(str_t folder) { + path_list_t const list = file_enum_folder(folder, ALLOC); + + for (ptrdiff_t i = 0; i < list.files.size; i++) { + str_t item = WRAP_STR(list.files.values[i]); + string_t file = path_join(folder, item, ALLOC); + path_type_t type = path_type(WRAP_STR(file)); + unit_type_t utype = unit_type(WRAP_STR(file)); + + switch (type) { + case PATH_FILE: + if (utype != UNIT_NONE) { + unit_t unit = { .path = file, .type = utype }; + DA_INIT(unit.dependencies, 0, ALLOC); + DA_APPEND(units, unit); + } else + DA_DESTROY(file); + break; + + case PATH_FOLDER: enum_sources(WRAP_STR(file)); + default: DA_DESTROY(file); + } + } + + path_list_destroy(list); +} + +void skip_comment(FILE *f) { + char c = fgetc(f); + if (c != '/' && c != '*') + return; + if (c == '/') + while (c != '\n') { + c = fgetc(f); + if (c == '\\') + fgetc(f); + } + else + while (c != '*') { + c = fgetc(f); + if (c == '*' && fgetc(f) == '/') + break; + } +} + +typedef struct { + int ok; + int is_local; + string_t path; +} include_t; + +include_t parse_include(FILE *f) { + include_t result = { .ok = 0 }; + char c = ' '; + while (c == ' ') c = fgetc(f); + if (c != '#') + return result; + c = ' '; + while (c == ' ') c = fgetc(f); + if (c != 'i') + return result; + char s[] = "nclude"; + for (int i = 0; i + 1 < sizeof s; i++) + if (fgetc(f) != s[i]) + return result; + c = ' '; + while (c == ' ') c = fgetc(f); + if (c != '"' && c != '<') + return result; + if (c == '"') + result.is_local = 1; + else + result.is_local = 0; + DA_INIT(result.path, 1, ALLOC); + for (;;) { + char z = fgetc(f); + if (c == '"' && z == '"') + break; + if (c == '<' && z == '>') + break; + if (z == '\n' || z == '\r' || z == '\0') { + DA_DESTROY(result.path); + return result; + } + result.path.values[result.path.size - 1] = z; + DA_RESIZE(result.path, result.path.size + 1); + } + DA_RESIZE(result.path, result.path.size - 1); + if (result.path.size == 0) { + DA_DESTROY(result.path); + return result; + } + c = ' '; + while (c == ' ') c = fgetc(f); + if (c != '\n' && c != '\r') { + DA_DESTROY(result.path); + return result; + } + result.ok = 1; + return result; +} + +str_t base_path(str_t path) { + ptrdiff_t n = 0; + while (path_index(path, n).size != 0) n++; + return path_take(path, n - 2); +} + +void parse_unit(unit_t *u) { + FILE *f = fopen(BS(u->path), "rt"); + if (f == NULL) { + printf("Can't read %s\n", BS(u->path)); + return; + } + + str_t base = base_path(WRAP_STR(u->path)); + + while (!feof(f)) { + char c = fgetc(f); + switch (c) { + case '/': skip_comment(f); break; + case '\n': { + include_t inc = parse_include(f); + if (inc.ok) { + if (inc.is_local) { + string_t temp = path_join(base, WRAP_STR(inc.path), + ALLOC); + string_t inc_path = path_norm(WRAP_STR(temp), ALLOC); + for (ptrdiff_t i = 0; i < units.size; i++) + if (AR_EQUAL(units.values[i].path, inc_path)) { + ptrdiff_t k = u->dependencies.size; + DA_RESIZE(u->dependencies, k + 1); + u->dependencies.values[k] = i; + break; + } + DA_DESTROY(temp); + DA_DESTROY(inc_path); + } + DA_DESTROY(inc.path); + } + } break; + default:; + } + } + + fclose(f); +} + +void parse_units(void) { + for (ptrdiff_t i = 0; i < units.size; i++) + parse_unit(units.values + i); +} + +int main(int argc, char **argv) { + ALLOC = kit_alloc_default(); + DA_INIT(units, 0, ALLOC); + + enum_sources(SZ("." DL "src")); + enum_sources(SZ("." DL "source")); + parse_units(); + + for (ptrdiff_t i = 0; i < units.size; i++) { + unit_t *u = units.values + i; + if (u->type == UNIT_HEADER) + printf("[ Header ] "); + else + printf("[ Source ] "); + printf("%s\n", BS(u->path)); + for (ptrdiff_t j = 0; j < u->dependencies.size; j++) + printf(" -> %s\n", + BS(units.values[u->dependencies.values[j]].path)); + } + + for (ptrdiff_t i = 0; i < units.size; i++) { + DA_DESTROY(units.values[i].path); + DA_DESTROY(units.values[i].dependencies); + } + DA_DESTROY(units); + + return 0; +} diff --git a/gen_cmake.c b/gen_cmake.c index a08ffb9..cfb4f24 100644 --- a/gen_cmake.c +++ b/gen_cmake.c @@ -1,5 +1,5 @@ #if 0 -gcc -fsanitize=address,leak gen_cmake.c -o gen_cmake && ./gen_cmake +gcc -fsanitize=address,undefined,leak gen_cmake.c -o gen_cmake && ./gen_cmake exit #endif @@ -1,5 +1,5 @@ #if 0 -gcc gen_inl.c -o gen_inl && ./gen_inl +gcc -fsanitize=address,undefined,leak gen_inl.c -o gen_inl && ./gen_inl exit #endif @@ -68,43 +68,33 @@ int write_file(FILE *out, char const *const source) { return 1; } - fprintf(out, "/*%s*\n", repeat(70, '*')); - fprintf(out, " *%s*\n", repeat(70, ' ')); - fprintf(out, " *%s*\n", repeat(70, ' ')); - fprintf(out, " * FILE: %s%s*\n", source, - repeat(58 - strlen(source), ' ')); - fprintf(out, " *%s*\n", repeat(70, ' ')); - fprintf(out, " *%s*\n", repeat(70, ' ')); - fprintf(out, " *%s*/\n", repeat(70, '*')); + fprintf(out, "/*%s*\n", repeat(67, '*')); + fprintf(out, " *%s*\n", repeat(67, ' ')); + fprintf(out, " * File: %s%s*\n", source, + repeat(55 - strlen(source), ' ')); + fprintf(out, " *%s*\n", repeat(67, ' ')); + fprintf(out, " *%s*/\n", repeat(67, '*')); char line[200]; char buf[400]; - int prev_empty = 0; while (fgets(line, 199, in) != NULL) { - int empty = is_empty_line(line) || is_local_include(line); - - if (empty) { - if (!prev_empty) - fprintf(out, "\n"); - } else { - int j = 0; - for (int i = 0; line[i] != '\0'; i++) { - if (line[i] == '\t') { - buf[j++] = ' '; - buf[j++] = ' '; - } else if (line[i] != '\n' && line[i] != '\r') - buf[j++] = line[i]; - } - buf[j] = '\0'; - fprintf(out, "%s\n", buf); + if (is_empty_line(line) || is_local_include(line)) + continue; + + int j = 0; + for (int i = 0; line[i] != '\0'; i++) { + if (line[i] == '\t') { + buf[j++] = ' '; + buf[j++] = ' '; + } else if (line[i] != '\n' && line[i] != '\r') + buf[j++] = line[i]; } - - prev_empty = empty; + buf[j] = '\0'; + fprintf(out, "%s\n", buf); } fclose(in); - fprintf(out, "\n"); return 0; } @@ -118,7 +108,6 @@ int main(int argc, char **argv) { fprintf(out, "#ifndef KIT_INL_H\n"); fprintf(out, "#define KIT_INL_H\n"); - fprintf(out, "\n"); for (int i = 0; i < sizeof SOURCES / sizeof *SOURCES; i++) if (write_file(out, SOURCES[i]) != 0) { diff --git a/include/kit.inl.h b/include/kit.inl.h index da2583d..44d22eb 100644 --- a/include/kit.inl.h +++ b/include/kit.inl.h @@ -1,20 +1,15 @@ #ifndef KIT_INL_H #define KIT_INL_H - -/************************************************************************ - * * - * * - * FILE: ./source/kit/status.h * - * * - * * - ************************************************************************/ +/********************************************************************* + * * + * File: ./source/kit/status.h * + * * + *********************************************************************/ #ifndef KIT_STATUS_H #define KIT_STATUS_H - #ifdef __cplusplus extern "C" { #endif - enum { KIT_OK, KIT_ERROR_BAD_ALLOC, @@ -25,43 +20,31 @@ enum { KIT_ERROR_FILE_DO_NOT_EXIST, KIT_ERROR_PATH_TOO_LONG }; - typedef int kit_status_t; - #ifdef __cplusplus } #endif - #endif - -/************************************************************************ - * * - * * - * FILE: ./source/kit/allocator.h * - * * - * * - ************************************************************************/ +/********************************************************************* + * * + * File: ./source/kit/allocator.h * + * * + *********************************************************************/ #ifndef KIT_ALLOCATOR_H #define KIT_ALLOCATOR_H - #include <stddef.h> - #ifdef __cplusplus extern "C" { #endif - enum { KIT_ALLOCATE, KIT_DEALLOCATE, KIT_REALLOCATE }; - typedef void *(*kit_allocate_fn)(int request, void *state, ptrdiff_t size, ptrdiff_t previous_size, void *pointer); - typedef struct { void *state; kit_allocate_fn allocate; } kit_allocator_t; - /* Application should implement this function if custom allocator * dispatch is enabled. * @@ -70,86 +53,67 @@ typedef struct { void *kit_alloc_dispatch(kit_allocator_t alloc, int request, ptrdiff_t size, ptrdiff_t previous_size, void *pointer); - kit_allocator_t kit_alloc_default(void); - #ifdef __cplusplus } #endif - #endif - -/************************************************************************ - * * - * * - * FILE: ./source/kit/array_ref.h * - * * - * * - ************************************************************************/ +/********************************************************************* + * * + * File: ./source/kit/array_ref.h * + * * + *********************************************************************/ #ifndef KIT_ARRAY_REF_H #define KIT_ARRAY_REF_H - #include <stddef.h> #include <stdint.h> - #ifdef __cplusplus extern "C" { #endif - typedef int (*kit_ar_compare_fn)(void const *left, void const *right); - int kit_ar_equal_bytes(ptrdiff_t left_element_size, ptrdiff_t left_size, void const *left_data, ptrdiff_t right_element_size, ptrdiff_t right_size, void const *right_data); - int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, void const *left_data, ptrdiff_t right_element_size, ptrdiff_t right_size, void const *right_data, kit_ar_compare_fn compare); - #define KIT_AR_MUT(type_) \ struct { \ ptrdiff_t size; \ type_ *values; \ } - #define KIT_AR(type_) \ struct { \ ptrdiff_t size; \ type_ const *values; \ } - #define KIT_AR_MUT_WRAP(name_, element_type_, array_) \ struct { \ ptrdiff_t size; \ element_type_ *values; \ } name_ = { .size = (sizeof(array_) / sizeof((array_)[0])), \ .values = (array_) } - #define KIT_AR_WRAP(name_, element_type_, array_) \ struct { \ ptrdiff_t size; \ element_type_ const *values; \ } name_ = { .size = (sizeof(array_) / sizeof((array_)[0])), \ .values = (array_) } - #define KIT_AR_EQUAL(left_, right_) \ kit_ar_equal_bytes(sizeof((left_).values[0]), (left_).size, \ (left_).values, sizeof((right_).values[0]), \ (right_).size, (right_).values) - #define KIT_AR_COMPARE(left_, right_, compare_) \ kit_ar_compare(sizeof((left_).values[0]), (left_).size, \ (left_).values, sizeof((right_).values[0]), \ (right_).size, (right_).values, \ (kit_ar_compare_fn) (compare_)) - #ifndef KIT_DISABLE_SHORT_NAMES # define ar_compare_fn kit_ar_compare_fn # define ar_equal_bytes kit_ar_equal_bytes # define ar_compare kit_ar_compare - # define AR_MUT KIT_AR_MUT # define AR KIT_AR # define AR_MUT_WRAP KIT_AR_MUT_WRAP @@ -157,40 +121,30 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, # define AR_EQUAL KIT_AR_EQUAL # define AR_COMPARE KIT_AR_COMPARE #endif - #ifdef __cplusplus } #endif - #endif - -/************************************************************************ - * * - * * - * FILE: ./source/kit/dynamic_array.h * - * * - * * - ************************************************************************/ +/********************************************************************* + * * + * File: ./source/kit/dynamic_array.h * + * * + *********************************************************************/ #ifndef KIT_DYNAMIC_ARRAY_H #define KIT_DYNAMIC_ARRAY_H - #ifdef __cplusplus extern "C" { #endif - typedef struct { ptrdiff_t capacity; ptrdiff_t size; void *values; kit_allocator_t alloc; } kit_da_void_t; - void kit_da_init(kit_da_void_t *array, ptrdiff_t element_size, ptrdiff_t size, kit_allocator_t alloc); - void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, ptrdiff_t size); - /* Dynamic array type definition. */ #define KIT_DA(element_type_) \ @@ -200,19 +154,16 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, element_type_ *values; \ kit_allocator_t alloc; \ } - /* Initialize dynamic array. */ #define KIT_DA_INIT(array_, size_, alloc_) \ kit_da_init((kit_da_void_t *) &(array_), \ sizeof((array_).values[0]), (size_), (alloc_)) - /* Declare and initialize dynamic array. */ #define KIT_DA_CREATE(name_, element_type_, size_) \ KIT_DA(element_type_) name_; \ KIT_DA_INIT(name_, (size_), kit_alloc_default()) - /* Destroy dynamic array. */ #define KIT_DA_DESTROY(array_) \ @@ -221,13 +172,11 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, kit_alloc_dispatch((array_).alloc, KIT_DEALLOCATE, 0, 0, \ (array_).values); \ } while (0) - /* Resize dynamic array. */ #define KIT_DA_RESIZE(array_, size_) \ kit_da_resize((kit_da_void_t *) &(array_), \ sizeof((array_).values[0]), size_) - /* Append a value to dynamic array. */ #define KIT_DA_APPEND(array_, value_) \ @@ -237,7 +186,6 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, if (kit_index_back_ < (array_).size) \ (array_).values[kit_index_back_] = (value_); \ } while (0) - /* Insert a value into dynamic array. */ #define KIT_DA_INSERT(array_, index_, value_) \ @@ -253,7 +201,6 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, (array_).values[kit_indert_n_] = (value_); \ } \ } while (0) - /* Erase a value from dynamic array. */ #define KIT_DA_ERASE(array_, index_) \ @@ -263,15 +210,12 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, (array_).values[i_ - 1] = (array_).values[i_]; \ KIT_DA_RESIZE((array_), (array_).size - 1); \ } while (0) - typedef KIT_DA(char) kit_string_t; - #ifndef KIT_DISABLE_SHORT_NAMES # define da_void_t kit_da_void_t # define da_init kit_da_init # define da_resize kit_da_resize # define string_t kit_string_t - # define DA KIT_DA # define DA_INIT KIT_DA_INIT # define DA_CREATE KIT_DA_CREATE @@ -281,35 +225,25 @@ typedef KIT_DA(char) kit_string_t; # define DA_INSERT KIT_DA_INSERT # define DA_ERASE KIT_DA_ERASE #endif - #ifdef __cplusplus } #endif - #endif - -/************************************************************************ - * * - * * - * FILE: ./source/kit/string_ref.h * - * * - * * - ************************************************************************/ +/********************************************************************* + * * + * File: ./source/kit/string_ref.h * + * * + *********************************************************************/ #ifndef KIT_STRING_REF_H #define KIT_STRING_REF_H - #include <string.h> - #ifdef __cplusplus extern "C" { #endif - typedef KIT_AR_MUT(char) kit_string_mut_t; typedef KIT_AR(char) kit_string_ref_t; - typedef kit_string_mut_t kit_out_str_t; typedef kit_string_ref_t kit_str_t; - #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-function" @@ -317,13 +251,11 @@ typedef kit_string_ref_t kit_str_t; # pragma GCC push_options # pragma GCC optimize("O3") #endif - static kit_str_t kit_str(ptrdiff_t const size, char const *const static_string) { kit_str_t const s = { .size = size, .values = static_string }; return s; } - /* Make a barbarian string for C standard library functions. * Not thread safe. * Use with caution. @@ -340,52 +272,39 @@ static char const *kit_make_bs(kit_str_t const s) { index = (index + 1) % 8; return result; } - #ifdef __GNUC__ # pragma GCC pop_options # pragma GCC diagnostic pop #endif - #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) - #ifndef KIT_DISABLE_SHORT_NAMES +# define BS(string_) kit_make_bs(KIT_WRAP_STR(string_)) # define string_mut_t kit_string_mut_t # define string_ref_t kit_string_ref_t # define out_str_t kit_out_str_t # 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 - #ifdef __cplusplus } #endif - #endif - -/************************************************************************ - * * - * * - * FILE: ./source/kit/file.h * - * * - * * - ************************************************************************/ +/********************************************************************* + * * + * File: ./source/kit/file.h * + * * + *********************************************************************/ #ifndef KIT_FILE_H #define KIT_FILE_H - #ifdef __cplusplus extern "C" { #endif - #if defined(_WIN32) && !defined(__CYGWIN__) # define KIT_PATH_DELIM_C '\\' # define KIT_PATH_DELIM "\\" @@ -395,59 +314,39 @@ extern "C" { # define KIT_PATH_DELIM "/" # define KIT_ENV_HOME "HOME" #endif - typedef enum { KIT_PATH_NONE, KIT_PATH_FILE, KIT_PATH_FOLDER } kit_path_type_t; - 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, kit_allocator_t alloc); - 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); - kit_status_t kit_file_create_folder(kit_str_t path); - kit_status_t kit_file_create_folder_recursive(kit_str_t path); - kit_status_t kit_file_remove(kit_str_t path); - kit_status_t kit_file_remove_folder(kit_str_t path); - kit_status_t kit_file_remove_recursive(kit_str_t path, kit_allocator_t alloc); - kit_path_type_t kit_path_type(kit_str_t path); - typedef struct { kit_status_t status; - int64_t time_modified_sec; int32_t time_modified_nsec; int64_t size; } kit_file_info_t; - kit_file_info_t kit_file_info(kit_str_t path); - typedef struct { kit_status_t status; KIT_DA(kit_string_t) files; } kit_path_list_t; - kit_path_list_t kit_file_enum_folder(kit_str_t path, kit_allocator_t alloc); - void kit_path_list_destroy(kit_path_list_t list); - #ifndef KIT_DISABLE_SHORT_NAMES # define path_norm kit_path_norm # define path_join kit_path_join @@ -468,36 +367,26 @@ void kit_path_list_destroy(kit_path_list_t list); # define path_list_t kit_path_list_t # define file_enum_folder kit_file_enum_folder # define path_list_destroy kit_path_list_destroy - # define PATH_DELIM_C KIT_PATH_DELIM_C # define PATH_DELIM KIT_PATH_DELIM # define ENV_HOME KIT_ENV_HOME - # define PATH_NONE KIT_PATH_NONE # define PATH_FILE KIT_PATH_FILE # define PATH_FOLDER KIT_PATH_FOLDER #endif - #ifdef __cplusplus } #endif - #endif - -/************************************************************************ - * * - * * - * FILE: ./source/kit/allocator.c * - * * - * * - ************************************************************************/ - +/********************************************************************* + * * + * File: ./source/kit/allocator.c * + * * + *********************************************************************/ #include <assert.h> - #ifndef KIT_DISABLE_SYSTEM_MALLOC # include <stdlib.h> #endif - static void *allocate(int request, void *state, ptrdiff_t size, ptrdiff_t previous_size, void *pointer) { #ifndef KIT_DISABLE_SYSTEM_MALLOC @@ -506,20 +395,17 @@ static void *allocate(int request, void *state, ptrdiff_t size, assert(previous_size == 0); assert(pointer == NULL); return malloc(size); - case KIT_DEALLOCATE: assert(size == 0); assert(pointer != NULL); free(pointer); return NULL; - case KIT_REALLOCATE: /* FIXME * Not implemented. */ assert(0); return NULL; - default: assert(0); } #else @@ -527,7 +413,6 @@ static void *allocate(int request, void *state, ptrdiff_t size, #endif return NULL; } - #ifndef KIT_ENABLE_CUSTOM_ALLOC_DISPATCH void *kit_alloc_dispatch(kit_allocator_t alloc, int request, ptrdiff_t size, ptrdiff_t previous_size, @@ -539,22 +424,16 @@ void *kit_alloc_dispatch(kit_allocator_t alloc, int request, pointer); } #endif - kit_allocator_t kit_alloc_default(void) { kit_allocator_t alloc = { .state = NULL, .allocate = allocate }; return alloc; } - -/************************************************************************ - * * - * * - * FILE: ./source/kit/array_ref.c * - * * - * * - ************************************************************************/ - +/********************************************************************* + * * + * File: ./source/kit/array_ref.c * + * * + *********************************************************************/ #include <string.h> - int kit_ar_equal_bytes(ptrdiff_t left_element_size, ptrdiff_t left_size, void const *left_data, ptrdiff_t right_element_size, @@ -571,7 +450,6 @@ int kit_ar_equal_bytes(ptrdiff_t left_element_size, return 0; return 1; } - int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, void const *left_data, ptrdiff_t right_element_size, ptrdiff_t right_size, @@ -595,39 +473,29 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, return 1; return 0; } - -/************************************************************************ - * * - * * - * FILE: ./source/kit/dynamic_array.c * - * * - * * - ************************************************************************/ - +/********************************************************************* + * * + * File: ./source/kit/dynamic_array.c * + * * + *********************************************************************/ #include <assert.h> #include <string.h> - void kit_da_init(kit_da_void_t *array, ptrdiff_t element_size, ptrdiff_t size, kit_allocator_t alloc) { assert(array != NULL); assert(element_size > 0); assert(size >= 0); assert(alloc.allocate != NULL); - memset(array, 0, sizeof(kit_da_void_t)); - if (size > 0) array->values = kit_alloc_dispatch(alloc, KIT_ALLOCATE, element_size * size, 0, NULL); - if (array->values != NULL) { array->capacity = size; array->size = size; } - array->alloc = alloc; } - static ptrdiff_t eval_capacity(ptrdiff_t current_cap, ptrdiff_t required_cap) { if (current_cap == 0) @@ -636,23 +504,18 @@ static ptrdiff_t eval_capacity(ptrdiff_t current_cap, while (cap < required_cap) cap *= 2; return cap; } - void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, ptrdiff_t size) { assert(array != NULL); assert(element_size > 0); assert(size >= 0); - if (size <= array->capacity) { array->size = size; } else { ptrdiff_t capacity = eval_capacity(array->capacity, size); - assert(array->alloc.allocate != NULL); - void *bytes = kit_alloc_dispatch( array->alloc, KIT_ALLOCATE, element_size * capacity, 0, NULL); - if (bytes != NULL) { if (array->size > 0) memcpy(bytes, array->values, element_size * array->size); @@ -665,21 +528,15 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size, } } } - -/************************************************************************ - * * - * * - * FILE: ./source/kit/file.c * - * * - * * - ************************************************************************/ - +/********************************************************************* + * * + * File: ./source/kit/file.c * + * * + *********************************************************************/ #include <assert.h> #include <stdlib.h> #include <string.h> - enum { PATH_BUF_SIZE = 4096 }; - #if defined(_WIN32) && !defined(__CYGWIN__) # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN 1 @@ -691,76 +548,58 @@ enum { PATH_BUF_SIZE = 4096 }; # include <sys/stat.h> # include <unistd.h> #endif - #ifdef __APPLE__ # define st_mtim st_mtimespec #endif - 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(".."); ptrdiff_t i, i1, j; - string_t norm; DA_INIT(norm, path.size, alloc); assert(norm.size == path.size); - if (norm.size != path.size) return norm; - memcpy(norm.values, path.values, path.size); - for (i1 = 0, i = 0; i < path.size; i++) { if (!is_delim(path.values[i])) continue; - str_t const s = { .size = i - i1 - 1, .values = path.values + i1 + 1 }; if (AR_EQUAL(s, parent)) { int have_parent = 0; ptrdiff_t i0 = 0; - for (j = 0; j < i1; j++) { if (norm.values[j] != '\0') have_parent = 1; if (is_delim(norm.values[j])) i0 = j; } - if (have_parent) { memset(norm.values + i0, '\0', i - i0); - if (!is_delim(path.values[i0])) norm.values[i] = '\0'; } } - i1 = i; } - ptrdiff_t size = 0; - for (i = 0; i < norm.size; i++) { if (norm.values[i] != '\0') { if (is_delim(norm.values[i])) @@ -770,39 +609,31 @@ kit_string_t kit_path_norm(kit_str_t const path, size++; } } - norm.size = size; return norm; } - kit_string_t kit_path_join(kit_str_t const left, kit_str_t const right, kit_allocator_t const alloc) { ptrdiff_t left_size = left.size; ptrdiff_t right_size = right.size; char const *right_values = right.values; - if (left_size > 0 && is_delim(left.values[left_size - 1])) left_size--; if (right_size > 0 && is_delim(right.values[0])) { right_size--; right_values++; } - kit_string_t joined; DA_INIT(joined, left_size + right_size + 1, alloc); assert(joined.size == left_size + right_size + 1); - if (joined.size != left_size + right_size + 1) return joined; - memcpy(joined.values, left.values, left_size); joined.values[left_size] = KIT_PATH_DELIM_C; memcpy(joined.values + left_size + 1, right_values, right_size); - return joined; } - kit_string_t kit_path_user(kit_allocator_t const alloc) { kit_string_t user = kit_get_env_(KIT_ENV_HOME, alloc); if (user.size == 0) { @@ -812,22 +643,18 @@ kit_string_t kit_path_user(kit_allocator_t const alloc) { } 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__ @@ -837,22 +664,17 @@ kit_string_t kit_path_cache(kit_allocator_t alloc) { 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 }; - ptrdiff_t i0 = 0; ptrdiff_t i = 0; ptrdiff_t n = 0; - for (; i < path.size; i++) { if (!is_delim(path.values[i])) continue; - if (i0 < i) { if (n++ == index) { s.values = path.values + i0; @@ -860,51 +682,39 @@ kit_str_t kit_path_index(kit_str_t const path, return s; } } - i0 = i + 1; } - if (n == index) { s.values = path.values + i0; s.size = i - i0; } - return s; } - kit_str_t kit_path_take(kit_str_t const path, ptrdiff_t const count) { str_t s = { .size = 0, .values = path.values }; - ptrdiff_t i0 = 0; ptrdiff_t i = 0; ptrdiff_t n = 0; - for (; i < path.size; i++) { if (!is_delim(path.values[i])) continue; - if (i0 < i) { if (n++ == count) { s.size = i; return s; } } - i0 = i + 1; } - if (n == count) s.size = i; - return s; } - #if defined(_WIN32) && !defined(__CYGWIN__) static void win32_prepare_path_(WCHAR *const buf, kit_str_t const path) { assert(path.size == 0 || path.values != NULL); assert(path.size + 5 < PATH_BUF_SIZE); - memset(buf, 0, PATH_BUF_SIZE); buf[0] = L'\\'; buf[1] = L'\\'; @@ -926,7 +736,6 @@ 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); - memset(buf, 0, PATH_BUF_SIZE); if (path.size > 0 && path.size + 1 < PATH_BUF_SIZE) memcpy(buf, path.values, path.size); @@ -935,7 +744,6 @@ static void unix_prepare_path_(char *const buf, char buf[PATH_BUF_SIZE]; \ unix_prepare_path_(buf, path) #endif - kit_status_t kit_file_create_folder(kit_str_t const path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) @@ -945,10 +753,8 @@ kit_status_t kit_file_create_folder(kit_str_t const path) { return mkdir(buf, 0755) == 0 ? KIT_OK : KIT_ERROR_MKDIR_FAILED; #endif } - kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { ptrdiff_t i; - for (i = 0;; i++) { str_t const part = kit_path_take(path, i); int const type = kit_path_type(part); @@ -962,10 +768,8 @@ kit_status_t kit_file_create_folder_recursive(kit_str_t const path) { if (part.size == path.size) break; } - return KIT_OK; } - kit_status_t kit_file_remove(kit_str_t const path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) @@ -974,7 +778,6 @@ kit_status_t kit_file_remove(kit_str_t const path) { return unlink(buf) == 0 ? KIT_OK : KIT_ERROR_UNLINK_FAILED; #endif } - kit_status_t kit_file_remove_folder(kit_str_t const path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) @@ -983,15 +786,12 @@ kit_status_t kit_file_remove_folder(kit_str_t const path) { return rmdir(buf) == 0 ? KIT_OK : KIT_ERROR_RMDIR_FAILED; #endif } - kit_status_t kit_file_remove_recursive(kit_str_t const path, kit_allocator_t const alloc) { int type = kit_path_type(path); ptrdiff_t i; - switch (type) { case KIT_PATH_FILE: return kit_file_remove(path); - case KIT_PATH_FOLDER: { kit_path_list_t list = kit_file_enum_folder(path, alloc); if (list.status != KIT_OK) { @@ -1006,13 +806,10 @@ kit_status_t kit_file_remove_recursive(kit_str_t const path, kit_path_list_destroy(list); return kit_file_remove_folder(path); } - default:; } - return KIT_ERROR_FILE_DO_NOT_EXIST; } - kit_path_type_t kit_path_type(kit_str_t const path) { PREPARE_PATH_BUF_; #if defined(_WIN32) && !defined(__CYGWIN__) @@ -1033,13 +830,10 @@ kit_path_type_t kit_path_type(kit_str_t const path) { #endif return KIT_PATH_NONE; } - kit_file_info_t kit_file_info(kit_str_t const path) { kit_file_info_t result; memset(&result, 0, sizeof result); - PREPARE_PATH_BUF_; - #if defined(_WIN32) && !defined(__CYGWIN__) HANDLE f = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -1055,14 +849,11 @@ kit_file_info_t kit_file_info(kit_str_t const path) { } else { assert(0); } - DWORD high; DWORD low = GetFileSize(f, &high); - result.size = (int64_t) ((((uint64_t) high) << 32) | (uint64_t) low); result.status = KIT_OK; - CloseHandle(f); return result; } @@ -1082,33 +873,25 @@ kit_file_info_t kit_file_info(kit_str_t const path) { return result; } #endif - result.status = KIT_ERROR_FILE_DO_NOT_EXIST; return result; } - kit_path_list_t kit_file_enum_folder(kit_str_t const path, kit_allocator_t const alloc) { PREPARE_PATH_BUF_; - kit_path_list_t result = { .status = KIT_OK }; DA_INIT(result.files, 0, alloc); - #if defined(_WIN32) && !defined(__CYGWIN__) if (path.size + 7 >= PATH_BUF_SIZE) { result.status = KIT_ERROR_PATH_TOO_LONG; return result; } - buf[path.size + 4] = '\\'; buf[path.size + 5] = '*'; - WIN32_FIND_DATAW data; HANDLE find = FindFirstFileW(buf, &data); - if (find == INVALID_HANDLE_VALUE) return result; - do { ptrdiff_t const n = result.files.size; DA_RESIZE(result.files, n + 1); @@ -1116,7 +899,6 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, result.status = KIT_ERROR_BAD_ALLOC; break; } - ptrdiff_t size = 0; while (size < MAX_PATH && data.cFileName[size] != L'\0') size++; DA_INIT(result.files.values[n], size, alloc); @@ -1125,34 +907,26 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, result.status = KIT_ERROR_BAD_ALLOC; break; } - for (ptrdiff_t i = 0; i < size; i++) result.files.values[n].values[i] = data.cFileName[i]; } while (FindNextFileW(find, &data) != 0); - FindClose(find); #else DIR *directory = opendir(buf); - if (directory == NULL) return result; - for (;;) { struct dirent *entry = readdir(directory); - if (entry == NULL) break; - if (entry->d_name[0] == '.') continue; - ptrdiff_t const n = result.files.size; DA_RESIZE(result.files, n + 1); if (result.files.size != n + 1) { result.status = KIT_ERROR_BAD_ALLOC; break; } - ptrdiff_t const size = (ptrdiff_t) strlen(entry->d_name); DA_INIT(result.files.values[n], size, alloc); if (result.files.values[n].size != size) { @@ -1160,22 +934,17 @@ kit_path_list_t kit_file_enum_folder(kit_str_t const path, result.status = KIT_ERROR_BAD_ALLOC; break; } - if (size > 0) memcpy(result.files.values[n].values, entry->d_name, size); } - closedir(directory); #endif - return result; } - void kit_path_list_destroy(kit_path_list_t list) { ptrdiff_t i; for (i = 0; i < list.files.size; i++) DA_DESTROY(list.files.values[i]); DA_DESTROY(list.files); } - #endif diff --git a/source/kit/file.h b/source/kit/file.h index 258fc37..52ebe25 100644 --- a/source/kit/file.h +++ b/source/kit/file.h @@ -19,12 +19,6 @@ extern "C" { # define KIT_ENV_HOME "HOME" #endif -typedef enum { - KIT_PATH_NONE, - KIT_PATH_FILE, - KIT_PATH_FOLDER -} kit_path_type_t; - 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, @@ -49,6 +43,12 @@ kit_status_t kit_file_remove_folder(kit_str_t path); kit_status_t kit_file_remove_recursive(kit_str_t path, kit_allocator_t alloc); +typedef enum { + KIT_PATH_NONE, + KIT_PATH_FILE, + KIT_PATH_FOLDER +} kit_path_type_t; + kit_path_type_t kit_path_type(kit_str_t path); typedef struct { @@ -84,10 +84,10 @@ void kit_path_list_destroy(kit_path_list_t list); # define file_remove kit_file_remove # define file_remove_folder kit_file_remove_folder # define file_remove_recursive kit_file_remove_recursive -# define path_type kit_path_type -# define file_size_result_t kit_file_size_result_t -# define file_size kit_file_size # define path_type_t kit_path_type_t +# define path_type kit_path_type +# define file_info_t kit_file_info_t +# define file_info kit_file_info # define path_list_t kit_path_list_t # define file_enum_folder kit_file_enum_folder # define path_list_destroy kit_path_list_destroy |