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.