From 4d80df6e306009d6c822127a7e4f4d3eaa2580b7 Mon Sep 17 00:00:00 2001 From: jgabaut <109908086+jgabaut@users.noreply.github.com> Date: Thu, 8 Aug 2024 06:09:21 +0200 Subject: [PATCH] feat: 0.4.4 Add option to block usage with an active temp session, drop list template, --enable-locate (#77) * chore: move list template to new file * feat: push calls return NULL when has_temp==1 and conf wants to * chore: rename __KLS_STRCPY() to avoid using __ namespacing * feat: collect common parts for push ops * feat: add enable-locate * chore: update bad_size test * feat: include profileapi.h instead of whole windows.h * chore: drop intrusive mention from readme * chore: bump invil to 0.2.15 * chore: update stego.lock * chore: bump version * chore: bump anvil version in stego.lock to 2.0.6 --- Makefile.am | 4 + README.md | 8 +- configure.ac | 9 +- docs/koliseo.doxyfile | 2 +- invil | 2 +- src/koliseo.c | 974 ++++++++++++++-------------------- src/koliseo.h | 629 ++++------------------ static/demo.c | 3 +- static/list_example.c | 3 +- stego.lock | 3 +- templates/list.h | 522 ++++++++++++++++++ tests/error/bad_size.k.stderr | 2 +- 12 files changed, 1046 insertions(+), 1115 deletions(-) create mode 100644 templates/list.h diff --git a/Makefile.am b/Makefile.am index 356506c..6c55942 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,6 +30,10 @@ AM_LDFLAGS = -O2 # Compiler flags AM_CFLAGS = $(KOLISEO_CFLAGS) -O2 -Werror -Wpedantic -Wall --std=c11 +if LOCATE_BUILD +AM_CFLAGS += -DKOLISEO_HAS_LOCATE +endif + if DEBUG_BUILD AM_LDFLAGS += -ggdb -O0 AM_CFLAGS += -DKLS_DEBUG_CORE -DKLS_SETCONF_DEBUG diff --git a/README.md b/README.md index 33e6527..6861fd1 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ ## What is this thing? This is a C library for an arena allocator, whose arenas are named `Koliseo`. - It offers a basic API to perform initalisation, push (request arena memory), reset and free of a `Koliseo`. + It offers a basic API to perform initialisation, push (request arena memory), reset and free of a `Koliseo`. If you compile it without defining any special macros, you will get the basic functionality. @@ -98,7 +98,7 @@ int main(void) ### Region A ready-to-go index for every allocation you make. - - It uses an intrusive linked list and (at the moment) has quite the memory overhead, due to hosting a couple static string buffers for the tags, so it may not be suited for all usecases. + - It uses a linked list and has some the memory overhead, due to hosting a couple static string buffers for the tags, so it may not be suited for all usecases. - Offers extended API with tagging arguments, to type/name your references - For now, two allocations backends can be chosen for the list, it can be stored: - In an inner Koliseo (this puts an extra limit to the total number of single allocations) @@ -121,10 +121,10 @@ int main(void) ### List template - Any time `LIST_T` is defined before including `koliseo.h`, a basic linked-list implementation supporting `Koliseo` allocation will be declared for the passed type. + Any time `LIST_T` is defined before including `templates/list.h`, a basic linked-list implementation supporting `Koliseo` allocation will be declared for the passed type. - It can be done also after building a static object for the library. - The `LIST_T` macro and the `koliseo.h` should be repeatable without issues, allowing definition of more than one list interface. + The `LIST_T` macro and the `templates/list.h` should be repeatable without issues, allowing definition of more than one list interface. This is implemented using some code-generating macros, which could rended build time slower if overused. diff --git a/configure.ac b/configure.ac index 313e00d..95e7dad 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ # Define the package name and version -AC_INIT([koliseo], [0.4.3], [jgabaut@github.com]) +AC_INIT([koliseo], [0.4.4], [jgabaut@github.com]) # Verify automake version and enable foreign option AM_INIT_AUTOMAKE([foreign -Wall]) @@ -11,6 +11,10 @@ build_windows=no build_mac=no echo "Host os: $host_os" +AC_ARG_ENABLE([locate], + [AS_HELP_STRING([--enable-locate], [Enable location signatures])], + [enable_locate=$enableval], + [enable_locate=no]) AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [Enable debug build])], [enable_debug=$enableval], @@ -35,6 +39,7 @@ AC_ARG_ENABLE([exper], [AS_HELP_STRING([--enable-exper], [Enable experimental features])], [enable_exper=$enableval], [enable_exper=no]) +AM_CONDITIONAL([LOCATE_BUILD], [test "$enable_locate" = "yes"]) AM_CONDITIONAL([DEBUG_BUILD], [test "$enable_debug" = "yes"]) AM_CONDITIONAL([CURSES_BUILD], [test "$enable_curses" = "yes"]) AM_CONDITIONAL([GULP_BUILD], [test "$enable_gulp" = "yes"]) @@ -104,7 +109,7 @@ AM_CONDITIONAL([LINUX_BUILD], [test "$build_linux" = "yes"]) # Set a default version number if not specified externally AC_ARG_VAR([VERSION], [Version number]) if test -z "$VERSION"; then - VERSION="0.4.3" + VERSION="0.4.4" fi # Output variables to the config.h header diff --git a/docs/koliseo.doxyfile b/docs/koliseo.doxyfile index de199a7..3104840 100644 --- a/docs/koliseo.doxyfile +++ b/docs/koliseo.doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = koliseo # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.4.3 +PROJECT_NUMBER = 0.4.4 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/invil b/invil index 7d41697..b6cf0b7 160000 --- a/invil +++ b/invil @@ -1 +1 @@ -Subproject commit 7d416977306ae19d30aa403f133f016474d0b1d1 +Subproject commit b6cf0b7efe34af35257dd4798abe627e2ef5a4dd diff --git a/src/koliseo.c b/src/koliseo.c index 1f84a40..a1097b2 100644 --- a/src/koliseo.c +++ b/src/koliseo.c @@ -25,9 +25,10 @@ static const KLS_Conf KLS_DEFAULT_CONF__ = { .kls_autoset_temp_regions = 0, .kls_collect_stats = 0, .kls_verbose_lvl = 0, + .kls_block_while_has_temp = 0, .kls_log_fp = NULL, .kls_log_filepath = "", -}; +}; /**< Inner config used for any Koliseo used to host the regions for another Koliseo in the KLS_BASIC config.*/ #endif KLS_Conf KLS_DEFAULT_CONF = { @@ -37,11 +38,12 @@ KLS_Conf KLS_DEFAULT_CONF = { .kls_reglist_kls_size = 0, .kls_autoset_temp_regions = 0, #endif // KOLISEO_HAS_REGION + .kls_block_while_has_temp = 0, .kls_collect_stats = 0, .kls_verbose_lvl = 0, .kls_log_fp = NULL, .kls_log_filepath = "", -}; +}; /**< Config used by any new Koliseo by default.*/ KLS_Stats KLS_STATS_DEFAULT = { .tot_pushes = 0, @@ -175,7 +177,7 @@ const char* kls_reglist_backend_string(KLS_RegList_Alloc_Backend kls_be) * Used to prepare a KLS_Conf without caring about KOLISEO_HAS_REGIONS. * @see KLS_Conf */ -KLS_Conf kls_conf_init(int autoset_regions, int alloc_backend, ptrdiff_t reglist_kls_size, int autoset_temp_regions, int collect_stats, int verbose_lvl, FILE* log_fp, const char* log_filepath) +KLS_Conf kls_conf_init(int autoset_regions, int alloc_backend, ptrdiff_t reglist_kls_size, int autoset_temp_regions, int collect_stats, int verbose_lvl, int block_while_has_temp, FILE* log_fp, const char* log_filepath) { KLS_Conf res = {0}; #ifdef KOLISEO_HAS_REGION @@ -191,6 +193,7 @@ KLS_Conf kls_conf_init(int autoset_regions, int alloc_backend, ptrdiff_t reglist #endif // KOLISEO_HAS_REGION res.kls_collect_stats = collect_stats; res.kls_verbose_lvl = verbose_lvl; + res.kls_block_while_has_temp = block_while_has_temp; res.kls_log_fp = log_fp; res.kls_log_filepath = log_filepath; @@ -202,6 +205,11 @@ KLS_Conf kls_conf_init(int autoset_regions, int alloc_backend, ptrdiff_t reglist */ void kls_dbg_features(void) { +#ifdef KOLISEO_HAS_LOCATE + fprintf(stderr, "[KLS] caller location APIs are enabled\n"); +#else + fprintf(stderr, "[KLS] caller location APIs are not enabled\n"); +#endif #ifdef KOLISEO_HAS_CURSES fprintf(stderr, "[KLS] ncurses.h integration is enabled\n"); #else @@ -364,12 +372,22 @@ void kls_log(Koliseo *kls, const char *tag, const char *format, ...) * @see kls_temp_start() * @see kls_temp_end() */ +#ifndef KOLISEO_HAS_LOCATE Koliseo *kls_new_alloc(ptrdiff_t size, kls_alloc_func alloc_func) +#else +Koliseo *kls_new_alloc_dbg(ptrdiff_t size, kls_alloc_func alloc_func, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE { if (size < (ptrdiff_t)sizeof(Koliseo)) { +#ifndef KOLISEO_HAS_LOCATE fprintf(stderr, "[ERROR] at %s(): invalid requested kls size (%td). Min accepted is: (%td).\n", __func__, size, (ptrdiff_t)sizeof(Koliseo)); +#else + fprintf(stderr, + "[ERROR] " KLS_Loc_Fmt "%s(): invalid requested kls size (%td). Min accepted is: (%td).\n", + KLS_Loc_Arg(loc), __func__, size, (ptrdiff_t)sizeof(Koliseo)); +#endif // KOLISEO_HAS_LOCATE //TODO Is it better to abort the program? return NULL; } @@ -435,7 +453,11 @@ Koliseo *kls_new_alloc(ptrdiff_t size, kls_alloc_func alloc_func) } #endif // KOLISEO_HAS_REGION } else { +#ifndef KOLISEO_HAS_LOCATE fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); +#else + fprintf(stderr, "[KLS] " KLS_Loc_Fmt "Failed %s() call.\n", KLS_Loc_Arg(loc), __func__); +#endif // KOLISEO_HAS_LOCATE exit(EXIT_FAILURE); } #ifdef KLS_DEBUG_CORE @@ -717,6 +739,62 @@ bool kls_set_conf(Koliseo *kls, KLS_Conf conf) return true; } +#ifndef KOLISEO_HAS_LOCATE +static inline void kls__check_available(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) +#else +static inline void kls__check_available_dbg(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE +{ + assert(kls != NULL); + ptrdiff_t available = kls->size - kls->offset; + ptrdiff_t padding = -kls->offset & (align - 1); + if (count > PTRDIFF_MAX / size || available - padding < size * count) { + if (count > PTRDIFF_MAX / size) { +#ifndef _WIN32 +#ifndef KOLISEO_HAS_LOCATE + fprintf(stderr, + "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%li].\n", + count, PTRDIFF_MAX / size); +#else + fprintf(stderr, + "[KLS] " KLS_Loc_Fmt "count [%td] was bigger than PTRDIFF_MAX/size [%li].\n", + KLS_Loc_Arg(loc), + count, PTRDIFF_MAX / size); +#endif // KOLISEO_HAS_LOCATE +#else +#ifndef KOLISEO_HAS_LOCATE + fprintf(stderr, + "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n", + count, PTRDIFF_MAX / size); +#else + fprintf(stderr, + "[KLS] " KLS_Loc_Fmt "count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n", + KLS_Loc_Arg(loc), + count, PTRDIFF_MAX / size); +#endif // KOLISEO_HAS_LOCATE +#endif // _WIN32 + } else { +#ifndef KOLISEO_HAS_LOCATE + fprintf(stderr, + "[KLS] Out of memory. size*count [%td] was bigger than available-padding [%td].\n", + size * count, available - padding); +#else + fprintf(stderr, + "[KLS] " KLS_Loc_Fmt "Out of memory. size*count [%td] was bigger than available-padding [%td].\n", + KLS_Loc_Arg(loc), + size * count, available - padding); +#endif // KOLISEO_HAS_LOCATE + } +#ifndef KOLISEO_HAS_LOCATE + fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); +#else + fprintf(stderr, "[KLS] " KLS_Loc_Fmt "Failed %s() call.\n", KLS_Loc_Arg(loc), __func__); +#endif // KOLISEO_HAS_LOCATE + kls_free(kls); + exit(EXIT_FAILURE); + } +} + /** * Takes a Koliseo pointer, and ptrdiff_t values for size, align and count. Tries pushing the specified amount of memory to the Koliseo data field, or goes to exit() if the operation fails. * Notably, it does NOT zero the memory region. @@ -744,28 +822,20 @@ void *kls_push(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__); exit(EXIT_FAILURE); } - ptrdiff_t available = kls->size - kls->offset; - ptrdiff_t padding = -kls->offset & (align - 1); - if (count > PTRDIFF_MAX / size || available - padding < size * count) { - if (count > PTRDIFF_MAX / size) { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%li].\n", - count, PTRDIFF_MAX / size); -#else - fprintf(stderr, - "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n", - count, PTRDIFF_MAX / size); -#endif - } else { - fprintf(stderr, - "[KLS] Out of memory. size*count [%td] was bigger than available-padding [%td].\n", - size * count, available - padding); - } - fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); - kls_free(kls); + if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) { + fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__); +#ifdef KLS_DEBUG_CORE + kls_log(kls, "ERROR", "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", __func__); exit(EXIT_FAILURE); +#endif // KLS_DEBUG_CORE + return NULL; } +#ifndef KOLISEO_HAS_LOCATE + kls__check_available(kls, size, align, count); +#else + kls__check_available_dbg(kls, size, align, count, KLS_HERE); +#endif // KOLISEO_HAS_LOCATE + ptrdiff_t padding = -kls->offset & (align - 1); char *p = kls->data + kls->offset + padding; kls->prev_offset = kls->offset; kls->offset += padding + size * count; @@ -815,8 +885,13 @@ void *kls_push(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) * @param count The multiplicative quantity to scale data size to push for. * @return A void pointer to the start of memory just pushed to the Koliseo. */ +#ifndef KOLISEO_HAS_LOCATE void *kls_push_zero(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) +#else +void *kls_push_zero_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE { #ifdef KLS_DEBUG_CORE @@ -834,29 +909,22 @@ void *kls_push_zero(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__); exit(EXIT_FAILURE); } - ptrdiff_t available = kls->size - kls->offset; - ptrdiff_t padding = -kls->offset & (align - 1); - if (count > PTRDIFF_MAX / size || (available - padding) < (size * count)) { - if (count > PTRDIFF_MAX / size) { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%li].\n", - count, PTRDIFF_MAX / size); + if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) { +#ifndef KOLISEO_HAS_LOCATE + fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__); #else - fprintf(stderr, - "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n", - count, PTRDIFF_MAX / size); -#endif - } else { - fprintf(stderr, - "[KLS] Out of memory. size*count [%td] was bigger than available-padding [%td].\n", - size * count, available - padding); - } - fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); - kls_free(kls); + fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__); + kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__); exit(EXIT_FAILURE); - //return 0; +#endif // KOLISEO_HAS_LOCATE + return NULL; } +#ifndef KOLISEO_HAS_LOCATE + kls__check_available(kls, size, align, count); +#else + kls__check_available_dbg(kls, size, align, count, loc); +#endif + ptrdiff_t padding = -kls->offset & (align - 1); char *p = kls->data + kls->offset + padding; //Zero new area memset(p, 0, size * count); @@ -899,64 +967,19 @@ void *kls_push_zero(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, return p; } -/** - * Takes a Koliseo pointer, and ptrdiff_t values for size, align and count. Tries pushing the specified amount of memory to the Koliseo data field, or goes to exit() if the operation fails. - * Notably, it zeroes the memory region. - * @param kls The Koliseo at hand. - * @param size The size for data to push. - * @param align The alignment for data to push. - * @param count The multiplicative quantity to scale data size to push for. - * @return A void pointer to the start of memory just pushed to the Koliseo. - */ -void *kls_push_zero_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, - ptrdiff_t count) -{ - -#ifdef KLS_DEBUG_CORE -#ifndef _WIN32 - struct timespec start_time, end_time; - clock_gettime(CLOCK_MONOTONIC, &start_time); -#else - LARGE_INTEGER start_time, end_time, frequency; - QueryPerformanceFrequency(&frequency); - QueryPerformanceCounter(&start_time); -#endif -#endif - - if (kls == NULL) { - fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__); - exit(EXIT_FAILURE); - } - - ptrdiff_t available = kls->size - kls->offset; - ptrdiff_t padding = -kls->offset & (align - 1); - if (count > PTRDIFF_MAX / size || (available - padding) < (size * count)) { - if (count > PTRDIFF_MAX / size) { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%li].\n", - count, PTRDIFF_MAX / size); -#else - fprintf(stderr, - "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n", - count, PTRDIFF_MAX / size); -#endif - } else { - fprintf(stderr, - "[KLS] Out of memory. size*count [%td] was bigger than available-padding [%td].\n", - size * count, available - padding); - } - fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); - kls_free(kls); - exit(EXIT_FAILURE); - //return 0; - } - char *p = kls->data + kls->offset + padding; - //Zero new area - memset(p, 0, size * count); - kls->prev_offset = kls->offset; - kls->offset += padding + size * count; #ifdef KOLISEO_HAS_REGION +static inline void kls__autoregion(const char* caller, Koliseo* kls, ptrdiff_t padding, const char* region_name, size_t region_name_len, const char* region_desc, size_t region_desc_len, int region_type) +{ + assert(caller != NULL); + assert(kls != NULL); + assert(region_name != NULL); + assert(region_name_len > 0); + size_t name_len = (region_name_len <= KLS_REGION_MAX_NAME_SIZE ? region_name_len : KLS_REGION_MAX_NAME_SIZE); + //assert(region_name_len <= KLS_REGION_MAX_NAME_SIZE); + assert(region_desc != NULL); + assert(region_desc_len > 0); + size_t desc_len = (region_desc_len <= KLS_REGION_MAX_DESC_SIZE ? region_desc_len : KLS_REGION_MAX_DESC_SIZE); + //assert(region_desc_len <= KLS_REGION_MAX_DESC_SIZE); if (kls->conf.kls_autoset_regions == 1) { KLS_Region *reg = NULL; switch (kls->conf.kls_reglist_alloc_backend) { @@ -970,11 +993,11 @@ void *kls_push_zero_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, } else { fprintf(stderr, "[ERROR] [%s()]: Exceeding kls->max_regions_kls_alloc_basic: {%i}.\n", - __func__, kls->max_regions_kls_alloc_basic); + caller, kls->max_regions_kls_alloc_basic); if (kls->conf.kls_verbose_lvl > 0) { kls_log(kls, "ERROR", "[%s()]: Exceeding kls->max_regions_kls_alloc_basic: {%i}.", - __func__, kls->max_regions_kls_alloc_basic); + caller, kls->max_regions_kls_alloc_basic); kls_rl_showList_toFile(kls->regs, kls->conf.kls_log_fp); print_kls_2file(kls->conf.kls_log_fp, kls->reglist_kls); print_kls_2file(kls->conf.kls_log_fp, kls); @@ -987,11 +1010,11 @@ void *kls_push_zero_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, default: { fprintf(stderr, "[ERROR] [%s()]: Unexpected KLS_RegList_Alloc_Backend value: {%i}.\n", - __func__, kls->conf.kls_reglist_alloc_backend); + caller, kls->conf.kls_reglist_alloc_backend); #ifdef KLS_DEBUG_CORE kls_log(kls, "ERROR", "%s(): Invalid KLS_RegList_Alloc_Backend value: {%i}.", - __func__, kls->conf.kls_reglist_alloc_backend); + caller, kls->conf.kls_reglist_alloc_backend); #endif kls_free(kls); exit(EXIT_FAILURE); @@ -1002,18 +1025,155 @@ void *kls_push_zero_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, reg->end_offset = kls->offset; reg->size = reg->end_offset - reg->begin_offset; reg->padding = padding; - reg->type = KLS_None; - strncpy(reg->name, KOLISEO_DEFAULT_REGION_NAME, - KLS_REGION_MAX_NAME_SIZE); - reg->name[KLS_REGION_MAX_NAME_SIZE] = '\0'; - strncpy(reg->desc, KOLISEO_DEFAULT_REGION_DESC, - KLS_REGION_MAX_DESC_SIZE); - reg->desc[KLS_REGION_MAX_DESC_SIZE] = '\0'; + reg->type = region_type; + strncpy(reg->name, region_name, + name_len); + reg->name[name_len] = '\0'; + strncpy(reg->desc, region_desc, + desc_len); + reg->desc[desc_len] = '\0'; //KLS_Region_List reglist = kls_emptyList(); //reglist = kls_cons(kls,reg,reglist); //kls->regs = kls_append(kls,reglist, kls->regs); kls->regs = kls_rl_cons(kls, reg, kls->regs); } +} + +static inline void kls__temp_autoregion(const char* caller, Koliseo_Temp* t_kls, ptrdiff_t padding, const char* region_name, size_t region_name_len, const char* region_desc, size_t region_desc_len, int region_type) +{ + assert(caller != NULL); + assert(t_kls != NULL); + Koliseo* kls = t_kls->kls; + assert(kls != NULL); + assert(region_name != NULL); + assert(region_name_len > 0); + size_t name_len = (region_name_len <= KLS_REGION_MAX_NAME_SIZE ? region_name_len : KLS_REGION_MAX_NAME_SIZE); + //assert(region_name_len <= KLS_REGION_MAX_NAME_SIZE); + assert(region_desc != NULL); + assert(region_desc_len > 0); + size_t desc_len = (region_desc_len <= KLS_REGION_MAX_DESC_SIZE ? region_desc_len : KLS_REGION_MAX_DESC_SIZE); + //assert(region_desc_len <= KLS_REGION_MAX_DESC_SIZE); + KLS_Region *reg = NULL; + if (t_kls->conf.kls_autoset_regions == 1) { + switch (t_kls->conf.tkls_reglist_alloc_backend) { + case KLS_REGLIST_ALLOC_LIBC: { + reg = (KLS_Region *) malloc(sizeof(KLS_Region)); + } + break; + case KLS_REGLIST_ALLOC_KLS_BASIC: { + if (kls_rl_length(t_kls->t_regs) < + t_kls->max_regions_kls_alloc_basic) { + reg = KLS_PUSH(t_kls->reglist_kls, KLS_Region); + } else { + fprintf(stderr, + "[ERROR] [%s()]: Exceeding t_kls->max_regions_kls_alloc_basic: {%i}.\n", + caller, t_kls->max_regions_kls_alloc_basic); + if (kls->conf.kls_verbose_lvl > 0) { + kls_log(kls, "ERROR", + "[%s()]: Exceeding t_kls->max_regions_kls_alloc_basic: {%i}.", + caller, t_kls->max_regions_kls_alloc_basic); + kls_rl_showList_toFile(t_kls->t_regs, + kls->conf.kls_log_fp); + print_kls_2file(kls->conf.kls_log_fp, + t_kls->reglist_kls); + print_kls_2file(kls->conf.kls_log_fp, kls); + } + kls_free(kls); + exit(EXIT_FAILURE); + } + } + break; + default: { + fprintf(stderr, + "[ERROR] %s(): Invalid conf.tkls_reglist_alloc_backend value: {%i}.\n", + caller, t_kls->conf.tkls_reglist_alloc_backend); +#ifdef KLS_DEBUG_CORE + kls_log(kls, "ERROR", + "%s(): Invalid conf.tkls_reglist_alloc_backend value: {%i}.\n", + caller, t_kls->conf.tkls_reglist_alloc_backend); +#endif + kls_free(kls); + exit(EXIT_FAILURE); + } + break; + } + reg->begin_offset = kls->prev_offset; + reg->end_offset = kls->offset; + reg->size = reg->end_offset - reg->begin_offset; + reg->padding = padding; + reg->type = KLS_None; + strncpy(reg->name, region_name, + name_len); + reg->name[name_len] = '\0'; + strncpy(reg->desc, region_desc, + desc_len); + reg->desc[desc_len] = '\0'; + //KLS_Region_List reglist = kls_emptyList(); + //reglist = kls_cons(kls,reg,reglist); + //t_kls->t_regs = kls_append(kls,reglist, t_kls->t_regs); + t_kls->t_regs = kls_rl_t_cons(t_kls, reg, t_kls->t_regs); + } +} +#endif // KOLISEO_HAS_REGION + +/** + * Takes a Koliseo pointer, and ptrdiff_t values for size, align and count. Tries pushing the specified amount of memory to the Koliseo data field, or goes to exit() if the operation fails. + * Notably, it zeroes the memory region. + * @param kls The Koliseo at hand. + * @param size The size for data to push. + * @param align The alignment for data to push. + * @param count The multiplicative quantity to scale data size to push for. + * @return A void pointer to the start of memory just pushed to the Koliseo. + */ +#ifndef KOLISEO_HAS_LOCATE +void *kls_push_zero_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count) +#else +void *kls_push_zero_AR_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE +{ + +#ifdef KLS_DEBUG_CORE +#ifndef _WIN32 + struct timespec start_time, end_time; + clock_gettime(CLOCK_MONOTONIC, &start_time); +#else + LARGE_INTEGER start_time, end_time, frequency; + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&start_time); +#endif +#endif + + if (kls == NULL) { + fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__); + exit(EXIT_FAILURE); + } + if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) { +#ifndef KOLISEO_HAS_LOCATE + fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__); +#else + fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__); + kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__); + exit(EXIT_FAILURE); +#endif // KOLISEO_HAS_LOCATE + return NULL; + } + +#ifndef KOLISEO_HAS_LOCATE + kls__check_available(kls, size, align, count); +#else + kls__check_available_dbg(kls, size, align, count, loc); +#endif + ptrdiff_t padding = -kls->offset & (align - 1); + char *p = kls->data + kls->offset + padding; + //Zero new area + memset(p, 0, size * count); + kls->prev_offset = kls->offset; + kls->offset += padding + size * count; + +#ifdef KOLISEO_HAS_REGION + kls__autoregion(__func__, kls, padding, KOLISEO_DEFAULT_REGION_NAME, strlen(KOLISEO_DEFAULT_REGION_NAME), KOLISEO_DEFAULT_REGION_DESC, strlen(KOLISEO_DEFAULT_REGION_DESC), KLS_None); #endif // KOLISEO_HAS_REGION char h_size[200]; @@ -1062,8 +1222,13 @@ void *kls_push_zero_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, * @param count The multiplicative quantity to scale data size to push for. * @return A void pointer to the start of memory just pushed to the referred Koliseo. */ +#ifndef KOLISEO_HAS_LOCATE void *kls_temp_push_zero_AR(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) +#else +void *kls_temp_push_zero_AR_dbg(Koliseo_Temp *t_kls, ptrdiff_t size, + ptrdiff_t align, ptrdiff_t count, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE { #ifdef KLS_DEBUG_CORE @@ -1088,95 +1253,20 @@ void *kls_temp_push_zero_AR(Koliseo_Temp *t_kls, ptrdiff_t size, __func__); exit(EXIT_FAILURE); } - ptrdiff_t available = kls->size - kls->offset; +#ifndef KOLISEO_HAS_LOCATE + kls__check_available(kls, size, align, count); +#else + kls__check_available_dbg(kls, size, align, count, loc); +#endif ptrdiff_t padding = -kls->offset & (align - 1); - if (count > PTRDIFF_MAX / size || (available - padding) < (size * count)) { - if (count > PTRDIFF_MAX / size) { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%li].\n", - count, PTRDIFF_MAX / size); -#else - fprintf(stderr, - "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n", - count, PTRDIFF_MAX / size); -#endif - } else { - fprintf(stderr, - "[KLS] Out of memory. size*count [%td] was bigger than available-padding [%td].\n", - size * count, available - padding); - } - fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); - kls_free(kls); - exit(EXIT_FAILURE); - //return 0; - } char *p = kls->data + kls->offset + padding; //Zero new area memset(p, 0, size * count); kls->prev_offset = kls->offset; kls->offset += padding + size * count; + #ifdef KOLISEO_HAS_REGION - KLS_Region *reg = NULL; - if (t_kls->conf.kls_autoset_regions == 1) { - switch (t_kls->conf.tkls_reglist_alloc_backend) { - case KLS_REGLIST_ALLOC_LIBC: { - reg = (KLS_Region *) malloc(sizeof(KLS_Region)); - } - break; - case KLS_REGLIST_ALLOC_KLS_BASIC: { - if (kls_rl_length(t_kls->t_regs) < - t_kls->max_regions_kls_alloc_basic) { - reg = KLS_PUSH(t_kls->reglist_kls, KLS_Region); - } else { - fprintf(stderr, - "[ERROR] [%s()]: Exceeding t_kls->max_regions_kls_alloc_basic: {%i}.\n", - __func__, t_kls->max_regions_kls_alloc_basic); - if (kls->conf.kls_verbose_lvl > 0) { - kls_log(kls, "ERROR", - "[%s()]: Exceeding t_kls->max_regions_kls_alloc_basic: {%i}.", - __func__, t_kls->max_regions_kls_alloc_basic); - kls_rl_showList_toFile(t_kls->t_regs, - kls->conf.kls_log_fp); - print_kls_2file(kls->conf.kls_log_fp, - t_kls->reglist_kls); - print_kls_2file(kls->conf.kls_log_fp, kls); - } - kls_free(kls); - exit(EXIT_FAILURE); - } - } - break; - default: { - fprintf(stderr, - "[ERROR] %s(): Invalid conf.tkls_reglist_alloc_backend value: {%i}.\n", - __func__, t_kls->conf.tkls_reglist_alloc_backend); -#ifdef KLS_DEBUG_CORE - kls_log(kls, "ERROR", - "%s(): Invalid conf.tkls_reglist_alloc_backend value: {%i}.\n", - __func__, t_kls->conf.tkls_reglist_alloc_backend); -#endif - kls_free(kls); - exit(EXIT_FAILURE); - } - break; - } - reg->begin_offset = kls->prev_offset; - reg->end_offset = kls->offset; - reg->size = reg->end_offset - reg->begin_offset; - reg->padding = padding; - reg->type = KLS_None; - strncpy(reg->name, KOLISEO_DEFAULT_REGION_NAME, - KLS_REGION_MAX_NAME_SIZE); - reg->name[KLS_REGION_MAX_NAME_SIZE] = '\0'; - strncpy(reg->desc, KOLISEO_DEFAULT_REGION_DESC, - KLS_REGION_MAX_DESC_SIZE); - reg->desc[KLS_REGION_MAX_DESC_SIZE] = '\0'; - //KLS_Region_List reglist = kls_emptyList(); - //reglist = kls_cons(kls,reg,reglist); - //t_kls->t_regs = kls_append(kls,reglist, t_kls->t_regs); - t_kls->t_regs = kls_rl_t_cons(t_kls, reg, t_kls->t_regs); - } + kls__temp_autoregion(__func__, t_kls, padding, KOLISEO_DEFAULT_REGION_NAME, strlen(KOLISEO_DEFAULT_REGION_NAME), KOLISEO_DEFAULT_REGION_DESC, strlen(KOLISEO_DEFAULT_REGION_DESC), KLS_None); #endif // KOLISEO_HAS_REGION char h_size[200]; @@ -1230,8 +1320,13 @@ void *kls_temp_push_zero_AR(Koliseo_Temp *t_kls, ptrdiff_t size, * @param desc The desc to assign to the resulting KLS_Region. * @return A void pointer to the start of memory just pushed to the Koliseo. */ +#ifndef KOLISEO_HAS_LOCATE void *kls_push_zero_named(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, char *name, char *desc) +#else +void *kls_push_zero_named_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count, char *name, char *desc, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE { #ifdef KLS_DEBUG_CORE @@ -1249,110 +1344,43 @@ void *kls_push_zero_named(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__); exit(EXIT_FAILURE); } - ptrdiff_t available = kls->size - kls->offset; - ptrdiff_t padding = -kls->offset & (align - 1); - if (count > PTRDIFF_MAX / size || (available - padding) < (size * count)) { - if (count > PTRDIFF_MAX / size) { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] count [%li] was bigger than PTRDIFF_MAX/size [%li].\n", - count, PTRDIFF_MAX / size); -#else - fprintf(stderr, - "[KLS] count [%lli] was bigger than PTRDIFF_MAX/size [%lli].\n", - count, PTRDIFF_MAX / size); -#endif - } else { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] Out of memory. size*count [%li] was bigger than available-padding [%li].\n", - size * count, available - padding); + if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) { +#ifndef KOLISEO_HAS_LOCATE + fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__); #else - fprintf(stderr, - "[KLS] Out of memory. size*count [%lli] was bigger than available-padding [%lli].\n", - size * count, available - padding); -#endif - } - fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); - kls_free(kls); + fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__); + kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__); exit(EXIT_FAILURE); - //return 0; +#endif // KOLISEO_HAS_LOCATE + return NULL; } +#ifndef KOLISEO_HAS_LOCATE + kls__check_available(kls, size, align, count); +#else + kls__check_available_dbg(kls, size, align, count, loc); +#endif + ptrdiff_t padding = -kls->offset & (align - 1); char *p = kls->data + kls->offset + padding; //Zero new area memset(p, 0, size * count); kls->prev_offset = kls->offset; kls->offset += padding + size * count; - if (kls->conf.kls_autoset_regions == 1) { - KLS_Region *reg = NULL; - switch (kls->conf.kls_reglist_alloc_backend) { - case KLS_REGLIST_ALLOC_LIBC: { - reg = (KLS_Region *) malloc(sizeof(KLS_Region)); - } - break; - case KLS_REGLIST_ALLOC_KLS_BASIC: { - if (kls_rl_length(kls->regs) < kls->max_regions_kls_alloc_basic) { - reg = KLS_PUSH(kls->reglist_kls, KLS_Region); - } else { - fprintf(stderr, - "[ERROR] [%s()]: Exceeding kls->max_regions_kls_alloc_basic: {%i}.\n", - __func__, kls->max_regions_kls_alloc_basic); - if (kls->conf.kls_verbose_lvl > 0) { - kls_log(kls, "ERROR", - "[%s()]: Exceeding kls->max_regions_kls_alloc_basic: {%i}.", - __func__, kls->max_regions_kls_alloc_basic); - kls_rl_showList_toFile(kls->regs, kls->conf.kls_log_fp); - print_kls_2file(kls->conf.kls_log_fp, kls->reglist_kls); - print_kls_2file(kls->conf.kls_log_fp, kls); - } - kls_free(kls); - exit(EXIT_FAILURE); - } - } - break; - default: { - fprintf(stderr, - "[ERROR] [%s()]: Unexpected KLS_RegList_Alloc_Backend value: {%i}.\n", - __func__, kls->conf.kls_reglist_alloc_backend); -#ifdef KLS_DEBUG_CORE - kls_log(kls, "ERROR", - "%s(): Invalid KLS_RegList_Alloc_Backend value: {%i}.", - __func__, kls->conf.kls_reglist_alloc_backend); -#endif - kls_free(kls); - exit(EXIT_FAILURE); - } - break; - } - reg->begin_offset = kls->prev_offset; - reg->end_offset = kls->offset; - reg->size = reg->end_offset - reg->begin_offset; - reg->padding = padding; - reg->type = KLS_None; - strncpy(reg->name, name, KLS_REGION_MAX_NAME_SIZE); - reg->name[KLS_REGION_MAX_NAME_SIZE] = '\0'; - strncpy(reg->desc, desc, KLS_REGION_MAX_DESC_SIZE); - reg->desc[KLS_REGION_MAX_DESC_SIZE] = '\0'; - //KLS_Region_List reglist = kls_emptyList(); - //reglist = kls_cons(kls,reg,reglist); - //kls->regs = kls_append(kls,reglist, kls->regs); - kls->regs = kls_rl_cons(kls, reg, kls->regs); + kls__autoregion(__func__, kls, padding, name, strlen(name)+1, desc, strlen(desc)+1, KLS_None); - char h_size[200]; - kls_formatSize(size * count, h_size, sizeof(h_size)); - //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size); - //kls_log("KLS",msg); + char h_size[200]; + kls_formatSize(size * count, h_size, sizeof(h_size)); + //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size); + //kls_log("KLS",msg); #ifdef KLS_DEBUG_CORE - kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset); - kls_log(kls, "KLS", - "API Level { %i } -> Pushed zeroes, size (%s) for KLS.", - int_koliseo_version(), h_size); - if (kls->conf.kls_verbose_lvl > 0) { - print_kls_2file(kls->conf.kls_log_fp, kls); - } -#endif + kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset); + kls_log(kls, "KLS", + "API Level { %i } -> Pushed zeroes, size (%s) for KLS.", + int_koliseo_version(), h_size); + if (kls->conf.kls_verbose_lvl > 0) { + print_kls_2file(kls->conf.kls_log_fp, kls); } +#endif #ifdef KLS_DEBUG_CORE if (kls->conf.kls_collect_stats == 1) { #ifndef _WIN32 @@ -1390,9 +1418,15 @@ void *kls_push_zero_named(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, * @param desc The desc to assign to the resulting KLS_Region. * @return A void pointer to the start of memory just pushed to the Koliseo. */ +#ifndef KOLISEO_HAS_LOCATE void *kls_temp_push_zero_named(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, char *name, char *desc) +#else +void *kls_temp_push_zero_named_dbg(Koliseo_Temp *t_kls, ptrdiff_t size, + ptrdiff_t align, ptrdiff_t count, char *name, + char *desc, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE { #ifdef KLS_DEBUG_CORE @@ -1419,113 +1453,33 @@ void *kls_temp_push_zero_named(Koliseo_Temp *t_kls, ptrdiff_t size, exit(EXIT_FAILURE); } - ptrdiff_t available = kls->size - kls->offset; - ptrdiff_t padding = -kls->offset & (align - 1); - if (count > PTRDIFF_MAX / size || (available - padding) < (size * count)) { - if (count > PTRDIFF_MAX / size) { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] count [%li] was bigger than PTRDIFF_MAX/size [%li].\n", - count, PTRDIFF_MAX / size); +#ifndef KOLISEO_HAS_LOCATE + kls__check_available(kls, size, align, count); #else - fprintf(stderr, - "[KLS] count [%lli] was bigger than PTRDIFF_MAX/size [%lli].\n", - count, PTRDIFF_MAX / size); + kls__check_available_dbg(kls, size, align, count, loc); #endif - } else { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] Out of memory. size*count [%li] was bigger than available-padding [%li].\n", - size * count, available - padding); -#else - fprintf(stderr, - "[KLS] Out of memory. size*count [%lli] was bigger than available-padding [%lli].\n", - size * count, available - padding); -#endif - } - fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); - kls_free(kls); - exit(EXIT_FAILURE); - //return 0; - } + ptrdiff_t padding = -kls->offset & (align - 1); char *p = kls->data + kls->offset + padding; //Zero new area memset(p, 0, size * count); kls->prev_offset = kls->offset; kls->offset += padding + size * count; - if (t_kls->conf.kls_autoset_regions == 1) { - KLS_Region *reg = NULL; - switch (t_kls->conf.tkls_reglist_alloc_backend) { - case KLS_REGLIST_ALLOC_LIBC: { - reg = (KLS_Region *) malloc(sizeof(KLS_Region)); - } - break; - case KLS_REGLIST_ALLOC_KLS_BASIC: { - if (kls_rl_length(t_kls->t_regs) < - t_kls->max_regions_kls_alloc_basic) { - reg = KLS_PUSH(t_kls->reglist_kls, KLS_Region); - } else { - fprintf(stderr, - "[ERROR] [%s()]: Exceeding t_kls->max_regions_kls_alloc_basic: {%i}.\n", - __func__, t_kls->max_regions_kls_alloc_basic); - if (kls->conf.kls_verbose_lvl > 0) { - kls_log(kls, "ERROR", - "[%s()]: Exceeding t_kls->max_regions_kls_alloc_basic: {%i}.", - __func__, t_kls->max_regions_kls_alloc_basic); - kls_rl_showList_toFile(t_kls->t_regs, - kls->conf.kls_log_fp); - print_kls_2file(kls->conf.kls_log_fp, - t_kls->reglist_kls); - print_kls_2file(kls->conf.kls_log_fp, kls); - } - kls_free(kls); - exit(EXIT_FAILURE); - } - } - break; - default: { - fprintf(stderr, - "[ERROR] %s(): Invalid conf.tkls_reglist_alloc_backend value: {%i}.\n", - __func__, t_kls->conf.tkls_reglist_alloc_backend); -#ifdef KLS_DEBUG_CORE - kls_log(kls, "ERROR", - "%s(): Invalid conf.tkls_reglist_alloc_backend value: {%i}.\n", - __func__, t_kls->conf.tkls_reglist_alloc_backend); -#endif - kls_free(kls); - exit(EXIT_FAILURE); - } - break; - } - reg->begin_offset = kls->prev_offset; - reg->end_offset = kls->offset; - reg->size = reg->end_offset - reg->begin_offset; - reg->padding = padding; - reg->type = KLS_None; - strncpy(reg->name, name, KLS_REGION_MAX_NAME_SIZE); - reg->name[KLS_REGION_MAX_NAME_SIZE] = '\0'; - strncpy(reg->desc, desc, KLS_REGION_MAX_DESC_SIZE); - reg->desc[KLS_REGION_MAX_DESC_SIZE] = '\0'; - //KLS_Region_List reglist = kls_emptyList(); - //reglist = kls_cons(kls,reg,reglist); - //t_kls->t_regs = kls_append(kls,reglist, t_kls->t_regs); - t_kls->t_regs = kls_rl_t_cons(t_kls, reg, t_kls->t_regs); + kls__temp_autoregion(__func__, t_kls, padding, name, strlen(name)+1, desc, strlen(desc)+1, KLS_None); - char h_size[200]; - kls_formatSize(size, h_size, sizeof(h_size)); - //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size); - //kls_log("KLS",msg); + char h_size[200]; + kls_formatSize(size, h_size, sizeof(h_size)); + //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size); + //kls_log("KLS",msg); #ifdef KLS_DEBUG_CORE - kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset); - kls_log(kls, "KLS", - "API Level { %i } -> Pushed zeroes, size (%s) for Temp_KLS.", - int_koliseo_version(), h_size); - if (kls->conf.kls_verbose_lvl > 0) { - print_kls_2file(kls->conf.kls_log_fp, kls); - } -#endif + kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset); + kls_log(kls, "KLS", + "API Level { %i } -> Pushed zeroes, size (%s) for Temp_KLS.", + int_koliseo_version(), h_size); + if (kls->conf.kls_verbose_lvl > 0) { + print_kls_2file(kls->conf.kls_log_fp, kls); } +#endif #ifdef KLS_DEBUG_CORE if (kls->conf.kls_collect_stats == 1) { #ifndef _WIN32 @@ -1563,8 +1517,13 @@ void *kls_temp_push_zero_named(Koliseo_Temp *t_kls, ptrdiff_t size, * @param desc The desc to assign to the resulting KLS_Region. * @return A void pointer to the start of memory just pushed to the referred Koliseo. */ +#ifndef KOLISEO_HAS_LOCATE void *kls_push_zero_typed(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, int type, char *name, char *desc) +#else +void *kls_push_zero_typed_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count, int type, char *name, char *desc, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE { #ifdef KLS_DEBUG_CORE #ifndef _WIN32 @@ -1580,110 +1539,43 @@ void *kls_push_zero_typed(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__); exit(EXIT_FAILURE); } - ptrdiff_t available = kls->size - kls->offset; - ptrdiff_t padding = -kls->offset & (align - 1); - if (count > PTRDIFF_MAX / size || (available - padding) < (size * count)) { - if (count > PTRDIFF_MAX / size) { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] count [%li] was bigger than PTRDIFF_MAX/size [%li].\n", - count, PTRDIFF_MAX / size); + if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) { +#ifndef KOLISEO_HAS_LOCATE + fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__); #else - fprintf(stderr, - "[KLS] count [%lli] was bigger than PTRDIFF_MAX/size [%lli].\n", - count, PTRDIFF_MAX / size); -#endif - } else { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] Out of memory. size*count [%li] was bigger than available-padding [%li].\n", - size * count, available - padding); -#else - fprintf(stderr, - "[KLS] Out of memory. size*count [%lli] was bigger than available-padding [%lli].\n", - size * count, available - padding); -#endif - } - fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); - kls_free(kls); + fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__); + kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__); exit(EXIT_FAILURE); - //return 0; +#endif // KOLISEO_HAS_LOCATE + return NULL; } +#ifndef KOLISEO_HAS_LOCATE + kls__check_available(kls, size, align, count); +#else + kls__check_available_dbg(kls, size, align, count, loc); +#endif + ptrdiff_t padding = -kls->offset & (align - 1); char *p = kls->data + kls->offset + padding; //Zero new area memset(p, 0, size * count); kls->prev_offset = kls->offset; kls->offset += padding + size * count; - if (kls->conf.kls_autoset_regions == 1) { - KLS_Region *reg = NULL; - switch (kls->conf.kls_reglist_alloc_backend) { - case KLS_REGLIST_ALLOC_LIBC: { - reg = (KLS_Region *) malloc(sizeof(KLS_Region)); - } - break; - case KLS_REGLIST_ALLOC_KLS_BASIC: { - if (kls_rl_length(kls->regs) < kls->max_regions_kls_alloc_basic) { - reg = KLS_PUSH(kls->reglist_kls, KLS_Region); - } else { - fprintf(stderr, - "[ERROR] [%s()]: Exceeding kls->max_regions_kls_alloc_basic: {%i}.\n", - __func__, kls->max_regions_kls_alloc_basic); - if (kls->conf.kls_verbose_lvl > 0) { - kls_log(kls, "ERROR", - "[%s()]: Exceeding kls->max_regions_kls_alloc_basic: {%i}.", - __func__, kls->max_regions_kls_alloc_basic); - kls_rl_showList_toFile(kls->regs, kls->conf.kls_log_fp); - print_kls_2file(kls->conf.kls_log_fp, kls->reglist_kls); - print_kls_2file(kls->conf.kls_log_fp, kls); - } - kls_free(kls); - exit(EXIT_FAILURE); - } - } - break; - default: { - fprintf(stderr, - "[ERROR] [%s()]: Unexpected KLS_RegList_Alloc_Backend value: {%i}.\n", - __func__, kls->conf.kls_reglist_alloc_backend); -#ifdef KLS_DEBUG_CORE - kls_log(kls, "ERROR", - "%s(): Invalid KLS_RegList_Alloc_Backend value: {%i}.", - __func__, kls->conf.kls_reglist_alloc_backend); -#endif - kls_free(kls); - exit(EXIT_FAILURE); - } - break; - } - reg->begin_offset = kls->prev_offset; - reg->end_offset = kls->offset; - reg->size = reg->end_offset - reg->begin_offset; - reg->padding = padding; - reg->type = type; - strncpy(reg->name, name, KLS_REGION_MAX_NAME_SIZE); - reg->name[KLS_REGION_MAX_NAME_SIZE] = '\0'; - strncpy(reg->desc, desc, KLS_REGION_MAX_DESC_SIZE); - reg->desc[KLS_REGION_MAX_DESC_SIZE] = '\0'; - //KLS_Region_List reglist = kls_emptyList(); - //reglist = kls_cons(kls,reg,reglist); - //kls->regs = kls_append(kls,reglist, kls->regs); - kls->regs = kls_rl_cons(kls, reg, kls->regs); + kls__autoregion(__func__, kls, padding, name, strlen(name), desc, strlen(desc), type); - char h_size[200]; - kls_formatSize(size * count, h_size, sizeof(h_size)); - //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size); - //kls_log("KLS",msg); + char h_size[200]; + kls_formatSize(size * count, h_size, sizeof(h_size)); + //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size); + //kls_log("KLS",msg); #ifdef KLS_DEBUG_CORE - kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset); - kls_log(kls, "KLS", - "API Level { %i } -> Pushed zeroes, size (%s) for KLS.", - int_koliseo_version(), h_size); - if (kls->conf.kls_verbose_lvl > 0) { - print_kls_2file(kls->conf.kls_log_fp, kls); - } -#endif + kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset); + kls_log(kls, "KLS", + "API Level { %i } -> Pushed zeroes, size (%s) for KLS.", + int_koliseo_version(), h_size); + if (kls->conf.kls_verbose_lvl > 0) { + print_kls_2file(kls->conf.kls_log_fp, kls); } +#endif #ifdef KLS_DEBUG_CORE if (kls->conf.kls_collect_stats == 1) { #ifndef _WIN32 @@ -1722,11 +1614,16 @@ void *kls_push_zero_typed(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, * @param desc The desc to assign to the resulting KLS_Region. * @return A void pointer to the start of memory just pushed to the referred Koliseo. */ +#ifndef KOLISEO_HAS_LOCATE void *kls_temp_push_zero_typed(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, int type, char *name, char *desc) +#else +void *kls_temp_push_zero_typed_dbg(Koliseo_Temp *t_kls, ptrdiff_t size, + ptrdiff_t align, ptrdiff_t count, int type, + char *name, char *desc, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE { - #ifdef KLS_DEBUG_CORE #ifndef _WIN32 struct timespec start_time, end_time; @@ -1749,112 +1646,33 @@ void *kls_temp_push_zero_typed(Koliseo_Temp *t_kls, ptrdiff_t size, __func__); exit(EXIT_FAILURE); } - ptrdiff_t available = kls->size - kls->offset; - ptrdiff_t padding = -kls->offset & (align - 1); - if (count > PTRDIFF_MAX / size || (available - padding) < (size * count)) { - if (count > PTRDIFF_MAX / size) { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] count [%li] was bigger than PTRDIFF_MAX/size [%li].\n", - count, PTRDIFF_MAX / size); -#else - fprintf(stderr, - "[KLS] count [%lli] was bigger than PTRDIFF_MAX/size [%lli].\n", - count, PTRDIFF_MAX / size); -#endif - } else { -#ifndef _WIN32 - fprintf(stderr, - "[KLS] Out of memory. size*count [%li] was bigger than available-padding [%li].\n", - size * count, available - padding); +#ifndef KOLISEO_HAS_LOCATE + kls__check_available(kls, size, align, count); #else - fprintf(stderr, - "[KLS] Out of memory. size*count [%lli] was bigger than available-padding [%lli].\n", - size * count, available - padding); + kls__check_available_dbg(kls, size, align, count, loc); #endif - } - fprintf(stderr, "[KLS] Failed %s() call.\n", __func__); - kls_free(kls); - exit(EXIT_FAILURE); - //return 0; - } + ptrdiff_t padding = -kls->offset & (align - 1); char *p = kls->data + kls->offset + padding; //Zero new area memset(p, 0, size * count); kls->prev_offset = kls->offset; kls->offset += padding + size * count; - if (t_kls->conf.kls_autoset_regions == 1) { - KLS_Region *reg = NULL; - switch (t_kls->conf.tkls_reglist_alloc_backend) { - case KLS_REGLIST_ALLOC_LIBC: { - reg = (KLS_Region *) malloc(sizeof(KLS_Region)); - } - break; - case KLS_REGLIST_ALLOC_KLS_BASIC: { - if (kls_rl_length(t_kls->t_regs) < - t_kls->max_regions_kls_alloc_basic) { - reg = KLS_PUSH(t_kls->reglist_kls, KLS_Region); - } else { - fprintf(stderr, - "[ERROR] [%s()]: Exceeding t_kls->max_regions_kls_alloc_basic: {%i}.\n", - __func__, t_kls->max_regions_kls_alloc_basic); - if (kls->conf.kls_verbose_lvl > 0) { - kls_log(kls, "ERROR", - "[%s()]: Exceeding t_kls->max_regions_kls_alloc_basic: {%i}.", - __func__, t_kls->max_regions_kls_alloc_basic); - kls_rl_showList_toFile(t_kls->t_regs, - kls->conf.kls_log_fp); - print_kls_2file(kls->conf.kls_log_fp, - t_kls->reglist_kls); - print_kls_2file(kls->conf.kls_log_fp, kls); - } - kls_free(kls); - exit(EXIT_FAILURE); - } - } - break; - default: { - fprintf(stderr, - "[ERROR] %s(): Invalid conf.tkls_reglist_alloc_backend value: {%i}.\n", - __func__, t_kls->conf.tkls_reglist_alloc_backend); -#ifdef KLS_DEBUG_CORE - kls_log(kls, "ERROR", - "%s(): Invalid conf.tkls_reglist_alloc_backend value: {%i}.\n", - __func__, t_kls->conf.tkls_reglist_alloc_backend); -#endif - kls_free(kls); - exit(EXIT_FAILURE); - } - break; - } - reg->begin_offset = kls->prev_offset; - reg->end_offset = kls->offset; - reg->size = reg->end_offset - reg->begin_offset; - reg->padding = padding; - reg->type = type; - strncpy(reg->name, name, KLS_REGION_MAX_NAME_SIZE); - reg->name[KLS_REGION_MAX_NAME_SIZE] = '\0'; - strncpy(reg->desc, desc, KLS_REGION_MAX_DESC_SIZE); - reg->desc[KLS_REGION_MAX_DESC_SIZE] = '\0'; - //KLS_Region_List reglist = kls_emptyList(); - //reglist = kls_cons(kls,reg,reglist); - //t_kls->t_regs = kls_append(kls,reglist, t_kls->t_regs); - t_kls->t_regs = kls_rl_t_cons(t_kls, reg, t_kls->t_regs); - char h_size[200]; - kls_formatSize(size * count, h_size, sizeof(h_size)); - //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size); - //kls_log("KLS",msg); + kls__temp_autoregion(__func__, t_kls, padding, name, strlen(name)+1, desc, strlen(desc)+1, type); + + char h_size[200]; + kls_formatSize(size * count, h_size, sizeof(h_size)); + //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size); + //kls_log("KLS",msg); #ifdef KLS_DEBUG_CORE - kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset); - kls_log(kls, "KLS", - "API Level { %i } -> Pushed zeroes, size (%s) for Temp_KLS.", - int_koliseo_version(), h_size); - if (kls->conf.kls_verbose_lvl > 0) { - print_kls_2file(kls->conf.kls_log_fp, kls); - } -#endif + kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset); + kls_log(kls, "KLS", + "API Level { %i } -> Pushed zeroes, size (%s) for Temp_KLS.", + int_koliseo_version(), h_size); + if (kls->conf.kls_verbose_lvl > 0) { + print_kls_2file(kls->conf.kls_log_fp, kls); } +#endif #ifdef KLS_DEBUG_CORE if (kls->conf.kls_collect_stats == 1) { #ifndef _WIN32 @@ -2458,7 +2276,11 @@ void kls_free(Koliseo *kls) * @return A Koliseo_Temp struct. * @see Koliseo_Temp */ +#ifndef KOLISEO_HAS_LOCATE Koliseo_Temp *kls_temp_start(Koliseo *kls) +#else +Koliseo_Temp *kls_temp_start_dbg(Koliseo *kls, Koliseo_Loc loc) +#endif // KOLISEO_HAS_LOCATE { if (kls == NULL) { fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__); @@ -4136,12 +3958,12 @@ void *kls_temp_pop_AR(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrd * Function to dupe a C string to a Koliseo, and return a pointer to the allocated string. * Unsafe, do not use. * @see KLS_PUSH_STR() - * @see __KLS_STRCPY() + * @see KLS__STRCPY() */ char* kls_strdup(Koliseo* kls, char* source) { char* dest = KLS_PUSH_STR(kls, source); - __KLS_STRCPY(dest, source); + KLS__STRCPY(dest, source); return dest; } @@ -4149,7 +3971,7 @@ char* kls_strdup(Koliseo* kls, char* source) * Function to dupe a C string array to a Koliseo, and return a pointer to the allocated array. * Unsafe, do not use. * @see KLS_STRDUP() - * @see __KLS_STRCPY() + * @see KLS__STRCPY() */ char** kls_strdup_arr(Koliseo* kls, size_t count, char** source) { @@ -4165,12 +3987,12 @@ char** kls_strdup_arr(Koliseo* kls, size_t count, char** source) * Function to dupe a C string to a Koliseo_Temp, and return a pointer to the allocated string. * Unsafe, do not use. * @see KLS_PUSH_STR_T() - * @see __KLS_STRCPY() + * @see KLS__STRCPY() */ char* kls_t_strdup(Koliseo_Temp* t_kls, char* source) { char* dest = KLS_PUSH_STR_T(t_kls, source); - __KLS_STRCPY(dest, source); + KLS__STRCPY(dest, source); return dest; } @@ -4178,7 +4000,7 @@ char* kls_t_strdup(Koliseo_Temp* t_kls, char* source) * Function to dupe a C string array to a Koliseo_Temp, and return a pointer to the allocated array. * Unsafe, do not use. * @see KLS_STRDUP_T() - * @see __KLS_STRCPY() + * @see KLS__STRCPY() */ char** kls_t_strdup_arr(Koliseo_Temp* t_kls, size_t count, char** source) { diff --git a/src/koliseo.h b/src/koliseo.h index fdaa856..87368dd 100644 --- a/src/koliseo.h +++ b/src/koliseo.h @@ -38,14 +38,46 @@ #ifdef KLS_DEBUG_CORE #include +/* +#ifndef KOLISEO_HAS_LOCATE +#define KOLISEO_HAS_LOCATE // Used for enabling caller location arguments for some APIs. +#endif // KOLISEO_HAS_LOCATE +*/ + #ifdef _WIN32 -#include //Used for QueryPerformanceFrequency(), QueryPerformanceCounter() +#include //Used for QueryPerformanceFrequency(), QueryPerformanceCounter() #endif -#endif //KLS_DEBUG_CORE +#endif //KLS_DEBUG_CORE + +#ifdef KOLISEO_HAS_LOCATE +typedef struct Koliseo_Loc { + const char* file; + const int line; + const char* func; +} Koliseo_Loc; + +#define KLS_HERE (Koliseo_Loc){ \ + .file = __FILE__, \ + .line = __LINE__, \ + .func = __func__, \ +} + +/** + * Defines a format string for Koliseo_Loc. + * @see KLS_Loc_Arg() + */ +#define KLS_Loc_Fmt "[%s:%i at %s():] " + +/** + * Defines a format macro for Koliseo_Loc args. + * @see KLS_Loc_Fmt + */ +#define KLS_Loc_Arg(loc) (loc.file), (loc.line), (loc.func) +#endif // KOLISEO_HAS_LOCATE #define KLS_MAJOR 0 /**< Represents current major release.*/ #define KLS_MINOR 4 /**< Represents current minor release.*/ -#define KLS_PATCH 3 /**< Represents current patch release.*/ +#define KLS_PATCH 4 /**< Represents current patch release.*/ typedef void*(kls_alloc_func)(size_t); /**< Used to select an allocation function for the arena's backing memory.*/ @@ -95,9 +127,10 @@ typedef struct KLS_Conf { int kls_verbose_lvl; /**< If > 0, makes the Koliseo try to acquire kls_log_fp from kls_log_filepath.*/ FILE *kls_log_fp; /**< FILE pointer used by the Koliseo to print its kls_log() output.*/ const char *kls_log_filepath; /**< String representing the path to the Koliseo logfile.*/ + int kls_block_while_has_temp; /**< If set to 1, make the Koliseo reject push calls while it has an open Koliseo_Temp.*/ } KLS_Conf; -KLS_Conf kls_conf_init(int autoset_regions, int alloc_backend, ptrdiff_t reglist_kls_size, int autoset_temp_regions, int collect_stats, int verbose_lvl, FILE* log_fp, const char* log_filepath); +KLS_Conf kls_conf_init(int autoset_regions, int alloc_backend, ptrdiff_t reglist_kls_size, int autoset_temp_regions, int collect_stats, int verbose_lvl, int block_while_has_temp, FILE* log_fp, const char* log_filepath); void kls_dbg_features(void); @@ -250,7 +283,7 @@ static const int KOLISEO_API_VERSION_INT = /** * Defines current API version string. */ -static const char KOLISEO_API_VERSION_STRING[] = "0.4.3"; /**< Represents current version with MAJOR.MINOR.PATCH format.*/ +static const char KOLISEO_API_VERSION_STRING[] = "0.4.4"; /**< Represents current version with MAJOR.MINOR.PATCH format.*/ /** * Returns current koliseo version as a string. @@ -407,7 +440,12 @@ int kls_get_maxRegions_KLS_BASIC(Koliseo * kls); int kls_temp_get_maxRegions_KLS_BASIC(Koliseo_Temp * t_kls); #endif +#ifndef KOLISEO_HAS_LOCATE Koliseo *kls_new_alloc(ptrdiff_t size, kls_alloc_func alloc_func); +#else +Koliseo *kls_new_alloc_dbg(ptrdiff_t size, kls_alloc_func alloc_func, Koliseo_Loc loc); +#define kls_new_alloc(size, alloc_func) kls_new_alloc_dbg((size), (alloc_func), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE #ifndef KLS_DEFAULT_ALLOCF #define KLS_DEFAULT_ALLOCF malloc /**< Defines the default allocation function.*/ @@ -426,15 +464,45 @@ Koliseo *kls_new_traced_AR_KLS_alloc(ptrdiff_t size, const char *output_path, #define kls_new_traced_AR_KLS(size, output_path, reglist_kls_size) kls_new_traced_AR_KLS_alloc((size), (output_path), (reglist_kls_size), KLS_DEFAULT_ALLOCF) //void* kls_push(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count); + +#ifndef KOLISEO_HAS_LOCATE void *kls_push_zero(Koliseo * kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count); +#else +void *kls_push_zero_dbg(Koliseo * kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count, Koliseo_Loc loc); + +#define kls_push_zero(kls, size, align, count) kls_push_zero_dbg((kls), (size), (align), (count), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE + +#ifndef KOLISEO_HAS_LOCATE void *kls_push_zero_AR(Koliseo * kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count); +#else +void *kls_push_zero_AR_dbg(Koliseo * kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count, Koliseo_Loc loc); +#define kls_push_zero_AR(kls, size, align, count) kls_push_zero_AR_dbg((kls), (size), (align), (count), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE + #ifdef KOLISEO_HAS_REGION + +#ifndef KOLISEO_HAS_LOCATE void *kls_push_zero_named(Koliseo * kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, char *name, char *desc); +#else +void *kls_push_zero_named_dbg(Koliseo * kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count, char *name, char *desc, Koliseo_Loc loc); +#define kls_push_zero_named(kls, size, align, count, name, desc) kls_push_zero_named_dbg((kls), (size), (align), (count), (name), (desc), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE + +#ifndef KOLISEO_HAS_LOCATE void *kls_push_zero_typed(Koliseo * kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, int type, char *name, char *desc); +#else +void *kls_push_zero_typed_dbg(Koliseo * kls, ptrdiff_t size, ptrdiff_t align, + ptrdiff_t count, int type, char *name, char *desc, Koliseo_Loc loc); +#define kls_push_zero_typed(kls, size, align, count, type, name, desc) kls_push_zero_typed_dbg((kls), (size), (align), (count), (type), (name), (desc), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE #endif // KOLISEO_HAS_REGION /** @@ -530,18 +598,46 @@ void kls_temp_showList_toWin(Koliseo_Temp * t_kls, WINDOW * win); #endif //KOLISEO_HAS_CURSES +#ifndef KOLISEO_HAS_LOCATE Koliseo_Temp *kls_temp_start(Koliseo * kls); +#else +Koliseo_Temp *kls_temp_start_dbg(Koliseo * kls, Koliseo_Loc loc); +#define kls_temp_start(kls) kls_temp_start_dbg((kls), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE //bool kls_temp_set_conf(Koliseo_Temp* t_kls, KLS_Temp_Conf conf); void kls_temp_end(Koliseo_Temp * tmp_kls); + +#ifndef KOLISEO_HAS_LOCATE void *kls_temp_push_zero_AR(Koliseo_Temp * t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count); +#else +void *kls_temp_push_zero_AR_dbg(Koliseo_Temp * t_kls, ptrdiff_t size, + ptrdiff_t align, ptrdiff_t count, Koliseo_Loc loc); +#define kls_temp_push_zero_AR(t_kls, size, align, count) kls_temp_push_zero_AR_dbg((t_kls), (size), (align), (count), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE + #ifdef KOLISEO_HAS_REGION +#ifndef KOLISEO_HAS_LOCATE void *kls_temp_push_zero_named(Koliseo_Temp * t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, char *name, char *desc); +#else +void *kls_temp_push_zero_named_dbg(Koliseo_Temp * t_kls, ptrdiff_t size, + ptrdiff_t align, ptrdiff_t count, char *name, + char *desc, Koliseo_Loc loc); +#define kls_temp_push_zero_named(t_kls, size, align, count, name, desc) kls_temp_push_zero_named_dbg((t_kls), (size), (align), (count), (name), (desc), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE + +#ifndef KOLISEO_HAS_LOCATE void *kls_temp_push_zero_typed(Koliseo_Temp * t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, int type, char *name, char *desc); +#else +void *kls_temp_push_zero_typed_dbg(Koliseo_Temp * t_kls, ptrdiff_t size, + ptrdiff_t align, ptrdiff_t count, int type, + char *name, char *desc, Koliseo_Loc loc); +#define kls_temp_push_zero_typed(t_kls, size, align, count, type, name, desc) kls_temp_push_zero_typed_dbg((t_kls), (size), (align), (count), (type), (name), (desc), KLS_HERE) +#endif // KOLISEO_HAS_LOCATE #endif // KOLISEO_HAS_REGION void print_temp_kls_2file(FILE * fp, const Koliseo_Temp * t_kls); void print_dbg_temp_kls(const Koliseo_Temp * t_kls); @@ -814,7 +910,7 @@ char** kls_strdup_arr(Koliseo* kls, size_t count, char** source); * @see KLS_STRDUP() * @see KLS_STRDUP_T() */ -#define __KLS_STRCPY(dest, source) do {\ +#define KLS__STRCPY(dest, source) do {\ strcpy((dest), (source));\ } while (0) @@ -842,524 +938,3 @@ char** kls_t_strdup_arr(Koliseo_Temp* t_kls, size_t count, char** source); #endif // __STDC_VERSION__ && __STDC_VERSION__ >= 201112L //We need C11 #endif //KOLISEO_H_ - -#ifdef LIST_T //This ensures the library never causes any trouble if this macro was not defined. -// jgabaut @ github.com/jgabaut -// SPDX-License-Identifier: GPL-3.0-only -/* - Copyright (C) 2023-2024 jgabaut - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, version 3 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -// list.h -// This is a template for a linked list, inspired by the dynamic array example in https://www.davidpriver.com/ctemplates.html#template-headers. -// Include this header multiple times to implement a -// simplistic linked list. Before inclusion define at -// least DLIST_T to the type the linked list can hold. -// See DLIST_NAME, DLIST_PREFIX and DLIST_LINKAGE for -// other customization points. -// -// If you define DLIST_DECLS_ONLY, only the declarations -// of the type and its function will be declared. -// -// Functions ending with _gl use malloc() for the nodes. -// Functions ending with _kls expect a Koliseo arg to use for allocating nodes. -// - -#ifndef LIST_HEADER_H -#define LIST_HEADER_H -// Inline functions, #defines and includes that will be -// needed for all instantiations can go up here. -#include // bool -#include // malloc, size_t - -#define LIST_IMPL(word) LIST_COMB1(LIST_PREFIX,word) -#define LIST_COMB1(pre, word) LIST_COMB2(pre, word) -#define LIST_COMB2(pre, word) pre##word - -#define LIST_HEADER_VERSION "0.1.0" - -#endif // LIST_HEADER_H - -// NOTE: this section is *not* guarded as it is intended -// to be included multiple times. - -#ifndef LIST_T -#error "LIST_T must be defined" -#endif - -// The name of the data type to be generated. -// If not given, will expand to something like -// `list_int` for an `int`. -#ifndef LIST_NAME -#define LIST_NAME LIST_COMB1(LIST_COMB1(list,_), LIST_T) -#endif - -// Prefix for generated functions. -#ifndef LIST_PREFIX -#define LIST_PREFIX LIST_COMB1(LIST_NAME, _) -#endif - -// Customize the linkage of the function. -#ifndef LIST_LINKAGE -#define LIST_LINKAGE static inline -#endif - -// Suffix for generated list item struct. -#ifndef LIST_I_SUFFIX -#define LIST_I_SUFFIX item -#endif - -// The name of the item data type to be generated. -#ifndef LIST_ITEM_NAME -#define LIST_ITEM_NAME LIST_COMB1(LIST_COMB1(LIST_T,_), LIST_I_SUFFIX) -#endif - -typedef struct LIST_ITEM_NAME LIST_ITEM_NAME; -struct LIST_ITEM_NAME { - LIST_T* value; - struct LIST_ITEM_NAME* next; -}; -typedef LIST_ITEM_NAME* LIST_NAME; - -#define LIST_nullList LIST_IMPL(nullList) -#define LIST_isEmpty LIST_IMPL(isEmpty) -#define LIST_head LIST_IMPL(head) -#define LIST_tail LIST_IMPL(tail) -#define LIST_cons_gl LIST_IMPL(cons_gl) -#define LIST_cons_kls LIST_IMPL(cons_kls) -#define LIST_free_gl LIST_IMPL(free_gl) -#define LIST_member LIST_IMPL(member) -#define LIST_length LIST_IMPL(length) -#define LIST_append_gl LIST_IMPL(append_gl) -#define LIST_append_kls LIST_IMPL(append_kls) -#define LIST_reverse_gl LIST_IMPL(reverse_gl) -#define LIST_reverse_kls LIST_IMPL(reverse_kls) -#define LIST_copy_gl LIST_IMPL(copy_gl) -#define LIST_copy_kls LIST_IMPL(copy_kls) -#define LIST_remove_gl LIST_IMPL(remove_gl) -#define LIST_remove_kls LIST_IMPL(remove_kls) -#define LIST_intersect_gl LIST_IMPL(intersect_gl) -#define LIST_intersect_kls LIST_IMPL(intersect_kls) -#define LIST_diff_gl LIST_IMPL(diff_gl) -#define LIST_diff_kls LIST_IMPL(diff_kls) - -#ifdef LIST_DECLS_ONLY - -LIST_LINKAGE -LIST_NAME -LIST_nullList(void); - -LIST_LINKAGE -bool -LIST_isEmpty(LIST_NAME list); - -LIST_LINKAGE -LIST_T* -LIST_head(LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_tail(LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_cons_gl(LIST_T* element, LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_cons_kls(Koliseo* kls, LIST_T* element, LIST_NAME list); - -LIST_LINKAGE -void -LIST_free_gl(LIST_NAME list); - -LIST_LINKAGE -bool -LIST_member(LIST_T* element, LIST_NAME list); - -LIST_LINKAGE -int -LIST_length(LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_append_gl(LIST_NAME l1, LIST_NAME l2); - -LIST_LINKAGE -LIST_NAME -LIST_append_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2); - -LIST_LINKAGE -LIST_NAME -LIST_reverse_gl(LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_reverse_kls(Koliseo* kls, LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_copy_gl(LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_copy_kls(Koliseo* kls, LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_remove_gl(LIST_T* element, LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_remove_kls(Koliseo* kls, LIST_T* element, LIST_NAME list); - -LIST_LINKAGE -LIST_NAME -LIST_intersect_gl(LIST_NAME l1, LIST_NAME l2); - -LIST_LINKAGE -LIST_NAME -LIST_intersect_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2); - -LIST_LINKAGE -LIST_NAME -LIST_diff_gl(LIST_NAME l1, LIST_NAME l2); - -LIST_LINKAGE -LIST_NAME -LIST_diff_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2); -#else - -LIST_LINKAGE -LIST_NAME -LIST_nullList(void) -{ - return NULL; -} - -LIST_LINKAGE -bool -LIST_isEmpty(LIST_NAME list) -{ - if (list == NULL) { - return true; - }; - return false; -} - -LIST_LINKAGE -LIST_T* -LIST_head(LIST_NAME list) -{ - if (LIST_isEmpty(list)) { - fprintf(stderr, "%s at %i: %s(): List is empty.\n", __FILE__, __LINE__, __func__); - return NULL; - } - return list->value; -} - -LIST_LINKAGE -LIST_NAME -LIST_tail(LIST_NAME list) -{ - if (LIST_isEmpty(list)) { - fprintf(stderr, "%s at %i: %s(): List is empty.\n", __FILE__, __LINE__, __func__); - return NULL; - } - return list->next; -} - -LIST_LINKAGE -LIST_NAME -LIST_cons_gl(LIST_T* element, LIST_NAME list) -{ - LIST_NAME t; - t = (LIST_NAME) malloc(sizeof(LIST_ITEM_NAME)); - t->value = element; - t->next = list; - return t; -} - -LIST_LINKAGE -LIST_NAME -LIST_cons_kls(Koliseo* kls, LIST_T* element, LIST_NAME list) -{ - if (kls == NULL) { - fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); - return NULL; - } - LIST_NAME t; - t = (LIST_NAME) KLS_PUSH_EX(kls, LIST_ITEM_NAME, "List node"); - if (t == NULL ) { - fprintf(stderr, "%s at %i: %s(): Failed KLS_PUSH_EX() call.\n", __FILE__, __LINE__, __func__); - return NULL; - } - t->value = element; - t->next = list; - return t; -} - -LIST_LINKAGE -void -LIST_free_gl(LIST_NAME list) -{ - if (LIST_isEmpty(list)) { - return; - } else { - LIST_free_gl(LIST_tail(list)); - free(list); - } - return; -} - -LIST_LINKAGE -bool -LIST_member(LIST_T* element, LIST_NAME list) -{ - if (LIST_isEmpty(list)) { - return false; - } else { - if (element == LIST_head(list)) { - return true; - } else { - return LIST_member(element, LIST_tail(list)); - } - } -} - -LIST_LINKAGE -int -LIST_length(LIST_NAME list) -{ - if (LIST_isEmpty(list)) { - return 0; - } else { - return 1 + LIST_length(LIST_tail(list)); - } -} - -LIST_LINKAGE -LIST_NAME -LIST_append_gl(LIST_NAME l1, LIST_NAME l2) -{ - if (LIST_isEmpty(l1)) { - return l2; - } else { - return LIST_cons_gl(LIST_head(l1), LIST_append_gl(LIST_tail(l1), l2)); - } -} - -LIST_LINKAGE -LIST_NAME -LIST_append_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2) -{ - if (kls == NULL) { - fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); - return NULL; - } - if (LIST_isEmpty(l1)) { - return l2; - } else { - return LIST_cons_kls(kls, LIST_head(l1), LIST_append_kls(kls, LIST_tail(l1), l2)); - } -} - -LIST_LINKAGE -LIST_NAME -LIST_reverse_gl(LIST_NAME list) -{ - if (LIST_isEmpty(list)) { - return LIST_nullList(); - } else { - return LIST_append_gl(LIST_reverse_gl(LIST_tail(list)), LIST_cons_gl(LIST_head(list), LIST_nullList())); - } -} - -LIST_LINKAGE -LIST_NAME -LIST_reverse_kls(Koliseo* kls, LIST_NAME list) -{ - if (kls == NULL) { - fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); - return NULL; - } - if (LIST_isEmpty(list)) { - return LIST_nullList(); - } else { - return LIST_append_kls(kls, LIST_reverse_kls(kls, LIST_tail(list)), LIST_cons_kls(kls, LIST_head(list), LIST_nullList())); - } -} - -LIST_LINKAGE -LIST_NAME -LIST_copy_gl(LIST_NAME list) -{ - if (LIST_isEmpty(list)) { - return list; - } else { - return LIST_cons_gl(LIST_head(list), LIST_copy_gl(LIST_tail(list))); - } -} - -LIST_LINKAGE -LIST_NAME -LIST_copy_kls(Koliseo* kls, LIST_NAME list) -{ - if (kls == NULL) { - fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); - return NULL; - } - if (LIST_isEmpty(list)) { - return list; - } else { - return LIST_cons_kls(kls, LIST_head(list), LIST_copy_kls(kls, LIST_tail(list))); - } - -} - -LIST_LINKAGE -LIST_NAME -LIST_remove_gl(LIST_T* element, LIST_NAME list) -{ - if (LIST_isEmpty(list)) { - return LIST_nullList(); - } else { - if (element == LIST_head(list)) { - return LIST_tail(list); - } else { - return LIST_cons_gl(LIST_head(list), LIST_remove_gl(element, LIST_tail(list))); - } - } -} - -LIST_LINKAGE -LIST_NAME -LIST_remove_kls(Koliseo* kls, LIST_T* element, LIST_NAME list) -{ - if (kls == NULL) { - fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); - return NULL; - } - if (LIST_isEmpty(list)) { - return LIST_nullList(); - } else { - if (element == LIST_head(list)) { - return LIST_tail(list); - } else { - return LIST_cons_kls(kls, LIST_head(list), LIST_remove_kls(kls, element, LIST_tail(list))); - } - } -} - -LIST_LINKAGE -LIST_NAME -LIST_intersect_gl(LIST_NAME l1, LIST_NAME l2) -{ - if (LIST_isEmpty(l1) || LIST_isEmpty(l2)) { - return LIST_nullList(); - } - if (LIST_member(LIST_head(l1), l2) && !(LIST_member(LIST_head(l1), LIST_tail(l2)))) { - return LIST_cons_gl(LIST_head(l1), LIST_intersect_gl(LIST_tail(l1), l2)); - } else { - return LIST_intersect_gl(LIST_tail(l1), l2); - } -} - -LIST_LINKAGE -LIST_NAME -LIST_intersect_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2) -{ - if (kls == NULL) { - fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); - return NULL; - } - if (LIST_isEmpty(l1) || LIST_isEmpty(l2)) { - return LIST_nullList(); - } - if (LIST_member(LIST_head(l1), l2) && !(LIST_member(LIST_head(l1), LIST_tail(l2)))) { - return LIST_cons_kls(kls, LIST_head(l1), LIST_intersect_kls(kls, LIST_tail(l1), l2)); - } else { - return LIST_intersect_kls(kls, LIST_tail(l1), l2); - } -} - -LIST_LINKAGE -LIST_NAME -LIST_diff_gl(LIST_NAME l1, LIST_NAME l2) -{ - if (LIST_isEmpty(l1) || LIST_isEmpty(l2)) { - return l1; - } else { - if (!LIST_member(LIST_head(l1), l2) && !LIST_member(LIST_head(l1), LIST_tail(l1))) { - return LIST_cons_gl(LIST_head(l1), LIST_diff_gl(LIST_tail(l1), l2)); - } else { - return LIST_diff_gl(LIST_tail(l1), l2); - } - } -} - -LIST_LINKAGE -LIST_NAME -LIST_diff_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2) -{ - if (kls == NULL) { - fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); - return NULL; - } - if (LIST_isEmpty(l1) || LIST_isEmpty(l2)) { - return l1; - } else { - if (!LIST_member(LIST_head(l1), l2) && !LIST_member(LIST_head(l1), LIST_tail(l1))) { - return LIST_cons_kls(kls, LIST_head(l1), LIST_diff_kls(kls, LIST_tail(l1), l2)); - } else { - return LIST_diff_kls(kls, LIST_tail(l1), l2); - } - } -} -#endif - -// Cleanup -// These need to be undef'ed so they can be redefined the -// next time you need to instantiate this template. -#undef LIST_T -#undef LIST_PREFIX -#undef LIST_NAME -#undef LIST_LINKAGE -#undef LIST_I_SUFFIX -#undef LIST_ITEM_NAME -#undef LIST_nullList -#undef LIST_isEmpty -#undef LIST_head -#undef LIST_tail -#undef LIST_cons_gl -#undef LIST_cons_kls -#undef LIST_free_gl -#undef LIST_member -#undef LIST_length -#undef LIST_append_gl -#undef LIST_append_kls -#undef LIST_reverse_gl -#undef LIST_reverse_kls -#undef LIST_copy_gl -#undef LIST_copy_kls -#undef LIST_remove_gl -#undef LIST_remove_kls -#undef LIST_intersect_gl -#undef LIST_intersect_kls -#undef LIST_diff_gl -#undef LIST_diff_kls -#ifdef LIST_DECLS_ONLY -#undef LIST_DECLS_ONLY -#endif // LIST_DECLS_ONLY -#endif // LIST_T diff --git a/static/demo.c b/static/demo.c index 5b32097..f7fd6b2 100644 --- a/static/demo.c +++ b/static/demo.c @@ -44,7 +44,8 @@ int main(int argc, char **argv) int KLS_REGLIST_ALLOC_KLS_BASIC = -1; #endif - KLS_Conf kls_config = kls_conf_init(1, KLS_REGLIST_ALLOC_KLS_BASIC, KLS_DEFAULT_SIZE, 1, 1, 1, NULL, "./static/debug_log.txt"); + int block_usage_with_open_temp = 0; + KLS_Conf kls_config = kls_conf_init(1, KLS_REGLIST_ALLOC_KLS_BASIC, KLS_DEFAULT_SIZE, 1, 1, 1, block_usage_with_open_temp, NULL, "./static/debug_log.txt"); printf("[Init Koliseo] [size: %i]\n", KLS_DEFAULT_SIZE); Koliseo *kls = kls_new_conf(KLS_DEFAULT_SIZE, kls_config); diff --git a/static/list_example.c b/static/list_example.c index 4ccbcb3..d00ea75 100644 --- a/static/list_example.c +++ b/static/list_example.c @@ -1,6 +1,7 @@ +#include #define LIST_T int #define LIST_NAME IntList -#include +#include "../templates/list.h" int main(void) { printf("KLS API: v%s\n", string_koliseo_version()); diff --git a/stego.lock b/stego.lock index 97dfa0a..ad3c809 100644 --- a/stego.lock +++ b/stego.lock @@ -1,6 +1,6 @@ [ anvil ] -version = "2.0.5" +version = "2.0.6" kern = "amboso-C" [ build ] @@ -64,3 +64,4 @@ testsdir = "ok" "0.4.1" = "Region is an optional feature, move pop ops under experimental features" "0.4.2" = "Add list template, fix KLS_PUSH_ARR_T_NAMED(), bump amboso to 2.0.5, invil to 0.2.9" "0.4.3" = "Fix format specifiers for ptrdiff_t (thanks to khushal-banks), bump anvil to 2.0.6, invil to 0.2.13" +"0.4.4" = "Drop list template from main header, add configurable block for Koliseo usage while a Koliseo_Temp is active on it, add --enable-locate to include caller location in some APIs, bump invil to 0.2.15" diff --git a/templates/list.h b/templates/list.h new file mode 100644 index 0000000..049eb21 --- /dev/null +++ b/templates/list.h @@ -0,0 +1,522 @@ +// jgabaut @ github.com/jgabaut +// SPDX-License-Identifier: GPL-3.0-only +/* + Copyright (C) 2023-2024 jgabaut + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 3 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +// list.h +// This is a template for a linked list, inspired by the dynamic array example in https://www.davidpriver.com/ctemplates.html#template-headers. +// Include this header multiple times to implement a +// simplistic linked list. Before inclusion define at +// least LIST_T to the type the linked list can hold. +// See LIST_NAME, LIST_PREFIX and LIST_LINKAGE for +// other customization points. +// +// If you define LIST_DECLS_ONLY, only the declarations +// of the type and its function will be declared. +// +// Functions ending with _gl use malloc() for the nodes. +// Functions ending with _kls expect a Koliseo arg to use for allocating nodes. +// + +#ifndef LIST_HEADER_H +#define LIST_HEADER_H +// Inline functions, #defines and includes that will be +// needed for all instantiations can go up here. +#include // bool +#include // malloc, size_t + +#define LIST_IMPL(word) LIST_COMB1(LIST_PREFIX,word) +#define LIST_COMB1(pre, word) LIST_COMB2(pre, word) +#define LIST_COMB2(pre, word) pre##word + +#define LIST_HEADER_VERSION "0.1.0" + +#endif // LIST_HEADER_H + +// NOTE: this section is *not* guarded as it is intended +// to be included multiple times. + +#ifndef LIST_T +#error "LIST_T must be defined to use this list template" +#endif + +#ifndef KOLISEO_H_ // Using code must include koliseo.h before this file +#error "This list template needs koliseo.h inclusion before usage" +#endif + +// The name of the data type to be generated. +// If not given, will expand to something like +// `list_int` for an `int`. +#ifndef LIST_NAME +#define LIST_NAME LIST_COMB1(LIST_COMB1(list,_), LIST_T) +#endif + +// Prefix for generated functions. +#ifndef LIST_PREFIX +#define LIST_PREFIX LIST_COMB1(LIST_NAME, _) +#endif + +// Customize the linkage of the function. +#ifndef LIST_LINKAGE +#define LIST_LINKAGE static inline +#endif + +// Suffix for generated list item struct. +#ifndef LIST_I_SUFFIX +#define LIST_I_SUFFIX item +#endif + +// The name of the item data type to be generated. +#ifndef LIST_ITEM_NAME +#define LIST_ITEM_NAME LIST_COMB1(LIST_COMB1(LIST_T,_), LIST_I_SUFFIX) +#endif + +typedef struct LIST_ITEM_NAME LIST_ITEM_NAME; +struct LIST_ITEM_NAME { + LIST_T* value; + struct LIST_ITEM_NAME* next; +}; +typedef LIST_ITEM_NAME* LIST_NAME; + +#define LIST_nullList LIST_IMPL(nullList) +#define LIST_isEmpty LIST_IMPL(isEmpty) +#define LIST_head LIST_IMPL(head) +#define LIST_tail LIST_IMPL(tail) +#define LIST_cons_gl LIST_IMPL(cons_gl) +#define LIST_cons_kls LIST_IMPL(cons_kls) +#define LIST_free_gl LIST_IMPL(free_gl) +#define LIST_member LIST_IMPL(member) +#define LIST_length LIST_IMPL(length) +#define LIST_append_gl LIST_IMPL(append_gl) +#define LIST_append_kls LIST_IMPL(append_kls) +#define LIST_reverse_gl LIST_IMPL(reverse_gl) +#define LIST_reverse_kls LIST_IMPL(reverse_kls) +#define LIST_copy_gl LIST_IMPL(copy_gl) +#define LIST_copy_kls LIST_IMPL(copy_kls) +#define LIST_remove_gl LIST_IMPL(remove_gl) +#define LIST_remove_kls LIST_IMPL(remove_kls) +#define LIST_intersect_gl LIST_IMPL(intersect_gl) +#define LIST_intersect_kls LIST_IMPL(intersect_kls) +#define LIST_diff_gl LIST_IMPL(diff_gl) +#define LIST_diff_kls LIST_IMPL(diff_kls) + +#ifdef LIST_DECLS_ONLY + +LIST_LINKAGE +LIST_NAME +LIST_nullList(void); + +LIST_LINKAGE +bool +LIST_isEmpty(LIST_NAME list); + +LIST_LINKAGE +LIST_T* +LIST_head(LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_tail(LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_cons_gl(LIST_T* element, LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_cons_kls(Koliseo* kls, LIST_T* element, LIST_NAME list); + +LIST_LINKAGE +void +LIST_free_gl(LIST_NAME list); + +LIST_LINKAGE +bool +LIST_member(LIST_T* element, LIST_NAME list); + +LIST_LINKAGE +int +LIST_length(LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_append_gl(LIST_NAME l1, LIST_NAME l2); + +LIST_LINKAGE +LIST_NAME +LIST_append_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2); + +LIST_LINKAGE +LIST_NAME +LIST_reverse_gl(LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_reverse_kls(Koliseo* kls, LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_copy_gl(LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_copy_kls(Koliseo* kls, LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_remove_gl(LIST_T* element, LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_remove_kls(Koliseo* kls, LIST_T* element, LIST_NAME list); + +LIST_LINKAGE +LIST_NAME +LIST_intersect_gl(LIST_NAME l1, LIST_NAME l2); + +LIST_LINKAGE +LIST_NAME +LIST_intersect_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2); + +LIST_LINKAGE +LIST_NAME +LIST_diff_gl(LIST_NAME l1, LIST_NAME l2); + +LIST_LINKAGE +LIST_NAME +LIST_diff_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2); +#else + +LIST_LINKAGE +LIST_NAME +LIST_nullList(void) +{ + return NULL; +} + +LIST_LINKAGE +bool +LIST_isEmpty(LIST_NAME list) +{ + if (list == NULL) { + return true; + }; + return false; +} + +LIST_LINKAGE +LIST_T* +LIST_head(LIST_NAME list) +{ + if (LIST_isEmpty(list)) { + fprintf(stderr, "%s at %i: %s(): List is empty.\n", __FILE__, __LINE__, __func__); + return NULL; + } + return list->value; +} + +LIST_LINKAGE +LIST_NAME +LIST_tail(LIST_NAME list) +{ + if (LIST_isEmpty(list)) { + fprintf(stderr, "%s at %i: %s(): List is empty.\n", __FILE__, __LINE__, __func__); + return NULL; + } + return list->next; +} + +LIST_LINKAGE +LIST_NAME +LIST_cons_gl(LIST_T* element, LIST_NAME list) +{ + LIST_NAME t; + t = (LIST_NAME) malloc(sizeof(LIST_ITEM_NAME)); + t->value = element; + t->next = list; + return t; +} + +LIST_LINKAGE +LIST_NAME +LIST_cons_kls(Koliseo* kls, LIST_T* element, LIST_NAME list) +{ + if (kls == NULL) { + fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); + return NULL; + } + LIST_NAME t; + t = (LIST_NAME) KLS_PUSH_EX(kls, LIST_ITEM_NAME, "List node"); + if (t == NULL ) { + fprintf(stderr, "%s at %i: %s(): Failed KLS_PUSH_EX() call.\n", __FILE__, __LINE__, __func__); + return NULL; + } + t->value = element; + t->next = list; + return t; +} + +LIST_LINKAGE +void +LIST_free_gl(LIST_NAME list) +{ + if (LIST_isEmpty(list)) { + return; + } else { + LIST_free_gl(LIST_tail(list)); + free(list); + } + return; +} + +LIST_LINKAGE +bool +LIST_member(LIST_T* element, LIST_NAME list) +{ + if (LIST_isEmpty(list)) { + return false; + } else { + if (element == LIST_head(list)) { + return true; + } else { + return LIST_member(element, LIST_tail(list)); + } + } +} + +LIST_LINKAGE +int +LIST_length(LIST_NAME list) +{ + if (LIST_isEmpty(list)) { + return 0; + } else { + return 1 + LIST_length(LIST_tail(list)); + } +} + +LIST_LINKAGE +LIST_NAME +LIST_append_gl(LIST_NAME l1, LIST_NAME l2) +{ + if (LIST_isEmpty(l1)) { + return l2; + } else { + return LIST_cons_gl(LIST_head(l1), LIST_append_gl(LIST_tail(l1), l2)); + } +} + +LIST_LINKAGE +LIST_NAME +LIST_append_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2) +{ + if (kls == NULL) { + fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); + return NULL; + } + if (LIST_isEmpty(l1)) { + return l2; + } else { + return LIST_cons_kls(kls, LIST_head(l1), LIST_append_kls(kls, LIST_tail(l1), l2)); + } +} + +LIST_LINKAGE +LIST_NAME +LIST_reverse_gl(LIST_NAME list) +{ + if (LIST_isEmpty(list)) { + return LIST_nullList(); + } else { + return LIST_append_gl(LIST_reverse_gl(LIST_tail(list)), LIST_cons_gl(LIST_head(list), LIST_nullList())); + } +} + +LIST_LINKAGE +LIST_NAME +LIST_reverse_kls(Koliseo* kls, LIST_NAME list) +{ + if (kls == NULL) { + fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); + return NULL; + } + if (LIST_isEmpty(list)) { + return LIST_nullList(); + } else { + return LIST_append_kls(kls, LIST_reverse_kls(kls, LIST_tail(list)), LIST_cons_kls(kls, LIST_head(list), LIST_nullList())); + } +} + +LIST_LINKAGE +LIST_NAME +LIST_copy_gl(LIST_NAME list) +{ + if (LIST_isEmpty(list)) { + return list; + } else { + return LIST_cons_gl(LIST_head(list), LIST_copy_gl(LIST_tail(list))); + } +} + +LIST_LINKAGE +LIST_NAME +LIST_copy_kls(Koliseo* kls, LIST_NAME list) +{ + if (kls == NULL) { + fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); + return NULL; + } + if (LIST_isEmpty(list)) { + return list; + } else { + return LIST_cons_kls(kls, LIST_head(list), LIST_copy_kls(kls, LIST_tail(list))); + } + +} + +LIST_LINKAGE +LIST_NAME +LIST_remove_gl(LIST_T* element, LIST_NAME list) +{ + if (LIST_isEmpty(list)) { + return LIST_nullList(); + } else { + if (element == LIST_head(list)) { + return LIST_tail(list); + } else { + return LIST_cons_gl(LIST_head(list), LIST_remove_gl(element, LIST_tail(list))); + } + } +} + +LIST_LINKAGE +LIST_NAME +LIST_remove_kls(Koliseo* kls, LIST_T* element, LIST_NAME list) +{ + if (kls == NULL) { + fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); + return NULL; + } + if (LIST_isEmpty(list)) { + return LIST_nullList(); + } else { + if (element == LIST_head(list)) { + return LIST_tail(list); + } else { + return LIST_cons_kls(kls, LIST_head(list), LIST_remove_kls(kls, element, LIST_tail(list))); + } + } +} + +LIST_LINKAGE +LIST_NAME +LIST_intersect_gl(LIST_NAME l1, LIST_NAME l2) +{ + if (LIST_isEmpty(l1) || LIST_isEmpty(l2)) { + return LIST_nullList(); + } + if (LIST_member(LIST_head(l1), l2) && !(LIST_member(LIST_head(l1), LIST_tail(l2)))) { + return LIST_cons_gl(LIST_head(l1), LIST_intersect_gl(LIST_tail(l1), l2)); + } else { + return LIST_intersect_gl(LIST_tail(l1), l2); + } +} + +LIST_LINKAGE +LIST_NAME +LIST_intersect_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2) +{ + if (kls == NULL) { + fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); + return NULL; + } + if (LIST_isEmpty(l1) || LIST_isEmpty(l2)) { + return LIST_nullList(); + } + if (LIST_member(LIST_head(l1), l2) && !(LIST_member(LIST_head(l1), LIST_tail(l2)))) { + return LIST_cons_kls(kls, LIST_head(l1), LIST_intersect_kls(kls, LIST_tail(l1), l2)); + } else { + return LIST_intersect_kls(kls, LIST_tail(l1), l2); + } +} + +LIST_LINKAGE +LIST_NAME +LIST_diff_gl(LIST_NAME l1, LIST_NAME l2) +{ + if (LIST_isEmpty(l1) || LIST_isEmpty(l2)) { + return l1; + } else { + if (!LIST_member(LIST_head(l1), l2) && !LIST_member(LIST_head(l1), LIST_tail(l1))) { + return LIST_cons_gl(LIST_head(l1), LIST_diff_gl(LIST_tail(l1), l2)); + } else { + return LIST_diff_gl(LIST_tail(l1), l2); + } + } +} + +LIST_LINKAGE +LIST_NAME +LIST_diff_kls(Koliseo* kls, LIST_NAME l1, LIST_NAME l2) +{ + if (kls == NULL) { + fprintf(stderr, "%s at %i: %s(): Koliseo is NULL.\n", __FILE__, __LINE__, __func__); + return NULL; + } + if (LIST_isEmpty(l1) || LIST_isEmpty(l2)) { + return l1; + } else { + if (!LIST_member(LIST_head(l1), l2) && !LIST_member(LIST_head(l1), LIST_tail(l1))) { + return LIST_cons_kls(kls, LIST_head(l1), LIST_diff_kls(kls, LIST_tail(l1), l2)); + } else { + return LIST_diff_kls(kls, LIST_tail(l1), l2); + } + } +} +#endif // LIST_DECLS_ONLY + +// Cleanup +// These need to be undef'ed so they can be redefined the +// next time you need to instantiate this template. +#undef LIST_T +#undef LIST_PREFIX +#undef LIST_NAME +#undef LIST_LINKAGE +#undef LIST_I_SUFFIX +#undef LIST_ITEM_NAME +#undef LIST_nullList +#undef LIST_isEmpty +#undef LIST_head +#undef LIST_tail +#undef LIST_cons_gl +#undef LIST_cons_kls +#undef LIST_free_gl +#undef LIST_member +#undef LIST_length +#undef LIST_append_gl +#undef LIST_append_kls +#undef LIST_reverse_gl +#undef LIST_reverse_kls +#undef LIST_copy_gl +#undef LIST_copy_kls +#undef LIST_remove_gl +#undef LIST_remove_kls +#undef LIST_intersect_gl +#undef LIST_intersect_kls +#undef LIST_diff_gl +#undef LIST_diff_kls +#ifdef LIST_DECLS_ONLY +#undef LIST_DECLS_ONLY +#endif // LIST_HEADER_H diff --git a/tests/error/bad_size.k.stderr b/tests/error/bad_size.k.stderr index e23c7ef..e1dc5de 100644 --- a/tests/error/bad_size.k.stderr +++ b/tests/error/bad_size.k.stderr @@ -1,2 +1,2 @@ -[ERROR] at kls_new_alloc(): invalid requested kls size (-1). Min accepted is: (104). +[ERROR] at kls_new_alloc(): invalid requested kls size (-1). Min accepted is: (112). [ERROR] [kls_push_zero_AR()]: Passed Koliseo was NULL.