remove ucx (breaks build) newapi

Sat, 15 Apr 2023 15:45:42 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 15 Apr 2023 15:45:42 +0200
branch
newapi
changeset 172
706080c30af6
parent 171
5065d0d52680
child 173
809581724cc7

remove ucx (breaks build)

make/Makefile.mk file | annotate | diff | comparison | revisions
ucx/Makefile file | annotate | diff | comparison | revisions
ucx/README file | annotate | diff | comparison | revisions
ucx/allocator.c file | annotate | diff | comparison | revisions
ucx/array.c file | annotate | diff | comparison | revisions
ucx/avl.c file | annotate | diff | comparison | revisions
ucx/buffer.c file | annotate | diff | comparison | revisions
ucx/list.c file | annotate | diff | comparison | revisions
ucx/logging.c file | annotate | diff | comparison | revisions
ucx/map.c file | annotate | diff | comparison | revisions
ucx/mempool.c file | annotate | diff | comparison | revisions
ucx/properties.c file | annotate | diff | comparison | revisions
ucx/stack.c file | annotate | diff | comparison | revisions
ucx/string.c file | annotate | diff | comparison | revisions
ucx/test.c file | annotate | diff | comparison | revisions
ucx/ucx.c file | annotate | diff | comparison | revisions
ucx/ucx/allocator.h file | annotate | diff | comparison | revisions
ucx/ucx/array.h file | annotate | diff | comparison | revisions
ucx/ucx/avl.h file | annotate | diff | comparison | revisions
ucx/ucx/buffer.h file | annotate | diff | comparison | revisions
ucx/ucx/list.h file | annotate | diff | comparison | revisions
ucx/ucx/logging.h file | annotate | diff | comparison | revisions
ucx/ucx/map.h file | annotate | diff | comparison | revisions
ucx/ucx/mempool.h file | annotate | diff | comparison | revisions
ucx/ucx/properties.h file | annotate | diff | comparison | revisions
ucx/ucx/stack.h file | annotate | diff | comparison | revisions
ucx/ucx/string.h file | annotate | diff | comparison | revisions
ucx/ucx/test.h file | annotate | diff | comparison | revisions
ucx/ucx/ucx.h file | annotate | diff | comparison | revisions
ucx/ucx/utils.h file | annotate | diff | comparison | revisions
ucx/utils.c file | annotate | diff | comparison | revisions
ui/Makefile file | annotate | diff | comparison | revisions
--- a/make/Makefile.mk	Sat Apr 15 15:42:31 2023 +0200
+++ b/make/Makefile.mk	Sat Apr 15 15:45:42 2023 +0200
@@ -1,7 +1,7 @@
 #
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 #
-# Copyright 2013 Olaf Wintermann. All rights reserved.
+# Copyright 2023 Olaf Wintermann. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -41,9 +41,6 @@
 $(BUILD_DIRS):
 	mkdir -p $@
 
-ucx: FORCE
-	cd ucx; $(MAKE)
-
 ui: FORCE
 	cd ui; $(MAKE) all
 
--- a/ucx/Makefile	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
-#
-# Copyright 2013 Olaf Wintermann. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-#   1. Redistributions of source code must retain the above copyright
-#      notice, this list of conditions and the following disclaimer.
-#
-#   2. Redistributions in binary form must reproduce the above copyright
-#      notice, this list of conditions and the following disclaimer in the
-#      documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-
-BUILD_ROOT = ../
-include ../config.mk
-
-# list of source files
-SRC  = utils.c
-SRC += list.c
-SRC += map.c
-SRC += avl.c
-SRC += properties.c
-SRC += mempool.c
-SRC += string.c
-SRC += test.c
-SRC += allocator.c
-SRC += logging.c
-SRC += buffer.c
-SRC += stack.c
-SRC += ucx.c
-SRC += array.c
-
-OBJ   = $(SRC:%.c=../build/ucx/%.$(OBJ_EXT))
-
-UCX_LIB = ../build/lib/libucx.$(LIB_EXT)
-
-all: ../build/ucx $(UCX_LIB)
-
-$(UCX_LIB): $(OBJ)
-	$(AR) $(ARFLAGS) $(UCX_LIB) $(OBJ)
-
-../build/ucx:
-	mkdir -p ../build/ucx
-
-../build/ucx/%.$(OBJ_EXT): %.c
-	$(CC) $(CFLAGS) -o $@ -c $<
-
--- a/ucx/README	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-UCX is a library for common data structures, algorithms and string functions.
-
-More informations at: https://develop.uap-core.de/ucx/
-
--- a/ucx/allocator.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/allocator.h"
-
-#include <stdlib.h>
-
-static UcxAllocator default_allocator = {
-    NULL,
-    ucx_default_malloc,
-    ucx_default_calloc,
-    ucx_default_realloc,
-    ucx_default_free
-};
-
-UcxAllocator *ucx_default_allocator() {
-    UcxAllocator *allocator = &default_allocator;
-    return allocator;
-}
-
-void *ucx_default_malloc(void *ignore, size_t n) {
-    return malloc(n);
-}
-
-void *ucx_default_calloc(void *ignore, size_t n, size_t size) {
-    return calloc(n, size);
-}
-
-void *ucx_default_realloc(void *ignore, void *data, size_t n) {
-    return realloc(data, n);
-}
-
-void ucx_default_free(void *ignore, void *data) {
-    free(data);
-}
--- a/ucx/array.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2019 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define _GNU_SOURCE /* we want to use qsort_r(), if available */
-#define __STDC_WANT_LIB_EXT1__ 1 /* use qsort_s, if available */
-
-
-#include "ucx/array.h"
-#include "ucx/utils.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#ifndef UCX_ARRAY_DISABLE_QSORT
-#ifdef __GLIBC__
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
-#define ucx_array_sort_impl qsort_r
-#endif /* glibc version >= 2.8 */
-#elif /* not  __GLIBC__ */ defined(__APPLE__) || defined(__FreeBSD__)
-#define ucx_array_sort_impl ucx_qsort_r
-#define USE_UCX_QSORT_R
-#elif /* not (__APPLE || __FreeBSD__) */ defined(__sun)
-#if __STDC_VERSION__ >= 201112L
-#define ucx_array_sort_impl qsort_s
-#endif
-#endif /* __GLIBC__, __APLE__, __FreeBSD__, __sun */
-#endif /* UCX_ARRAY_DISABLE_QSORT */
-
-#ifndef ucx_array_sort_impl
-#define ucx_array_sort_impl ucx_mergesort
-#endif
-
-static int ucx_array_ensurecap(UcxArray *array, size_t reqcap) {
-    size_t required_capacity = array->capacity;
-    while (reqcap > required_capacity) {
-        if (required_capacity * 2 < required_capacity)
-            return 1;
-        required_capacity <<= 1;
-    }
-    if (ucx_array_reserve(array, required_capacity)) {
-        return 1;
-    }
-    return 0;
-}
-
-int ucx_array_util_set_a(UcxAllocator* alloc, void** array, size_t* capacity,
-    size_t elmsize, size_t index, void* data) {
-    
-    if(!alloc || !capacity || !array) {
-        errno = EINVAL;
-        return 1;
-    }
-    
-    size_t newcapacity = *capacity;
-    while(index >= newcapacity) {
-        if(ucx_szmul(newcapacity, 2, &newcapacity)) {
-            errno = EOVERFLOW;
-            return 1;
-        }        
-    }
-
-    size_t memlen, offset;
-    if(ucx_szmul(newcapacity, elmsize, &memlen)) {
-        errno = EOVERFLOW;
-        return 1;
-    }
-    /* we don't need to check index*elmsize - it is smaller than memlen */
-    
-    
-    void* newptr = alrealloc(alloc, *array, memlen);
-    if(newptr == NULL) {
-        errno = ENOMEM; /* we cannot assume that every allocator sets this */
-        return 1;
-    }
-    *array = newptr;
-    *capacity = newcapacity;
-    
-    
-    char* dest = *array;
-    dest += elmsize*index;
-    memcpy(dest, data, elmsize);
-    
-    return 0;
-}
-
-int ucx_array_util_setptr_a(UcxAllocator* alloc, void** array, size_t* capacity,
-    size_t index, void* data) {
-    
-    return ucx_array_util_set_a(alloc, array, capacity, sizeof(void*),
-            index, &data);
-}
-
-UcxArray* ucx_array_new(size_t capacity, size_t elemsize) {
-    return ucx_array_new_a(capacity, elemsize, ucx_default_allocator());
-}
-
-UcxArray* ucx_array_new_a(size_t capacity, size_t elemsize,
-        UcxAllocator* allocator) {
-    UcxArray* array = almalloc(allocator, sizeof(UcxArray));
-    if(array) {
-        ucx_array_init_a(array, capacity, elemsize, allocator);
-    }
-    return array;
-}
-
-void ucx_array_init(UcxArray* array, size_t capacity, size_t elemsize) {
-    ucx_array_init_a(array, capacity, elemsize, ucx_default_allocator());
-}
-
-void ucx_array_init_a(UcxArray* array, size_t capacity, size_t elemsize,
-        UcxAllocator* allocator) {
-    
-    array->allocator = allocator;
-    array->elemsize = elemsize;
-    array->size = 0;
-    array->data = alcalloc(allocator, capacity, elemsize);
-    
-    if (array->data) {
-        array->capacity = capacity;
-    } else {
-        array->capacity = 0;
-    }
-}
-
-int ucx_array_clone(UcxArray* dest, UcxArray const* src) {
-    if (ucx_array_ensurecap(dest, src->capacity)) {
-        return 1;
-    }
-    
-    dest->elemsize = src->elemsize;
-    dest->size = src->size;
-    
-    if (dest->data) {
-        memcpy(dest->data, src->data, src->size*src->elemsize);
-    }
-    
-    return 0;
-}
-
-int ucx_array_equals(UcxArray const *array1, UcxArray const *array2,
-        cmp_func cmpfnc, void* data) {
-    
-    if (array1->size != array2->size || array1->elemsize != array2->elemsize) {
-        return 0;
-    } else {
-        if (array1->size == 0)
-            return 1;
-        
-        size_t elemsize;
-        if (cmpfnc == NULL) {
-            cmpfnc = ucx_cmp_mem;
-            elemsize = array1->elemsize;
-            data = &elemsize;
-        }
-        
-        for (size_t i = 0 ; i < array1->size ; i++) {
-            int r = cmpfnc(
-                    ucx_array_at(array1, i),
-                    ucx_array_at(array2, i),
-                    data);
-            if (r != 0)
-                return 0;
-        }
-        return 1;
-    }
-}
-
-void ucx_array_destroy(UcxArray *array) {
-    if(array->data)
-        alfree(array->allocator, array->data);
-    array->data = NULL;
-    array->capacity = array->size = 0;
-}
-
-void ucx_array_free(UcxArray *array) {
-    ucx_array_destroy(array);
-    alfree(array->allocator, array);
-}
-
-int ucx_array_append_from(UcxArray *array, void *data, size_t count) {
-    if (ucx_array_ensurecap(array, array->size + count))
-        return 1;
-    
-    void* dest = ucx_array_at(array, array->size);
-    if (data) {
-        memcpy(dest, data, array->elemsize*count);
-    } else {
-        memset(dest, 0, array->elemsize*count);
-    }
-    array->size += count;
-    
-    return 0;
-}
-
-int ucx_array_prepend_from(UcxArray *array, void *data, size_t count) {
-    if (ucx_array_ensurecap(array, array->size + count))
-        return 1;
-    
-    if (array->size > 0) {
-        void *dest = ucx_array_at(array, count);
-        memmove(dest, array->data, array->elemsize*array->size);
-    }
-    
-    if (data) {
-        memcpy(array->data, data, array->elemsize*count);
-    } else {
-        memset(array->data, 0, array->elemsize*count);
-    }
-    array->size += count;
-        
-    return 0;
-}
-
-int ucx_array_set_from(UcxArray *array, size_t index,
-        void *data, size_t count) {
-    if (ucx_array_ensurecap(array, index + count))
-        return 1;
-    
-    if (index+count > array->size) {
-        array->size = index+count;
-    }
-    
-    void *dest = ucx_array_at(array, index);
-    if (data) {
-        memcpy(dest, data, array->elemsize*count);
-    } else {
-        memset(dest, 0, array->elemsize*count);
-    }
-    
-    return 0;
-}
-
-int ucx_array_concat(UcxArray *array1, const UcxArray *array2) {
-    
-    if (array1->elemsize != array2->elemsize)
-        return 1;
-    
-    size_t capacity = array1->capacity+array2->capacity;
-        
-    if (array1->capacity < capacity) {
-        if (ucx_array_reserve(array1, capacity)) {
-            return 1;
-        }
-    }
-    
-    void* dest = ucx_array_at(array1, array1->size);
-    memcpy(dest, array2->data, array2->size*array2->elemsize);
-    
-    array1->size += array2->size;
-    
-    return 0;
-}
-
-void *ucx_array_at(UcxArray const *array, size_t index) {
-    char* memory = array->data;
-    char* loc = memory + index*array->elemsize;
-    return loc;
-}
-
-size_t ucx_array_find(UcxArray const *array, void *elem,
-        cmp_func cmpfnc, void *data) {
-    
-    size_t elemsize;
-    if (cmpfnc == NULL) {
-        cmpfnc = ucx_cmp_mem;
-        elemsize = array->elemsize;
-        data = &elemsize;
-    }
-
-    if (array->size > 0) {
-        for (size_t i = 0 ; i < array->size ; i++) {
-            void* ptr = ucx_array_at(array, i);
-            if (cmpfnc(ptr, elem, data) == 0) {
-                return i;
-            }
-        }
-        return array->size;
-    } else {
-        return 0;
-    }
-}
-
-int ucx_array_contains(UcxArray const *array, void *elem,
-        cmp_func cmpfnc, void *data) {
-    return ucx_array_find(array, elem, cmpfnc, data) != array->size;
-}
-
-static void ucx_mergesort_merge(void *arrdata,size_t elemsize,
-        cmp_func cmpfnc, void *data,
-        size_t start, size_t mid, size_t end) { 
-    
-    char* array = arrdata;
-    
-    size_t rightstart = mid + 1; 
-  
-    if (cmpfnc(array + mid*elemsize,
-            array + rightstart*elemsize, data) <= 0) {
-        /* already sorted */
-        return;
-    }
-  
-    /* we need memory for one element */
-    void *value = malloc(elemsize);
-    
-    while (start <= mid && rightstart <= end) { 
-        if (cmpfnc(array + start*elemsize,
-                array + rightstart*elemsize, data) <= 0) { 
-            start++; 
-        } else {
-            /* save the value from the right */
-            memcpy(value, array + rightstart*elemsize, elemsize);
-                        
-            /* shift all left elements one element to the right */
-            size_t shiftcount = rightstart-start;
-            void *startptr = array + start*elemsize;
-            void *dest = array + (start+1)*elemsize;
-            memmove(dest, startptr, shiftcount*elemsize);
-            
-            /* bring the first value from the right to the left */
-            memcpy(startptr, value, elemsize);
-  
-            start++; 
-            mid++; 
-            rightstart++; 
-        }
-    }
-    
-    /* free the temporary memory */
-    free(value);
-} 
-  
-static void ucx_mergesort_impl(void *arrdata, size_t elemsize,
-        cmp_func cmpfnc, void *data, size_t l, size_t r) { 
-    if (l < r) {
-        size_t m = l + (r - l) / 2; 
-  
-        ucx_mergesort_impl(arrdata, elemsize, cmpfnc, data, l, m); 
-        ucx_mergesort_impl(arrdata, elemsize, cmpfnc, data, m + 1, r); 
-        ucx_mergesort_merge(arrdata, elemsize, cmpfnc, data, l, m, r);
-    } 
-}
-
-static void ucx_mergesort(void *arrdata, size_t count, size_t elemsize,
-        cmp_func cmpfnc, void *data) {
-    
-    ucx_mergesort_impl(arrdata, elemsize, cmpfnc, data, 0, count-1);
-}
-
-#ifdef USE_UCX_QSORT_R
-struct cmpfnc_swapargs_info {
-    cmp_func func;
-    void *data;
-};
-
-static int cmp_func_swap_args(void *data, const void *x, const void *y) {
-    struct cmpfnc_swapargs_info* info = data;
-    return info->func(x, y, info->data);
-}
-
-static void ucx_qsort_r(void *array, size_t count, size_t elemsize,
-		     cmp_func cmpfnc, void *data) {
-    struct cmpfnc_swapargs_info info;
-    info.func = cmpfnc;
-    info.data = data;
-    qsort_r(array, count, elemsize, &info, cmp_func_swap_args);
-}
-#endif /* USE_UCX_QSORT_R */
-
-void ucx_array_sort(UcxArray* array, cmp_func cmpfnc, void *data) {
-    ucx_array_sort_impl(array->data, array->size, array->elemsize,
-            cmpfnc, data);
-}
-
-void ucx_array_remove(UcxArray *array, size_t index) {
-    array->size--;
-    if (index < array->size) {
-        void* dest = ucx_array_at(array, index);
-        void* src = ucx_array_at(array, index+1);
-        memmove(dest, src, (array->size - index)*array->elemsize);
-    }
-}
-
-void ucx_array_remove_fast(UcxArray *array, size_t index) {
-    array->size--;
-    if (index < array->size) {       
-        void* dest = ucx_array_at(array, index);
-        void* src = ucx_array_at(array, array->size);
-        memcpy(dest, src, array->elemsize);
-    }
-}
-
-int ucx_array_shrink(UcxArray* array) {
-    void* newptr = alrealloc(array->allocator, array->data,
-                array->size*array->elemsize);
-    if (newptr) {
-        array->data = newptr;
-        array->capacity = array->size;
-        return 0;
-    } else {
-        return 1;
-    }
-}
-
-int ucx_array_resize(UcxArray* array, size_t capacity) {
-    if (array->capacity >= capacity) {
-        void* newptr = alrealloc(array->allocator, array->data,
-                capacity*array->elemsize);
-        if (newptr) {
-            array->data = newptr;
-            array->capacity = capacity;
-            if (array->size > array->capacity) {
-                array->size = array->capacity;
-            }
-            return 0;
-        } else {
-            return 1;
-        }
-    } else {
-        return ucx_array_reserve(array, capacity);
-    }
-}
-
-int ucx_array_reserve(UcxArray* array, size_t capacity) {
-    if (array->capacity > capacity) {
-        return 0;
-    } else {
-        void* newptr = alrealloc(array->allocator, array->data,
-                capacity*array->elemsize);
-        if (newptr) {
-            array->data = newptr;
-            array->capacity = capacity;
-            return 0;
-        } else {
-            return 1;
-        }
-    }
-}
-
-int ucx_array_grow(UcxArray* array, size_t count) {
-    return ucx_array_reserve(array, array->size+count);
-}
--- a/ucx/avl.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,373 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/avl.h"
-
-#include <limits.h>
-
-#define ptrcast(ptr) ((void*)(ptr))
-#define alloc_tree(al) (UcxAVLTree*) almalloc((al), sizeof(UcxAVLTree))
-#define alloc_node(al) (UcxAVLNode*) almalloc((al), sizeof(UcxAVLNode))
-
-static void ucx_avl_connect(UcxAVLTree *tree,
-        UcxAVLNode *node, UcxAVLNode *child, intptr_t nullkey) {
-    if (child) {
-        child->parent = node;
-    }
-    // if child is NULL, nullkey decides if left or right pointer is cleared
-    if (tree->cmpfunc(
-        ptrcast(child ? child->key : nullkey),
-        ptrcast(node->key), tree->userdata) > 0) {
-      node->right = child;
-    } else {
-      node->left = child;
-    }
-    size_t lh = node->left ? node->left->height : 0;
-    size_t rh = node->right ? node->right->height : 0;
-    node->height = 1 + (lh > rh ? lh : rh);
-}
-
-#define avlheight(node) ((node) ? (node)->height : 0)
-
-static UcxAVLNode* avl_rotright(UcxAVLTree *tree, UcxAVLNode *l0) {
-    UcxAVLNode *p = l0->parent;
-    UcxAVLNode *l1 = l0->left;
-    if (p) {
-        ucx_avl_connect(tree, p, l1, 0);
-    } else {
-        l1->parent = NULL;
-    }
-    ucx_avl_connect(tree, l0, l1->right, l1->key);
-    ucx_avl_connect(tree, l1, l0, 0);
-    return l1;
-}
-
-static UcxAVLNode* avl_rotleft(UcxAVLTree *tree, UcxAVLNode *l0) {
-    UcxAVLNode *p = l0->parent;
-    UcxAVLNode *l1 = l0->right;
-    if (p) {
-        ucx_avl_connect(tree, p, l1, 0);
-    } else {
-        l1->parent = NULL;
-    }
-    ucx_avl_connect(tree, l0, l1->left, l1->key);
-    ucx_avl_connect(tree, l1, l0, 0);
-    return l1;
-}
-
-static void ucx_avl_balance(UcxAVLTree *tree, UcxAVLNode *n) {
-    int lh = avlheight(n->left);
-    int rh = avlheight(n->right);
-    n->height = 1 + (lh > rh ? lh : rh);
-    
-    if (lh - rh == 2) {
-      UcxAVLNode *c = n->left;
-      if (avlheight(c->right) - avlheight(c->left) == 1) {
-        avl_rotleft(tree, c);
-      }
-      n = avl_rotright(tree, n);
-    } else if (rh - lh == 2) {  
-      UcxAVLNode *c = n->right;
-      if (avlheight(c->left) - avlheight(c->right) == 1) {
-        avl_rotright(tree, c);
-      }
-      n = avl_rotleft(tree, n);
-    }
-
-    if (n->parent) {
-      ucx_avl_balance(tree, n->parent);
-    } else {
-      tree->root = n;
-    }
-}
-
-UcxAVLTree *ucx_avl_new(cmp_func cmpfunc) {
-    return ucx_avl_new_a(cmpfunc, ucx_default_allocator());
-}
-
-UcxAVLTree *ucx_avl_new_a(cmp_func cmpfunc, UcxAllocator *allocator) {
-    UcxAVLTree* tree = alloc_tree(allocator);
-    if (tree) {
-        tree->allocator = allocator;
-        tree->cmpfunc = cmpfunc;
-        tree->root = NULL;
-        tree->userdata = NULL;
-    }
-    
-    return tree;
-}
-
-static void ucx_avl_free_node(UcxAllocator *al, UcxAVLNode *node) {
-    if (node) {
-        ucx_avl_free_node(al, node->left);
-        ucx_avl_free_node(al, node->right);
-        alfree(al, node);
-    }
-}
-
-void ucx_avl_free(UcxAVLTree *tree) {
-    UcxAllocator *al = tree->allocator;
-    ucx_avl_free_node(al, tree->root);
-    alfree(al, tree);
-}
-
-static void ucx_avl_free_content_node(UcxAllocator *al, UcxAVLNode *node,
-        ucx_destructor destr) {
-    if (node) {
-        ucx_avl_free_content_node(al, node->left, destr);
-        ucx_avl_free_content_node(al, node->right, destr);
-        if (destr) {
-            destr(node->value);
-        } else {
-            alfree(al, node->value);
-        }
-    }
-}
-
-void ucx_avl_free_content(UcxAVLTree *tree, ucx_destructor destr) {
-    ucx_avl_free_content_node(tree->allocator, tree->root, destr);
-}
-
-UcxAVLNode *ucx_avl_get_node(UcxAVLTree *tree, intptr_t key) {
-    UcxAVLNode *n = tree->root;
-    int cmpresult;
-    while (n && (cmpresult = tree->cmpfunc(
-            ptrcast(key), ptrcast(n->key), tree->userdata))) {
-        n = cmpresult > 0 ? n->right : n->left;
-    }
-    return n;
-}
-
-void *ucx_avl_get(UcxAVLTree *tree, intptr_t key) {
-    UcxAVLNode *n = ucx_avl_get_node(tree, key);
-    return n ? n->value : NULL;
-}
-
-UcxAVLNode *ucx_avl_find_node(UcxAVLTree *tree, intptr_t key,
-        distance_func dfnc, int mode) {
-    UcxAVLNode *n = tree->root;
-    UcxAVLNode *closest = NULL;
-
-    intmax_t cmpresult;
-    intmax_t closest_dist;
-    closest_dist = mode == UCX_AVL_FIND_LOWER_BOUNDED ? INTMAX_MIN : INTMAX_MAX;
-    
-    while (n && (cmpresult = dfnc(
-            ptrcast(key), ptrcast(n->key), tree->userdata))) {
-        if (mode == UCX_AVL_FIND_CLOSEST) {
-            intmax_t dist = cmpresult;
-            if (dist < 0) dist *= -1;
-            if (dist < closest_dist) {
-                closest_dist = dist;
-                closest = n;
-            }
-        } else if (mode == UCX_AVL_FIND_LOWER_BOUNDED && cmpresult <= 0) {
-            if (cmpresult > closest_dist) {
-                closest_dist = cmpresult;
-                closest = n;
-            }
-        } else if (mode == UCX_AVL_FIND_UPPER_BOUNDED && cmpresult >= 0) {
-            if (cmpresult < closest_dist) {
-                closest_dist = cmpresult;
-                closest = n;
-            }
-        }
-        n = cmpresult > 0 ? n->right : n->left;
-    }
-    return n ? n : closest;
-}
-
-void *ucx_avl_find(UcxAVLTree *tree, intptr_t key,
-        distance_func dfnc, int mode) {
-    UcxAVLNode *n = ucx_avl_find_node(tree, key, dfnc, mode);
-    return n ? n->value : NULL;
-}
-
-int ucx_avl_put(UcxAVLTree *tree, intptr_t key, void *value) {
-    return ucx_avl_put_s(tree, key, value, NULL);
-}
-
-int ucx_avl_put_s(UcxAVLTree *tree, intptr_t key, void *value,
-        void **oldvalue) {
-    if (tree->root) {
-        UcxAVLNode *n = tree->root;
-        int cmpresult;
-        while ((cmpresult = tree->cmpfunc(
-                ptrcast(key), ptrcast(n->key), tree->userdata))) {
-            UcxAVLNode *m = cmpresult > 0 ? n->right : n->left;
-            if (m) {
-                n = m;
-            } else {
-                break;
-            }
-        }
-
-        if (cmpresult) {
-            UcxAVLNode* e = alloc_node(tree->allocator);
-            if (e) {
-                e->key = key; e->value = value; e->height = 1;
-                e->parent = e->left = e->right = NULL;
-                ucx_avl_connect(tree, n, e, 0);
-                ucx_avl_balance(tree, n);
-                return 0;
-            } else {
-                return 1;
-            }
-        } else {
-            if (oldvalue) {
-                *oldvalue = n->value;
-            }
-            n->value = value;
-            return 0;
-        }
-    } else {
-        tree->root = alloc_node(tree->allocator);
-        if (tree->root) {
-            tree->root->key = key; tree->root->value = value;
-            tree->root->height = 1;
-            tree->root->parent = tree->root->left = tree->root->right = NULL;
-            
-            if (oldvalue) {
-                *oldvalue = NULL;
-            }
-            
-            return 0;
-        } else {
-            return 1;
-        }
-    }
-}
-
-int ucx_avl_remove(UcxAVLTree *tree, intptr_t key) {
-    return ucx_avl_remove_s(tree, key, NULL, NULL);
-}
-    
-int ucx_avl_remove_node(UcxAVLTree *tree, UcxAVLNode *node) {
-    return ucx_avl_remove_s(tree, node->key, NULL, NULL);
-}
-
-int ucx_avl_remove_s(UcxAVLTree *tree, intptr_t key,
-        intptr_t *oldkey, void **oldvalue) {
-    
-    UcxAVLNode *n = tree->root;
-    int cmpresult;
-    while (n && (cmpresult = tree->cmpfunc(
-            ptrcast(key), ptrcast(n->key), tree->userdata))) {
-        n = cmpresult > 0 ? n->right : n->left;
-    }
-    if (n) {
-        if (oldkey) {
-            *oldkey = n->key;
-        }
-        if (oldvalue) {
-            *oldvalue = n->value;
-        }
-        
-        UcxAVLNode *p = n->parent;
-        if (n->left && n->right) {
-            UcxAVLNode *s = n->right;
-            while (s->left) {
-                s = s->left;
-            }
-            ucx_avl_connect(tree, s->parent, s->right, s->key);
-            n->key = s->key; n->value = s->value;
-            p = s->parent;
-            alfree(tree->allocator, s);
-        } else {
-            if (p) {
-                ucx_avl_connect(tree, p, n->right ? n->right:n->left, n->key);
-            } else {
-                tree->root = n->right ? n->right : n->left;
-                if (tree->root) {
-                    tree->root->parent = NULL;
-                }
-            }
-            alfree(tree->allocator, n);
-        }
-
-        if (p) {
-            ucx_avl_balance(tree, p);
-        }
-        
-        return 0;
-    } else {
-        return 1;
-    }
-}
-
-static size_t ucx_avl_countn(UcxAVLNode *node) {
-    if (node) {
-        return 1 + ucx_avl_countn(node->left) + ucx_avl_countn(node->right);
-    } else {
-        return 0;
-    }
-}
-
-size_t ucx_avl_count(UcxAVLTree *tree) {
-    return ucx_avl_countn(tree->root);
-}
-
-UcxAVLNode* ucx_avl_pred(UcxAVLNode* node) {
-    if (node->left) {
-        UcxAVLNode* n = node->left;
-        while (n->right) {
-            n = n->right;
-        }
-        return n;
-    } else {
-        UcxAVLNode* n = node;
-        while (n->parent) {
-            if (n->parent->right == n) {
-                return n->parent;
-            } else {
-                n = n->parent;
-            }
-        }
-        return NULL;
-    }
-}
-
-UcxAVLNode* ucx_avl_succ(UcxAVLNode* node) {
-    if (node->right) {
-        UcxAVLNode* n = node->right;
-        while (n->left) {
-            n = n->left;
-        }
-        return n;
-    } else {
-        UcxAVLNode* n = node;
-        while (n->parent) {
-            if (n->parent->left == n) {
-                return n->parent;
-            } else {
-                n = n->parent;
-            }
-        }
-        return NULL;
-    }
-}
--- a/ucx/buffer.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,297 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/buffer.h"
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-UcxBuffer *ucx_buffer_new(void *space, size_t capacity, int flags) {
-    UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer));
-    if (buffer) {
-        buffer->flags = flags;
-        if (!space) {
-            buffer->space = (char*)malloc(capacity);
-            if (!buffer->space) {
-                free(buffer);
-                return NULL;
-            }
-            memset(buffer->space, 0, capacity);
-            buffer->flags |= UCX_BUFFER_AUTOFREE;
-        } else {
-            buffer->space = (char*)space;
-        }
-        buffer->capacity = capacity;
-        buffer->size = 0;
-
-        buffer->pos = 0;
-    }
-
-    return buffer;
-}
-
-void ucx_buffer_free(UcxBuffer *buffer) {
-    if ((buffer->flags & UCX_BUFFER_AUTOFREE) == UCX_BUFFER_AUTOFREE) {
-        free(buffer->space);
-    }
-    free(buffer);
-}
-
-UcxBuffer* ucx_buffer_extract(
-        UcxBuffer *src, size_t start, size_t length, int flags) {
-    if (src->size == 0 || length == 0 ||
-        ((size_t)-1) - start < length || start+length > src->capacity)
-    {
-        return NULL;
-    }
-
-    UcxBuffer *dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
-    if (dst) {
-        dst->space = (char*)malloc(length);
-        if (!dst->space) {
-            free(dst);
-            return NULL;
-        }
-        dst->capacity = length;
-        dst->size = length;
-        dst->flags = flags | UCX_BUFFER_AUTOFREE;
-        dst->pos = 0;
-        memcpy(dst->space, src->space+start, length);
-    }
-    return dst;
-}
-
-int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence) {
-    size_t npos;
-    switch (whence) {
-    case SEEK_CUR:
-        npos = buffer->pos;
-        break;
-    case SEEK_END:
-        npos = buffer->size;
-        break;
-    case SEEK_SET:
-        npos = 0;
-        break;
-    default:
-        return -1;
-    }
-
-    size_t opos = npos;
-    npos += offset;
-    
-    if ((offset > 0 && npos < opos) || (offset < 0 && npos > opos)) {
-        return -1;
-    }
-    
-    if (npos >= buffer->size) {
-        return -1;
-    } else {
-        buffer->pos = npos;
-        return 0;
-    }
-
-}
-
-int ucx_buffer_eof(UcxBuffer *buffer) {
-    return buffer->pos >= buffer->size;
-}
-
-int ucx_buffer_extend(UcxBuffer *buffer, size_t len) {
-    size_t newcap = buffer->capacity;
-    
-    if (buffer->capacity + len < buffer->capacity) {
-        return -1;
-    }
-    
-    while (buffer->capacity + len > newcap) {
-        newcap <<= 1;
-        if (newcap < buffer->capacity) {
-            return -1;
-        }
-    }
-    
-    char *newspace = (char*)realloc(buffer->space, newcap);
-    if (newspace) {
-        memset(newspace+buffer->size, 0, newcap-buffer->size);
-        buffer->space = newspace;
-        buffer->capacity = newcap;
-    } else {
-        return -1;
-    }
-    
-    return 0;
-}
-
-size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
-        UcxBuffer *buffer) {
-    size_t len;
-    if(ucx_szmul(size, nitems, &len)) {
-        return 0;
-    }
-    size_t required = buffer->pos + len;
-    if (buffer->pos > required) {
-        return 0;
-    }
-    
-    if (required > buffer->capacity) {
-        if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
-            if (ucx_buffer_extend(buffer, required - buffer->capacity)) {
-                return 0;
-            }
-        } else {
-            len = buffer->capacity - buffer->pos;
-            if (size > 1) {
-                len -= len%size;
-            }
-        }
-    }
-    
-    if (len == 0) {
-        return len;
-    }
-    
-    memcpy(buffer->space + buffer->pos, ptr, len);
-    buffer->pos += len;
-    if(buffer->pos > buffer->size) {
-        buffer->size = buffer->pos;
-    }
-    
-    return len / size;
-}
-
-size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
-        UcxBuffer *buffer) {
-    size_t len;
-    if(ucx_szmul(size, nitems, &len)) {
-        return 0;
-    }
-    if (buffer->pos + len > buffer->size) {
-        len = buffer->size - buffer->pos;
-        if (size > 1) len -= len%size;
-    }
-    
-    if (len <= 0) {
-        return len;
-    }
-    
-    memcpy(ptr, buffer->space + buffer->pos, len);
-    buffer->pos += len;
-    
-    return len / size;
-}
-
-int ucx_buffer_putc(UcxBuffer *buffer, int c) {
-    if(buffer->pos >= buffer->capacity) {
-        if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
-            if(ucx_buffer_extend(buffer, 1)) {
-                return EOF;
-            }
-        } else {
-            return EOF;
-        }
-    }
-    
-    c &= 0xFF;
-    buffer->space[buffer->pos] = (char) c;
-    buffer->pos++;
-    if(buffer->pos > buffer->size) {
-        buffer->size = buffer->pos;
-    }
-    return c;
-}
-
-int ucx_buffer_getc(UcxBuffer *buffer) {
-    if (ucx_buffer_eof(buffer)) {
-        return EOF;
-    } else {
-        int c = ((unsigned char*)buffer->space)[buffer->pos];
-        buffer->pos++;
-        return c;
-    }
-}
-
-size_t ucx_buffer_puts(UcxBuffer *buffer, const char *str) {
-    return ucx_buffer_write((const void*)str, 1, strlen(str), buffer);
-}
-
-int ucx_buffer_shift_left(UcxBuffer* buffer, size_t shift) {
-    if (shift >= buffer->size) {
-        buffer->pos = buffer->size = 0;
-    } else {
-        memmove(buffer->space, buffer->space + shift, buffer->size - shift);
-        buffer->size -= shift;
-        
-        if (buffer->pos >= shift) {
-            buffer->pos -= shift;
-        } else {
-            buffer->pos = 0;
-        }
-    }
-    return 0;
-}
-
-int ucx_buffer_shift_right(UcxBuffer* buffer, size_t shift) {
-    size_t req_capacity = buffer->size + shift;
-    size_t movebytes;
-    
-    // auto extend buffer, if required and enabled
-    if (buffer->capacity < req_capacity) {
-        if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
-            if (ucx_buffer_extend(buffer, req_capacity - buffer->capacity)) {
-                return 1;
-            }
-            movebytes = buffer->size;
-        } else {
-            movebytes = buffer->capacity - shift;
-        }
-    } else {
-        movebytes = buffer->size;
-    }
-    
-    memmove(buffer->space + shift, buffer->space, movebytes);
-    buffer->size = shift+movebytes;
-    
-    buffer->pos += shift;
-    if (buffer->pos > buffer->size) {
-        buffer->pos = buffer->size;
-    }
-    
-    return 0;
-}
-
-int ucx_buffer_shift(UcxBuffer* buffer, off_t shift) {
-    if (shift < 0) {
-        return ucx_buffer_shift_left(buffer, (size_t) (-shift));
-    } else if (shift > 0) {
-        return ucx_buffer_shift_right(buffer, (size_t) shift);
-    } else {
-        return 0;
-    }
-}
--- a/ucx/list.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,428 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/list.h"
-
-UcxList *ucx_list_clone(const UcxList *l, copy_func fnc, void *data) {
-    return ucx_list_clone_a(ucx_default_allocator(), l, fnc, data);
-}
-
-UcxList *ucx_list_clone_a(UcxAllocator *alloc, const UcxList *l,
-        copy_func fnc, void *data) {
-    UcxList *ret = NULL;
-    while (l) {
-        if (fnc) {
-            ret = ucx_list_append_a(alloc, ret, fnc(l->data, data));
-        } else {
-            ret = ucx_list_append_a(alloc, ret, l->data);
-        }
-        l = l->next;
-    }
-    return ret;
-}
-
-int ucx_list_equals(const UcxList *l1, const UcxList *l2,
-        cmp_func fnc, void* data) {
-    if (l1 == l2) return 1;
-    
-    while (l1 != NULL && l2 != NULL) {
-        if (fnc == NULL) {
-            if (l1->data != l2->data) return 0;
-        } else {
-            if (fnc(l1->data, l2->data, data) != 0) return 0;
-        }
-        l1 = l1->next;
-        l2 = l2->next;
-    }
-    
-    return (l1 == NULL && l2 == NULL);
-}
-
-void ucx_list_free(UcxList *l) {
-    ucx_list_free_a(ucx_default_allocator(), l);
-}
-
-void ucx_list_free_a(UcxAllocator *alloc, UcxList *l) {
-    UcxList *e = l, *f;
-    while (e != NULL) {
-        f = e;
-        e = e->next;
-        alfree(alloc, f);
-    }
-}
-
-void ucx_list_free_content(UcxList* list, ucx_destructor destr) {
-    if (!destr) destr = free;
-    while (list != NULL) {
-        destr(list->data);
-        list = list->next;
-    }
-}
-
-UcxList *ucx_list_append(UcxList *l, void *data)  {
-    return ucx_list_append_a(ucx_default_allocator(), l, data);
-}
-
-UcxList *ucx_list_append_a(UcxAllocator *alloc, UcxList *l, void *data)  {
-    UcxList *nl = (UcxList*) almalloc(alloc, sizeof(UcxList));
-    if (!nl) {
-        return NULL;
-    }
-    
-    nl->data = data;
-    nl->next = NULL;
-    if (l) {
-        UcxList *t = ucx_list_last(l);
-        t->next = nl;
-        nl->prev = t;
-        return l;
-    } else {
-        nl->prev = NULL;
-        return nl;
-    }
-}
-
-UcxList *ucx_list_prepend(UcxList *l, void *data) {
-    return ucx_list_prepend_a(ucx_default_allocator(), l, data);
-}
-
-UcxList *ucx_list_prepend_a(UcxAllocator *alloc, UcxList *l, void *data) {
-    UcxList *nl = ucx_list_append_a(alloc, NULL, data);
-    if (!nl) {
-        return NULL;
-    }
-    l = ucx_list_first(l);
-    
-    if (l) {
-        nl->next = l;
-        l->prev = nl;
-    }
-    return nl;
-}
-
-UcxList *ucx_list_concat(UcxList *l1, UcxList *l2) {
-    if (l1) {
-        UcxList *last = ucx_list_last(l1);
-        last->next = l2;
-        if (l2) {
-            l2->prev = last;
-        }
-        return l1;
-    } else {
-        return l2;
-    }
-}
-
-UcxList *ucx_list_last(const UcxList *l) {
-    if (l == NULL) return NULL;
-    
-    const UcxList *e = l;
-    while (e->next != NULL) {
-        e = e->next;
-    }
-    return (UcxList*)e;
-}
-
-ssize_t ucx_list_indexof(const UcxList *list, const UcxList *elem) {
-    ssize_t index = 0;
-    while (list) {
-        if (list == elem) {
-            return index;
-        }
-        list = list->next;
-        index++;
-    }
-    return -1;
-}
-
-UcxList *ucx_list_get(const UcxList *l, size_t index) {
-    if (l == NULL) return NULL;
-
-    const UcxList *e = l;
-    while (e->next && index > 0) {
-        e = e->next;
-        index--;
-    }
-    
-    return (UcxList*)(index == 0 ? e : NULL);
-}
-
-ssize_t ucx_list_find(const UcxList *l, void *elem,
-        cmp_func fnc, void *cmpdata) {
-    ssize_t index = 0;
-    UCX_FOREACH(e, l) {
-        if (fnc) {
-            if (fnc(elem, e->data, cmpdata) == 0) {
-                return index;
-            }
-        } else {
-            if (elem == e->data) {
-                return index;
-            }
-        }
-        index++;
-    }
-    return -1;
-}
-
-int ucx_list_contains(const UcxList *l, void *elem,
-        cmp_func fnc, void *cmpdata) {
-    return ucx_list_find(l, elem, fnc, cmpdata) > -1;
-}
-
-size_t ucx_list_size(const UcxList *l) {
-    if (l == NULL) return 0;
-    
-    const UcxList *e = l;
-    size_t s = 1;
-    while (e->next != NULL) {
-        e = e->next;
-        s++;
-    }
-
-    return s;
-}
-
-static UcxList *ucx_list_sort_merge(size_t length,
-        UcxList* ls, UcxList* le, UcxList* re,
-        cmp_func fnc, void* data) {
-
-    UcxList** sorted = (UcxList**) malloc(sizeof(UcxList*)*length);
-    UcxList *rc, *lc;
-
-    lc = ls; rc = le;
-    size_t n = 0;
-    while (lc && lc != le && rc != re) {
-        if (fnc(lc->data, rc->data, data) <= 0) {
-            sorted[n] = lc;
-            lc = lc->next;
-        } else {
-            sorted[n] = rc;
-            rc = rc->next;
-        }
-        n++;
-    }
-    while (lc && lc != le) {
-        sorted[n] = lc;
-        lc = lc->next;
-        n++;
-    }
-    while (rc && rc != re) {
-        sorted[n] = rc;
-        rc = rc->next;
-        n++;
-    }
-
-    // Update pointer
-    sorted[0]->prev = NULL;
-    for (int i = 0 ; i < length-1 ; i++) {
-        sorted[i]->next = sorted[i+1];
-        sorted[i+1]->prev = sorted[i];
-    }
-    sorted[length-1]->next = NULL;
-
-    UcxList *ret = sorted[0];
-    free(sorted);
-    return ret;
-}
-
-UcxList *ucx_list_sort(UcxList *l, cmp_func fnc, void *data) {
-    if (l == NULL) {
-        return NULL;
-    }
-
-    UcxList *lc;
-    size_t ln = 1;
-
-    UcxList *ls = l, *le, *re;
-    
-    // check how many elements are already sorted
-    lc = ls;
-    while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) {
-        lc = lc->next;
-        ln++;
-    }
-    le = lc->next;
-
-    if (le == NULL) {
-        return l; // this list is already sorted :)
-    } else {
-        UcxList *rc;
-        size_t rn = 1;
-        rc = le;
-        // skip already sorted elements
-        while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) {
-            rc = rc->next;
-            rn++;
-        }
-        re = rc->next;
-
-        // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them
-        UcxList *sorted = ucx_list_sort_merge(ln+rn,
-                ls, le, re,
-                fnc, data);
-        
-        // Something left? Sort it!
-        size_t remainder_length = ucx_list_size(re);
-        if (remainder_length > 0) {
-            UcxList *remainder = ucx_list_sort(re, fnc, data);
-
-            // merge sorted list with (also sorted) remainder
-            l = ucx_list_sort_merge(ln+rn+remainder_length,
-                    sorted, remainder, NULL, fnc, data);
-        } else {
-            // no remainder - we've got our sorted list
-            l = sorted;
-        }
-
-        return l;
-    }
-}
-
-UcxList *ucx_list_first(const UcxList *l) {
-    if (!l) {
-        return NULL;
-    }
-    
-    const UcxList *e = l;
-    while (e->prev) {
-        e = e->prev;
-    }
-    return (UcxList *)e;
-}
-
-UcxList *ucx_list_remove(UcxList *l, UcxList *e) {
-    return ucx_list_remove_a(ucx_default_allocator(), l, e);
-}
-    
-UcxList *ucx_list_remove_a(UcxAllocator *alloc, UcxList *l, UcxList *e) {
-    if (l == e) {
-        l = e->next;
-    }
-    
-    if (e->next) {
-        e->next->prev = e->prev;
-    }
-    
-    if (e->prev) {
-        e->prev->next = e->next;
-    }
-    
-    alfree(alloc, e);
-    return l;
-}
-
-
-static UcxList* ucx_list_setoperation_a(UcxAllocator *allocator,
-        UcxList const *left, UcxList const *right,
-        cmp_func cmpfnc, void* cmpdata,
-        copy_func cpfnc, void* cpdata,
-        int op) {
-    
-    UcxList *res = NULL;
-    UcxList *cur = NULL;
-    const UcxList *src = left;
-    
-    do {
-        UCX_FOREACH(node, src) {
-            void* elem = node->data;
-            if (
-                (op == 0 && !ucx_list_contains(res, elem, cmpfnc, cmpdata)) ||
-                (op == 1 && ucx_list_contains(right, elem, cmpfnc, cmpdata)) ||
-                (op == 2 && !ucx_list_contains(right, elem, cmpfnc, cmpdata))) {
-                UcxList *nl = almalloc(allocator, sizeof(UcxList));
-                nl->prev = cur;
-                nl->next = NULL;
-                if (cpfnc) {
-                    nl->data = cpfnc(elem, cpdata);
-                } else {
-                    nl->data = elem;
-                }
-                if (cur != NULL)
-                    cur->next = nl;
-                cur = nl;
-                if (res == NULL)
-                    res = cur;
-            }
-        }
-        if (op == 0 && src == left)
-            src = right;
-        else
-            src = NULL;
-    } while (src != NULL);
-    
-    return res;
-}
-
-UcxList* ucx_list_union(UcxList const *left, UcxList const *right,
-        cmp_func cmpfnc, void* cmpdata,
-        copy_func cpfnc, void* cpdata) {
-    return ucx_list_union_a(ucx_default_allocator(),
-            left, right, cmpfnc, cmpdata, cpfnc, cpdata);
-}
-
-UcxList* ucx_list_union_a(UcxAllocator *allocator,
-        UcxList const *left, UcxList const *right,
-        cmp_func cmpfnc, void* cmpdata,
-        copy_func cpfnc, void* cpdata) {
-    
-    return ucx_list_setoperation_a(allocator, left, right,
-            cmpfnc, cmpdata, cpfnc, cpdata, 0);
-}
-
-UcxList* ucx_list_intersection(UcxList const *left, UcxList const *right,
-        cmp_func cmpfnc, void* cmpdata,
-        copy_func cpfnc, void* cpdata) {
-    return ucx_list_intersection_a(ucx_default_allocator(), left, right,
-            cmpfnc, cmpdata, cpfnc, cpdata);
-}
-
-UcxList* ucx_list_intersection_a(UcxAllocator *allocator,
-        UcxList const *left, UcxList const *right,
-        cmp_func cmpfnc, void* cmpdata,
-        copy_func cpfnc, void* cpdata) {
-    
-    return ucx_list_setoperation_a(allocator, left, right,
-            cmpfnc, cmpdata, cpfnc, cpdata, 1);
-}
-
-UcxList* ucx_list_difference(UcxList const *left, UcxList const *right,
-        cmp_func cmpfnc, void* cmpdata,
-        copy_func cpfnc, void* cpdata) {
-    return ucx_list_difference_a(ucx_default_allocator(), left, right,
-            cmpfnc, cmpdata, cpfnc, cpdata);
-}
-
-UcxList* ucx_list_difference_a(UcxAllocator *allocator,
-        UcxList const *left, UcxList const *right,
-        cmp_func cmpfnc, void* cmpdata,
-        copy_func cpfnc, void* cpdata) {
-    
-    return ucx_list_setoperation_a(allocator, left, right,
-            cmpfnc, cmpdata, cpfnc, cpdata, 2);
-}
--- a/ucx/logging.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/logging.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <time.h>
-
-UcxLogger *ucx_logger_new(void *stream, unsigned int level, unsigned int mask) {
-    UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger));
-    if (logger != NULL) {
-        logger->stream = stream;
-        logger->writer = (write_func)fwrite;
-        logger->dateformat = (char*) "%F %T %z ";
-        logger->level = level;
-        logger->mask = mask;
-        logger->levels = ucx_map_new(8);
-        
-        unsigned int l;
-        l = UCX_LOGGER_ERROR;
-        ucx_map_int_put(logger->levels, l, (void*) "[ERROR]");
-        l = UCX_LOGGER_WARN;
-        ucx_map_int_put(logger->levels, l, (void*) "[WARNING]");
-        l = UCX_LOGGER_INFO;
-        ucx_map_int_put(logger->levels, l, (void*) "[INFO]");
-        l = UCX_LOGGER_DEBUG;
-        ucx_map_int_put(logger->levels, l, (void*) "[DEBUG]");
-        l = UCX_LOGGER_TRACE;
-        ucx_map_int_put(logger->levels, l, (void*) "[TRACE]");
-    }
-
-    return logger;
-}
-
-void ucx_logger_free(UcxLogger *logger) {
-    ucx_map_free(logger->levels);
-    free(logger);
-}
-
-// estimated max. message length (documented)
-#define UCX_LOGGER_MSGMAX 4096
-
-void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
-        const unsigned int line, const char *format, ...) {
-    if (level <= logger->level) {
-        char msg[UCX_LOGGER_MSGMAX];
-        const char *text;
-        size_t k = 0;
-        size_t n;
-        
-        if ((logger->mask & UCX_LOGGER_LEVEL) > 0) {
-            text = (const char*) ucx_map_int_get(logger->levels, level);
-            if (!text) {
-                text = "[UNKNOWN]";
-            }
-            n = strlen(text);
-            n = n > 256 ? 256 : n;
-            memcpy(msg+k, text, n);
-            k += n;
-            msg[k++] = ' ';
-        }
-        if ((logger->mask & UCX_LOGGER_TIMESTAMP) > 0) {
-            time_t now = time(NULL);
-            k += strftime(msg+k, 128, logger->dateformat, localtime(&now));
-        }
-        if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
-            char *fpart = strrchr(file, '/');
-            if (fpart) file = fpart+1;
-            fpart = strrchr(file, '\\');
-            if (fpart) file = fpart+1;
-            n = strlen(file);
-            memcpy(msg+k, file, n);
-            k += n;
-            k += sprintf(msg+k, ":%u ", line);
-        }
-        
-        if (k > 0) {
-            msg[k++] = '-'; msg[k++] = ' ';
-        }
-        
-        va_list args;
-        va_start (args, format);
-        k += vsnprintf(msg+k, UCX_LOGGER_MSGMAX-k-1, format, args);
-        va_end (args);        
-        
-        msg[k++] = '\n';
-        
-        logger->writer(msg, 1, k, logger->stream);
-    }
-}
--- a/ucx/map.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,402 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/map.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-UcxMap *ucx_map_new(size_t size) {
-    return ucx_map_new_a(NULL, size);
-}
-
-UcxMap *ucx_map_new_a(UcxAllocator *allocator, size_t size) {
-    if(size == 0) {
-        size = 16;
-    }
-       
-    if(!allocator) {
-        allocator = ucx_default_allocator();
-    }
-    
-    UcxMap *map = (UcxMap*)almalloc(allocator, sizeof(UcxMap));
-    if (!map) {
-        return NULL;
-    }
-    
-    map->allocator = allocator;
-    map->map = (UcxMapElement**)alcalloc(
-            allocator, size, sizeof(UcxMapElement*));
-    if(map->map == NULL) {
-        alfree(allocator, map);
-        return NULL;
-    }
-    map->size = size;
-    map->count = 0;
-
-    return map;
-}
-
-static void ucx_map_free_elmlist_contents(UcxMap *map) {
-    for (size_t n = 0 ; n < map->size ; n++) {
-        UcxMapElement *elem = map->map[n];
-        if (elem != NULL) {
-            do {
-                UcxMapElement *next = elem->next;
-                alfree(map->allocator, elem->key.data);
-                alfree(map->allocator, elem);
-                elem = next;
-            } while (elem != NULL);
-        }
-    }
-}
-
-void ucx_map_free(UcxMap *map) {
-    ucx_map_free_elmlist_contents(map);
-    alfree(map->allocator, map->map);
-    alfree(map->allocator, map);
-}
-
-void ucx_map_free_content(UcxMap *map, ucx_destructor destr) {
-    UcxMapIterator iter = ucx_map_iterator(map);
-    void *val;
-    UCX_MAP_FOREACH(key, val, iter) {
-        if (destr) {
-            destr(val);
-        } else {
-            alfree(map->allocator, val);
-        }
-    }
-}
-
-void ucx_map_clear(UcxMap *map) {
-    if (map->count == 0) {
-        return; // nothing to do
-    }
-    ucx_map_free_elmlist_contents(map);
-    memset(map->map, 0, map->size*sizeof(UcxMapElement*));
-    map->count = 0;
-}
-
-int ucx_map_copy(UcxMap const *from, UcxMap *to, copy_func fnc, void *data) {
-    UcxMapIterator i = ucx_map_iterator(from);
-    void *value;
-    UCX_MAP_FOREACH(key, value, i) {
-        if (ucx_map_put(to, key, fnc ? fnc(value, data) : value)) {
-            return 1;
-        }
-    }
-    return 0;
-}
-
-UcxMap *ucx_map_clone(UcxMap const *map, copy_func fnc, void *data) {
-    return ucx_map_clone_a(ucx_default_allocator(), map, fnc, data);
-}
-
-UcxMap *ucx_map_clone_a(UcxAllocator *allocator,
-        UcxMap const *map, copy_func fnc, void *data) {
-    size_t bs = (map->count * 5) >> 1;
-    UcxMap *newmap = ucx_map_new_a(allocator, bs > map->size ? bs : map->size);
-    if (!newmap) {
-        return NULL;
-    }
-    ucx_map_copy(map, newmap, fnc, data);
-    return newmap;
-}
-
-int ucx_map_rehash(UcxMap *map) {
-    size_t load = (map->size * 3) >> 2;
-    if (map->count > load) {
-        UcxMap oldmap;
-        oldmap.map = map->map;
-        oldmap.size = map->size;
-        oldmap.count = map->count;
-        oldmap.allocator = map->allocator;
-        
-        map->size = (map->count * 5) >> 1;
-        map->map = (UcxMapElement**)alcalloc(
-                map->allocator, map->size, sizeof(UcxMapElement*));
-        if (!map->map) {
-            *map = oldmap;
-            return 1;
-        }
-        map->count = 0;
-        ucx_map_copy(&oldmap, map, NULL, NULL);
-        
-        /* free the UcxMapElement list of oldmap */
-        ucx_map_free_elmlist_contents(&oldmap);
-        alfree(map->allocator, oldmap.map);
-    }
-    return 0;
-}
-
-int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
-    UcxAllocator *allocator = map->allocator;
-    
-    if (key.hash == 0) {
-        key.hash = ucx_hash((const char*)key.data, key.len);
-    }
-    
-    struct UcxMapKey mapkey;
-    mapkey.hash = key.hash;
-
-    size_t slot = mapkey.hash%map->size;
-    UcxMapElement *elm = map->map[slot];
-    UcxMapElement *prev = NULL;
-
-    while (elm && elm->key.hash < mapkey.hash) {
-        prev = elm;
-        elm = elm->next;
-    }
-    
-    if (!elm || elm->key.hash != mapkey.hash) {
-        UcxMapElement *e = (UcxMapElement*)almalloc(
-                allocator, sizeof(UcxMapElement));
-        if (!e) {
-            return -1;
-        }
-        e->key.data = NULL;
-        if (prev) {
-            prev->next = e;
-        } else {
-            map->map[slot] = e;
-        }
-        e->next = elm;
-        elm = e;
-    }
-    
-    if (!elm->key.data) {
-        void *kd = almalloc(allocator, key.len);
-        if (!kd) {
-            return -1;
-        }
-        memcpy(kd, key.data, key.len);
-        mapkey.data = kd;
-        mapkey.len = key.len;
-        elm->key = mapkey;
-        map->count++;
-    }
-    elm->data = data;
-
-    return 0;
-}
-
-static void* ucx_map_get_and_remove(UcxMap *map, UcxKey key, int remove) {
-    if(key.hash == 0) {
-        key.hash = ucx_hash((const char*)key.data, key.len);
-    }
-    
-    size_t slot = key.hash%map->size;
-    UcxMapElement *elm = map->map[slot];
-    UcxMapElement *pelm = NULL;
-    while (elm && elm->key.hash <= key.hash) {
-        if(elm->key.hash == key.hash) {
-            int n = (key.len > elm->key.len) ? elm->key.len : key.len;
-            if (memcmp(elm->key.data, key.data, n) == 0) {
-                void *data = elm->data;
-                if (remove) {
-                    if (pelm) {
-                        pelm->next = elm->next;
-                    } else {
-                        map->map[slot] = elm->next;
-                    }
-                    alfree(map->allocator, elm->key.data);
-                    alfree(map->allocator, elm);
-                    map->count--;
-                }
-
-                return data;
-            }
-        }
-        pelm = elm;
-        elm = pelm->next;
-    }
-
-    return NULL;
-}
-
-void *ucx_map_get(UcxMap const *map, UcxKey key) {
-    return ucx_map_get_and_remove((UcxMap *)map, key, 0);
-}
-
-void *ucx_map_remove(UcxMap *map, UcxKey key) {
-    return ucx_map_get_and_remove(map, key, 1);
-}
-
-UcxKey ucx_key(const void *data, size_t len) {
-    UcxKey key;
-    key.data = data;
-    key.len = len;
-    key.hash = ucx_hash((const char*)data, len);
-    return key;
-}
-
-
-int ucx_hash(const char *data, size_t len) {
-    /* murmur hash 2 */
-
-    int m = 0x5bd1e995;
-    int r = 24;
-
-    int h = 25 ^ len;
-
-    int i = 0;
-    while (len >= 4) {
-        int k = data[i + 0] & 0xFF;
-        k |= (data[i + 1] & 0xFF) << 8;
-        k |= (data[i + 2] & 0xFF) << 16;
-        k |= (data[i + 3] & 0xFF) << 24;
-
-        k *= m;
-        k ^= k >> r;
-        k *= m;
-
-        h *= m;
-        h ^= k;
-
-        i += 4;
-        len -= 4;
-    }
-
-    switch (len) {
-        case 3: h ^= (data[i + 2] & 0xFF) << 16;
-        /* no break */
-        case 2: h ^= (data[i + 1] & 0xFF) << 8;
-        /* no break */
-        case 1: h ^= (data[i + 0] & 0xFF); h *= m;
-        /* no break */
-    }
-
-    h ^= h >> 13;
-    h *= m;
-    h ^= h >> 15;
-
-    return h;
-}
-
-UcxMapIterator ucx_map_iterator(UcxMap const *map) {
-    UcxMapIterator i;
-    i.map = map;
-    i.cur = NULL;
-    i.index = 0;
-    return i;
-}
-
-int ucx_map_iter_next(UcxMapIterator *i, UcxKey *key, void **elm) {
-    UcxMapElement *e = i->cur;
-    
-    if (e) {
-        e = e->next;
-    } else {
-        e = i->map->map[0];
-    }
-    
-    while (i->index < i->map->size) {
-        if (e) {
-            if (e->data) {
-                i->cur = e;
-                *elm = e->data;
-                key->data = e->key.data;
-                key->hash = e->key.hash;
-                key->len = e->key.len;
-                return 1;
-            }
-
-            e = e->next;
-        } else {
-            i->index++;
-            
-            if (i->index < i->map->size) {
-                e = i->map->map[i->index];
-            }
-        }
-    }
-    
-    return 0;
-}
-
-UcxMap* ucx_map_union(const UcxMap *first, const UcxMap *second,
-                      copy_func cpfnc, void* cpdata) {
-    return ucx_map_union_a(ucx_default_allocator(),
-            first, second, cpfnc, cpdata);
-}
-
-UcxMap* ucx_map_union_a(UcxAllocator *allocator,
-                        const UcxMap *first, const UcxMap *second,
-                        copy_func cpfnc, void* cpdata) {
-    UcxMap* result = ucx_map_clone_a(allocator, first, cpfnc, cpdata);
-    ucx_map_copy(second, result, cpfnc, cpdata);
-    return result;
-}
-
-UcxMap* ucx_map_intersection(const UcxMap *first, const UcxMap *second,
-                             copy_func cpfnc, void* cpdata) {
-    return ucx_map_intersection_a(ucx_default_allocator(),
-            first, second, cpfnc, cpdata);
-}
-
-UcxMap* ucx_map_intersection_a(UcxAllocator *allocator,
-                               const UcxMap *first, const UcxMap *second,
-                               copy_func cpfnc, void* cpdata) {
-    UcxMap *result = ucx_map_new_a(allocator, first->size < second->size ?
-            first->size : second->size);
-
-    UcxMapIterator iter = ucx_map_iterator(first);
-    void* value;
-    UCX_MAP_FOREACH(key, value, iter) {
-        if (ucx_map_get(second, key)) {
-            ucx_map_put(result, key, cpfnc ? cpfnc(value, cpdata) : value);
-        }
-    }
-
-    return result;
-}
-
-UcxMap* ucx_map_difference(const UcxMap *first, const UcxMap *second,
-                           copy_func cpfnc, void* cpdata) {
-    return ucx_map_difference_a(ucx_default_allocator(),
-            first, second, cpfnc, cpdata);
-}
-
-UcxMap* ucx_map_difference_a(UcxAllocator *allocator,
-                             const UcxMap *first, const UcxMap *second,
-                             copy_func cpfnc, void* cpdata) {
-
-    UcxMap *result = ucx_map_new_a(allocator, first->size - second->count);
-
-    UcxMapIterator iter = ucx_map_iterator(first);
-    void* value;
-    UCX_MAP_FOREACH(key, value, iter) {
-        if (!ucx_map_get(second, key)) {
-            ucx_map_put(result, key, cpfnc ? cpfnc(value, cpdata) : value);
-        }
-    }
-
-    ucx_map_rehash(result);
-    return result;
-}
\ No newline at end of file
--- a/ucx/mempool.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/mempool.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#ifdef __cplusplus
-#define __STDC_FORMAT_MACROS
-#endif
-#include <inttypes.h>
-
-/** Capsule for destructible memory chunks. */
-typedef struct {
-    /** The destructor for the memory chunk. */
-    ucx_destructor destructor;
-    /**
-     * First byte of the memory chunk.
-     * Note, that the address <code>&amp;c</code> is also the address
-     * of the whole memory chunk.
-     */
-    char c;
-} ucx_memchunk;
-
-/** Capsule for data and its destructor. */
-typedef struct {
-    /** The destructor for the data. */
-    ucx_destructor destructor;
-    /** A pointer to the data. */
-    void           *ptr;
-} ucx_regdestr;
-
-#ifdef __cplusplus
-extern "C"
-#endif
-void ucx_mempool_shared_destr(void* ptr) {
-    ucx_regdestr *rd = (ucx_regdestr*)ptr;
-    rd->destructor(rd->ptr);
-}
-
-UcxMempool *ucx_mempool_new(size_t n) {
-    size_t poolsz;
-    if(ucx_szmul(n, sizeof(void*), &poolsz)) {
-        return NULL;
-    }
-    
-    UcxMempool *pool = (UcxMempool*)malloc(sizeof(UcxMempool));
-    if (!pool) {
-        return NULL;
-    }
-    
-    pool->data = (void**) malloc(poolsz);
-    if (pool->data == NULL) {
-        free(pool);
-        return NULL;
-    }
-    
-    pool->ndata = 0;
-    pool->size = n;
-    
-    UcxAllocator *allocator = (UcxAllocator*)malloc(sizeof(UcxAllocator));
-    if(!allocator) {
-        free(pool->data);
-        free(pool);
-        return NULL;
-    }
-    allocator->malloc = (ucx_allocator_malloc)ucx_mempool_malloc;
-    allocator->calloc = (ucx_allocator_calloc)ucx_mempool_calloc;
-    allocator->realloc = (ucx_allocator_realloc)ucx_mempool_realloc;
-    allocator->free = (ucx_allocator_free)ucx_mempool_free;
-    allocator->pool = pool;
-    pool->allocator = allocator;
-    
-    return pool;
-}
-
-int ucx_mempool_chcap(UcxMempool *pool, size_t newcap) {
-    if (newcap < pool->ndata) {
-        return 1;
-    }
-    
-    size_t newcapsz;
-    if(ucx_szmul(newcap, sizeof(void*), &newcapsz)) {
-        return 1;
-    }
-    
-    void **data = (void**) realloc(pool->data, newcapsz);
-    if (data) {
-        pool->data = data; 
-        pool->size = newcap;
-        return 0;
-    } else {
-        return 1;
-    }
-}
-
-void *ucx_mempool_malloc(UcxMempool *pool, size_t n) {
-    if(((size_t)-1) - sizeof(ucx_destructor) < n) {
-        return NULL;
-    }
-    
-    if (pool->ndata >= pool->size) {
-        size_t newcap = pool->size*2;
-        if (newcap < pool->size || ucx_mempool_chcap(pool, newcap)) {
-            return NULL;
-        }
-    }
-
-    void *p = malloc(sizeof(ucx_destructor) + n);
-    ucx_memchunk *mem = (ucx_memchunk*)p;
-    if (!mem) {
-        return NULL;
-    }
-
-    mem->destructor = NULL;
-    pool->data[pool->ndata] = mem;
-    pool->ndata++;
-
-    return &(mem->c);
-}
-
-void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize) {
-    size_t msz;
-    if(ucx_szmul(nelem, elsize, &msz)) {
-        return NULL;
-    }
-    
-    void *ptr = ucx_mempool_malloc(pool, msz);
-    if (!ptr) {
-        return NULL;
-    }
-    memset(ptr, 0, nelem * elsize);
-    return ptr;
-}
-
-void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n) {
-    if(((size_t)-1) - sizeof(ucx_destructor) < n) {
-        return NULL;
-    }
-    
-    char *mem = ((char*)ptr) - sizeof(ucx_destructor);
-    char *newm = (char*) realloc(mem, n + sizeof(ucx_destructor));
-    if (!newm) {
-        return NULL;
-    }
-    if (mem != newm) {
-        for(size_t i=0 ; i < pool->ndata ; i++) {
-            if(pool->data[i] == mem) {
-                pool->data[i] = newm;
-                return newm + sizeof(ucx_destructor);
-            }
-        }
-        fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
-          (intptr_t)ptr, (intptr_t)pool);
-        abort();
-    } else {
-        return newm + sizeof(ucx_destructor);
-    }
-}
-
-void ucx_mempool_free(UcxMempool *pool, void *ptr) {
-    ucx_memchunk *chunk = (ucx_memchunk*)((char*)ptr-sizeof(ucx_destructor));
-    for(size_t i=0 ; i<pool->ndata ; i++) {
-        if(chunk == pool->data[i]) {
-            if(chunk->destructor != NULL) {
-                chunk->destructor(&(chunk->c));
-            }
-            free(chunk);
-            size_t last_index = pool->ndata - 1;
-            if(i != last_index) {
-                pool->data[i] = pool->data[last_index];
-                pool->data[last_index] = NULL;
-            }
-            pool->ndata--;
-            return;
-        }
-    }
-    fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
-            (intptr_t)ptr, (intptr_t)pool);
-    abort();
-}
-
-void ucx_mempool_destroy(UcxMempool *pool) {
-    ucx_memchunk *chunk;
-    for(size_t i=0 ; i<pool->ndata ; i++) {
-        chunk = (ucx_memchunk*) pool->data[i];
-        if(chunk) {
-            if(chunk->destructor) {
-                chunk->destructor(&(chunk->c));
-            }
-            free(chunk);
-        }
-    }
-    free(pool->data);
-    free(pool->allocator);
-    free(pool);
-}
-
-void ucx_mempool_set_destr(void *ptr, ucx_destructor func) {
-    *(ucx_destructor*)((char*)ptr-sizeof(ucx_destructor)) = func;
-}
-
-void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr) {
-    ucx_regdestr *rd = (ucx_regdestr*)ucx_mempool_malloc(
-            pool,
-            sizeof(ucx_regdestr));
-    rd->destructor = destr;
-    rd->ptr = ptr;
-    ucx_mempool_set_destr(rd, ucx_mempool_shared_destr);
-}
-
--- a/ucx/properties.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/properties.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-UcxProperties *ucx_properties_new() {
-    UcxProperties *parser = (UcxProperties*)malloc(
-            sizeof(UcxProperties));
-    if(!parser) {
-        return NULL;
-    }
-    
-    parser->buffer = NULL;
-    parser->buflen = 0;
-    parser->pos = 0;
-    parser->tmp = NULL;
-    parser->tmplen = 0;
-    parser->tmpcap = 0;
-    parser->error = 0;
-    parser->delimiter = '=';
-    parser->comment1 = '#';
-    parser->comment2 = 0;
-    parser->comment3 = 0;   
-    
-    return parser;
-}
-
-void ucx_properties_free(UcxProperties *parser) {
-    if(parser->tmp) {
-        free(parser->tmp);
-    }
-    free(parser);
-}
-
-void ucx_properties_fill(UcxProperties *parser, char *buf, size_t len) {
-    parser->buffer = buf;
-    parser->buflen = len;
-    parser->pos = 0;
-}
-
-static void parser_tmp_append(UcxProperties *parser, char *buf, size_t len) {
-    if(parser->tmpcap - parser->tmplen < len) {
-        size_t newcap = parser->tmpcap + len + 64;
-        parser->tmp = (char*)realloc(parser->tmp, newcap);
-        parser->tmpcap = newcap;
-    }
-    memcpy(parser->tmp + parser->tmplen, buf, len);
-    parser->tmplen += len;
-}
-
-int ucx_properties_next(UcxProperties *parser, sstr_t *name, sstr_t *value)  {   
-    if(parser->tmplen > 0) {
-        char *buf = parser->buffer + parser->pos;
-        size_t len = parser->buflen - parser->pos;
-        sstr_t str = sstrn(buf, len);
-        sstr_t nl = sstrchr(str, '\n');
-        if(nl.ptr) {
-            size_t newlen = (size_t)(nl.ptr - buf) + 1;
-            parser_tmp_append(parser, buf, newlen);
-            // the tmp buffer contains exactly one line now
-            
-            char *orig_buf = parser->buffer;
-            size_t orig_len = parser->buflen;
-            
-            parser->buffer = parser->tmp;
-            parser->buflen = parser->tmplen;
-            parser->pos = 0;    
-            parser->tmp = NULL;
-            parser->tmpcap = 0;
-            parser->tmplen = 0;
-            // run ucx_properties_next with the tmp buffer as main buffer
-            int ret = ucx_properties_next(parser, name, value);
-            
-            // restore original buffer
-            parser->tmp = parser->buffer;
-            parser->buffer = orig_buf;
-            parser->buflen = orig_len;
-            parser->pos = newlen;
-            
-            /*
-             * if ret == 0 the tmp buffer contained just space or a comment
-             * we parse again with the original buffer to get a name/value
-             * or a new tmp buffer
-             */
-            return ret ? ret : ucx_properties_next(parser, name, value);
-        } else {
-            parser_tmp_append(parser, buf, len);
-            return 0;
-        }
-    } else if(parser->tmp) {
-        free(parser->tmp);
-        parser->tmp = NULL;
-    }
-    
-    char comment1 = parser->comment1;
-    char comment2 = parser->comment2;
-    char comment3 = parser->comment3;
-    char delimiter = parser->delimiter;
-    
-    // get one line and parse it
-    while(parser->pos < parser->buflen) {
-        char *buf = parser->buffer + parser->pos;
-        size_t len = parser->buflen - parser->pos;
-        
-        /*
-         * First we check if we have at least one line. We also get indices of
-         * delimiter and comment chars
-         */
-        size_t delimiter_index = 0;
-        size_t comment_index = 0;
-        int has_comment = 0;
-
-        size_t i = 0;
-        char c = 0;
-        for(;i<len;i++) {
-            c = buf[i];
-            if(c == comment1 || c == comment2 || c == comment3) {
-                if(comment_index == 0) {
-                    comment_index = i;
-                    has_comment = 1;
-                }
-            } else if(c == delimiter) {
-                if(delimiter_index == 0 && !has_comment) {
-                    delimiter_index = i;
-                }
-            } else if(c == '\n') {
-                break;
-            }
-        }
-
-        if(c != '\n') {
-            // we don't have enough data for a line
-            // store remaining bytes in temporary buffer for next round
-            parser->tmpcap = len + 128;
-            parser->tmp = (char*)malloc(parser->tmpcap);
-            parser->tmplen = len;
-            memcpy(parser->tmp, buf, len);
-            return 0;
-        }
-        
-        sstr_t line = has_comment ? sstrn(buf, comment_index) : sstrn(buf, i);
-        // check line
-        if(delimiter_index == 0) {
-            line = sstrtrim(line);
-            if(line.length != 0) {
-                parser->error = 1;
-            }
-        } else {
-            sstr_t n = sstrn(buf, delimiter_index);
-            sstr_t v = sstrn(
-                    buf + delimiter_index + 1,
-                    line.length - delimiter_index - 1); 
-            n = sstrtrim(n);
-            v = sstrtrim(v);
-            if(n.length != 0 || v.length != 0) {
-                *name = n;
-                *value = v;
-                parser->pos += i + 1;
-                return 1;
-            } else {
-                parser->error = 1;
-            }
-        }
-        
-        parser->pos += i + 1;
-    }
-    
-    return 0;
-}
-
-int ucx_properties2map(UcxProperties *parser, UcxMap *map) {
-    sstr_t name;
-    sstr_t value;
-    while(ucx_properties_next(parser, &name, &value)) {
-        value = sstrdup_a(map->allocator, value);
-        if(!value.ptr) {
-            return 1;
-        }
-        if(ucx_map_sstr_put(map, name, value.ptr)) {
-            alfree(map->allocator, value.ptr);
-            return 1;
-        }
-    }
-    if (parser->error) {
-        return parser->error;
-    } else {
-        return 0;
-    }
-}
-
-// buffer size is documented - change doc, when you change bufsize!
-#define UCX_PROPLOAD_BUFSIZE  1024
-int ucx_properties_load(UcxMap *map, FILE *file) {
-    UcxProperties *parser = ucx_properties_new();
-    if(!(parser && map && file)) {
-        return 1;
-    }
-    
-    int error = 0;
-    size_t r;
-    char buf[UCX_PROPLOAD_BUFSIZE];
-    while((r = fread(buf, 1, UCX_PROPLOAD_BUFSIZE, file)) != 0) {
-        ucx_properties_fill(parser, buf, r);
-        error = ucx_properties2map(parser, map);
-        if (error) {
-            break;
-        }
-    }
-    ucx_properties_free(parser);
-    return error;
-}
-
-int ucx_properties_store(UcxMap *map, FILE *file) {
-    UcxMapIterator iter = ucx_map_iterator(map);
-    void *v;
-    sstr_t value;
-    size_t written;
-
-    UCX_MAP_FOREACH(k, v, iter) {
-        value = sstr((char*)v);
-
-        written = 0;
-        written += fwrite(k.data, 1, k.len, file);
-        written += fwrite(" = ", 1, 3, file);
-        written += fwrite(value.ptr, 1, value.length, file);
-        written += fwrite("\n", 1, 1, file);
-
-        if (written != k.len + value.length + 4) {
-            return 1;
-        }
-    }
-
-    return 0;
-}
-
--- a/ucx/stack.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/stack.h"
-
-#include <string.h>
-
-static size_t ucx_stack_align(size_t n) {
-    int align = n % sizeof(void*);
-    if (align) {
-        n += sizeof(void*) - align;
-    }
-    return n;
-}
-
-void ucx_stack_init(UcxStack *stack, char* space, size_t size) {
-    stack->size = size - size % sizeof(void*);
-    stack->space = space;
-    stack->top = NULL;
-    
-    stack->allocator.pool = stack;
-    stack->allocator.malloc = (ucx_allocator_malloc) ucx_stack_malloc;
-    stack->allocator.calloc = (ucx_allocator_calloc) ucx_stack_calloc;
-    stack->allocator.realloc = (ucx_allocator_realloc) ucx_stack_realloc;
-    stack->allocator.free = (ucx_allocator_free) ucx_stack_free;
-}
-
-void *ucx_stack_malloc(UcxStack *stack, size_t n) {
-
-    if (ucx_stack_avail(stack) < ucx_stack_align(n)) {
-        return NULL;
-    } else {
-        char *prev = stack->top;
-        if (stack->top) {
-            stack->top += ucx_stack_align(ucx_stack_topsize(stack));
-        } else {
-            stack->top = stack->space;
-        }
-        
-        ((struct ucx_stack_metadata*)stack->top)->prev = prev;
-        ((struct ucx_stack_metadata*)stack->top)->size = n;
-        stack->top += sizeof(struct ucx_stack_metadata);
-        
-        return stack->top;
-    }
-}
-
-void *ucx_stack_calloc(UcxStack *stack, size_t nelem, size_t elsize) {
-    void *mem = ucx_stack_malloc(stack, nelem*elsize);
-    memset(mem, 0, nelem*elsize);
-    return mem;
-}
-
-void *ucx_stack_realloc(UcxStack *stack, void *ptr, size_t n) {
-    if (ptr == stack->top) {
-        if (stack->size - (stack->top - stack->space) < ucx_stack_align(n)) {
-            return NULL;
-        } else {
-            ((struct ucx_stack_metadata*)stack->top - 1)->size = n;
-            return ptr;
-        }
-    } else {
-        if (ucx_stack_align(((struct ucx_stack_metadata*)ptr - 1)->size) <
-                ucx_stack_align(n)) {
-            void *nptr = ucx_stack_malloc(stack, n);
-            if (nptr) {
-                memcpy(nptr, ptr, n);
-                ucx_stack_free(stack, ptr);
-                
-                return nptr;
-            } else {
-                return NULL;
-            }
-        } else {
-            ((struct ucx_stack_metadata*)ptr - 1)->size = n;
-            return ptr;
-        }
-    }
-}
-
-void ucx_stack_free(UcxStack *stack, void *ptr) {
-    if (ptr == stack->top) {
-        stack->top = ((struct ucx_stack_metadata*) stack->top - 1)->prev;
-    } else {
-        struct ucx_stack_metadata *next = (struct ucx_stack_metadata*)(
-            (char*)ptr +
-            ucx_stack_align(((struct ucx_stack_metadata*) ptr - 1)->size)
-        );
-        next->prev = ((struct ucx_stack_metadata*) ptr - 1)->prev;
-    }
-}
-
-void ucx_stack_popn(UcxStack *stack, void *dest, size_t n) {
-    if (ucx_stack_empty(stack)) {
-        return;
-    }
-    
-    if (dest) {
-        size_t len = ucx_stack_topsize(stack);
-        if (len > n) {
-            len = n;
-        }
-
-        memcpy(dest, stack->top, len);
-    }
-    
-    ucx_stack_free(stack, stack->top);
-}
-
-size_t ucx_stack_avail(UcxStack *stack) {
-    size_t avail = ((stack->top ? (stack->size
-                    - (stack->top - stack->space)
-                    - ucx_stack_align(ucx_stack_topsize(stack)))
-                    : stack->size));
-    
-    if (avail > sizeof(struct ucx_stack_metadata)) {
-        return avail - sizeof(struct ucx_stack_metadata);
-    } else {
-        return 0;
-    }
-}
-
-void *ucx_stack_push(UcxStack *stack, size_t n, const void *data) {
-    void *space = ucx_stack_malloc(stack, n);
-    if (space) {
-        memcpy(space, data, n);
-    }
-    return space;
-}
-
-void *ucx_stack_pusharr(UcxStack *stack,
-        size_t nelem, size_t elsize, const void *data) {
-    
-    // skip the memset by using malloc
-    void *space = ucx_stack_malloc(stack, nelem*elsize);
-    if (space) {
-        memcpy(space, data, nelem*elsize);
-    }
-    return space;
-}
--- a/ucx/string.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,807 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/string.h"
-
-#include "ucx/allocator.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <ctype.h>
-
-#ifndef _WIN32
-#include <strings.h> /* for strncasecmp() */
-#endif /* _WIN32 */
-
-sstr_t sstr(char *cstring) {
-    sstr_t string;
-    string.ptr = cstring;
-    string.length = strlen(cstring);
-    return string;
-}
-
-sstr_t sstrn(char *cstring, size_t length) {
-    sstr_t string;
-    string.ptr = cstring;
-    string.length = length;
-    return string;
-}
-
-scstr_t scstr(const char *cstring) {
-    scstr_t string;
-    string.ptr = cstring;
-    string.length = strlen(cstring);
-    return string;
-}
-
-scstr_t scstrn(const char *cstring, size_t length) {
-    scstr_t string;
-    string.ptr = cstring;
-    string.length = length;
-    return string;
-}
-
-
-size_t scstrnlen(size_t n, ...) {
-    if (n == 0) return 0;
-    
-    va_list ap;
-    va_start(ap, n);
-    
-    size_t size = 0;
-
-    for (size_t i = 0 ; i < n ; i++) {
-        scstr_t str = va_arg(ap, scstr_t);
-        if(SIZE_MAX - str.length < size) {
-            size = SIZE_MAX;
-            break;
-        }
-        size += str.length;
-    }
-    va_end(ap);
-
-    return size;
-}
-
-static sstr_t sstrvcat_a(
-        UcxAllocator *a,
-        size_t count,
-        scstr_t s1,
-        va_list ap) {
-    sstr_t str;
-    str.ptr = NULL;
-    str.length = 0;
-    if(count < 2) {
-        return str;
-    }
-    
-    scstr_t s2 = va_arg (ap, scstr_t);
-    
-    if(((size_t)-1) - s1.length < s2.length) {
-        return str;
-    }
-    
-    scstr_t *strings = (scstr_t*) calloc(count, sizeof(scstr_t));
-    if(!strings) {
-        return str;
-    }
-    
-    // get all args and overall length
-    strings[0] = s1;
-    strings[1] = s2;
-    size_t slen = s1.length + s2.length;
-    int error = 0;
-    for (size_t i=2;i<count;i++) {
-        scstr_t s = va_arg (ap, scstr_t);
-        strings[i] = s;
-        if(((size_t)-1) - s.length < slen) {
-            error = 1;
-            break;
-        }
-        slen += s.length;
-    }
-    if(error) {
-        free(strings);
-        return str;
-    }
-    
-    // create new string
-    str.ptr = (char*) almalloc(a, slen + 1);
-    str.length = slen;
-    if(!str.ptr) {
-        free(strings);
-        str.length = 0;
-        return str;
-    }
-    
-    // concatenate strings
-    size_t pos = 0;
-    for (size_t i=0;i<count;i++) {
-        scstr_t s = strings[i];
-        memcpy(str.ptr + pos, s.ptr, s.length);
-        pos += s.length;
-    }
-    
-    str.ptr[str.length] = '\0';
-    
-    free(strings);
-    
-    return str;
-}
-
-sstr_t scstrcat(size_t count, scstr_t s1, ...) {
-    va_list ap;
-    va_start(ap, s1);
-    sstr_t s = sstrvcat_a(ucx_default_allocator(), count, s1, ap);
-    va_end(ap);
-    return s;
-}
-
-sstr_t scstrcat_a(UcxAllocator *a, size_t count, scstr_t s1, ...) {
-    va_list ap;
-    va_start(ap, s1);
-    sstr_t s = sstrvcat_a(a, count, s1, ap);
-    va_end(ap);
-    return s;
-}
-
-static int ucx_substring(
-        size_t str_length,
-        size_t start,
-        size_t length,
-        size_t *newlen,
-        size_t *newpos)
-{
-    *newlen = 0;
-    *newpos = 0;
-    
-    if(start > str_length) {
-        return 0;
-    }
-    
-    if(length > str_length - start) {
-        length = str_length - start;
-    }
-    *newlen = length;
-    *newpos = start;
-    return 1;
-}
-
-sstr_t sstrsubs(sstr_t s, size_t start) {
-    return sstrsubsl (s, start, s.length-start);
-}
-
-sstr_t sstrsubsl(sstr_t s, size_t start, size_t length) {
-    size_t pos;
-    sstr_t ret = { NULL, 0 };
-    if(ucx_substring(s.length, start, length, &ret.length, &pos)) {
-        ret.ptr = s.ptr + pos;
-    }
-    return ret;
-}
-
-scstr_t scstrsubs(scstr_t string, size_t start) {
-    return scstrsubsl(string, start, string.length-start);
-}
-
-scstr_t scstrsubsl(scstr_t s, size_t start, size_t length) {
-    size_t pos;
-    scstr_t ret = { NULL, 0 };
-    if(ucx_substring(s.length, start, length, &ret.length, &pos)) {
-        ret.ptr = s.ptr + pos;
-    }
-    return ret;
-}
-
-
-static int ucx_strchr(const char *str, size_t length, int chr, size_t *pos) {
-    for(size_t i=0;i<length;i++) {
-        if(str[i] == chr) {
-            *pos = i;
-            return 1;
-        }
-    }
-    return 0;
-}
-
-static int ucx_strrchr(const char *str, size_t length, int chr, size_t *pos) {
-    if(length > 0) {
-        for(size_t i=length ; i>0 ; i--) {
-            if(str[i-1] == chr) {
-                *pos = i-1;
-                return 1;
-            }
-        }
-    }
-    return 0;
-}
-
-sstr_t sstrchr(sstr_t s, int c) {
-    size_t pos = 0;
-    if(ucx_strchr(s.ptr, s.length, c, &pos)) {
-        return sstrsubs(s, pos);
-    }
-    return sstrn(NULL, 0);
-}
-
-sstr_t sstrrchr(sstr_t s, int c) {
-    size_t pos = 0;
-    if(ucx_strrchr(s.ptr, s.length, c, &pos)) {
-        return sstrsubs(s, pos);
-    }
-    return sstrn(NULL, 0);
-}
-
-scstr_t scstrchr(scstr_t s, int c) {
-    size_t pos = 0;
-    if(ucx_strchr(s.ptr, s.length, c, &pos)) {
-        return scstrsubs(s, pos);
-    }
-    return scstrn(NULL, 0);
-}
-
-scstr_t scstrrchr(scstr_t s, int c) {
-    size_t pos = 0;
-    if(ucx_strrchr(s.ptr, s.length, c, &pos)) {
-        return scstrsubs(s, pos);
-    }
-    return scstrn(NULL, 0);
-}
-
-#define ptable_r(dest, useheap, ptable, index) (dest = useheap ? \
-    ((size_t*)ptable)[index] : (size_t) ((uint8_t*)ptable)[index])
-
-#define ptable_w(useheap, ptable, index, src) do {\
-    if (!useheap) ((uint8_t*)ptable)[index] = (uint8_t) src;\
-    else ((size_t*)ptable)[index] = src;\
-    } while (0);
-
-
-static const char* ucx_strstr(
-        const char *str,
-        size_t length,
-        const char *match,
-        size_t matchlen,
-        size_t *newlen)
-{
-    *newlen = length;
-    if (matchlen == 0) {
-        return str;
-    }
-    
-    const char *result = NULL;
-    size_t resultlen = 0;
-    
-    /*
-     * IMPORTANT:
-     * our prefix table contains the prefix length PLUS ONE
-     * this is our decision, because we want to use the full range of size_t
-     * the original algorithm needs a (-1) at one single place
-     * and we want to avoid that
-     */
-    
-    /* static prefix table */
-    static uint8_t s_prefix_table[256];
-    
-    /* check pattern length and use appropriate prefix table */
-    /* if the pattern exceeds static prefix table, allocate on the heap */
-    register int useheap = matchlen > 255;
-    register void* ptable = useheap ?
-        calloc(matchlen+1, sizeof(size_t)): s_prefix_table;
-    
-    /* keep counter in registers */
-    register size_t i, j;
-    
-    /* fill prefix table */
-    i = 0; j = 0;
-    ptable_w(useheap, ptable, i, j);
-    while (i < matchlen) {
-        while (j >= 1 && match[j-1] != match[i]) {
-            ptable_r(j, useheap, ptable, j-1);
-        }
-        i++; j++;
-        ptable_w(useheap, ptable, i, j);
-    }
-
-    /* search */
-    i = 0; j = 1;
-    while (i < length) {
-        while (j >= 1 && str[i] != match[j-1]) {
-            ptable_r(j, useheap, ptable, j-1);
-        }
-        i++; j++;
-        if (j-1 == matchlen) {
-            size_t start = i - matchlen;
-            result = str + start;
-            resultlen = length - start;
-            break;
-        }
-    }
-
-    /* if prefix table was allocated on the heap, free it */
-    if (ptable != s_prefix_table) {
-        free(ptable);
-    }
-    
-    *newlen = resultlen;
-    return result;
-}
-
-sstr_t scstrsstr(sstr_t string, scstr_t match) {
-    sstr_t result;
-    
-    size_t reslen;
-    const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen);
-    if(!resstr) {
-        result.ptr = NULL;
-        result.length = 0;
-        return result;
-    }
-    
-    size_t pos = resstr - string.ptr;
-    result.ptr = string.ptr + pos;
-    result.length = reslen;
-    
-    return result;
-}
-
-scstr_t scstrscstr(scstr_t string, scstr_t match) {
-    scstr_t result;
-    
-    size_t reslen;
-    const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen);
-    if(!resstr) {
-        result.ptr = NULL;
-        result.length = 0;
-        return result;
-    }
-    
-    size_t pos = resstr - string.ptr;
-    result.ptr = string.ptr + pos;
-    result.length = reslen;
-    
-    return result;
-}
-
-#undef ptable_r
-#undef ptable_w
-
-sstr_t* scstrsplit(scstr_t s, scstr_t d, ssize_t *n) {
-    return scstrsplit_a(ucx_default_allocator(), s, d, n);
-}
-
-sstr_t* scstrsplit_a(UcxAllocator *allocator, scstr_t s, scstr_t d, ssize_t *n) {
-    if (s.length == 0 || d.length == 0) {
-        *n = -1;
-        return NULL;
-    }
-    
-    /* special cases: delimiter is at least as large as the string */
-    if (d.length >= s.length) {
-        /* exact match */
-        if (sstrcmp(s, d) == 0) {
-            *n = 0;
-            return NULL;
-        } else /* no match possible */ {
-            *n = 1;
-            sstr_t *result = (sstr_t*) almalloc(allocator, sizeof(sstr_t));
-            if(result) {
-                *result = sstrdup_a(allocator, s);
-            } else {
-                *n = -2;
-            }
-            return result;
-        }
-    }
-    
-    ssize_t nmax = *n;
-    size_t arrlen = 16;
-    sstr_t* result = (sstr_t*) alcalloc(allocator, arrlen, sizeof(sstr_t));
-
-    if (result) {
-        scstr_t curpos = s;
-        ssize_t j = 1;
-        while (1) {
-            scstr_t match;
-            /* optimize for one byte delimiters */
-            if (d.length == 1) {
-                match = curpos;
-                for (size_t i = 0 ; i < curpos.length ; i++) {
-                    if (curpos.ptr[i] == *(d.ptr)) {
-                        match.ptr = curpos.ptr + i;
-                        break;
-                    }
-                    match.length--;
-                }
-            } else {
-                match = scstrscstr(curpos, d);
-            }
-            if (match.length > 0) {
-                /* is this our last try? */
-                if (nmax == 0 || j < nmax) {
-                    /* copy the current string to the array */
-                    scstr_t item = scstrn(curpos.ptr, match.ptr - curpos.ptr);
-                    result[j-1] = sstrdup_a(allocator, item);
-                    size_t processed = item.length + d.length;
-                    curpos.ptr += processed;
-                    curpos.length -= processed;
-
-                    /* allocate memory for the next string */
-                    j++;
-                    if (j > arrlen) {
-                        arrlen *= 2;
-                        size_t reallocsz;
-                        sstr_t* reallocated = NULL;
-                        if(!ucx_szmul(arrlen, sizeof(sstr_t), &reallocsz)) {
-                            reallocated = (sstr_t*) alrealloc(
-                                    allocator, result, reallocsz);
-                        }
-                        if (reallocated) {
-                            result = reallocated;
-                        } else {
-                            for (ssize_t i = 0 ; i < j-1 ; i++) {
-                                alfree(allocator, result[i].ptr);
-                            }
-                            alfree(allocator, result);
-                            *n = -2;
-                            return NULL;
-                        }
-                    }
-                } else {
-                    /* nmax reached, copy the _full_ remaining string */
-                    result[j-1] = sstrdup_a(allocator, curpos);
-                    break;
-                }
-            } else {
-                /* no more matches, copy last string */
-                result[j-1] = sstrdup_a(allocator, curpos);
-                break;
-            }
-        }
-        *n = j;
-    } else {
-        *n = -2;
-    }
-
-    return result;
-}
-
-int scstrcmp(scstr_t s1, scstr_t s2) {
-    if (s1.length == s2.length) {
-        return memcmp(s1.ptr, s2.ptr, s1.length);
-    } else if (s1.length > s2.length) {
-        return 1;
-    } else {
-        return -1;
-    }
-}
-
-int scstrcasecmp(scstr_t s1, scstr_t s2) {
-    if (s1.length == s2.length) {
-#ifdef _WIN32
-        return _strnicmp(s1.ptr, s2.ptr, s1.length);
-#else
-        return strncasecmp(s1.ptr, s2.ptr, s1.length);
-#endif
-    } else if (s1.length > s2.length) {
-        return 1;
-    } else {
-        return -1;
-    }
-}
-
-sstr_t scstrdup(scstr_t s) {
-    return sstrdup_a(ucx_default_allocator(), s);
-}
-
-sstr_t scstrdup_a(UcxAllocator *allocator, scstr_t s) {
-    sstr_t newstring;
-    newstring.ptr = (char*)almalloc(allocator, s.length + 1);
-    if (newstring.ptr) {
-        newstring.length = s.length;
-        newstring.ptr[newstring.length] = 0;
-        
-        memcpy(newstring.ptr, s.ptr, s.length);
-    } else {
-        newstring.length = 0;
-    }
-    
-    return newstring;
-}
-
-
-static size_t ucx_strtrim(const char *s, size_t len, size_t *newlen) {
-    const char *newptr = s;
-    size_t length = len;
-    
-    while(length > 0 && isspace(*newptr)) {
-        newptr++;
-        length--;
-    }
-    while(length > 0 && isspace(newptr[length-1])) {
-        length--;
-    }
-    
-    *newlen = length;
-    return newptr - s;
-}
-
-sstr_t sstrtrim(sstr_t string) {
-    sstr_t newstr;
-    newstr.ptr = string.ptr
-                 + ucx_strtrim(string.ptr, string.length, &newstr.length);
-    return newstr;
-}
-
-scstr_t scstrtrim(scstr_t string) {
-    scstr_t newstr;
-    newstr.ptr = string.ptr
-                 + ucx_strtrim(string.ptr, string.length, &newstr.length);
-    return newstr;
-}
-
-int scstrprefix(scstr_t string, scstr_t prefix) {
-    if (string.length == 0) {
-        return prefix.length == 0;
-    }
-    if (prefix.length == 0) {
-        return 1;
-    }
-    
-    if (prefix.length > string.length) {
-        return 0;
-    } else {
-        return memcmp(string.ptr, prefix.ptr, prefix.length) == 0;
-    }
-}
-
-int scstrsuffix(scstr_t string, scstr_t suffix) {
-    if (string.length == 0) {
-        return suffix.length == 0;
-    }
-    if (suffix.length == 0) {
-        return 1;
-    }
-    
-    if (suffix.length > string.length) {
-        return 0;
-    } else {
-        return memcmp(string.ptr+string.length-suffix.length,
-            suffix.ptr, suffix.length) == 0;
-    }
-}
-
-int scstrcaseprefix(scstr_t string, scstr_t prefix) {
-    if (string.length == 0) {
-        return prefix.length == 0;
-    }
-    if (prefix.length == 0) {
-        return 1;
-    }
-    
-    if (prefix.length > string.length) {
-        return 0;
-    } else {
-        scstr_t subs = scstrsubsl(string, 0, prefix.length);
-        return scstrcasecmp(subs, prefix) == 0;
-    }
-}
-
-int scstrcasesuffix(scstr_t string, scstr_t suffix) {
-    if (string.length == 0) {
-        return suffix.length == 0;
-    }
-    if (suffix.length == 0) {
-        return 1;
-    }
-    
-    if (suffix.length > string.length) {
-        return 0;
-    } else {
-        scstr_t subs = scstrsubs(string, string.length-suffix.length);
-        return scstrcasecmp(subs, suffix) == 0;
-    }
-}
-
-sstr_t scstrlower(scstr_t string) {
-    sstr_t ret = sstrdup(string);
-    for (size_t i = 0; i < ret.length ; i++) {
-        ret.ptr[i] = tolower(ret.ptr[i]);
-    }
-    return ret;
-}
-
-sstr_t scstrlower_a(UcxAllocator *allocator, scstr_t string) {
-    sstr_t ret = sstrdup_a(allocator, string);
-    for (size_t i = 0; i < ret.length ; i++) {
-        ret.ptr[i] = tolower(ret.ptr[i]);
-    }
-    return ret;
-}
-
-sstr_t scstrupper(scstr_t string) {
-    sstr_t ret = sstrdup(string);
-    for (size_t i = 0; i < ret.length ; i++) {
-        ret.ptr[i] = toupper(ret.ptr[i]);
-    }
-    return ret;
-}
-
-sstr_t scstrupper_a(UcxAllocator *allocator, scstr_t string) {
-    sstr_t ret = sstrdup_a(allocator, string);
-    for (size_t i = 0; i < ret.length ; i++) {
-        ret.ptr[i] = toupper(ret.ptr[i]);
-    }
-    return ret;
-}
-
-#define REPLACE_INDEX_BUFFER_MAX 100
-
-struct scstrreplace_ibuf {
-    size_t* buf;
-    unsigned int len; /* small indices */
-    struct scstrreplace_ibuf* next;
-};
-
-static void scstrrepl_free_ibuf(struct scstrreplace_ibuf *buf) {
-    while (buf) {
-        struct scstrreplace_ibuf *next = buf->next;
-        free(buf->buf);
-        free(buf);
-        buf = next;
-    }
-}
-
-sstr_t scstrreplacen_a(UcxAllocator *allocator, scstr_t str,
-                     scstr_t pattern, scstr_t replacement, size_t replmax) {
-
-    if (pattern.length == 0 || pattern.length > str.length || replmax == 0)
-        return sstrdup(str);
-
-    /* Compute expected buffer length */
-    size_t ibufmax = str.length / pattern.length;
-    size_t ibuflen = replmax < ibufmax ? replmax : ibufmax;
-    if (ibuflen > REPLACE_INDEX_BUFFER_MAX) {
-        ibuflen = REPLACE_INDEX_BUFFER_MAX;
-    }
-
-    /* Allocate first index buffer */
-    struct scstrreplace_ibuf *firstbuf, *curbuf;
-    firstbuf = curbuf = calloc(1, sizeof(struct scstrreplace_ibuf));
-    if (!firstbuf) return sstrn(NULL, 0);
-    firstbuf->buf = calloc(ibuflen, sizeof(size_t));
-    if (!firstbuf->buf) {
-        free(firstbuf);
-        return sstrn(NULL, 0);
-    }
-
-    /* Search occurrences */
-    scstr_t searchstr = str;
-    size_t found = 0;
-    do {
-        scstr_t match = scstrscstr(searchstr, pattern);
-        if (match.length > 0) {
-            /* Allocate next buffer in chain, if required */
-            if (curbuf->len == ibuflen) {
-                struct scstrreplace_ibuf *nextbuf =
-                        calloc(1, sizeof(struct scstrreplace_ibuf));
-                if (!nextbuf) {
-                    scstrrepl_free_ibuf(firstbuf);
-                    return sstrn(NULL, 0);
-                }
-                nextbuf->buf = calloc(ibuflen, sizeof(size_t));
-                if (!nextbuf->buf) {
-                    free(nextbuf);
-                    scstrrepl_free_ibuf(firstbuf);
-                    return sstrn(NULL, 0);
-                }
-                curbuf->next = nextbuf;
-                curbuf = nextbuf;
-            }
-
-            /* Record match index */
-            found++;
-            size_t idx = match.ptr - str.ptr;
-            curbuf->buf[curbuf->len++] = idx;
-            searchstr.ptr = match.ptr + pattern.length;
-            searchstr.length = str.length - idx - pattern.length;
-        } else {
-            break;
-        }
-    } while (searchstr.length > 0 && found < replmax);
-
-    /* Allocate result string */
-    sstr_t result;
-    {
-        ssize_t adjlen = (ssize_t) replacement.length - (ssize_t) pattern.length;
-        size_t rcount = 0;
-        curbuf = firstbuf;
-        do {
-            rcount += curbuf->len;
-            curbuf = curbuf->next;
-        } while (curbuf);
-        result.length = str.length + rcount * adjlen;
-        result.ptr = almalloc(allocator, result.length);
-        if (!result.ptr) {
-            scstrrepl_free_ibuf(firstbuf);
-            return sstrn(NULL, 0);
-        }
-    }
-
-    /* Build result string */
-    curbuf = firstbuf;
-    size_t srcidx = 0;
-    char* destptr = result.ptr;
-    do {
-        for (size_t i = 0; i < curbuf->len; i++) {
-            /* Copy source part up to next match*/
-            size_t idx = curbuf->buf[i];
-            size_t srclen = idx - srcidx;
-            if (srclen > 0) {
-                memcpy(destptr, str.ptr+srcidx, srclen);
-                destptr += srclen;
-                srcidx += srclen;
-            }
-
-            /* Copy the replacement and skip the source pattern */
-            srcidx += pattern.length;
-            memcpy(destptr, replacement.ptr, replacement.length);
-            destptr += replacement.length;
-        }
-        curbuf = curbuf->next;
-    } while (curbuf);
-    memcpy(destptr, str.ptr+srcidx, str.length-srcidx);
-
-    /* Free index buffer */
-    scstrrepl_free_ibuf(firstbuf);
-
-    return result;
-}
-
-sstr_t scstrreplacen(scstr_t str, scstr_t pattern,
-        scstr_t replacement, size_t replmax) {
-    return scstrreplacen_a(ucx_default_allocator(),
-            str, pattern, replacement, replmax);
-}
-
-
-// type adjustment functions
-scstr_t ucx_sc2sc(scstr_t str) {
-    return str;
-}
-scstr_t ucx_ss2sc(sstr_t str) {
-    scstr_t cs;
-    cs.ptr = str.ptr;
-    cs.length = str.length;
-    return cs;
-}
-scstr_t ucx_ss2c_s(scstr_t c) {
-    return c;
-}
--- a/ucx/test.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/test.h"
-
-UcxTestSuite* ucx_test_suite_new() {
-    UcxTestSuite* suite = (UcxTestSuite*) malloc(sizeof(UcxTestSuite));
-    if (suite != NULL) {
-        suite->success = 0;
-        suite->failure = 0;
-        suite->tests = NULL;
-    }
-
-    return suite;
-}
-
-void ucx_test_suite_free(UcxTestSuite* suite) {
-    UcxTestList *l = suite->tests;
-    while (l != NULL) {
-        UcxTestList *e = l;
-        l = l->next;
-        free(e);
-    }
-    free(suite);
-}
-
-int ucx_test_register(UcxTestSuite* suite, UcxTest test) {
-    if (suite->tests) {
-        UcxTestList *newelem = (UcxTestList*) malloc(sizeof(UcxTestList));
-        if (newelem) {
-            newelem->test = test;
-            newelem->next = NULL;
-            
-            UcxTestList *last = suite->tests;
-            while (last->next) {
-                last = last->next;
-            }
-            last->next = newelem;
-            
-            return EXIT_SUCCESS;
-        } else {
-            return EXIT_FAILURE;
-        }
-    } else {
-        suite->tests = (UcxTestList*) malloc(sizeof(UcxTestList));
-        if (suite->tests) {
-            suite->tests->test = test;
-            suite->tests->next = NULL;
-            
-            return EXIT_SUCCESS;
-        } else {
-            return EXIT_FAILURE;
-        }
-    }
-}
-
-void ucx_test_run(UcxTestSuite* suite, FILE* output) {
-    suite->success = 0;
-    suite->failure = 0;
-    for (UcxTestList* elem = suite->tests ; elem ; elem = elem->next) {
-        elem->test(suite, output);
-    }
-    fwrite("\nAll test completed.\n", 1, 21, output);
-    fprintf(output, "  Total:   %u\n  Success: %u\n  Failure: %u\n",
-            suite->success+suite->failure, suite->success, suite->failure);
-}
--- a/ucx/ucx.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/**
- * @mainpage UAP Common Extensions
- * Library with common and useful functions, macros and data structures.
- * <p>
- * Latest available source:<br>
- * <a href="https://sourceforge.net/projects/ucx/files/">
- * https://sourceforge.net/projects/ucx/files/</a>
- * </p>
- * 
- * <p>
- * Repositories:<br>
- * <a href="https://sourceforge.net/p/ucx/code">
- * https://sourceforge.net/p/ucx/code</a>
- * -&nbsp;or&nbsp;-
- * <a href="https://develop.uap-core.de/hg/ucx">
- * https://develop.uap-core.de/hg/ucx</a>
- * </p>
- * 
- * <h2>LICENCE</h2>
- * 
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/ucx.h"
-
-int ucx_szmul_impl(size_t a, size_t b, size_t *result) {
-    if(a == 0 || b == 0) {
-        *result = 0;
-        return 0;
-    }
-    size_t r = a * b;
-    if(r / b == a) {
-        *result = r;
-        return 0;
-    } else {
-        *result = 0;
-        return 1;
-    }
-}
-
--- a/ucx/ucx/allocator.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * Allocator for custom memory management.
- * 
- * A UCX allocator consists of a pointer to the memory area / pool and four
- * function pointers to memory management functions operating on this memory
- * area / pool. These functions shall behave equivalent to the standard libc
- * functions <code>malloc(), calloc(), realloc()</code> and <code>free()</code>.
- * 
- * The signature of the memory management functions is based on the signature
- * of the respective libc function but each of them takes the pointer to the
- * memory area / pool as first argument.
- * 
- * As the pointer to the memory area / pool can be arbitrarily chosen, any data
- * can be provided to the memory management functions. A UcxMempool is just
- * one example.
- * 
- * @see mempool.h
- * @see UcxMap
- * 
- * @file   allocator.h
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_ALLOCATOR_H
-#define	UCX_ALLOCATOR_H
-
-#include "ucx.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * A function pointer to the allocators <code>malloc()</code> function.
- * @see UcxAllocator
- */
-typedef void*(*ucx_allocator_malloc)(void *pool, size_t n);
-
-/**
- * A function pointer to the allocators <code>calloc()</code> function.
- * @see UcxAllocator
- */
-typedef void*(*ucx_allocator_calloc)(void *pool, size_t n, size_t size);
-
-/**
- * A function pointer to the allocators <code>realloc()</code> function.
- * @see UcxAllocator
- */
-typedef void*(*ucx_allocator_realloc)(void *pool, void *data, size_t n);
-
-/**
- * A function pointer to the allocators <code>free()</code> function.
- * @see UcxAllocator
- */
-typedef void(*ucx_allocator_free)(void *pool, void *data);
-
-/**
- * UCX allocator data structure containing memory management functions.
- */
-typedef struct {
-    /** Pointer to an area of memory or a complex memory pool.
-     * This pointer will be passed to any memory management function as first
-     * argument.
-     */
-    void *pool;
-    /**
-     * The <code>malloc()</code> function for this allocator.
-     */
-    ucx_allocator_malloc  malloc;
-    /**
-     * The <code>calloc()</code> function for this allocator.
-     */
-    ucx_allocator_calloc  calloc;
-    /**
-     * The <code>realloc()</code> function for this allocator.
-     */
-    ucx_allocator_realloc realloc;
-    /**
-     * The <code>free()</code> function for this allocator.
-     */
-    ucx_allocator_free    free;
-} UcxAllocator;
-
-/**
- * Returns a pointer to the default allocator.
- * 
- * The default allocator contains wrappers to the standard libc memory
- * management functions. Use this function to get a pointer to a globally
- * available allocator. You may also define an own UcxAllocator by assigning
- * #UCX_ALLOCATOR_DEFAULT to a variable and pass the address of this variable
- * to any function that takes a UcxAllocator as argument. Note that using
- * this function is the recommended way of passing a default allocator, thus
- * it never runs out of scope.
- * 
- * @return a pointer to the default allocator
- * 
- * @see UCX_ALLOCATOR_DEFAULT
- */
-UcxAllocator *ucx_default_allocator();
-
-/**
- * A wrapper for the standard libc <code>malloc()</code> function.
- * @param ignore ignored (may be used by allocators for pooled memory)
- * @param n argument passed to <code>malloc()</code>
- * @return return value of <code>malloc()</code>
- */
-void *ucx_default_malloc(void *ignore, size_t n);
-/**
- * A wrapper for the standard libc <code>calloc()</code> function.
- * @param ignore ignored (may be used by allocators for pooled memory)
- * @param n argument passed to <code>calloc()</code>
- * @param size  argument passed to <code>calloc()</code>
- * @return return value of <code>calloc()</code>
- */
-void *ucx_default_calloc(void *ignore, size_t n, size_t size);
-/**
- * A wrapper for the standard libc <code>realloc()</code> function.
- * @param ignore ignored (may be used by allocators for pooled memory)
- * @param data argumend passed to <code>realloc()</code>
- * @param n argument passed to <code>realloc()</code>
- * @return return value of <code>realloc()</code>
- */
-void *ucx_default_realloc(void *ignore, void *data, size_t n);
-/**
- * A wrapper for the standard libc <code>free()</code> function.
- * @param ignore ignored (may be used by allocators for pooled memory)
- * @param data argument passed to <code>free()</code>
- */
-void ucx_default_free(void *ignore, void *data);
-
-/**
- * Shorthand for calling an allocators malloc function.
- * @param allocator the allocator to use
- * @param n size of space to allocate
- * @return a pointer to the allocated memory area
- */
-#define almalloc(allocator, n) ((allocator)->malloc((allocator)->pool, n))
-
-/**
- * Shorthand for calling an allocators calloc function.
- * @param allocator the allocator to use
- * @param n the count of elements the space should be allocated for
- * @param size the size of each element
- * @return a pointer to the allocated memory area
- */
-#define alcalloc(allocator, n, size) \
-        ((allocator)->calloc((allocator)->pool, n, size))
-
-/**
- * Shorthand for calling an allocators realloc function.
- * @param allocator the allocator to use
- * @param ptr the pointer to the memory area that shall be reallocated
- * @param n the new size of the allocated memory area
- * @return a pointer to the reallocated memory area
- */
-#define alrealloc(allocator, ptr, n) \
-        ((allocator)->realloc((allocator)->pool, ptr, n))
-
-/**
- * Shorthand for calling an allocators free function.
- * @param allocator the allocator to use
- * @param ptr the pointer to the memory area that shall be freed
- */
-#define alfree(allocator, ptr) ((allocator)->free((allocator)->pool, ptr))
-
-/**
- * Convenient macro for a default allocator <code>struct</code> definition.
- */
-#define UCX_ALLOCATOR_DEFAULT {NULL, \
-        ucx_default_malloc, ucx_default_calloc, ucx_default_realloc, \
-        ucx_default_free }
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_ALLOCATOR_H */
-
--- a/ucx/ucx/array.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,460 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2019 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * Dynamically allocated array implementation.
- * 
- * @file   array.h
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_ARRAY_H
-#define	UCX_ARRAY_H
-
-#include "ucx.h"
-#include "allocator.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * UCX array type.
- */
-typedef struct {
-    /**
-     * The current capacity of the array.
-     */
-    size_t capacity;
-    /**
-     * The actual number of elements in the array.
-     */
-    size_t size;
-    /**
-     * The size of an individual element in bytes.
-     */
-    size_t elemsize;
-    /**
-     * A pointer to the data.
-     */
-    void* data;
-    /**
-     * The allocator used for the data.
-     */
-    UcxAllocator* allocator;
-} UcxArray;
-
-/**
- * Sets an element in an arbitrary user defined array.
- * The data is copied from the specified data location.
- * 
- * If the capacity is insufficient, the array is automatically reallocated and
- * the possibly new pointer is stored in the <code>array</code> argument.
- * 
- * On reallocation the capacity of the array is doubled until it is sufficient.
- * The new capacity is stored back to <code>capacity</code>.
- *  
- * @param array a pointer to location of the array pointer
- * @param capacity a pointer to the capacity
- * @param elmsize the size of each element
- * @param idx the index of the element to set
- * @param data a pointer to the element data
- * @return zero on success or non-zero on error (errno will be set)
- */
-#define ucx_array_util_set(array, capacity, elmsize, idx, data) \
-    ucx_array_util_set_a(ucx_default_allocator(), (void**)(array), capacity, \
-                         elmsize, idx, data)
-
-/**
- * Sets an element in an arbitrary user defined array.
- * The data is copied from the specified data location.
- * 
- * If the capacity is insufficient, the array is automatically reallocated
- * using the specified allocator and the possibly new pointer is stored in
- * the <code>array</code> argument.
- * 
- * On reallocation the capacity of the array is doubled until it is sufficient.
- * The new capacity is stored back to <code>capacity</code>. 
- * 
- * @param alloc the allocator that shall be used to reallocate the array
- * @param array a pointer to location of the array pointer
- * @param capacity a pointer to the capacity
- * @param elmsize the size of each element
- * @param idx the index of the element to set
- * @param data a pointer to the element data
- * @return zero on success or non-zero on error (errno will be set)
- */
-int ucx_array_util_set_a(UcxAllocator* alloc, void** array, size_t* capacity,
-    size_t elmsize, size_t idx, void* data);
-
-/**
- * Stores a pointer in an arbitrary user defined array.
- * The element size of the array must be sizeof(void*).
- * 
- * If the capacity is insufficient, the array is automatically reallocated and
- * the possibly new pointer is stored in the <code>array</code> argument.
- * 
- * On reallocation the capacity of the array is doubled until it is sufficient.
- * The new capacity is stored back to <code>capacity</code>.
- *  
- * @param array a pointer to location of the array pointer
- * @param capacity a pointer to the capacity
- * @param idx the index of the element to set
- * @param ptr the pointer to store
- * @return zero on success or non-zero on error (errno will be set)
- */
-#define ucx_array_util_setptr(array, capacity, idx, ptr) \
-    ucx_array_util_setptr_a(ucx_default_allocator(), (void**)(array), \
-                            capacity, idx, ptr)
-
-/**
- * Stores a pointer in an arbitrary user defined array.
- * The element size of the array must be sizeof(void*).
- * 
- * If the capacity is insufficient, the array is automatically reallocated
- * using the specified allocator and the possibly new pointer is stored in
- * the <code>array</code> argument.
- * 
- * On reallocation the capacity of the array is doubled until it is sufficient.
- * The new capacity is stored back to <code>capacity</code>. 
- * 
- * @param alloc the allocator that shall be used to reallocate the array
- * @param array a pointer to location of the array pointer
- * @param capacity a pointer to the capacity
- * @param idx the index of the element to set
- * @param ptr the pointer to store
- * @return zero on success or non-zero on error (errno will be set)
- */
-int ucx_array_util_setptr_a(UcxAllocator* alloc, void** array, size_t* capacity,
-    size_t idx, void* ptr);
-
-
-/**
- * Creates a new UCX array with the given capacity and element size.
- * @param capacity the initial capacity
- * @param elemsize the element size
- * @return a pointer to a new UCX array structure
- */
-UcxArray* ucx_array_new(size_t capacity, size_t elemsize);
-
-/**
- * Creates a new UCX array using the specified allocator.
- * 
- * @param capacity the initial capacity
- * @param elemsize the element size
- * @param allocator the allocator to use
- * @return a pointer to new UCX array structure
- */
-UcxArray* ucx_array_new_a(size_t capacity, size_t elemsize,
-        UcxAllocator* allocator);
-
-/**
- * Initializes a UCX array structure with the given capacity and element size.
- * The structure must be uninitialized as the data pointer will be overwritten.
- * 
- * @param array the structure to initialize
- * @param capacity the initial capacity
- * @param elemsize the element size
- */
-void ucx_array_init(UcxArray* array, size_t capacity, size_t elemsize);
-
-/**
- * Initializes a UCX array structure using the specified allocator.
- * The structure must be uninitialized as the data pointer will be overwritten.
- * 
- * @param array the structure to initialize
- * @param capacity the initial capacity
- * @param elemsize the element size
- * @param allocator the allocator to use
- */
-void ucx_array_init_a(UcxArray* array, size_t capacity, size_t elemsize,
-        UcxAllocator* allocator);
-
-/**
- * Creates an shallow copy of an array.
- * 
- * This function clones the specified array by using memcpy().
- * If the destination capacity is insufficient, an automatic reallocation is
- * attempted.
- * 
- * Note: if the destination array is uninitialized, the behavior is undefined.
- * 
- * @param dest the array to copy to
- * @param src the array to copy from
- * @return zero on success, non-zero on reallocation failure.
- */
-int ucx_array_clone(UcxArray* dest, UcxArray const* src);
-
-
-/**
- * Compares two UCX arrays element-wise by using a compare function.
- *
- * Elements of the two specified arrays are compared by using the specified
- * compare function and the additional data. The type and content of this
- * additional data depends on the cmp_func() used.
- * 
- * This function always returns zero, if the element sizes of the arrays do
- * not match and performs no comparisons in this case.
- * 
- * @param array1 the first array
- * @param array2 the second array
- * @param cmpfnc the compare function
- * @param data additional data for the compare function
- * @return 1, if and only if the two arrays equal element-wise, 0 otherwise
- */
-int ucx_array_equals(UcxArray const *array1, UcxArray const *array2,
-        cmp_func cmpfnc, void* data);
-
-/**
- * Destroys the array.
- * 
- * The data is freed and both capacity and count are reset to zero.
- * If the array structure itself has been dynamically allocated, it has to be
- * freed separately.
- * 
- * @param array the array to destroy
- */
-void ucx_array_destroy(UcxArray *array);
-
-/**
- * Destroys and frees the array.
- * 
- * @param array the array to free
- */
-void ucx_array_free(UcxArray *array);
-
-/**
- * Inserts elements at the end of the array.
- * 
- * This is an O(1) operation.
- * The array will automatically grow, if the capacity is exceeded.
- * If a pointer to data is provided, the data is copied into the array with
- * memcpy(). Otherwise the new elements are completely zeroed.
- * 
- * @param array a pointer the array where to append the data
- * @param data a pointer to the data to insert (may be <code>NULL</code>)
- * @param count number of elements to copy from data (if data is
- * <code>NULL</code>, zeroed elements are appended)
- * @return zero on success, non-zero if a reallocation was necessary but failed
- * @see ucx_array_set_from()
- * @see ucx_array_append()
- */
-int ucx_array_append_from(UcxArray *array, void *data, size_t count);
-
-
-/**
- * Inserts elements at the beginning of the array.
- * 
- * This is an expensive operation, because the contents must be moved.
- * If there is no particular reason to prepend data, you should use
- * ucx_array_append_from() instead.
- * 
- * @param array a pointer the array where to prepend the data
- * @param data a pointer to the data to insert (may be <code>NULL</code>)
- * @param count number of elements to copy from data (if data is
- * <code>NULL</code>, zeroed elements are inserted)
- * @return zero on success, non-zero if a reallocation was necessary but failed
- * @see ucx_array_append_from()
- * @see ucx_array_set_from()
- * @see ucx_array_prepend()
- */
-int ucx_array_prepend_from(UcxArray *array, void *data, size_t count);
-
-
-/**
- * Sets elements starting at the specified index.
- * 
- * If the any index is out of bounds, the array automatically grows.
- * The pointer to the data may be NULL, in which case the elements are zeroed. 
- * 
- * @param array a pointer the array where to set the data
- * @param index the index of the element to set
- * @param data a pointer to the data to insert (may be <code>NULL</code>)
- * @param count number of elements to copy from data (if data is
- * <code>NULL</code>, the memory in the array is zeroed)
- * @return zero on success, non-zero if a reallocation was necessary but failed
- * @see ucx_array_append_from()
- * @see ucx_array_set()
- */
-int ucx_array_set_from(UcxArray *array, size_t index, void *data, size_t count);
-
-/**
- * Concatenates two arrays.
- * 
- * The contents of the second array are appended to the first array in one
- * single operation. The second array is otherwise left untouched.
- * 
- * The first array may grow automatically. If this fails, both arrays remain
- * unmodified.
- * 
- * @param array1 first array
- * @param array2 second array
- * @return zero on success, non-zero if reallocation was necessary but failed 
- * or the element size does not match
- */
-int ucx_array_concat(UcxArray *array1, const UcxArray *array2);
-
-/**
- * Returns a pointer to the array element at the specified index.
- * 
- * @param array the array to retrieve the element from
- * @param index index of the element to return
- * @return a pointer to the element at the specified index or <code>NULL</code>,
- * if the index is greater than the array size
- */
-void *ucx_array_at(UcxArray const* array, size_t index);
-
-/**
- * Returns the index of an element containing the specified data.
- *
- * This function uses a cmp_func() to compare the data of each list element
- * with the specified data. If no cmp_func is provided, memcmp() is used.
- * 
- * If the array contains the data more than once, the index of the first
- * occurrence is returned.
- * If the array does not contain the data, the size of array is returned.
- *  
- * @param array the array where to search for the data
- * @param elem the element data
- * @param cmpfnc the compare function
- * @param data additional data for the compare function
- * @return the index of the element containing the specified data or the size of
- * the array, if the data is not found in this array
- */
-size_t ucx_array_find(UcxArray const *array, void *elem,
-    cmp_func cmpfnc, void *data);
-
-/**
- * Checks, if an array contains a specific element.
- * 
- * An element is found, if ucx_array_find() returns a value less than the size.
- * 
- * @param array the array where to search for the data
- * @param elem the element data
- * @param cmpfnc the compare function
- * @param data additional data for the compare function
- * @return 1, if and only if the array contains the specified element data
- * @see ucx_array_find()
- */
-int ucx_array_contains(UcxArray const *array, void *elem,
-    cmp_func cmpfnc, void *data);
-
-/**
- * Sorts a UcxArray with the best available sort algorithm.
- * 
- * The qsort_r() function is used, if available (glibc, FreeBSD or MacOS).
- * The order of arguments is automatically adjusted for the FreeBSD and MacOS
- * version of qsort_r().
- * 
- * If qsort_r() is not available, a merge sort algorithm is used, which is
- * guaranteed to use no more additional memory than for exactly one element.
- * 
- * @param array the array to sort
- * @param cmpfnc the function that shall be used to compare the element data
- * @param data additional data for the cmp_func() or <code>NULL</code>
- */
-void ucx_array_sort(UcxArray* array, cmp_func cmpfnc, void *data);
-
-/**
- * Removes an element from the array.
- * 
- * This is in general an expensive operation, because several elements may
- * be moved. If the order of the elements is not relevant, use
- * ucx_array_remove_fast() instead.
- * 
- * @param array pointer to the array from which the element shall be removed
- * @param index the index of the element to remove
- */
-void ucx_array_remove(UcxArray *array, size_t index);
-
-/**
- * Removes an element from the array.
- * 
- * This is an O(1) operation, but does not maintain the order of the elements.
- * The last element in the array is moved to the location of the removed
- * element.
- * 
- * @param array pointer to the array from which the element shall be removed
- * @param index the index of the element to remove
- */
-void ucx_array_remove_fast(UcxArray *array, size_t index);
-
-/**
- * Shrinks the memory to exactly fit the contents.
- * 
- * After this operation, the capacity equals the size.
- * 
- * @param array a pointer to the array
- * @return zero on success, non-zero if reallocation failed
- */
-int ucx_array_shrink(UcxArray* array);
-
-/**
- * Sets the capacity of the array.
- * 
- * If the new capacity is smaller than the size of the array, the elements
- * are removed and the size is adjusted accordingly.
- * 
- * @param array a pointer to the array
- * @param capacity the new capacity
- * @return zero on success, non-zero if reallocation failed
- */
-int ucx_array_resize(UcxArray* array, size_t capacity);
-
-/**
- * Resizes the array only, if the capacity is insufficient.
- * 
- * If the requested capacity is smaller than the current capacity, this
- * function does nothing.
- * 
- * @param array a pointer to the array
- * @param capacity the guaranteed capacity
- * @return zero on success, non-zero if reallocation failed
- */
-int ucx_array_reserve(UcxArray* array, size_t capacity);
-
-/**
- * Resizes the capacity, if the specified number of elements would not fit.
- * 
- * A call to ucx_array_grow(array, count) is effectively the same as
- * ucx_array_reserve(array, array->size+count).
- * 
- * @param array a pointer to the array
- * @param count the number of elements that should additionally fit
- * into the array
- * @return zero on success, non-zero if reallocation failed
- */
-int ucx_array_grow(UcxArray* array, size_t count);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_ARRAY_H */
-
--- a/ucx/ucx/avl.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,353 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @file avl.h
- * 
- * AVL tree implementation.
- * 
- * This binary search tree implementation allows average O(1) insertion and
- * removal of elements (excluding binary search time).
- * 
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_AVL_H
-#define UCX_AVL_H
-
-#include "ucx.h"
-#include "allocator.h"
-#include <inttypes.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * UCX AVL Node type.
- * 
- * @see UcxAVLNode
- */
-typedef struct UcxAVLNode UcxAVLNode;
-
-/**
- * UCX AVL Node.
- */
-struct UcxAVLNode {
-    /**
-     * The key for this node.
-     */
-    intptr_t key;
-    /**
-     * Data contained by this node.
-     */
-    void *value;
-    /**
-     * The height of this (sub)-tree.
-     */
-    size_t height;
-    /**
-     * Parent node.
-     */
-    UcxAVLNode *parent;
-    /**
-     * Root node of left subtree.
-     */
-    UcxAVLNode *left;
-    /**
-     * Root node of right subtree.
-     */
-    UcxAVLNode *right;
-};
-
-/**
- * UCX AVL Tree.
- */
-typedef struct {
-    /**
-     * The UcxAllocator that shall be used to manage the memory for node data.
-     */
-    UcxAllocator *allocator;
-    /**
-     * Root node of the tree.
-     */
-    UcxAVLNode *root;
-    /**
-     * Compare function that shall be used to compare the UcxAVLNode keys.
-     * @see UcxAVLNode.key
-     */
-    cmp_func cmpfunc;
-    /**
-     * Custom user data.
-     * This data will also be provided to the cmpfunc.
-     */
-    void *userdata;
-} UcxAVLTree;
-
-/**
- * Initializes a new UcxAVLTree with a default allocator.
- * 
- * @param cmpfunc the compare function that shall be used
- * @return a new UcxAVLTree object
- * @see ucx_avl_new_a()
- */
-UcxAVLTree *ucx_avl_new(cmp_func cmpfunc);
-
-/**
- * Initializes a new UcxAVLTree with the specified allocator.
- * 
- * The cmpfunc should be capable of comparing two keys within this AVL tree.
- * So if you want to use null terminated strings as keys, you could use the
- * ucx_cmp_str() function here.
- * 
- * @param cmpfunc the compare function that shall be used
- * @param allocator the UcxAllocator that shall be used
- * @return a new UcxAVLTree object
- */
-UcxAVLTree *ucx_avl_new_a(cmp_func cmpfunc, UcxAllocator *allocator);
-
-/**
- * Destroys a UcxAVLTree.
- * 
- * Note, that the contents are not automatically freed.
- * Use may use #ucx_avl_free_content() before calling this function.
- * 
- * @param tree the tree to destroy
- * @see ucx_avl_free_content()
- */
-void ucx_avl_free(UcxAVLTree *tree);
-
-/**
- * Frees the contents of a UcxAVLTree.
- * 
- * This is a convenience function that iterates over the tree and passes all
- * values to the specified destructor function.
- * 
- * If no destructor is specified (<code>NULL</code>), the free() function of
- * the tree's own allocator is used.
- * 
- * You must ensure, that it is valid to pass each value in the map to the same
- * destructor function.
- * 
- * You should free the entire tree afterwards, as the contents will be invalid.
- * 
- * @param tree for which the contents shall be freed
- * @param destr optional pointer to a destructor function
- * @see ucx_avl_free()
- */
-void ucx_avl_free_content(UcxAVLTree *tree, ucx_destructor destr);
-
-/**
- * Macro for initializing a new UcxAVLTree with the default allocator and a
- * ucx_cmp_ptr() compare function.
- * 
- * @return a new default UcxAVLTree object
- */
-#define ucx_avl_default_new() \
-    ucx_avl_new_a(ucx_cmp_ptr, ucx_default_allocator())
-
-/**
- * Gets the node from the tree, that is associated with the specified key.
- * @param tree the UcxAVLTree
- * @param key the key
- * @return the node (or <code>NULL</code>, if the key is not present)
- */
-UcxAVLNode *ucx_avl_get_node(UcxAVLTree *tree, intptr_t key);
-
-/**
- * Gets the value from the tree, that is associated with the specified key.
- * @param tree the UcxAVLTree
- * @param key the key
- * @return the value (or <code>NULL</code>, if the key is not present)
- */
-void *ucx_avl_get(UcxAVLTree *tree, intptr_t key);
-
-/**
- * A mode for #ucx_avl_find_node() with the same behavior as
- * #ucx_avl_get_node().
- */
-#define UCX_AVL_FIND_EXACT         0
-/**
- * A mode for #ucx_avl_find_node() finding the node whose key is at least
- * as large as the specified key.
- */
-#define UCX_AVL_FIND_LOWER_BOUNDED 1
-/**
- * A mode for #ucx_avl_find_node() finding the node whose key is at most
- * as large as the specified key.
- */
-#define UCX_AVL_FIND_UPPER_BOUNDED 2
-/**
- * A mode for #ucx_avl_find_node() finding the node with a key that is as close
- * to the specified key as possible. If the key is present, the behavior is
- * like #ucx_avl_get_node(). This mode only returns <code>NULL</code> on
- * empty trees.
- */
-#define UCX_AVL_FIND_CLOSEST       3
-
-/**
- * Finds a node within the tree. The following modes are supported:
- * <ul>
- * <li>#UCX_AVL_FIND_EXACT: the same behavior as #ucx_avl_get_node()</li>
- * <li>#UCX_AVL_FIND_LOWER_BOUNDED: finds the node whose key is at least
- * as large as the specified key</li>
- * <li>#UCX_AVL_FIND_UPPER_BOUNDED: finds the node whose key is at most
- * as large as the specified key</li>
- * <li>#UCX_AVL_FIND_CLOSEST: finds the node with a key that is as close to
- * the specified key as possible. If the key is present, the behavior is
- * like #ucx_avl_get_node(). This mode only returns <code>NULL</code> on
- * empty trees.</li> 
- * </ul>
- * 
- * The distance function provided MUST agree with the compare function of
- * the AVL tree.
- * 
- * @param tree the UcxAVLTree
- * @param key the key
- * @param dfnc the distance function
- * @param mode the find mode
- * @return the node (or <code>NULL</code>, if no node can be found)
- */
-UcxAVLNode *ucx_avl_find_node(UcxAVLTree *tree, intptr_t key,
-        distance_func dfnc, int mode);
-
-/**
- * Finds a value within the tree.
- * See #ucx_avl_find_node() for details.
- * 
- * @param tree the UcxAVLTree
- * @param key the key
- * @param dfnc the distance function
- * @param mode the find mode
- * @return the value (or <code>NULL</code>, if no value can be found)
- */
-void *ucx_avl_find(UcxAVLTree *tree, intptr_t key,
-        distance_func dfnc, int mode);
-
-/**
- * Puts a key/value pair into the tree.
- * 
- * Attention: use this function only, if a possible old value does not need
- * to be preserved.
- * 
- * @param tree the UcxAVLTree
- * @param key the key
- * @param value the new value
- * @return zero, if and only if the operation succeeded
- */
-int ucx_avl_put(UcxAVLTree *tree, intptr_t key, void *value);
-
-/**
- * Puts a key/value pair into the tree.
- * 
- * This is a secure function which saves the old value to the variable pointed
- * at by oldvalue.
- * 
- * @param tree the UcxAVLTree
- * @param key the key
- * @param value the new value
- * @param oldvalue optional: a pointer to the location where a possible old
- * value shall be stored
- * @return zero, if and only if the operation succeeded
- */
-int ucx_avl_put_s(UcxAVLTree *tree, intptr_t key, void *value, void **oldvalue);
-
-/**
- * Removes a node from the AVL tree.
- * 
- * Note: the specified node is logically removed. The tree implementation
- * decides which memory area is freed. In most cases the here provided node
- * is freed, so its further use is generally undefined.
- * 
- * @param tree the UcxAVLTree
- * @param node the node to remove
- * @return zero, if and only if an element has been removed
- */
-int ucx_avl_remove_node(UcxAVLTree *tree, UcxAVLNode *node);
-
-/**
- * Removes an element from the AVL tree.
- * 
- * @param tree the UcxAVLTree
- * @param key the key
- * @return zero, if and only if an element has been removed
- */
-int ucx_avl_remove(UcxAVLTree *tree, intptr_t key);
-
-/**
- * Removes an element from the AVL tree.
- * 
- * This is a secure function which saves the old key and value data from node
- * to the variables at the location of oldkey and oldvalue (if specified), so
- * they can be freed afterwards (if necessary).
- * 
- * Note: the returned key in oldkey is possibly not the same as the provided
- * key for the lookup (in terms of memory location).
- * 
- * @param tree the UcxAVLTree
- * @param key the key of the element to remove
- * @param oldkey optional: a pointer to the location where the old key shall be
- * stored
- * @param oldvalue optional: a pointer to the location where the old value
- * shall be stored
- * @return zero, if and only if an element has been removed
- */
-int ucx_avl_remove_s(UcxAVLTree *tree, intptr_t key,
-        intptr_t *oldkey, void **oldvalue);
-
-/**
- * Counts the nodes in the specified UcxAVLTree.
- * @param tree the AVL tree
- * @return the node count
- */
-size_t ucx_avl_count(UcxAVLTree *tree);
-
-/**
- * Finds the in-order predecessor of the given node.
- * @param node an AVL node
- * @return the in-order predecessor of the given node, or <code>NULL</code> if
- * the given node is the in-order minimum
- */
-UcxAVLNode* ucx_avl_pred(UcxAVLNode* node);
-
-/**
- * Finds the in-order successor of the given node.
- * @param node an AVL node
- * @return the in-order successor of the given node, or <code>NULL</code> if
- * the given node is the in-order maximum
- */
-UcxAVLNode* ucx_avl_succ(UcxAVLNode* node);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_AVL_H */
-
--- a/ucx/ucx/buffer.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file buffer.h
- * 
- * Advanced buffer implementation.
- * 
- * Instances of UcxBuffer can be used to read from or to write to like one
- * would do with a stream. This allows the use of ucx_stream_copy() to copy
- * contents from one buffer to another.
- * 
- * Some features for convenient use of the buffer
- * can be enabled. See the documentation of the macro constants for more
- * information.
- * 
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_BUFFER_H
-#define	UCX_BUFFER_H
-
-#include "ucx.h"
-#include <sys/types.h>
-#include <stdio.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * No buffer features enabled (all flags cleared).
- */
-#define UCX_BUFFER_DEFAULT      0x00
-
-/**
- * If this flag is enabled, the buffer will automatically free its contents.
- */
-#define UCX_BUFFER_AUTOFREE     0x01
-
-/**
- * If this flag is enabled, the buffer will automatically extends its capacity.
- */
-#define UCX_BUFFER_AUTOEXTEND   0x02
-
-/** UCX Buffer. */
-typedef struct {
-    /** A pointer to the buffer contents. */
-    char *space;
-    /** Current position of the buffer. */
-    size_t pos;
-    /** Current capacity (i.e. maximum size) of the buffer. */
-    size_t capacity;
-    /** Current size of the buffer content. */
-    size_t size;
-    /**
-     * Flag register for buffer features.
-     * @see #UCX_BUFFER_DEFAULT
-     * @see #UCX_BUFFER_AUTOFREE
-     * @see #UCX_BUFFER_AUTOEXTEND
-     */
-    int flags;
-} UcxBuffer;
-
-/**
- * Creates a new buffer.
- * 
- * <b>Note:</b> you may provide <code>NULL</code> as argument for
- * <code>space</code>. Then this function will allocate the space and enforce
- * the #UCX_BUFFER_AUTOFREE flag.
- * 
- * @param space pointer to the memory area, or <code>NULL</code> to allocate
- * new memory
- * @param capacity the capacity of the buffer
- * @param flags buffer features (see UcxBuffer.flags)
- * @return the new buffer
- */
-UcxBuffer *ucx_buffer_new(void *space, size_t capacity, int flags);
-
-/**
- * Destroys a buffer.
- * 
- * If the #UCX_BUFFER_AUTOFREE feature is enabled, the contents of the buffer
- * are also freed.
- * 
- * @param buffer the buffer to destroy
- */
-void ucx_buffer_free(UcxBuffer* buffer);
-
-/**
- * Creates a new buffer and fills it with extracted content from another buffer.
- * 
- * <b>Note:</b> the #UCX_BUFFER_AUTOFREE feature is enforced for the new buffer.
- * 
- * @param src the source buffer
- * @param start the start position of extraction
- * @param length the count of bytes to extract (must not be zero)
- * @param flags feature mask for the new buffer
- * @return a new buffer containing the extraction
- */
-UcxBuffer* ucx_buffer_extract(UcxBuffer *src,
-        size_t start, size_t length, int flags);
-
-/**
- * A shorthand macro for the full extraction of the buffer.
- * 
- * @param src the source buffer
- * @param flags feature mask for the new buffer
- * @return a new buffer with the extracted content
- */
-#define ucx_buffer_clone(src,flags) \
-    ucx_buffer_extract(src, 0, (src)->capacity, flags)
-
-
-/**
- * Shifts the contents of the buffer by the given offset.
- * 
- * If the offset is positive, the contents are shifted to the right.
- * If auto extension is enabled, the buffer grows, if necessary.
- * In case the auto extension fails, this function returns a non-zero value and
- * no contents are changed.
- * If auto extension is disabled, the contents that do not fit into the buffer
- * are discarded.
- * 
- * If the offset is negative, the contents are shifted to the left where the
- * first <code>shift</code> bytes are discarded.
- * The new size of the buffer is the old size minus
- * the absolute shift value.
- * If this value is larger than the buffer size, the buffer is emptied (but
- * not cleared, see the security note below).
- * 
- * The buffer position gets shifted alongside with the content but is kept
- * within the boundaries of the buffer.
- * 
- * <b>Security note:</b> the shifting operation does <em>not</em> erase the
- * previously occupied memory cells. You can easily do that manually, e.g. by
- * calling <code>memset(buffer->space, 0, shift)</code> for a right shift or
- * <code>memset(buffer->size, 0, buffer->capacity-buffer->size)</code>
- * for a left shift.
- * 
- * @param buffer the buffer
- * @param shift the shift offset (negative means left shift)
- * @return 0 on success, non-zero if a required auto-extension fails
- */
-int ucx_buffer_shift(UcxBuffer* buffer, off_t shift);
-
-/**
- * Shifts the buffer to the right.
- * See ucx_buffer_shift() for details.
- * 
- * @param buffer the buffer
- * @param shift the shift offset
- * @return 0 on success, non-zero if a required auto-extension fails
- * @see ucx_buffer_shift()
- */
-int ucx_buffer_shift_right(UcxBuffer* buffer, size_t shift);
-
-/**
- * Shifts the buffer to the left.
- * 
- * See ucx_buffer_shift() for details. Note, however, that this method expects
- * a positive shift offset.
- * 
- * Since a left shift cannot fail due to memory allocation problems, this
- * function always returns zero.
- * 
- * @param buffer the buffer
- * @param shift the shift offset
- * @return always zero
- * @see ucx_buffer_shift()
- */
-int ucx_buffer_shift_left(UcxBuffer* buffer, size_t shift);
-
-
-/**
- * Moves the position of the buffer.
- * 
- * The new position is relative to the <code>whence</code> argument.
- *
- * SEEK_SET marks the start of the buffer.
- * SEEK_CUR marks the current position.
- * SEEK_END marks the end of the buffer.
- * 
- * With an offset of zero, this function sets the buffer position to zero
- * (SEEK_SET), the buffer size (SEEK_END) or leaves the buffer position
- * unchanged (SEEK_CUR).
- * 
- * @param buffer
- * @param offset position offset relative to <code>whence</code>
- * @param whence one of SEEK_SET, SEEK_CUR or SEEK_END
- * @return 0 on success, non-zero if the position is invalid
- *
- */
-int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence);
-
-/**
- * Clears the buffer by resetting the position and deleting the data.
- * 
- * The data is deleted by a zeroing it with call to <code>memset()</code>.
- * 
- * @param buffer the buffer to be cleared
- */
-#define ucx_buffer_clear(buffer) memset((buffer)->space, 0, (buffer)->size); \
-        (buffer)->size = 0; (buffer)->pos = 0;
-
-/**
- * Tests, if the buffer position has exceeded the buffer capacity.
- * 
- * @param buffer the buffer to test
- * @return non-zero, if the current buffer position has exceeded the last
- * available byte of the buffer.
- */
-int ucx_buffer_eof(UcxBuffer *buffer);
-
-
-/**
- * Extends the capacity of the buffer.
- * 
- * <b>Note:</b> The buffer capacity increased by a power of two. I.e.
- * the buffer capacity is doubled, as long as it would not hold the current
- * content plus the additional required bytes.
- * 
- * <b>Attention:</b> the argument provided is the number of <i>additional</i>
- * bytes the buffer shall hold. It is <b>NOT</b> the total number of bytes the
- * buffer shall hold.
- * 
- * @param buffer the buffer to extend
- * @param additional_bytes the number of additional bytes the buffer shall
- * <i>at least</i> hold
- * @return 0 on success or a non-zero value on failure
- */
-int ucx_buffer_extend(UcxBuffer *buffer, size_t additional_bytes);
-
-/**
- * Writes data to a UcxBuffer.
- * 
- * The position of the buffer is increased by the number of bytes written.
- * 
- * @param ptr a pointer to the memory area containing the bytes to be written
- * @param size the length of one element
- * @param nitems the element count
- * @param buffer the UcxBuffer to write to
- * @return the total count of bytes written
- */
-size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
-        UcxBuffer *buffer);
-
-/**
- * Reads data from a UcxBuffer.
- * 
- * The position of the buffer is increased by the number of bytes read.
- * 
- * @param ptr a pointer to the memory area where to store the read data
- * @param size the length of one element
- * @param nitems the element count
- * @param buffer the UcxBuffer to read from
- * @return the total number of elements read
- */
-size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
-        UcxBuffer *buffer);
-
-/**
- * Writes a character to a buffer.
- * 
- * The least significant byte of the argument is written to the buffer. If the
- * end of the buffer is reached and #UCX_BUFFER_AUTOEXTEND feature is enabled,
- * the buffer capacity is extended by ucx_buffer_extend(). If the feature is
- * disabled or buffer extension fails, <code>EOF</code> is returned.
- * 
- * On successful write the position of the buffer is increased.
- * 
- * @param buffer the buffer to write to
- * @param c the character to write as <code>int</code> value
- * @return the byte that has bean written as <code>int</code> value or
- * <code>EOF</code> when the end of the stream is reached and automatic
- * extension is not enabled or not possible
- */
-int ucx_buffer_putc(UcxBuffer *buffer, int c);
-
-/**
- * Gets a character from a buffer.
- * 
- * The current position of the buffer is increased after a successful read.
- * 
- * @param buffer the buffer to read from
- * @return the character as <code>int</code> value or <code>EOF</code>, if the
- * end of the buffer is reached
- */
-int ucx_buffer_getc(UcxBuffer *buffer);
-
-/**
- * Writes a string to a buffer.
- * 
- * @param buffer the buffer
- * @param str the string
- * @return the number of bytes written
- */
-size_t ucx_buffer_puts(UcxBuffer *buffer, const char *str);
-
-/**
- * Returns the complete buffer content as sstr_t.
- * @param buffer the buffer
- * @return the result of <code>sstrn()</code> with the buffer space and size
- * as arguments
- */
-#define ucx_buffer_to_sstr(buffer) sstrn((buffer)->space, (buffer)->size)
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_BUFFER_H */
-
--- a/ucx/ucx/list.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,512 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * Doubly linked list implementation.
- * 
- * @file   list.h
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_LIST_H
-#define	UCX_LIST_H
-
-#include "ucx.h"
-#include "allocator.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * Loop statement for UCX lists.
- * 
- * The first argument is the name of the iteration variable. The scope of
- * this variable is limited to the <code>UCX_FOREACH</code> statement.
- * 
- * The second argument is a pointer to the list. In most cases this will be the
- * pointer to the first element of the list, but it may also be an arbitrary
- * element of the list. The iteration will then start with that element.
- * 
- * @param list The first element of the list
- * @param elem The variable name of the element
- */
-#define UCX_FOREACH(elem,list) \
-        for (UcxList* elem = (UcxList*) list ; elem != NULL ; elem = elem->next)
-
-/**
- * UCX list type.
- * @see UcxList
- */
-typedef struct UcxList UcxList;
-
-/**
- * UCX list structure.
- */
-struct UcxList {
-    /**
-     * List element payload.
-     */
-    void    *data;
-    /**
-     * Pointer to the next list element or <code>NULL</code>, if this is the
-     * last element.
-     */
-    UcxList *next;
-    /**
-     * Pointer to the previous list element or <code>NULL</code>, if this is
-     * the first element.
-     */
-    UcxList *prev;
-};
-
-/**
- * Creates an element-wise copy of a list.
- * 
- * This function clones the specified list by creating new list elements and
- * copying the data with the specified copy_func(). If no copy_func() is
- * specified, a shallow copy is created and the new list will reference the
- * same data as the source list.
- * 
- * @param list the list to copy
- * @param cpyfnc a pointer to the function that shall copy an element (may be
- * <code>NULL</code>)
- * @param data additional data for the copy_func()
- * @return a pointer to the copy
- */
-UcxList *ucx_list_clone(const UcxList *list, copy_func cpyfnc, void* data);
-
-/**
- * Creates an element-wise copy of a list using a UcxAllocator.
- * 
- * See ucx_list_clone() for details.
- * 
- * You might want to pass the allocator via the <code>data</code> parameter,
- * to access it within the copy function for making deep copies.
- * 
- * @param allocator the allocator to use
- * @param list the list to copy
- * @param cpyfnc a pointer to the function that shall copy an element (may be
- * <code>NULL</code>)
- * @param data additional data for the copy_func()
- * @return a pointer to the copy
- * @see ucx_list_clone()
- */
-UcxList *ucx_list_clone_a(UcxAllocator *allocator, const UcxList *list,
-        copy_func cpyfnc, void* data);
-
-/**
- * Compares two UCX lists element-wise by using a compare function.
- * 
- * Each element of the two specified lists are compared by using the specified
- * compare function and the additional data. The type and content of this
- * additional data depends on the cmp_func() used.
- * 
- * If the list pointers denote elements within a list, the lists are compared
- * starting with the denoted elements. Thus any previous elements are not taken
- * into account. This might be useful to check, if certain list tails match
- * each other.
- * 
- * @param list1 the first list
- * @param list2 the second list
- * @param cmpfnc the compare function
- * @param data additional data for the compare function
- * @return 1, if and only if the two lists equal element-wise, 0 otherwise
- */
-int ucx_list_equals(const UcxList *list1, const UcxList *list2,
-        cmp_func cmpfnc, void* data);
-
-/**
- * Destroys the entire list.
- * 
- * The members of the list are not automatically freed, so ensure they are
- * otherwise referenced or destroyed by ucx_list_free_contents().
- * Otherwise, a memory leak is likely to occur.
- * 
- * <b>Caution:</b> the argument <b>MUST</b> denote an entire list (i.e. a call
- * to ucx_list_first() on the argument must return the argument itself)
- * 
- * @param list the list to free
- * @see ucx_list_free_contents()
- */
-void ucx_list_free(UcxList *list);
-
-/**
- * Destroys the entire list using a UcxAllocator.
- * 
- * See ucx_list_free() for details.
- * 
- * @param allocator the allocator to use
- * @param list the list to free
- * @see ucx_list_free()
- */
-void ucx_list_free_a(UcxAllocator *allocator, UcxList *list);
-
-/**
- * Destroys the contents of the specified list by calling the specified
- * destructor on each of them.
- * 
- * Note, that the contents are not usable afterwards and the list should be
- * destroyed with ucx_list_free().
- *
- * If no destructor is specified (<code>NULL</code>), stdlib's free() is used.
- * 
- * @param list the list for which the contents shall be freed
- * @param destr optional destructor function
- * @see ucx_list_free()
- */
-void ucx_list_free_content(UcxList* list, ucx_destructor destr);
-
-
-/**
- * Inserts an element at the end of the list.
- * 
- * This is generally an O(n) operation, as the end of the list is retrieved with
- * ucx_list_last().
- * 
- * @param list the list where to append the data, or <code>NULL</code> to
- * create a new list
- * @param data the data to insert
- * @return <code>list</code>, if it is not <code>NULL</code> or a pointer to
- * the newly created list otherwise
- */
-UcxList *ucx_list_append(UcxList *list, void *data);
-
-/**
- * Inserts an element at the end of the list using a UcxAllocator.
- * 
- * See ucx_list_append() for details.
- * 
- * @param allocator the allocator to use
- * @param list the list where to append the data, or <code>NULL</code> to
- * create a new list
- * @param data the data to insert
- * @return <code>list</code>, if it is not <code>NULL</code> or a pointer to
- * the newly created list otherwise
- * @see ucx_list_append()
- */
-UcxList *ucx_list_append_a(UcxAllocator *allocator, UcxList *list, void *data);
-
-
-/**
- * Inserts an element at the beginning of the list.
- * 
- * You <i>should</i> overwrite the old list pointer by calling
- * <code>mylist = ucx_list_prepend(mylist, mydata);</code>. However, you may
- * also perform successive calls of ucx_list_prepend() on the same list pointer,
- * as this function always searchs for the head of the list with
- * ucx_list_first().
- * 
- * @param list the list where to insert the data or <code>NULL</code> to create
- * a new list
- * @param data the data to insert
- * @return a pointer to the new list head
- */
-UcxList *ucx_list_prepend(UcxList *list, void *data);
-
-/**
- * Inserts an element at the beginning of the list using a UcxAllocator.
- * 
- * See ucx_list_prepend() for details.
- * 
- * @param allocator the allocator to use
- * @param list the list where to insert the data or <code>NULL</code> to create
- * a new list
- * @param data the data to insert
- * @return a pointer to the new list head
- * @see ucx_list_prepend()
- */
-UcxList *ucx_list_prepend_a(UcxAllocator *allocator, UcxList *list, void *data);
-
-/**
- * Concatenates two lists.
- * 
- * Either of the two arguments may be <code>NULL</code>.
- * 
- * This function modifies the references to the next/previous element of
- * the last/first element of <code>list1</code>/<code>
- * list2</code>.
- * 
- * @param list1 first list
- * @param list2 second list
- * @return if <code>list1</code> is <code>NULL</code>, <code>list2</code> is
- * returned, otherwise <code>list1</code> is returned
- */
-UcxList *ucx_list_concat(UcxList *list1, UcxList *list2);
-
-/**
- * Returns the first element of a list.
- * 
- * If the argument is the list pointer, it is directly returned. Otherwise
- * this function traverses to the first element of the list and returns the
- * list pointer.
- * 
- * @param elem one element of the list
- * @return the first element of the list, the specified element is a member of
- */
-UcxList *ucx_list_first(const UcxList *elem);
-
-/**
- * Returns the last element of a list.
- * 
- * If the argument has no successor, it is the last element and therefore
- * directly returned. Otherwise this function traverses to the last element of
- * the list and returns it.
- * 
- * @param elem one element of the list
- * @return the last element of the list, the specified element is a member of
- */
-UcxList *ucx_list_last(const UcxList *elem);
-
-/**
- * Returns the list element at the specified index.
- * 
- * @param list the list to retrieve the element from
- * @param index index of the element to return
- * @return the element at the specified index or <code>NULL</code>, if the
- * index is greater than the list size
- */
-UcxList *ucx_list_get(const UcxList *list, size_t index);
-
-/**
- * Returns the index of an element.
- * 
- * @param list the list where to search for the element
- * @param elem the element to find
- * @return the index of the element or -1 if the list does not contain the
- * element
- */
-ssize_t ucx_list_indexof(const UcxList *list, const UcxList *elem);
-
-/**
- * Returns the element count of the list.
- * 
- * @param list the list whose elements are counted
- * @return the element count
- */
-size_t ucx_list_size(const UcxList *list);
-
-/**
- * Returns the index of an element containing the specified data.
- *
- * This function uses a cmp_func() to compare the data of each list element
- * with the specified data. If no cmp_func is provided, the pointers are
- * compared.
- * 
- * If the list contains the data more than once, the index of the first
- * occurrence is returned.
- *  
- * @param list the list where to search for the data
- * @param elem the element data
- * @param cmpfnc the compare function
- * @param data additional data for the compare function
- * @return the index of the element containing the specified data or -1 if the
- * data is not found in this list
- */
-ssize_t ucx_list_find(const UcxList *list, void *elem,
-    cmp_func cmpfnc, void *data);
-
-/**
- * Checks, if a list contains a specific element.
- * 
- * An element is found, if ucx_list_find() returns a value greater than -1.
- * 
- * @param list the list where to search for the data
- * @param elem the element data
- * @param cmpfnc the compare function
- * @param data additional data for the compare function
- * @return 1, if and only if the list contains the specified element data
- * @see ucx_list_find()
- */
-int ucx_list_contains(const UcxList *list, void *elem,
-    cmp_func cmpfnc, void *data);
-
-/**
- * Sorts a UcxList with natural merge sort.
- * 
- * This function uses O(n) additional temporary memory for merge operations
- * that is automatically freed after each merge.
- * 
- * As the head of the list might change, you <b>MUST</b> call this function
- * as follows: <code>mylist = ucx_list_sort(mylist, mycmpfnc, mydata);</code>.
- * 
- * @param list the list to sort
- * @param cmpfnc the function that shall be used to compare the element data
- * @param data additional data for the cmp_func()
- * @return the sorted list
- */
-UcxList *ucx_list_sort(UcxList *list, cmp_func cmpfnc, void *data);
-
-/**
- * Removes an element from the list.
- * 
- * If the first element is removed, the list pointer changes. So it is
- * <i>highly recommended</i> to <i>always</i> update the pointer by calling
- * <code>mylist = ucx_list_remove(mylist, myelem);</code>.
- * 
- * @param list the list from which the element shall be removed
- * @param element the element to remove
- * @return returns the updated list pointer or <code>NULL</code>, if the list
- * is now empty
- */
-UcxList *ucx_list_remove(UcxList *list, UcxList *element);
-
-/**
- * Removes an element from the list using a UcxAllocator.
- * 
- * See ucx_list_remove() for details.
- * 
- * @param allocator the allocator to use
- * @param list the list from which the element shall be removed
- * @param element the element to remove
- * @return returns the updated list pointer or <code>NULL</code>, if the list
- * @see ucx_list_remove()
- */
-UcxList *ucx_list_remove_a(UcxAllocator *allocator, UcxList *list,
-        UcxList *element);
-
-/**
- * Returns the union of two lists.
- * 
- * The union is a list of unique elements regarding cmpfnc obtained from
- * both source lists.
- * 
- * @param left the left source list
- * @param right the right source list
- * @param cmpfnc a function to compare elements
- * @param cmpdata additional data for the compare function
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new list containing the union
- */
-UcxList* ucx_list_union(const UcxList *left, const UcxList *right,
-    cmp_func cmpfnc, void* cmpdata,
-    copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the union of two lists.
- * 
- * The union is a list of unique elements regarding cmpfnc obtained from
- * both source lists.
- * 
- * @param allocator allocates the new list elements
- * @param left the left source list
- * @param right the right source list
- * @param cmpfnc a function to compare elements
- * @param cmpdata additional data for the compare function
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new list containing the union
- */
-UcxList* ucx_list_union_a(UcxAllocator *allocator,
-    const UcxList *left, const UcxList *right,
-    cmp_func cmpfnc, void* cmpdata,
-    copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the intersection of two lists.
- * 
- * The intersection contains all elements of the left list
- * (including duplicates) that can be found in the right list.
- * 
- * @param left the left source list
- * @param right the right source list
- * @param cmpfnc a function to compare elements
- * @param cmpdata additional data for the compare function
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new list containing the intersection
- */
-UcxList* ucx_list_intersection(const UcxList *left, const UcxList *right,
-    cmp_func cmpfnc, void* cmpdata,
-    copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the intersection of two lists.
- * 
- * The intersection contains all elements of the left list
- * (including duplicates) that can be found in the right list.
- * 
- * @param allocator allocates the new list elements
- * @param left the left source list
- * @param right the right source list
- * @param cmpfnc a function to compare elements
- * @param cmpdata additional data for the compare function
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new list containing the intersection
- */
-UcxList* ucx_list_intersection_a(UcxAllocator *allocator,
-    const UcxList *left, const UcxList *right,
-    cmp_func cmpfnc, void* cmpdata,
-    copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the difference of two lists.
- * 
- * The difference contains all elements of the left list
- * (including duplicates) that are not equal to any element of the right list.
- * 
- * @param left the left source list
- * @param right the right source list
- * @param cmpfnc a function to compare elements
- * @param cmpdata additional data for the compare function
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new list containing the difference
- */
-UcxList* ucx_list_difference(const UcxList *left, const UcxList *right,
-    cmp_func cmpfnc, void* cmpdata,
-    copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the difference of two lists.
- * 
- * The difference contains all elements of the left list
- * (including duplicates) that are not equal to any element of the right list.
- * 
- * @param allocator allocates the new list elements
- * @param left the left source list
- * @param right the right source list
- * @param cmpfnc a function to compare elements
- * @param cmpdata additional data for the compare function
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new list containing the difference
- */
-UcxList* ucx_list_difference_a(UcxAllocator *allocator,
-    const UcxList *left, const UcxList *right,
-    cmp_func cmpfnc, void* cmpdata,
-    copy_func cpfnc, void* cpdata);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_LIST_H */
-
--- a/ucx/ucx/logging.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * Logging API.
- * 
- * @file   logging.h
- * @author Mike Becker, Olaf Wintermann
- */
-#ifndef UCX_LOGGING_H
-#define UCX_LOGGING_H
-
-#include "ucx.h"
-#include "map.h"
-#include "string.h"
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* leave enough space for custom log levels */
-
-/** Log level for error messages. */
-#define UCX_LOGGER_ERROR        0x00
-    
-/** Log level for warning messages. */
-#define UCX_LOGGER_WARN         0x10
-
-/** Log level for information messages. */
-#define UCX_LOGGER_INFO         0x20
-
-/** Log level for debug messages. */
-#define UCX_LOGGER_DEBUG        0x30
-
-/** Log level for trace messages. */
-#define UCX_LOGGER_TRACE        0x40
-
-/**
- * Output flag for the log level. 
- * If this flag is set, the log message will contain the log level.
- * @see UcxLogger.mask
- */
-#define UCX_LOGGER_LEVEL        0x01
-
-/**
- * Output flag for the timestmap.
- * If this flag is set, the log message will contain the timestmap.
- * @see UcxLogger.mask
- */
-#define UCX_LOGGER_TIMESTAMP    0x02
-
-/**
- * Output flag for the source.
- * If this flag is set, the log message will contain the source file and line
- * number.
- * @see UcxLogger.mask
- */
-#define UCX_LOGGER_SOURCE       0x04
-
-/**
- * The UCX Logger object.
- */
-typedef struct {
-    /** The stream this logger writes its messages to.*/
-    void *stream;
-
-    /**
-     * The write function that shall be used.
-     * For standard file or stdout loggers this might be standard fwrite
-     * (default).
-     */
-    write_func writer;
-
-    /**
-     * The date format for timestamp outputs including the delimiter
-     * (default: <code>"%F %T %z "</code>).
-     * @see UCX_LOGGER_TIMESTAMP
-     */
-    char *dateformat;
-
-    /**
-     * The level, this logger operates on.
-     * If a log command is issued, the message will only be logged, if the log
-     * level of the message is less or equal than the log level of the logger.
-     */
-    unsigned int level;
-
-    /**
-     * A configuration mask for automatic output. 
-     * For each flag that is set, the logger automatically outputs some extra
-     * information like the timestamp or the source file and line number.
-     * See the documentation for the flags for details.
-     */
-    unsigned int mask;
-
-    /**
-     * A map of valid log levels for this logger.
-     * 
-     * The keys represent all valid log levels and the values provide string
-     * representations, that are used, if the UCX_LOGGER_LEVEL flag is set.
-     * 
-     * The exact data types are <code>unsigned int</code> for the key and
-     * <code>const char*</code> for the value.
-     * 
-     * @see UCX_LOGGER_LEVEL
-     */
-    UcxMap* levels;
-} UcxLogger;
-
-/**
- * Creates a new logger.
- * @param stream the stream, which the logger shall write to
- * @param level the level on which the logger shall operate
- * @param mask configuration mask (cf. UcxLogger.mask)
- * @return a new logger object
- */
-UcxLogger *ucx_logger_new(void *stream, unsigned int level, unsigned int mask);
-
-/**
- * Destroys the logger.
- * 
- * The map containing the valid log levels is also automatically destroyed.
- * 
- * @param logger the logger to destroy
- */
-void ucx_logger_free(UcxLogger* logger);
-
-/**
- * Internal log function - use macros instead.
- * 
- * This function uses the <code>format</code> and variadic arguments for a
- * printf()-style output of the log message.
- * 
- * Dependent on the UcxLogger.mask some information is prepended. The complete
- * format is:
- * 
- * <code>[LEVEL] [TIMESTAMP] [SOURCEFILE]:[LINENO] message</code>
- *
- * The source file name is reduced to the actual file name. This is necessary to
- * get consistent behavior over different definitions of the __FILE__ macro.
- *
- * <b>Attention:</b> the message (including automatically generated information)
- * is limited to 4096 characters. The level description is limited to
- * 256 characters and the timestamp string is limited to 128 characters.
- * 
- * @param logger the logger to use
- * @param level the level to log on
- * @param file information about the source file
- * @param line information about the source line number
- * @param format format string
- * @param ... arguments
- * @see ucx_logger_log()
- */
-void ucx_logger_logf(UcxLogger *logger, unsigned int level, const char* file,
-        const unsigned int line, const char* format, ...);
-
-/**
- * Registers a custom log level.
- * @param logger the logger
- * @param level the log level as unsigned integer
- * @param name a string literal describing the level
- */
-#define ucx_logger_register_level(logger, level, name) {\
-        unsigned int l; \
-            l = level; \
-            ucx_map_int_put(logger->levels, l, (void*) "[" name "]"); \
-        } while (0);
-
-/**
- * Logs a message at the specified level.
- * @param logger the logger to use
- * @param level the level to log the message on
- * @param ... format string and arguments
- * @see ucx_logger_logf()
- */
-#define ucx_logger_log(logger, level, ...) \
-    ucx_logger_logf(logger, level, __FILE__, __LINE__, __VA_ARGS__)
-
-/**
- * Shortcut for logging an error message.
- * @param logger the logger to use
- * @param ... format string and arguments
- * @see ucx_logger_logf()
- */
-#define ucx_logger_error(logger, ...) \
-    ucx_logger_log(logger, UCX_LOGGER_ERROR, __VA_ARGS__)
-
-/**
- * Shortcut for logging an information message.
- * @param logger the logger to use
- * @param ... format string and arguments
- * @see ucx_logger_logf()
- */
-#define ucx_logger_info(logger, ...) \
-    ucx_logger_log(logger, UCX_LOGGER_INFO, __VA_ARGS__)
-
-/**
- * Shortcut for logging a warning message.
- * @param logger the logger to use
- * @param ... format string and arguments
- * @see ucx_logger_logf()
- */
-#define ucx_logger_warn(logger, ...) \
-    ucx_logger_log(logger, UCX_LOGGER_WARN, __VA_ARGS__)
-
-/**
- * Shortcut for logging a debug message.
- * @param logger the logger to use
- * @param ... format string and arguments
- * @see ucx_logger_logf()
- */
-#define ucx_logger_debug(logger, ...) \
-    ucx_logger_log(logger, UCX_LOGGER_DEBUG, __VA_ARGS__)
-
-/**
- * Shortcut for logging a trace message.
- * @param logger the logger to use
- * @param ... format string and arguments
- * @see ucx_logger_logf()
- */
-#define ucx_logger_trace(logger, ...) \
-    ucx_logger_log(logger, UCX_LOGGER_TRACE, __VA_ARGS__)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* UCX_LOGGING_H */
--- a/ucx/ucx/map.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,549 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file map.h
- * 
- * Hash map implementation.
- * 
- * This implementation uses murmur hash 2 and separate chaining with linked
- * lists.
- * 
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_MAP_H
-#define	UCX_MAP_H
-
-#include "ucx.h"
-#include "string.h"
-#include "allocator.h"
-#include <stdio.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * Loop statement for UCX maps.
- * 
- * The <code>key</code> variable is implicitly defined, but the
- * <code>value</code> variable must be already declared as type information
- * cannot be inferred.
- * 
- * @param key the variable name for the key
- * @param value the variable name for the value
- * @param iter a UcxMapIterator
- * @see ucx_map_iterator()
- */
-#define UCX_MAP_FOREACH(key,value,iter) \
-        for(UcxKey key;ucx_map_iter_next(&iter,&key, (void**)&value);)
-
-/** Type for the UCX map. @see UcxMap */
-typedef struct UcxMap          UcxMap;
-
-/** Type for a key of a UcxMap. @see UcxKey */
-typedef struct UcxKey          UcxKey;
-
-/** Type for an element of a UcxMap. @see UcxMapElement */
-typedef struct UcxMapElement   UcxMapElement;
-
-/** Type for an iterator over a UcxMap. @see UcxMapIterator */
-typedef struct UcxMapIterator  UcxMapIterator;
-
-/** Structure for the UCX map. */
-struct UcxMap {
-    /** An allocator that is used for the map elements. */
-    UcxAllocator  *allocator;
-    /** The array of map element lists. */
-    UcxMapElement **map;
-    /** The size of the map is the length of the element list array. */
-    size_t        size;
-    /** The count of elements currently stored in this map. */
-    size_t        count;
-};
-
-/** Structure to publicly denote a key of a UcxMap. */
-struct UcxKey {
-    /** The key data. */
-    const void *data;
-    /** The length of the key data. */
-    size_t     len;
-    /** A cache for the hash value of the key data. */
-    int        hash;
-};
-
-/** Internal structure for a key of a UcxMap. */
-struct UcxMapKey {
-    /** The key data. */
-    void    *data;
-    /** The length of the key data. */
-    size_t  len;
-    /** The hash value of the key data. */
-    int     hash;
-};
-
-/** Structure for an element of a UcxMap. */
-struct UcxMapElement {
-    /** The value data. */
-    void              *data;
-    
-    /** A pointer to the next element in the current list. */
-    UcxMapElement     *next;
-    
-    /** The corresponding key. */
-    struct UcxMapKey  key;
-};
-
-/** Structure for an iterator over a UcxMap. */
-struct UcxMapIterator {
-    /** The map to iterate over. */
-    UcxMap const  *map;
-    
-    /** The current map element. */
-    UcxMapElement *cur;
-    
-    /**
-     * The current index of the element list array.
-     * <b>Attention: </b> this is <b>NOT</b> the element index! Do <b>NOT</b>
-     * manually iterate over the map by increasing this index. Use
-     * ucx_map_iter_next().
-     * @see UcxMap.map*/
-    size_t        index;
-};
-
-/**
- * Creates a new hash map with the specified size.
- * @param size the size of the hash map
- * @return a pointer to the new hash map
- */
-UcxMap *ucx_map_new(size_t size);
-
-/**
- * Creates a new hash map with the specified size using a UcxAllocator.
- * @param allocator the allocator to use
- * @param size the size of the hash map
- * @return a pointer to the new hash map
- */
-UcxMap *ucx_map_new_a(UcxAllocator *allocator, size_t size);
-
-/**
- * Frees a hash map.
- * 
- * <b>Note:</b> the contents are <b>not</b> freed, use ucx_map_free_content()
- * before calling this function to achieve that.
- * 
- * @param map the map to be freed
- * @see ucx_map_free_content()
- */
-void ucx_map_free(UcxMap *map);
-
-/**
- * Frees the contents of a hash map.
- * 
- * This is a convenience function that iterates over the map and passes all
- * values to the specified destructor function.
- * 
- * If no destructor is specified (<code>NULL</code>), the free() function of
- * the map's own allocator is used.
- * 
- * You must ensure, that it is valid to pass each value in the map to the same
- * destructor function.
- * 
- * You should free or clear the map afterwards, as the contents will be invalid.
- * 
- * @param map for which the contents shall be freed
- * @param destr optional pointer to a destructor function
- * @see ucx_map_free()
- * @see ucx_map_clear()
- */
-void ucx_map_free_content(UcxMap *map, ucx_destructor destr);
-
-/**
- * Clears a hash map.
- * 
- * <b>Note:</b> the contents are <b>not</b> freed, use ucx_map_free_content()
- * before calling this function to achieve that.
- * 
- * @param map the map to be cleared
- * @see ucx_map_free_content()
- */
-void ucx_map_clear(UcxMap *map);
-
-
-/**
- * Copies contents from a map to another map using a copy function.
- * 
- * <b>Note:</b> The destination map does not need to be empty. However, if it
- * contains data with keys that are also present in the source map, the contents
- * are overwritten.
- * 
- * @param from the source map
- * @param to the destination map
- * @param fnc the copy function or <code>NULL</code> if the pointer address
- * shall be copied
- * @param data additional data for the copy function
- * @return 0 on success or a non-zero value on memory allocation errors
- */
-int ucx_map_copy(UcxMap const *from, UcxMap *to, copy_func fnc, void *data);
-
-/**
- * Clones the map and rehashes if necessary.
- * 
- * <b>Note:</b> In contrast to ucx_map_rehash() the load factor is irrelevant.
- * This function <i>always</i> ensures a new UcxMap.size of at least
- * 2.5*UcxMap.count.
- * 
- * @param map the map to clone
- * @param fnc the copy function to use or <code>NULL</code> if the new and
- * the old map shall share the data pointers
- * @param data additional data for the copy function
- * @return the cloned map
- * @see ucx_map_copy()
- */
-UcxMap *ucx_map_clone(UcxMap const *map, copy_func fnc, void *data);
-
-/**
- * Clones the map and rehashes if necessary.
- *
- * <b>Note:</b> In contrast to ucx_map_rehash() the load factor is irrelevant.
- * This function <i>always</i> ensures a new UcxMap.size of at least
- * 2.5*UcxMap.count.
- *
- * @param allocator the allocator to use for the cloned map
- * @param map the map to clone
- * @param fnc the copy function to use or <code>NULL</code> if the new and
- * the old map shall share the data pointers
- * @param data additional data for the copy function
- * @return the cloned map
- * @see ucx_map_copy()
- */
-UcxMap *ucx_map_clone_a(UcxAllocator *allocator,
-                        UcxMap const *map, copy_func fnc, void *data);
-
-/**
- * Increases size of the hash map, if necessary.
- * 
- * The load value is 0.75*UcxMap.size. If the element count exceeds the load
- * value, the map needs to be rehashed. Otherwise no action is performed and
- * this function simply returns 0.
- * 
- * The rehashing process ensures, that the UcxMap.size is at least
- * 2.5*UcxMap.count. So there is enough room for additional elements without
- * the need of another soon rehashing.
- * 
- * You can use this function to dramatically increase access performance.
- * 
- * @param map the map to rehash
- * @return 1, if a memory allocation error occurred, 0 otherwise
- */
-int ucx_map_rehash(UcxMap *map);
-
-/**
- * Puts a key/value-pair into the map.
- * 
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- */
-int ucx_map_put(UcxMap *map, UcxKey key, void *value);
-
-/**
- * Retrieves a value by using a key.
- * 
- * @param map the map
- * @param key the key
- * @return the value
- */
-void* ucx_map_get(UcxMap const *map, UcxKey key);
-
-/**
- * Removes a key/value-pair from the map by using the key.
- * 
- * @param map the map
- * @param key the key
- * @return the removed value
- */
-void* ucx_map_remove(UcxMap *map, UcxKey key);
-
-/**
- * Shorthand for putting data with a sstr_t key into the map.
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- * @see ucx_map_put()
- */
-#define ucx_map_sstr_put(map, key, value) \
-    ucx_map_put(map, ucx_key(key.ptr, key.length), (void*)value)
-
-/**
- * Shorthand for putting data with a C string key into the map.
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- * @see ucx_map_put()
- */
-#define ucx_map_cstr_put(map, key, value) \
-    ucx_map_put(map, ucx_key(key, strlen(key)), (void*)value)
-
-/**
- * Shorthand for putting data with an integer key into the map.
- * @param map the map
- * @param key the key
- * @param value the value
- * @return 0 on success, non-zero value on failure
- * @see ucx_map_put()
- */
-#define ucx_map_int_put(map, key, value) \
-    ucx_map_put(map, ucx_key(&key, sizeof(key)), (void*)value)
-
-/**
- * Shorthand for getting data from the map with a sstr_t key.
- * @param map the map
- * @param key the key
- * @return the value
- * @see ucx_map_get()
- */
-#define ucx_map_sstr_get(map, key) \
-    ucx_map_get(map, ucx_key(key.ptr, key.length))
-
-/**
- * Shorthand for getting data from the map with a C string key.
- * @param map the map
- * @param key the key
- * @return the value
- * @see ucx_map_get()
- */
-#define ucx_map_cstr_get(map, key) \
-    ucx_map_get(map, ucx_key(key, strlen(key)))
-
-/**
- * Shorthand for getting data from the map with an integer key.
- * @param map the map
- * @param key the key
- * @return the value
- * @see ucx_map_get()
- */
-#define ucx_map_int_get(map, key) \
-    ucx_map_get(map, ucx_key(&key, sizeof(int)))
-
-/**
- * Shorthand for removing data from the map with a sstr_t key.
- * @param map the map
- * @param key the key
- * @return the removed value
- * @see ucx_map_remove()
- */
-#define ucx_map_sstr_remove(map, key) \
-    ucx_map_remove(map, ucx_key(key.ptr, key.length))
-
-/**
- * Shorthand for removing data from the map with a C string key.
- * @param map the map
- * @param key the key
- * @return the removed value
- * @see ucx_map_remove()
- */
-#define ucx_map_cstr_remove(map, key) \
-    ucx_map_remove(map, ucx_key(key, strlen(key)))
-
-/**
- * Shorthand for removing data from the map with an integer key.
- * @param map the map
- * @param key the key
- * @return the removed value
- * @see ucx_map_remove()
- */
-#define ucx_map_int_remove(map, key) \
-    ucx_map_remove(map, ucx_key(&key, sizeof(key)))
-
-/**
- * Creates a UcxKey based on the given data.
- * 
- * This function implicitly computes the hash.
- * 
- * @param data the data for the key
- * @param len the length of the data
- * @return a UcxKey with implicitly computed hash
- * @see ucx_hash()
- */
-UcxKey ucx_key(const void *data, size_t len);
-
-/**
- * Computes a murmur hash-2.
- * 
- * @param data the data to hash
- * @param len the length of the data
- * @return the murmur hash-2 of the data
- */
-int ucx_hash(const char *data, size_t len);
-
-/**
- * Creates an iterator for a map.
- * 
- * <b>Note:</b> A UcxMapIterator iterates over all elements in all element
- * lists successively. Therefore the order highly depends on the key hashes and
- * may vary under different map sizes. So generally you may <b>NOT</b> rely on
- * the iteration order.
- * 
- * <b>Note:</b> The iterator is <b>NOT</b> initialized. You need to call
- * ucx_map_iter_next() at least once before accessing any information. However,
- * it is not recommended to access the fields of a UcxMapIterator directly.
- * 
- * @param map the map to create the iterator for
- * @return an iterator initialized on the first element of the
- * first element list
- * @see ucx_map_iter_next()
- */
-UcxMapIterator ucx_map_iterator(UcxMap const *map);
-
-/**
- * Proceeds to the next element of the map (if any).
- * 
- * Subsequent calls on the same iterator proceed to the next element and
- * store the key/value-pair into the memory specified as arguments of this
- * function.
- * 
- * If no further elements are found, this function returns zero and leaves the
- * last found key/value-pair in memory.
- * 
- * @param iterator the iterator to use
- * @param key a pointer to the memory where to store the key
- * @param value a pointer to the memory where to store the value
- * @return 1, if another element was found, 0 if all elements has been processed
- * @see ucx_map_iterator()
- */
-int ucx_map_iter_next(UcxMapIterator *iterator, UcxKey *key, void **value);
-
-/**
- * Returns the union of two maps.
- *
- * The union is a fresh map which is filled by two successive calls of
- * ucx_map_copy() on the two input maps.
- *
- * @param first the first source map
- * @param second the second source map
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new map containing the union
- */
-UcxMap* ucx_map_union(const UcxMap *first, const UcxMap *second,
-                      copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the union of two maps.
- *
- * The union is a fresh map which is filled by two successive calls of
- * ucx_map_copy() on the two input maps.
- *
- * @param allocator the allocator that shall be used by the new map
- * @param first the first source map
- * @param second the second source map
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new map containing the union
- */
-UcxMap* ucx_map_union_a(UcxAllocator *allocator,
-                        const UcxMap *first, const UcxMap *second,
-                        copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the intersection of two maps.
- *
- * The intersection is defined as a copy of the first map with every element
- * removed that has no valid key in the second map.
- *
- * @param first the first source map
- * @param second the second source map
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new map containing the intersection
- */
-UcxMap* ucx_map_intersection(const UcxMap *first, const UcxMap *second,
-                             copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the intersection of two maps.
- *
- * The intersection is defined as a copy of the first map with every element
- * removed that has no valid key in the second map.
- *
- * @param allocator the allocator that shall be used by the new map
- * @param first the first source map
- * @param second the second source map
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new map containing the intersection
- */
-UcxMap* ucx_map_intersection_a(UcxAllocator *allocator,
-                               const UcxMap *first, const UcxMap *second,
-                               copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the difference of two maps.
- *
- * The difference contains a copy of all elements of the first map
- * for which the corresponding keys cannot be found in the second map.
- *
- * @param first the first source map
- * @param second the second source map
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new list containing the difference
- */
-UcxMap* ucx_map_difference(const UcxMap *first, const UcxMap *second,
-                           copy_func cpfnc, void* cpdata);
-
-/**
- * Returns the difference of two maps.
- *
- * The difference contains a copy of all elements of the first map
- * for which the corresponding keys cannot be found in the second map.
- *
- * @param allocator the allocator that shall be used by the new map
- * @param first the first source map
- * @param second the second source map
- * @param cpfnc a function to copy the elements
- * @param cpdata additional data for the copy function
- * @return a new list containing the difference
- */
-UcxMap* ucx_map_difference_a(UcxAllocator *allocator,
-                             const UcxMap *first, const UcxMap *second,
-                             copy_func cpfnc, void* cpdata);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_MAP_H */
-
--- a/ucx/ucx/mempool.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file mempool.h
- * 
- * Memory pool implementation.
- * 
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_MEMPOOL_H
-#define	UCX_MEMPOOL_H
-
-#include "ucx.h"
-#include "allocator.h"
-#include <stddef.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * UCX mempool structure.
- */
-typedef struct {
-    /** UcxAllocator based on this pool */
-    UcxAllocator *allocator;
-    
-    /** List of pointers to pooled memory. */
-    void         **data;
-    
-    /** Count of pooled memory items. */
-    size_t       ndata;
-    
-    /** Memory pool size. */
-    size_t       size;
-} UcxMempool;
-
-/** Shorthand for a new default memory pool with a capacity of 16 elements. */
-#define ucx_mempool_new_default() ucx_mempool_new(16)
-
-
-/**
- * Creates a memory pool with the specified initial size.
- * 
- * As the created memory pool automatically grows in size by factor two when
- * trying to allocate memory on a full pool, it is recommended that you use
- * a power of two for the initial size.
- * 
- * @param n initial pool size (should be a power of two, e.g. 16)
- * @return a pointer to the new memory pool
- * @see ucx_mempool_new_default()
- */
-UcxMempool *ucx_mempool_new(size_t n);
-
-/**
- * Resizes a memory pool.
- * 
- * This function will fail if the new capacity is not sufficient for the
- * present data.
- * 
- * @param pool the pool to resize
- * @param newcap the new capacity
- * @return zero on success or non-zero on failure
- */
-int ucx_mempool_chcap(UcxMempool *pool, size_t newcap);
-
-/**
- * Allocates pooled memory.
- * 
- * @param pool the memory pool
- * @param n amount of memory to allocate
- * @return a pointer to the allocated memory
- * @see ucx_allocator_malloc()
- */
-void *ucx_mempool_malloc(UcxMempool *pool, size_t n);
-/**
- * Allocates a pooled memory array.
- * 
- * The content of the allocated memory is set to zero.
- * 
- * @param pool the memory pool
- * @param nelem amount of elements to allocate
- * @param elsize amount of memory per element
- * @return a pointer to the allocated memory
- * @see ucx_allocator_calloc()
- */
-void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize);
-
-/**
- * Reallocates pooled memory.
- * 
- * If the memory to be reallocated is not contained by the specified pool, the
- * behavior is undefined.
- * 
- * @param pool the memory pool
- * @param ptr a pointer to the memory that shall be reallocated
- * @param n the new size of the memory
- * @return a pointer to the new location of the memory
- * @see ucx_allocator_realloc()
- */
-void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n);
-
-/**
- * Frees pooled memory.
- * 
- * Before freeing the memory, the specified destructor function (if any)
- * is called.
- * 
- * If you specify memory, that is not pooled by the specified memory pool, the
- * program will terminate with a call to <code>abort()</code>.
- * 
- * @param pool the memory pool
- * @param ptr a pointer to the memory that shall be freed
- * @see ucx_mempool_set_destr()
- */
-void ucx_mempool_free(UcxMempool *pool, void *ptr);
-
-/**
- * Destroys a memory pool.
- * 
- * For each element the destructor function (if any) is called and the element
- * is freed.
- * 
- * Each of the registered destructor function that has no corresponding element
- * within the pool (namely those registered by ucx_mempool_reg_destr) is
- * called interleaving with the element destruction, but with guarantee to the
- * order in which they were registered (FIFO order).
- * 
- * 
- * @param pool the mempool to destroy
- */
-void ucx_mempool_destroy(UcxMempool *pool);
-
-/**
- * Sets a destructor function for the specified memory.
- * 
- * The destructor is automatically called when the memory is freed or the
- * pool is destroyed.
- * A destructor for pooled memory <b>MUST NOT</b> free the memory itself,
- * as this is done by the pool. Use a destructor to free any resources
- * managed by the pooled object.
- * 
- * The only requirement for the specified memory is, that it <b>MUST</b> be
- * pooled memory by a UcxMempool or an element-compatible mempool. The pointer
- * to the destructor function is saved in a reserved area before the actual
- * memory.
- * 
- * @param ptr pooled memory
- * @param func a pointer to the destructor function
- * @see ucx_mempool_free()
- * @see ucx_mempool_destroy()
- */
-void ucx_mempool_set_destr(void *ptr, ucx_destructor func);
-
-/**
- * Registers a destructor function for the specified (non-pooled) memory.
- *
- * This is useful, if you have memory that has not been allocated by a mempool,
- * but shall be managed by a mempool.
- * 
- * This function creates an entry in the specified mempool and the memory will
- * therefore (logically) convert to pooled memory.
- * <b>However, this does not cause the memory to be freed automatically!</b>.
- * If you want to use this function, make the memory pool free non-pooled
- * memory, the specified destructor function must call <code>free()</code>
- * by itself. But keep in mind, that you then MUST NOT use this destructor
- * function with pooled memory (e.g. in ucx_mempool_set_destr()), as it
- * would cause a double-free.
- * 
- * @param pool the memory pool
- * @param ptr data the destructor is registered for
- * @param destr a pointer to the destructor function
- */
-void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_MEMPOOL_H */
-
--- a/ucx/ucx/properties.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * @file properties.h
- * 
- * Load / store utilities for properties files.
- * 
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_PROPERTIES_H
-#define	UCX_PROPERTIES_H
-
-#include "ucx.h"
-#include "map.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/**
- * UcxProperties object for parsing properties data.
- * Most of the fields are for internal use only. You may configure the
- * properties parser, e.g. by changing the used delimiter or specifying 
- * up to three different characters that shall introduce comments.
- */
-typedef struct {
-    /**
-     * Input buffer (don't set manually).
-     * Automatically set by calls to ucx_properties_fill().
-     */
-    char   *buffer;
-    
-    /**
-     * Length of the input buffer (don't set manually).
-     * Automatically set by calls to ucx_properties_fill().
-     */
-    size_t buflen;
-    
-    /**
-     * Current buffer position (don't set manually).
-     * Used by ucx_properties_next().
-     */
-    size_t pos;
-    
-    /**
-     * Internal temporary buffer (don't set manually).
-     * Used by ucx_properties_next().
-     */
-    char   *tmp;
-    
-    /**
-     * Internal temporary buffer length (don't set manually).
-     * Used by ucx_properties_next().
-     */
-    size_t tmplen;
-    
-    /**
-     * Internal temporary buffer capacity (don't set manually).
-     * Used by ucx_properties_next().
-     */
-    size_t tmpcap;
-    
-    /**
-     * Parser error code.
-     * This is always 0 on success and a nonzero value on syntax errors.
-     * The value is set by ucx_properties_next().
-     */
-    int    error;
-    
-    /**
-     * The delimiter that shall be used.
-     * This is '=' by default.
-     */
-    char   delimiter;
-    
-    /**
-     * The first comment character.
-     * This is '#' by default.
-     */
-    char   comment1;
-    
-    /**
-     * The second comment character.
-     * This is not set by default.
-     */
-    char   comment2;
-    
-    /**
-     * The third comment character.
-     * This is not set by default.
-     */
-    char   comment3;
-} UcxProperties;
-
-
-/**
- * Constructs a new UcxProperties object.
- * @return a pointer to the new UcxProperties object
- */
-UcxProperties *ucx_properties_new();
-
-/**
- * Destroys a UcxProperties object.
- * @param prop the UcxProperties object to destroy
- */
-void ucx_properties_free(UcxProperties *prop);
-
-/**
- * Sets the input buffer for the properties parser.
- * 
- * After calling this function, you may parse the data by calling
- * ucx_properties_next() until it returns 0. The function ucx_properties2map()
- * is a convenience function that reads as much data as possible by using this
- * function.
- * 
- * 
- * @param prop the UcxProperties object
- * @param buf a pointer to the new buffer
- * @param len the payload length of the buffer
- * @see ucx_properties_next()
- * @see ucx_properties2map()
- */
-void ucx_properties_fill(UcxProperties *prop, char *buf, size_t len);
-
-/**
- * Retrieves the next key/value-pair.
- * 
- * This function returns a nonzero value as long as there are key/value-pairs
- * found. If no more key/value-pairs are found, you may refill the input buffer
- * with ucx_properties_fill().
- * 
- * <b>Attention:</b> the sstr_t.ptr pointers of the output parameters point to
- * memory within the input buffer of the parser and will get invalid some time.
- * If you want long term copies of the key/value-pairs, use sstrdup() after
- * calling this function.
- * 
- * @param prop the UcxProperties object
- * @param name a pointer to the sstr_t that shall contain the property name
- * @param value a pointer to the sstr_t that shall contain the property value
- * @return Nonzero, if a key/value-pair was successfully retrieved
- * @see ucx_properties_fill()
- */
-int ucx_properties_next(UcxProperties *prop, sstr_t *name, sstr_t *value);
-
-/**
- * Retrieves all available key/value-pairs and puts them into a UcxMap.
- * 
- * This is done by successive calls to ucx_properties_next() until no more
- * key/value-pairs can be retrieved.
- * 
- * The memory for the map values is allocated by the map's own allocator.
- * 
- * @param prop the UcxProperties object
- * @param map the target map
- * @return The UcxProperties.error code (i.e. 0 on success).
- * @see ucx_properties_fill()
- * @see UcxMap.allocator
- */
-int ucx_properties2map(UcxProperties *prop, UcxMap *map);
-
-/**
- * Loads a properties file to a UcxMap.
- * 
- * This is a convenience function that reads data from an input
- * stream until the end of the stream is reached.
- * 
- * @param map the map object to write the key/value-pairs to
- * @param file the <code>FILE*</code> stream to read from
- * @return 0 on success, or a non-zero value on error
- * 
- * @see ucx_properties_fill()
- * @see ucx_properties2map()
- */
-int ucx_properties_load(UcxMap *map, FILE *file);
-
-/**
- * Stores a UcxMap to a file.
- * 
- * The key/value-pairs are written by using the following format:
- * 
- * <code>[key] = [value]\\n</code>
- * 
- * @param map the map to store
- * @param file the <code>FILE*</code> stream to write to
- * @return 0 on success, or a non-zero value on error
- */
-int ucx_properties_store(UcxMap *map, FILE *file);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_PROPERTIES_H */
-
--- a/ucx/ucx/stack.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file stack.h
- * 
- * Default stack memory allocation implementation.
- * 
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_STACK_H
-#define	UCX_STACK_H
-
-#include "ucx.h"
-#include "allocator.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-
-/**
- * UCX stack structure.
- */
-typedef struct {
-    /** UcxAllocator based on this stack */
-    UcxAllocator allocator;
-    
-    /** Stack size. */
-    size_t size;
-    
-    /** Pointer to the bottom of the stack */
-    char *space;
-    
-    /** Pointer to the top of the stack */
-    char *top;
-} UcxStack;
-
-/**
- * Metadata for each UCX stack element.
- */
-struct ucx_stack_metadata {
-    /**
-     * Location of the previous element (<code>NULL</code> if this is the first)
-     */
-    char *prev;
-    
-    /** Size of this element */
-    size_t size;
-};
-
-/**
- * Initializes UcxStack structure with memory.
- * 
- * @param stack a pointer to an uninitialized stack structure
- * @param space the memory area that shall be managed
- * @param size size of the memory area
- * @return a new UcxStack structure
- */
-void ucx_stack_init(UcxStack *stack, char* space, size_t size);
-
-/**
- * Allocates stack memory.
- * 
- * @param stack a pointer to the stack
- * @param n amount of memory to allocate
- * @return a pointer to the allocated memory or <code>NULL</code> on stack
- * overflow
- * @see ucx_allocator_malloc()
- */
-void *ucx_stack_malloc(UcxStack *stack, size_t n);
-
-/**
- * Allocates memory with #ucx_stack_malloc() and copies the specified data if
- * the allocation was successful.
- * 
- * @param stack a pointer to the stack
- * @param n amount of memory to allocate
- * @param data a pointer to the data to copy
- * @return a pointer to the allocated memory
- * @see ucx_stack_malloc
- */
-void *ucx_stack_push(UcxStack *stack, size_t n, const void *data);
-
-/**
- * Allocates an array of stack memory
- * 
- * The content of the allocated memory is set to zero.
- * 
- * @param stack a pointer to the stack
- * @param nelem amount of elements to allocate
- * @param elsize amount of memory per element
- * @return a pointer to the allocated memory
- * @see ucx_allocator_calloc()
- */
-void *ucx_stack_calloc(UcxStack *stack, size_t nelem, size_t elsize);
-
-/**
- * Allocates memory with #ucx_stack_calloc() and copies the specified data if
- * the allocation was successful.
- * 
- * @param stack a pointer to the stack
- * @param nelem amount of elements to allocate
- * @param elsize amount of memory per element
- * @param data a pointer to the data
- * @return a pointer to the allocated memory
- * @see ucx_stack_calloc
- */
-void *ucx_stack_pusharr(UcxStack *stack,
-        size_t nelem, size_t elsize, const void *data);
-
-/**
- * Reallocates memory on the stack.
- * 
- * Shrinking memory is always safe. Extending memory can be very expensive. 
- * 
- * @param stack the stack
- * @param ptr a pointer to the memory that shall be reallocated
- * @param n the new size of the memory
- * @return a pointer to the new location of the memory
- * @see ucx_allocator_realloc()
- */
-void *ucx_stack_realloc(UcxStack *stack, void *ptr, size_t n);
-
-/**
- * Frees memory on the stack.
- * 
- * Freeing stack memory behaves in a special way.
- * 
- * If the element, that should be freed, is the top most element of the stack,
- * it is removed from the stack. Otherwise it is marked as freed. Marked
- * elements are removed, when they become the top most elements of the stack.
- * 
- * @param stack a pointer to the stack
- * @param ptr a pointer to the memory that shall be freed
- */
-void ucx_stack_free(UcxStack *stack, void *ptr);
-
-
-/**
- * Returns the size of the top most element.
- * @param stack a pointer to the stack
- * @return the size of the top most element
- */
-#define ucx_stack_topsize(stack) ((stack)->top ? ((struct ucx_stack_metadata*)\
-                                  (stack)->top - 1)->size : 0)
-
-/**
- * Removes the top most element from the stack and copies the content to <code>
- * dest</code>, if specified.
- * 
- * Use #ucx_stack_topsize()# to get the amount of memory that must be available
- * at the location of <code>dest</code>.
- * 
- * @param stack a pointer to the stack
- * @param dest the location where the contents shall be written to, or <code>
- * NULL</code>, if the element shall only be removed.
- * @see ucx_stack_free
- * @see ucx_stack_popn
- */
-#define ucx_stack_pop(stack, dest) ucx_stack_popn(stack, dest, (size_t)-1)
-
-/**
- * Removes the top most element from the stack and copies the content to <code>
- * dest</code>.
- * 
- * This function copies at most <code>n</code> bytes to the destination, but
- * the element is always freed as a whole.
- * If the element was larger than <code>n</code>, the remaining data is lost.
- * 
- * @param stack a pointer to the stack
- * @param dest the location where the contents shall be written to
- * @param n copies at most n bytes to <code>dest</code>
- * @see ucx_stack_pop
- */
-void ucx_stack_popn(UcxStack *stack, void *dest, size_t n);
-
-/**
- * Returns the remaining available memory on the specified stack.
- * 
- * @param stack a pointer to the stack
- * @return the remaining available memory
- */
-size_t ucx_stack_avail(UcxStack *stack);
-
-/**
- * Checks, if the stack is empty.
- * 
- * @param stack a pointer to the stack
- * @return nonzero, if the stack is empty, zero otherwise
- */
-#define ucx_stack_empty(stack) (!(stack)->top)
-
-/**
- * Computes a recommended size for the stack memory area. Note, that
- * reallocations have not been taken into account, so you might need to reserve
- * twice as much memory to allow many reallocations.
- * 
- * @param size the approximate payload
- * @param elems the approximate count of element allocations
- * @return a recommended size for the stack space based on the information
- * provided
- */
-#define ucx_stack_dim(size, elems) (size+sizeof(struct ucx_stack_metadata) * \
-                                    (elems + 1))
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_STACK_H */
-
--- a/ucx/ucx/string.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1201 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * Bounded string implementation.
- * 
- * The UCX strings (<code>sstr_t</code>) provide an alternative to C strings.
- * The main difference to C strings is, that <code>sstr_t</code> does <b>not
- * need to be <code>NULL</code>-terminated</b>. Instead the length is stored
- * within the structure.
- * 
- * When using <code>sstr_t</code>, developers must be full aware of what type
- * of string (<code>NULL</code>-terminated) or not) they are using, when 
- * accessing the <code>char* ptr</code> directly.
- * 
- * The UCX string module provides some common string functions, known from
- * standard libc, working with <code>sstr_t</code>.
- * 
- * @file   string.h
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_STRING_H
-#define	UCX_STRING_H
-
-#include "ucx.h"
-#include "allocator.h"
-#include <stddef.h>
-
-/*
- * Use this macro to disable the shortcuts if you experience macro collision.
- */
-#ifndef UCX_NO_SSTR_SHORTCUTS
-/**
- * Shortcut for a <code>sstr_t struct</code>
- * or <code>scstr_t struct</code> literal.
- */
-#define ST(s) { s, sizeof(s)-1 }
-
-/** Shortcut for the conversion of a C string to a <code>sstr_t</code>. */
-#define S(s) sstrn(s, sizeof(s)-1)
-
-/** Shortcut for the conversion of a C string to a <code>scstr_t</code>. */
-#define SC(s) scstrn(s, sizeof(s)-1)
-#endif /* UCX_NO_SSTR_SHORTCUTS */
-
-/*
- * Use this macro to disable the format macros.
- */
-#ifndef UCX_NO_SSTR_FORMAT_MACROS
-/** Expands a sstr_t or scstr_t to printf arguments. */
-#define SFMT(s) (int) (s).length, (s).ptr
-
-/** Format specifier for a sstr_t or scstr_t. */
-#define PRIsstr ".*s"
-#endif /* UCX_NO_SSTR_FORMAT_MACROS */
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-  
-/**
- * The UCX string structure.
- */
-typedef struct {
-   /** A pointer to the string
-    * (<b>not necessarily <code>NULL</code>-terminated</b>) */
-    char *ptr;
-    /** The length of the string */
-    size_t length;
-} sstr_t;
-
-/**
- * The UCX string structure for immutable (constant) strings.
- */
-typedef struct {
-    /** A constant pointer to the immutable string
-     * (<b>not necessarily <code>NULL</code>-terminated</b>) */
-    const char *ptr;
-    /** The length of the string */
-    size_t length;
-} scstr_t;
-
-#ifdef	__cplusplus
-}
-#endif
-
-
-#ifdef __cplusplus
-/**
- * One of two type adjustment functions that return an scstr_t.
- * 
- * Used <b>internally</b> to convert a UCX string to an immutable UCX string.
- * 
- * <b>Do not use this function manually.</b>
- * 
- * @param str some sstr_t
- * @return an immutable (scstr_t) version of the provided string.
- */
-inline scstr_t s2scstr(sstr_t s) {
-    scstr_t c;
-    c.ptr = s.ptr;
-    c.length = s.length;
-    return c;
-}
-
-/**
- * One of two type adjustment functions that return an scstr_t.
- * 
- * Used <b>internally</b> to convert a UCX string to an immutable UCX string.
- * This variant is used, when the string is already immutable and no operation
- * needs to be performed.
- * 
- * <b>Do not use this function manually.</b>
- * 
- * @param str some scstr_t
- * @return the argument itself
- */
-inline scstr_t s2scstr(scstr_t str) {
-    return str;
-}
-
-/**
- * Converts a UCX string to an immutable UCX string (scstr_t).
- * @param str some UCX string
- * @return an immutable version of the provided string
- */
-#define SCSTR(s) s2scstr(s)
-#else
-
-/**
- * One of two type adjustment functions that return an scstr_t.
- * 
- * Used <b>internally</b> to convert a UCX string to an immutable UCX string.
- * This variant is used, when the string is already immutable and no operation
- * needs to be performed.
- * 
- * <b>Do not use this function manually.</b>
- * 
- * @param str some scstr_t
- * @return the argument itself
- */
-scstr_t ucx_sc2sc(scstr_t str);
-
-/**
- * One of two type adjustment functions that return an scstr_t.
- * 
- * Used <b>internally</b> to convert a UCX string to an immutable UCX string.
- * 
- * <b>Do not use this function manually.</b>
- * 
- * @param str some sstr_t
- * @return an immutable (scstr_t) version of the provided string.
- */
-scstr_t ucx_ss2sc(sstr_t str);
-
-#if __STDC_VERSION__ >= 201112L
-/**
- * Converts a UCX string to an immutable UCX string (scstr_t).
- * @param str some UCX string
- * @return an immutable version of the provided string
- */
-#define SCSTR(str) _Generic(str, sstr_t: ucx_ss2sc, scstr_t: ucx_sc2sc)(str)
-
-#elif defined(__GNUC__) || defined(__clang__)
-
-/**
- * Converts a UCX string to an immutable UCX string (scstr_t).
- * @param str some UCX string
- * @return an immutable version of the provided string
- */
-#define SCSTR(str) __builtin_choose_expr( \
-        __builtin_types_compatible_p(typeof(str), sstr_t), \
-        ucx_ss2sc, \
-        ucx_sc2sc)(str)
-
-#elif defined(__sun)
-
-/**
- * Converts a UCX string to an immutable UCX string (scstr_t).
- * @param str some UCX string
- * @return the an immutable version of the provided string
- */
-#define SCSTR(str) ({typeof(str) ucx_tmp_var_str = str; \
-	scstr_t ucx_tmp_var_c; \
-	ucx_tmp_var_c.ptr = ucx_tmp_var_str.ptr;\
-	ucx_tmp_var_c.length = ucx_tmp_var_str.length;\
-	ucx_tmp_var_c; })
-#else /* no generics and no builtins */
-
-/**
- * Converts a UCX string to an immutable UCX string (scstr_t).
- * 
- * This <b>internal</b> function (ab)uses the C standard an expects one single
- * argument which is then implicitly converted to scstr_t without a warning.
- * 
- * <b>Do not use this function manually.</b>
- * 
- * @return the an immutable version of the provided string
- */
-scstr_t ucx_ss2c_s();
-
-/**
- * Converts a UCX string to an immutable UCX string (scstr_t).
- * @param str some UCX string
- * @return the an immutable version of the provided string
- */
-#define SCSTR(str) ucx_ss2c_s(str)
-#endif /* C11 feature test */
-
-#endif /* C++ */
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-
-/**
- * Creates a new sstr_t based on a C string.
- * 
- * The length is implicitly inferred by using a call to <code>strlen()</code>.
- *
- * <b>Note:</b> the sstr_t will share the specified pointer to the C string.
- * If you do want a copy, use sstrdup() on the return value of this function.
- * 
- * If you need to wrap a constant string, use scstr().
- * 
- * @param cstring the C string to wrap
- * @return a new sstr_t containing the C string
- * 
- * @see sstrn()
- */
-sstr_t sstr(char *cstring);
-
-/**
- * Creates a new sstr_t of the specified length based on a C string.
- *
- * <b>Note:</b> the sstr_t will share the specified pointer to the C string.
- * If you do want a copy, use sstrdup() on the return value of this function.
- * 
- * If you need to wrap a constant string, use scstrn().
- * 
- * @param cstring  the C string to wrap
- * @param length   the length of the string
- * @return a new sstr_t containing the C string
- * 
- * @see sstr()
- * @see S()
- */
-sstr_t sstrn(char *cstring, size_t length);
-
-/**
- * Creates a new scstr_t based on a constant C string.
- * 
- * The length is implicitly inferred by using a call to <code>strlen()</code>.
- *
- * <b>Note:</b> the scstr_t will share the specified pointer to the C string.
- * If you do want a copy, use scstrdup() on the return value of this function.
- * 
- * @param cstring the C string to wrap
- * @return a new scstr_t containing the C string
- * 
- * @see scstrn()
- */
-scstr_t scstr(const char *cstring);
-
-
-/**
- * Creates a new scstr_t of the specified length based on a constant C string.
- *
- * <b>Note:</b> the scstr_t will share the specified pointer to the C string.
- * If you do want a copy, use scstrdup() on the return value of this function. * 
- * 
- * @param cstring  the C string to wrap
- * @param length   the length of the string
- * @return a new scstr_t containing the C string
- * 
- * @see scstr()
- */
-scstr_t scstrn(const char *cstring, size_t length);
-
-/**
- * Returns the accumulated length of all specified strings.
- * 
- * <b>Attention:</b> if the count argument is larger than the count of the
- * specified strings, the behavior is undefined.
- *
- * @param count    the total number of specified strings
- * @param ...      all strings
- * @return the accumulated length of all strings
- */
-size_t scstrnlen(size_t count, ...);
-
-/**
- * Returns the accumulated length of all specified strings.
- * 
- * <b>Attention:</b> if the count argument is larger than the count of the
- * specified strings, the behavior is undefined.
- * 
- * @param count    the total number of specified strings
- * @param ...      all strings
- * @return the cumulated length of all strings
- */
-#define sstrnlen(count, ...) scstrnlen(count, __VA_ARGS__)
-
-/**
- * Concatenates two or more strings.
- * 
- * The resulting string will be allocated by standard <code>malloc()</code>. 
- * So developers <b>MUST</b> pass the sstr_t.ptr to <code>free()</code>.
- * 
- * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
- * terminated.
- *
- * @param count   the total number of strings to concatenate
- * @param s1      first string
- * @param ...     all remaining strings
- * @return the concatenated string
- */
-sstr_t scstrcat(size_t count, scstr_t s1, ...);
-
-/**
- * Concatenates two or more strings.
- * 
- * The resulting string will be allocated by standard <code>malloc()</code>. 
- * So developers <b>MUST</b> pass the sstr_t.ptr to <code>free()</code>.
- * 
- * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
- * terminated.
- * 
- * @param count   the total number of strings to concatenate
- * @param s1      first string
- * @param ...     all remaining strings
- * @return the concatenated string
- */
-#define sstrcat(count, s1, ...) scstrcat(count, SCSTR(s1), __VA_ARGS__)
-
-/**
- * Concatenates two or more strings using a UcxAllocator.
- * 
- * The resulting string must be freed by the allocators <code>free()</code>
- * implementation.
- * 
- * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
- * terminated.
- *
- * @param alloc   the allocator to use
- * @param count   the total number of strings to concatenate
- * @param s1      first string
- * @param ...     all remaining strings
- * @return the concatenated string
- * 
- * @see scstrcat()
- */
-sstr_t scstrcat_a(UcxAllocator *alloc, size_t count, scstr_t s1, ...);
-
-/**
- * Concatenates two or more strings using a UcxAllocator.
- * 
- * The resulting string must be freed by the allocators <code>free()</code>
- * implementation.
- * 
- * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
- * terminated.
- *
- * @param alloc   the allocator to use
- * @param count   the total number of strings to concatenate
- * @param s1      first string
- * @param ...     all remaining strings
- * @return the concatenated string
- * 
- * @see sstrcat()
- */
-#define sstrcat_a(alloc, count, s1, ...) \
-    scstrcat_a(alloc, count, SCSTR(s1), __VA_ARGS__)
-
-/**
- * Returns a substring starting at the specified location.
- * 
- * <b>Attention:</b> the new string references the same memory area as the
- * input string and is <b>NOT</b> required to be <code>NULL</code>-terminated.
- * Use sstrdup() to get a copy.
- * 
- * @param string input string
- * @param start  start location of the substring
- * @return a substring of <code>string</code> starting at <code>start</code>
- * 
- * @see sstrsubsl()
- * @see sstrchr()
- */
-sstr_t sstrsubs(sstr_t string, size_t start);
-
-/**
- * Returns a substring with the given length starting at the specified location.
- * 
- * <b>Attention:</b> the new string references the same memory area as the
- * input string and is <b>NOT</b> required to be <code>NULL</code>-terminated.
- * Use sstrdup() to get a copy.
- * 
- * @param string input string
- * @param start  start location of the substring
- * @param length the maximum length of the substring
- * @return a substring of <code>string</code> starting at <code>start</code>
- * with a maximum length of <code>length</code>
- * 
- * @see sstrsubs()
- * @see sstrchr()
- */
-sstr_t sstrsubsl(sstr_t string, size_t start, size_t length);
-
-/**
- * Returns a substring of an immutable string starting at the specified
- * location.
- * 
- * <b>Attention:</b> the new string references the same memory area as the
-* input string and is <b>NOT</b> required to be <code>NULL</code>-terminated.
- * Use scstrdup() to get a copy.
- * 
- * @param string input string
- * @param start  start location of the substring
- * @return a substring of <code>string</code> starting at <code>start</code>
- * 
- * @see scstrsubsl()
- * @see scstrchr()
- */
-scstr_t scstrsubs(scstr_t string, size_t start);
-
-/**
- * Returns a substring of an immutable string with a maximum length starting
- * at the specified location.
- * 
- * <b>Attention:</b> the new string references the same memory area as the
- * input string and is <b>NOT</b> required to be <code>NULL</code>-terminated.
- * Use scstrdup() to get a copy.
- * 
- * @param string input string
- * @param start  start location of the substring
- * @param length the maximum length of the substring
- * @return a substring of <code>string</code> starting at <code>start</code>
- * with a maximum length of <code>length</code>
- * 
- * @see scstrsubs()
- * @see scstrchr()
- */
-scstr_t scstrsubsl(scstr_t string, size_t start, size_t length);
-
-/**
- * Returns a substring starting at the location of the first occurrence of the
- * specified character.
- * 
- * If the string does not contain the character, an empty string is returned.
- * 
- * @param string the string where to locate the character
- * @param chr    the character to locate
- * @return       a substring starting at the first location of <code>chr</code>
- * 
- * @see sstrsubs()
- */
-sstr_t sstrchr(sstr_t string, int chr);
-
-/**
- * Returns a substring starting at the location of the last occurrence of the
- * specified character.
- * 
- * If the string does not contain the character, an empty string is returned.
- * 
- * @param string the string where to locate the character
- * @param chr    the character to locate
- * @return       a substring starting at the last location of <code>chr</code>
- * 
- * @see sstrsubs()
- */
-sstr_t sstrrchr(sstr_t string, int chr);
-
-/**
- * Returns an immutable substring starting at the location of the first
- * occurrence of the specified character.
- * 
- * If the string does not contain the character, an empty string is returned.
- * 
- * @param string the string where to locate the character
- * @param chr    the character to locate
- * @return       a substring starting at the first location of <code>chr</code>
- * 
- * @see scstrsubs()
- */
-scstr_t scstrchr(scstr_t string, int chr);
-
-/**
- * Returns an immutable substring starting at the location of the last
- * occurrence of the specified character.
- * 
- * If the string does not contain the character, an empty string is returned.
- * 
- * @param string the string where to locate the character
- * @param chr    the character to locate
- * @return       a substring starting at the last location of <code>chr</code>
- * 
- * @see scstrsubs()
- */
-scstr_t scstrrchr(scstr_t string, int chr);
-
-/**
- * Returns a substring starting at the location of the first occurrence of the
- * specified string.
- * 
- * If the string does not contain the other string, an empty string is returned.
- * 
- * If <code>match</code> is an empty string, the complete <code>string</code> is
- * returned.
- * 
- * @param string the string to be scanned
- * @param match  string containing the sequence of characters to match
- * @return       a substring starting at the first occurrence of
- *               <code>match</code>, or an empty string, if the sequence is not
- *               present in <code>string</code>
- */
-sstr_t scstrsstr(sstr_t string, scstr_t match);
-
-/**
- * Returns a substring starting at the location of the first occurrence of the
- * specified string.
- * 
- * If the string does not contain the other string, an empty string is returned.
- * 
- * If <code>match</code> is an empty string, the complete <code>string</code> is
- * returned.
- * 
- * @param string the string to be scanned
- * @param match  string containing the sequence of characters to match
- * @return       a substring starting at the first occurrence of
- *               <code>match</code>, or an empty string, if the sequence is not
- *               present in <code>string</code>
- */
-#define sstrstr(string, match) scstrsstr(string, SCSTR(match))
-
-/**
- * Returns an immutable substring starting at the location of the
- * first occurrence of the specified immutable string.
- * 
- * If the string does not contain the other string, an empty string is returned.
- * 
- * If <code>match</code> is an empty string, the complete <code>string</code> is
- * returned.
- * 
- * @param string the string to be scanned
- * @param match  string containing the sequence of characters to match
- * @return       a substring starting at the first occurrence of
- *               <code>match</code>, or an empty string, if the sequence is not
- *               present in <code>string</code>
- */
-scstr_t scstrscstr(scstr_t string, scstr_t match);
-
-/**
- * Returns an immutable substring starting at the location of the
- * first occurrence of the specified immutable string.
- * 
- * If the string does not contain the other string, an empty string is returned.
- * 
- * If <code>match</code> is an empty string, the complete <code>string</code> is
- * returned.
- * 
- * @param string the string to be scanned
- * @param match  string containing the sequence of characters to match
- * @return       a substring starting at the first occurrence of
- *               <code>match</code>, or an empty string, if the sequence is not
- *               present in <code>string</code>
- */
-#define sstrscstr(string, match) scstrscstr(string, SCSTR(match))
-
-/**
- * Splits a string into parts by using a delimiter string.
- * 
- * This function will return <code>NULL</code>, if one of the following happens:
- * <ul>
- *   <li>the string length is zero</li>
- *   <li>the delimeter length is zero</li>
- *   <li>the string equals the delimeter</li>
- *   <li>memory allocation fails</li>
- * </ul>
- * 
- * The integer referenced by <code>count</code> is used as input and determines
- * the maximum size of the resulting array, i.e. the maximum count of splits to
- * perform + 1.
- * 
- * The integer referenced by <code>count</code> is also used as output and is
- * set to
- * <ul>
- *   <li>-2, on memory allocation errors</li>
- *   <li>-1, if either the string or the delimiter is an empty string</li>
- *   <li>0, if the string equals the delimiter</li>
- *   <li>1, if the string does not contain the delimiter</li>
- *   <li>the count of array items, otherwise</li>
- * </ul>
- * 
- * If the string starts with the delimiter, the first item of the resulting
- * array will be an empty string.
- * 
- * If the string ends with the delimiter and the maximum list size is not
- * exceeded, the last array item will be an empty string.
- * In case the list size would be exceeded, the last array item will be the
- * remaining string after the last split, <i>including</i> the terminating
- * delimiter.
- * 
- * <b>Attention:</b> The array pointer <b>AND</b> all sstr_t.ptr of the array
- * items must be manually passed to <code>free()</code>. Use scstrsplit_a() with
- * an allocator to managed memory, to avoid this.
- *
- * @param string the string to split
- * @param delim  the delimiter string
- * @param count  IN: the maximum size of the resulting array (0 = no limit),
- *               OUT: the actual size of the array
- * @return a sstr_t array containing the split strings or
- * <code>NULL</code> on error
- * 
- * @see scstrsplit_a()
- */
-sstr_t* scstrsplit(scstr_t string, scstr_t delim, ssize_t *count);
-
-/**
- * Splits a string into parts by using a delimiter string.
- * 
- * This function will return <code>NULL</code>, if one of the following happens:
- * <ul>
- *   <li>the string length is zero</li>
- *   <li>the delimeter length is zero</li>
- *   <li>the string equals the delimeter</li>
- *   <li>memory allocation fails</li>
- * </ul>
- * 
- * The integer referenced by <code>count</code> is used as input and determines
- * the maximum size of the resulting array, i.e. the maximum count of splits to
- * perform + 1.
- * 
- * The integer referenced by <code>count</code> is also used as output and is
- * set to
- * <ul>
- *   <li>-2, on memory allocation errors</li>
- *   <li>-1, if either the string or the delimiter is an empty string</li>
- *   <li>0, if the string equals the delimiter</li>
- *   <li>1, if the string does not contain the delimiter</li>
- *   <li>the count of array items, otherwise</li>
- * </ul>
- * 
- * If the string starts with the delimiter, the first item of the resulting
- * array will be an empty string.
- * 
- * If the string ends with the delimiter and the maximum list size is not
- * exceeded, the last array item will be an empty string.
- * In case the list size would be exceeded, the last array item will be the
- * remaining string after the last split, <i>including</i> the terminating
- * delimiter.
- * 
- * <b>Attention:</b> The array pointer <b>AND</b> all sstr_t.ptr of the array
- * items must be manually passed to <code>free()</code>. Use sstrsplit_a() with
- * an allocator to managed memory, to avoid this.
- *
- * @param string the string to split
- * @param delim  the delimiter string
- * @param count  IN: the maximum size of the resulting array (0 = no limit),
- *               OUT: the actual size of the array
- * @return a sstr_t array containing the split strings or
- * <code>NULL</code> on error
- * 
- * @see sstrsplit_a()
- */
-#define sstrsplit(string, delim, count) \
-    scstrsplit(SCSTR(string), SCSTR(delim), count)
-
-/**
- * Performing scstrsplit() using a UcxAllocator.
- * 
- * <i>Read the description of scstrsplit() for details.</i>
- * 
- * The memory for the sstr_t.ptr pointers of the array items and the memory for
- * the sstr_t array itself are allocated by using the UcxAllocator.malloc()
- * function.
- * 
- * @param allocator the UcxAllocator used for allocating memory
- * @param string the string to split
- * @param delim  the delimiter string
- * @param count  IN: the maximum size of the resulting array (0 = no limit),
- *               OUT: the actual size of the array
- * @return a sstr_t array containing the split strings or
- * <code>NULL</code> on error
- * 
- * @see scstrsplit()
- */
-sstr_t* scstrsplit_a(UcxAllocator *allocator, scstr_t string, scstr_t delim,
-        ssize_t *count);
-
-/**
- * Performing sstrsplit() using a UcxAllocator.
- * 
- * <i>Read the description of sstrsplit() for details.</i>
- * 
- * The memory for the sstr_t.ptr pointers of the array items and the memory for
- * the sstr_t array itself are allocated by using the UcxAllocator.malloc()
- * function.
- * 
- * @param allocator the UcxAllocator used for allocating memory
- * @param string the string to split
- * @param delim  the delimiter string
- * @param count  IN: the maximum size of the resulting array (0 = no limit),
- *               OUT: the actual size of the array
- * @return a sstr_t array containing the split strings or
- * <code>NULL</code> on error
- * 
- * @see sstrsplit()
- */
-#define sstrsplit_a(allocator, string, delim, count) \
-    scstrsplit_a(allocator, SCSTR(string), SCSTR(delim), count)
-
-/**
- * Compares two UCX strings with standard <code>memcmp()</code>.
- * 
- * At first it compares the scstr_t.length attribute of the two strings. The
- * <code>memcmp()</code> function is called, if and only if the lengths match.
- * 
- * @param s1 the first string
- * @param s2 the second string
- * @return -1, if the length of s1 is less than the length of s2 or 1, if the 
- * length of s1 is greater than the length of s2 or the result of
- * <code>memcmp()</code> otherwise (i.e. 0 if the strings match)
- */
-int scstrcmp(scstr_t s1, scstr_t s2);
-
-/**
- * Compares two UCX strings with standard <code>memcmp()</code>.
- * 
- * At first it compares the sstr_t.length attribute of the two strings. The
- * <code>memcmp()</code> function is called, if and only if the lengths match.
- * 
- * @param s1 the first string
- * @param s2 the second string
- * @return -1, if the length of s1 is less than the length of s2 or 1, if the 
- * length of s1 is greater than the length of s2 or the result of
- * <code>memcmp()</code> otherwise (i.e. 0 if the strings match)
- */
-#define sstrcmp(s1, s2) scstrcmp(SCSTR(s1), SCSTR(s2))
-
-/**
- * Compares two UCX strings ignoring the case.
- * 
- * At first it compares the scstr_t.length attribute of the two strings. If and
- * only if the lengths match, both strings are compared char by char ignoring
- * the case.
- * 
- * @param s1 the first string
- * @param s2 the second string
- * @return -1, if the length of s1 is less than the length of s2 or 1, if the 
- * length of s1 is greater than the length of s2 or the result of the platform
- * specific string comparison function ignoring the case.
- */
-int scstrcasecmp(scstr_t s1, scstr_t s2);
-
-/**
- * Compares two UCX strings ignoring the case.
- * 
- * At first it compares the sstr_t.length attribute of the two strings. If and
- * only if the lengths match, both strings are compared char by char ignoring
- * the case.
- * 
- * @param s1 the first string
- * @param s2 the second string
- * @return -1, if the length of s1 is less than the length of s2 or 1, if the 
- * length of s1 is greater than the length of s2 or the result of the platform
- * specific string comparison function ignoring the case.
- */
-#define sstrcasecmp(s1, s2) scstrcasecmp(SCSTR(s1), SCSTR(s2))
-
-/**
- * Creates a duplicate of the specified string.
- * 
- * The new sstr_t will contain a copy allocated by standard
- * <code>malloc()</code>. So developers <b>MUST</b> pass the sstr_t.ptr to
- * <code>free()</code>.
- * 
- * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
- * terminated and mutable, regardless of the argument.
- * 
- * @param string the string to duplicate
- * @return a duplicate of the string
- * @see scstrdup_a()
- */
-sstr_t scstrdup(scstr_t string);
-
-/**
- * Creates a duplicate of the specified string.
- * 
- * The new sstr_t will contain a copy allocated by standard
- * <code>malloc()</code>. So developers <b>MUST</b> pass the sstr_t.ptr to
- * <code>free()</code>.
- * 
- * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
- * terminated, regardless of the argument.
- * 
- * @param string the string to duplicate
- * @return a duplicate of the string
- * @see sstrdup_a()
- */
-#define sstrdup(string) scstrdup(SCSTR(string))
-
-/**
- * Creates a duplicate of the specified string using a UcxAllocator.
- * 
- * The new sstr_t will contain a copy allocated by the allocators
- * UcxAllocator.malloc() function. So it is implementation depended, whether the
- * returned sstr_t.ptr pointer must be passed to the allocators
- * UcxAllocator.free() function manually.
- * 
- * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
- * terminated and mutable, regardless of the argument.
- * 
- * @param allocator a valid instance of a UcxAllocator
- * @param string the string to duplicate
- * @return a duplicate of the string
- * @see scstrdup()
- */
-sstr_t scstrdup_a(UcxAllocator *allocator, scstr_t string);
-
-/**
- * Creates a duplicate of the specified string using a UcxAllocator.
- * 
- * The new sstr_t will contain a copy allocated by the allocators
- * UcxAllocator.malloc() function. So it is implementation depended, whether the
- * returned sstr_t.ptr pointer must be passed to the allocators
- * UcxAllocator.free() function manually.
- * 
- * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>-
- * terminated, regardless of the argument.
- * 
- * @param allocator a valid instance of a UcxAllocator
- * @param string the string to duplicate
- * @return a duplicate of the string
- * @see scstrdup()
- */
-#define sstrdup_a(allocator, string) scstrdup_a(allocator, SCSTR(string))
-
-
-/**
- * Omits leading and trailing spaces.
- * 
- * This function returns a new sstr_t containing a trimmed version of the
- * specified string.
- * 
- * <b>Note:</b> the new sstr_t references the same memory, thus you
- * <b>MUST NOT</b> pass the sstr_t.ptr of the return value to
- * <code>free()</code>. It is also highly recommended to avoid assignments like
- * <code>mystr = sstrtrim(mystr);</code> as you lose the reference to the
- * source string. Assignments of this type are only permitted, if the
- * sstr_t.ptr of the source string does not need to be freed or if another
- * reference to the source string exists.
- * 
- * @param string the string that shall be trimmed
- * @return a new sstr_t containing the trimmed string
- */
-sstr_t sstrtrim(sstr_t string);
-
-/**
- * Omits leading and trailing spaces.
- * 
- * This function returns a new scstr_t containing a trimmed version of the
- * specified string.
- * 
- * <b>Note:</b> the new scstr_t references the same memory, thus you
- * <b>MUST NOT</b> pass the scstr_t.ptr of the return value to
- * <code>free()</code>. It is also highly recommended to avoid assignments like
- * <code>mystr = scstrtrim(mystr);</code> as you lose the reference to the
- * source string. Assignments of this type are only permitted, if the
- * scstr_t.ptr of the source string does not need to be freed or if another
- * reference to the source string exists.
- * 
- * @param string the string that shall be trimmed
- * @return a new scstr_t containing the trimmed string
- */
-scstr_t scstrtrim(scstr_t string);
-
-/**
- * Checks, if a string has a specific prefix.
- * 
- * @param string the string to check
- * @param prefix the prefix the string should have
- * @return 1, if and only if the string has the specified prefix, 0 otherwise
- */
-int scstrprefix(scstr_t string, scstr_t prefix);
-
-/**
- * Checks, if a string has a specific prefix.
- * 
- * @param string the string to check
- * @param prefix the prefix the string should have
- * @return 1, if and only if the string has the specified prefix, 0 otherwise
- */
-#define sstrprefix(string, prefix) scstrprefix(SCSTR(string), SCSTR(prefix))
-
-/**
- * Checks, if a string has a specific suffix.
- * 
- * @param string the string to check
- * @param suffix the suffix the string should have
- * @return 1, if and only if the string has the specified suffix, 0 otherwise
- */
-int scstrsuffix(scstr_t string, scstr_t suffix);
-
-/**
- * Checks, if a string has a specific suffix.
- *
- * @param string the string to check
- * @param suffix the suffix the string should have
- * @return 1, if and only if the string has the specified suffix, 0 otherwise
- */
-#define sstrsuffix(string, suffix) scstrsuffix(SCSTR(string), SCSTR(suffix))
-
-/**
- * Checks, if a string has a specific prefix, ignoring the case.
- * 
- * @param string the string to check
- * @param prefix the prefix the string should have
- * @return 1, if and only if the string has the specified prefix, 0 otherwise
- */
-int scstrcaseprefix(scstr_t string, scstr_t prefix);
-
-/**
- * Checks, if a string has a specific prefix, ignoring the case.
- * 
- * @param string the string to check
- * @param prefix the prefix the string should have
- * @return 1, if and only if the string has the specified prefix, 0 otherwise
- */
-#define sstrcaseprefix(string, prefix) \
-  scstrcaseprefix(SCSTR(string), SCSTR(prefix))
-
-/**
- * Checks, if a string has a specific suffix, ignoring the case.
- * 
- * @param string the string to check
- * @param suffix the suffix the string should have
- * @return 1, if and only if the string has the specified suffix, 0 otherwise
- */
-int scstrcasesuffix(scstr_t string, scstr_t suffix);
-
-/**
- * Checks, if a string has a specific suffix, ignoring the case.
- *
- * @param string the string to check
- * @param suffix the suffix the string should have
- * @return 1, if and only if the string has the specified suffix, 0 otherwise
- */
-#define sstrcasesuffix(string, suffix) \
-  scstrcasesuffix(SCSTR(string), SCSTR(suffix))
-
-/**
- * Returns a lower case version of a string.
- * 
- * This function creates a duplicate of the input string, first
- * (see scstrdup()).
- * 
- * @param string the input string
- * @return the resulting lower case string
- * @see scstrdup()
- */
-sstr_t scstrlower(scstr_t string);
-
-/**
- * Returns a lower case version of a string.
- * 
- * This function creates a duplicate of the input string, first
- * (see sstrdup()).
- * 
- * @param string the input string
- * @return the resulting lower case string
- */
-#define sstrlower(string) scstrlower(SCSTR(string))
-
-/**
- * Returns a lower case version of a string.
- * 
-  * This function creates a duplicate of the input string, first
- * (see scstrdup_a()).
- * 
- * @param allocator the allocator used for duplicating the string
- * @param string the input string
- * @return the resulting lower case string
- * @see scstrdup_a()
- */
-sstr_t scstrlower_a(UcxAllocator *allocator, scstr_t string);
-
-
-/**
- * Returns a lower case version of a string.
- * 
- * This function creates a duplicate of the input string, first
- * (see sstrdup_a()).
- * 
- * @param allocator the allocator used for duplicating the string
- * @param string the input string
- * @return the resulting lower case string
- */
-#define sstrlower_a(allocator, string) scstrlower_a(allocator, SCSTR(string))
-
-/**
- * Returns a upper case version of a string.
- * 
- * This function creates a duplicate of the input string, first
- * (see scstrdup()).
- * 
- * @param string the input string
- * @return the resulting upper case string
- * @see scstrdup()
- */
-sstr_t scstrupper(scstr_t string);
-
-/**
- * Returns a upper case version of a string.
- * 
- * This function creates a duplicate of the input string, first
- * (see sstrdup()).
- * 
- * @param string the input string
- * @return the resulting upper case string
- */
-#define sstrupper(string) scstrupper(SCSTR(string))
-
-/**
- * Returns a upper case version of a string.
- * 
- * This function creates a duplicate of the input string, first
- * (see scstrdup_a()).
- * 
- * @param allocator the allocator used for duplicating the string
- * @param string the input string
- * @return the resulting upper case string
- * @see scstrdup_a()
- */
-sstr_t scstrupper_a(UcxAllocator *allocator, scstr_t string);
-
-/**
- * Returns a upper case version of a string.
- * 
- * This function creates a duplicate of the input string, first
- * (see sstrdup_a()).
- * 
- * @param allocator the allocator used for duplicating the string
- * @param string the input string
- * @return the resulting upper case string
- */
-#define sstrupper_a(allocator, string) scstrupper_a(allocator, string)
-
-
-/**
- * Replaces a pattern in a string with another string.
- *
- * The pattern is taken literally and is no regular expression.
- * Replaces at most <code>replmax</code> occurrences.
- *
- * The resulting string is allocated by the specified allocator. I.e. it
- * depends on the used allocator, whether the sstr_t.ptr must be freed
- * manually.
- *
- * If allocation fails, the sstr_t.ptr of the return value is NULL.
- *
- * @param allocator the allocator to use
- * @param str the string where replacements should be applied
- * @param pattern the pattern to search for
- * @param replacement the replacement string
- * @param replmax maximum number of replacements
- * @return the resulting string after applying the replacements
- */
-sstr_t scstrreplacen_a(UcxAllocator *allocator, scstr_t str,
-        scstr_t pattern, scstr_t replacement, size_t replmax);
-
-/**
- * Replaces a pattern in a string with another string.
- *
- * The pattern is taken literally and is no regular expression.
- * Replaces at most <code>replmax</code> occurrences.
- *
- * The sstr_t.ptr of the resulting string must be freed manually.
- *
- * If allocation fails, the sstr_t.ptr of the return value is NULL.
- *
- * @param str the string where replacements should be applied
- * @param pattern the pattern to search for
- * @param replacement the replacement string
- * @param replmax maximum number of replacements
- * @return the resulting string after applying the replacements
- */
-sstr_t scstrreplacen(scstr_t str, scstr_t pattern,
-        scstr_t replacement, size_t replmax);
-
-/**
- * Replaces a pattern in a string with another string.
- *
- * The pattern is taken literally and is no regular expression.
- * Replaces at most <code>replmax</code> occurrences.
- *
- * The resulting string is allocated by the specified allocator. I.e. it
- * depends on the used allocator, whether the sstr_t.ptr must be freed
- * manually.
- *
- * @param allocator the allocator to use
- * @param str the string where replacements should be applied
- * @param pattern the pattern to search for
- * @param replacement the replacement string
- * @param replmax maximum number of replacements
- * @return the resulting string after applying the replacements
- */
-#define sstrreplacen_a(allocator, str, pattern, replacement, replmax) \
-        scstrreplacen_a(allocator, SCSTR(str), SCSTR(pattern), \
-            SCSTR(replacement), replmax)
-
-/**
- * Replaces a pattern in a string with another string.
- *
- * The pattern is taken literally and is no regular expression.
- * Replaces at most <code>replmax</code> occurrences.
- *
- * The sstr_t.ptr of the resulting string must be freed manually.
- *
- * If allocation fails, the sstr_t.ptr of the return value is NULL.
- *
- * @param str the string where replacements should be applied
- * @param pattern the pattern to search for
- * @param replacement the replacement string
- * @param replmax maximum number of replacements
- * @return the resulting string after applying the replacements
- */
-#define sstrreplacen(str, pattern, replacement, replmax) \
-        scstrreplacen(SCSTR(str), SCSTR(pattern), SCSTR(replacement), replmax)
-
-/**
- * Replaces a pattern in a string with another string.
- *
- * The pattern is taken literally and is no regular expression.
- * Replaces at most <code>replmax</code> occurrences.
- *
- * The resulting string is allocated by the specified allocator. I.e. it
- * depends on the used allocator, whether the sstr_t.ptr must be freed
- * manually.
- *
- * If allocation fails, the sstr_t.ptr of the return value is NULL.
- *
- * @param allocator the allocator to use
- * @param str the string where replacements should be applied
- * @param pattern the pattern to search for
- * @param replacement the replacement string
- * @return the resulting string after applying the replacements
- */
-#define sstrreplace_a(allocator, str, pattern, replacement) \
-        scstrreplacen_a(allocator, SCSTR(str), SCSTR(pattern), \
-            SCSTR(replacement), SIZE_MAX)
-
-/**
- * Replaces a pattern in a string with another string.
- *
- * The pattern is taken literally and is no regular expression.
- * Replaces at most <code>replmax</code> occurrences.
- *
- * The sstr_t.ptr of the resulting string must be freed manually.
- *
- * If allocation fails, the sstr_t.ptr of the return value is NULL.
- *
- * @param str the string where replacements should be applied
- * @param pattern the pattern to search for
- * @param replacement the replacement string
- * @return the resulting string after applying the replacements
- */
-#define sstrreplace(str, pattern, replacement) \
-        scstrreplacen(SCSTR(str), SCSTR(pattern), SCSTR(replacement), SIZE_MAX)
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_STRING_H */
--- a/ucx/ucx/test.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- 
-/**
- * @file: test.h
- * 
- * UCX Test Framework.
- * 
- * Usage of this test framework:
- *
- * **** IN HEADER FILE: ****
- *
- * <pre>
- * UCX_TEST(function_name);
- * UCX_TEST_SUBROUTINE(subroutine_name, paramlist); // optional
- * </pre>
- *
- * **** IN SOURCE FILE: ****
- * <pre>
- * UCX_TEST_SUBROUTINE(subroutine_name, paramlist) {
- *   // tests with UCX_TEST_ASSERT()
- * }
- * 
- * UCX_TEST(function_name) {
- *   // memory allocation and other stuff here
- *   #UCX_TEST_BEGIN
- *   // tests with UCX_TEST_ASSERT() and/or
- *   // calls with UCX_TEST_CALL_SUBROUTINE() here
- *   #UCX_TEST_END
- *   // cleanup of memory here
- * }
- * </pre>
- *
- * <b>Note:</b> if a test fails, a longjump is performed
- * back to the #UCX_TEST_BEGIN macro!
- * 
- * <b>Attention:</b> Do not call own functions within a test, that use
- * UCX_TEST_ASSERT() macros and are not defined by using UCX_TEST_SUBROUTINE().
- * 
- *
- * @author Mike Becker
- * @author Olaf Wintermann
- *
- */
-
-#ifndef UCX_TEST_H
-#define	UCX_TEST_H
-
-#include "ucx.h"
-#include <stdio.h>
-#include <string.h>
-#include <setjmp.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-#ifndef __FUNCTION__
-
-/**
- * Alias for the <code>__func__</code> preprocessor macro.
- * Some compilers use <code>__func__</code> and others use __FUNCTION__.
- * We use __FUNCTION__ so we define it for those compilers which use
- * <code>__func__</code>.
- */
-#define __FUNCTION__ __func__
-#endif
-
-/** Type for the UcxTestSuite. */
-typedef struct UcxTestSuite UcxTestSuite;
-
-/** Pointer to a test function. */
-typedef void(*UcxTest)(UcxTestSuite*,FILE*);
-
-/** Type for the internal list of test cases. */
-typedef struct UcxTestList UcxTestList;
-
-/** Structure for the internal list of test cases. */
-struct UcxTestList {
-    
-    /** Test case. */
-    UcxTest test;
-    
-    /** Pointer to the next list element. */
-    UcxTestList *next;
-};
-
-/**
- * A test suite containing multiple test cases.
- */
-struct UcxTestSuite {
-    
-    /** The number of successful tests after the suite has been run. */
-    unsigned int success;
-    
-    /** The number of failed tests after the suite has been run. */
-    unsigned int failure;
-    
-    /**
-     * Internal list of test cases.
-     * Use ucx_test_register() to add tests to this list.
-     */
-    UcxTestList *tests;
-};
-
-/**
- * Creates a new test suite.
- * @return a new test suite
- */
-UcxTestSuite* ucx_test_suite_new();
-
-/**
- * Destroys a test suite.
- * @param suite the test suite to destroy
- */
-void ucx_test_suite_free(UcxTestSuite* suite);
-
-/**
- * Registers a test function with the specified test suite.
- * 
- * @param suite the suite, the test function shall be added to
- * @param test the test function to register
- * @return <code>EXIT_SUCCESS</code> on success or
- * <code>EXIT_FAILURE</code> on failure
- */
-int ucx_test_register(UcxTestSuite* suite, UcxTest test);
-
-/**
- * Runs a test suite and writes the test log to the specified stream.
- * @param suite the test suite to run
- * @param outstream the stream the log shall be written to
- */
-void ucx_test_run(UcxTestSuite* suite, FILE* outstream);
-
-/**
- * Macro for a #UcxTest function header.
- * 
- * Use this macro to declare and/or define a #UcxTest function.
- * 
- * @param name the name of the test function
- */
-#define UCX_TEST(name) void name(UcxTestSuite* _suite_,FILE *_output_)
-
-/**
- * Marks the begin of a test.
- * <b>Note:</b> Any UCX_TEST_ASSERT() calls must be performed <b>after</b>
- * #UCX_TEST_BEGIN.
- * 
- * @see #UCX_TEST_END
- */
-#define UCX_TEST_BEGIN fwrite("Running ", 1, 8, _output_);\
-        fwrite(__FUNCTION__, 1, strlen(__FUNCTION__), _output_);\
-        fwrite("... ", 1, 4, _output_);\
-        jmp_buf _env_; \
-        if (!setjmp(_env_)) {
-
-/**
- * Checks a test assertion.
- * If the assertion is correct, the test carries on. If the assertion is not
- * correct, the specified message (terminated by a dot and a line break) is
- * written to the test suites output stream.
- * @param condition the condition to check
- * @param message the message that shall be printed out on failure
- */
-#define UCX_TEST_ASSERT(condition,message) if (!(condition)) { \
-        fwrite(message".\n", 1, 2+strlen(message), _output_); \
-        _suite_->failure++; \
-        longjmp(_env_, 1);\
-    }
-
-/**
- * Macro for a test subroutine function header.
- * 
- * Use this to declare and/or define a subroutine that can be called by using
- * UCX_TEST_CALL_SUBROUTINE().
- * 
- * @param name the name of the subroutine
- * @param ... the parameter list
- * 
- * @see UCX_TEST_CALL_SUBROUTINE()
- */
-#define UCX_TEST_SUBROUTINE(name,...) void name(UcxTestSuite* _suite_,\
-        FILE *_output_, jmp_buf _env_, __VA_ARGS__)
-
-/**
- * Macro for calling a test subroutine.
- * 
- * Subroutines declared with UCX_TEST_SUBROUTINE() can be called by using this
- * macro.
- * 
- * <b>Note:</b> You may <b>only</b> call subroutines within a #UCX_TEST_BEGIN-
- * #UCX_TEST_END-block.
- * 
- * @param name the name of the subroutine
- * @param ... the argument list
- * 
- * @see UCX_TEST_SUBROUTINE()
- */
-#define UCX_TEST_CALL_SUBROUTINE(name,...) \
-        name(_suite_,_output_,_env_,__VA_ARGS__);
-
-/**
- * Marks the end of a test.
- * <b>Note:</b> Any UCX_TEST_ASSERT() calls must be performed <b>before</b>
- * #UCX_TEST_END.
- * 
- * @see #UCX_TEST_BEGIN
- */
-#define UCX_TEST_END fwrite("success.\n", 1, 9, _output_); _suite_->success++;}
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_TEST_H */
-
--- a/ucx/ucx/ucx.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * Main UCX Header providing most common definitions.
- * 
- * @file   ucx.h
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_H
-#define	UCX_H
-
-/** Major UCX version as integer constant. */
-#define UCX_VERSION_MAJOR   2
-
-/** Minor UCX version as integer constant. */
-#define UCX_VERSION_MINOR   1
-
-/** Version constant which ensures to increase monotonically. */
-#define UCX_VERSION (((UCX_VERSION_MAJOR)<<16)|UCX_VERSION_MINOR)
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#ifdef _WIN32
-#if !(defined __ssize_t_defined || defined _SSIZE_T_)
-#include <BaseTsd.h>
-typedef SSIZE_T ssize_t;
-#define __ssize_t_defined
-#define _SSIZE_T_
-#endif /* __ssize_t_defined and _SSIZE_T */
-#else /* !_WIN32 */
-#include <sys/types.h>
-#endif /* _WIN32 */
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-    
-
-/**
- * A function pointer to a destructor function.
- * @see ucx_mempool_setdestr()
- * @see ucx_mempool_regdestr()
- */
-typedef void(*ucx_destructor)(void*);
-
-/**
- * Function pointer to a compare function.
- * 
- * The compare function shall take three arguments: the two values that shall be
- * compared and optional additional data.
- * The function shall then return -1 if the first argument is less than the
- * second argument, 1 if the first argument is greater than the second argument
- * and 0 if both arguments are equal. If the third argument is
- * <code>NULL</code>, it shall be ignored.
- */
-typedef int(*cmp_func)(const void*,const void*,void*);
-
-/**
- * Function pointer to a distance function.
- * 
- * The distance function shall take three arguments: the two values for which
- * the distance shall be computed and optional additional data.
- * The function shall then return the signed distance as integer value.
- */
-typedef intmax_t(*distance_func)(const void*,const void*,void*);
-
-/**
- * Function pointer to a copy function.
- * 
- * The copy function shall create a copy of the first argument and may use
- * additional data provided by the second argument. If the second argument is
- * <code>NULL</code>, it shall be ignored.
-
- * <b>Attention:</b> if pointers returned by functions of this type may be
- * passed to <code>free()</code> depends on the implementation of the
- * respective <code>copy_func</code>.
- */
-typedef void*(*copy_func)(const void*,void*);
-
-/**
- * Function pointer to a write function.
- * 
- * The signature of the write function shall be compatible to the signature
- * of standard <code>fwrite</code>, though it may use arbitrary data types for
- * source and destination.
- * 
- * The arguments shall contain (in ascending order): a pointer to the source,
- * the length of one element, the element count and a pointer to the
- * destination.
- */
-typedef size_t(*write_func)(const void*, size_t, size_t, void*);
-
-/**
- * Function pointer to a read function.
- * 
- * The signature of the read function shall be compatible to the signature
- * of standard <code>fread</code>, though it may use arbitrary data types for
- * source and destination.
- * 
- * The arguments shall contain (in ascending order): a pointer to the
- * destination, the length of one element, the element count and a pointer to
- * the source.
- */
-typedef size_t(*read_func)(void*, size_t, size_t, void*);
-
-
-
-#if __GNUC__ >= 5 || defined(__clang__)
-#define UCX_MUL_BUILTIN
-
-#if __WORDSIZE == 32
-/**
- * Alias for <code>__builtin_umul_overflow</code>.
- * 
- * Performs a multiplication of size_t values and checks for overflow.
- * 
- * @param a first operand
- * @param b second operand
- * @param result a pointer to a size_t, where the result should
- * be stored
- * @return zero, if no overflow occurred and the result is correct, non-zero
- * otherwise
- */
-#define ucx_szmul(a, b, result) __builtin_umul_overflow(a, b, result)
-#else /* __WORDSIZE != 32 */
-/**
- * Alias for <code>__builtin_umull_overflow</code>.
- * 
- * Performs a multiplication of size_t values and checks for overflow.
- * 
- * @param a first operand
- * @param b second operand
- * @param result a pointer to a size_t, where the result should
- * be stored
- * @return zero, if no overflow occurred and the result is correct, non-zero
- * otherwise
- */
-#define ucx_szmul(a, b, result) __builtin_umull_overflow(a, b, result)
-#endif /* __WORDSIZE */
-
-#else /* no GNUC or clang bultin */
-
-/**
- * Performs a multiplication of size_t values and checks for overflow.
-  *
- * @param a first operand
- * @param b second operand
- * @param result a pointer to a size_t, where the result should
- * be stored
- * @return zero, if no overflow occurred and the result is correct, non-zero
- * otherwise
- */
-#define ucx_szmul(a, b, result) ucx_szmul_impl(a, b, result)
-
-/**
- * Performs a multiplication of size_t values and checks for overflow.
- *
- * This is a custom implementation in case there is no compiler builtin
- * available.
- *
- * @param a first operand
- * @param b second operand
- * @param result a pointer to a size_t where the result should be stored
- * @return zero, if no overflow occurred and the result is correct, non-zero
- * otherwise
- */
-int ucx_szmul_impl(size_t a, size_t b, size_t *result);
-
-#endif
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* UCX_H */
-
--- a/ucx/ucx/utils.h	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,508 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @file utils.h
- * 
- * Compare, copy and printf functions.
- * 
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_UTILS_H
-#define UCX_UTILS_H
-
-#include "ucx.h"
-#include "string.h"
-#include "allocator.h"
-#include <inttypes.h>
-#include <string.h>
-#include <stdarg.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Default buffer size for ucx_stream_copy() and ucx_stream_ncopy().
- */
-#define UCX_STREAM_COPY_BUFSIZE 4096
-
-/**
- * Copies a string.
- * @param s the string to copy
- * @param data omitted
- * @return a pointer to a copy of s1 that can be passed to free(void*)
- */
-void *ucx_strcpy(const void *s, void *data);
-
-/**
- * Copies a memory area.
- * @param m a pointer to the memory area
- * @param n a pointer to the size_t containing the size of the memory area
- * @return a pointer to a copy of the specified memory area that can
- * be passed to free(void*)
- */
-void *ucx_memcpy(const void *m, void *n);
-
-
-/**
- * Reads data from a stream and writes it to another stream.
- * 
- * @param src the source stream
- * @param dest the destination stream
- * @param rfnc the read function
- * @param wfnc the write function
- * @param buf a pointer to the copy buffer or <code>NULL</code> if a buffer
- * shall be implicitly created on the heap
- * @param bufsize the size of the copy buffer - if <code>NULL</code> was
- * provided for <code>buf</code>, this is the size of the buffer that shall be
- * implicitly created
- * @param n the maximum number of bytes that shall be copied
- * @return the total number of bytes copied
-  */
-size_t ucx_stream_bncopy(void *src, void *dest, read_func rfnc, write_func wfnc,
-        char* buf, size_t bufsize, size_t n);
-
-/**
- * Shorthand for an unbounded ucx_stream_bncopy call using a default buffer.
- * 
- * @param src the source stream
- * @param dest the destination stream
- * @param rfnc the read function
- * @param wfnc the write function
- * @return total number of bytes copied
- * 
- * @see #UCX_STREAM_COPY_BUFSIZE
- */
-#define ucx_stream_copy(src,dest,rfnc,wfnc) ucx_stream_bncopy(\
-        src, dest, (read_func)rfnc, (write_func)wfnc, \
-        NULL, UCX_STREAM_COPY_BUFSIZE, (size_t)-1)
-
-/**
- * Shorthand for ucx_stream_bncopy using a default copy buffer.
- * 
- * @param src the source stream
- * @param dest the destination stream
- * @param rfnc the read function
- * @param wfnc the write function
- * @param n maximum number of bytes that shall be copied
- * @return total number of bytes copied
- */
-#define ucx_stream_ncopy(src,dest,rfnc,wfnc, n) ucx_stream_bncopy(\
-        src, dest, (read_func)rfnc, (write_func)wfnc, \
-        NULL, UCX_STREAM_COPY_BUFSIZE, n)
-
-/**
- * Shorthand for an unbounded ucx_stream_bncopy call using the specified buffer.
- * 
- * @param src the source stream
- * @param dest the destination stream
- * @param rfnc the read function
- * @param wfnc the write function
- * @param buf a pointer to the copy buffer or <code>NULL</code> if a buffer
- * shall be implicitly created on the heap
- * @param bufsize the size of the copy buffer - if <code>NULL</code> was
- * provided for <code>buf</code>, this is the size of the buffer that shall be
- * implicitly created
- * @return total number of bytes copied
- */
-#define ucx_stream_bcopy(src,dest,rfnc,wfnc, buf, bufsize) ucx_stream_bncopy(\
-        src, dest, (read_func)rfnc, (write_func)wfnc, \
-        buf, bufsize, (size_t)-1)
-
-/**
- * Wraps the strcmp function.
- * @param s1 string one
- * @param s2 string two
- * @param data omitted
- * @return the result of strcmp(s1, s2)
- */
-int ucx_cmp_str(const void *s1, const void *s2, void *data);
-
-/**
- * Wraps the strncmp function.
- * @param s1 string one
- * @param s2 string two
- * @param n a pointer to the size_t containing the third strncmp parameter
- * @return the result of strncmp(s1, s2, *n)
- */
-int ucx_cmp_strn(const void *s1, const void *s2, void *n);
-
-/**
- * Wraps the sstrcmp function.
- * @param s1 sstr one
- * @param s2 sstr two
- * @param data ignored
- * @return the result of sstrcmp(s1, s2)
- */
-int ucx_cmp_sstr(const void *s1, const void *s2, void *data);
-
-/**
- * Compares two integers of type int.
- * @param i1 pointer to integer one
- * @param i2 pointer to integer two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_int(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type long int.
- * @param i1 pointer to long integer one
- * @param i2 pointer to long integer two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_longint(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type long long.
- * @param i1 pointer to long long one
- * @param i2 pointer to long long two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_longlong(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type int16_t.
- * @param i1 pointer to int16_t one
- * @param i2 pointer to int16_t two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_int16(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type int32_t.
- * @param i1 pointer to int32_t one
- * @param i2 pointer to int32_t two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_int32(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type int64_t.
- * @param i1 pointer to int64_t one
- * @param i2 pointer to int64_t two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_int64(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type unsigned int.
- * @param i1 pointer to unsigned integer one
- * @param i2 pointer to unsigned integer two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_uint(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type unsigned long int.
- * @param i1 pointer to unsigned long integer one
- * @param i2 pointer to unsigned long integer two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_ulongint(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type unsigned long long.
- * @param i1 pointer to unsigned long long one
- * @param i2 pointer to unsigned long long two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_ulonglong(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type uint16_t.
- * @param i1 pointer to uint16_t one
- * @param i2 pointer to uint16_t two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_uint16(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type uint32_t.
- * @param i1 pointer to uint32_t one
- * @param i2 pointer to uint32_t two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_uint32(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two integers of type uint64_t.
- * @param i1 pointer to uint64_t one
- * @param i2 pointer to uint64_t two
- * @param data omitted
- * @return -1, if *i1 is less than *i2, 0 if both are equal,
- * 1 if *i1 is greater than *i2
- */
-int ucx_cmp_uint64(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type int.
- * @param i1 pointer to integer one
- * @param i2 pointer to integer two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_int(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type long int.
- * @param i1 pointer to long integer one
- * @param i2 pointer to long integer two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_longint(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type long long.
- * @param i1 pointer to long long one
- * @param i2 pointer to long long two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_longlong(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type int16_t.
- * @param i1 pointer to int16_t one
- * @param i2 pointer to int16_t two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_int16(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type int32_t.
- * @param i1 pointer to int32_t one
- * @param i2 pointer to int32_t two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_int32(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type int64_t.
- * @param i1 pointer to int64_t one
- * @param i2 pointer to int64_t two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_int64(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type unsigned int.
- * @param i1 pointer to unsigned integer one
- * @param i2 pointer to unsigned integer two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_uint(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type unsigned long int.
- * @param i1 pointer to unsigned long integer one
- * @param i2 pointer to unsigned long integer two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_ulongint(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type unsigned long long.
- * @param i1 pointer to unsigned long long one
- * @param i2 pointer to unsigned long long two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_ulonglong(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type uint16_t.
- * @param i1 pointer to uint16_t one
- * @param i2 pointer to uint16_t two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_uint16(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type uint32_t.
- * @param i1 pointer to uint32_t one
- * @param i2 pointer to uint32_t two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_uint32(const void *i1, const void *i2, void *data);
-
-/**
- * Distance function for integers of type uint64_t.
- * @param i1 pointer to uint64_t one
- * @param i2 pointer to uint64_t two
- * @param data omitted
- * @return i1 minus i2
- */
-intmax_t ucx_dist_uint64(const void *i1, const void *i2, void *data);
-
-/**
- * Compares two real numbers of type float.
- * @param f1 pointer to float one
- * @param f2 pointer to float two
- * @param data if provided: a pointer to precision (default: 1e-6f)
- * @return -1, if *f1 is less than *f2, 0 if both are equal,
- * 1 if *f1 is greater than *f2
- */
-
-int ucx_cmp_float(const void *f1, const void *f2, void *data);
-
-/**
- * Compares two real numbers of type double.
- * @param d1 pointer to double one
- * @param d2 pointer to double two
- * @param data if provided: a pointer to precision (default: 1e-14)
- * @return -1, if *d1 is less than *d2, 0 if both are equal,
- * 1 if *d1 is greater than *d2
- */
-int ucx_cmp_double(const void *d1, const void *d2, void *data);
-
-/**
- * Compares two pointers.
- * @param ptr1 pointer one
- * @param ptr2 pointer two
- * @param data omitted
- * @return -1 if ptr1 is less than ptr2, 0 if both are equal,
- * 1 if ptr1 is greater than ptr2
- */
-int ucx_cmp_ptr(const void *ptr1, const void *ptr2, void *data);
-
-/**
- * Compares two memory areas.
- * @param ptr1 pointer one
- * @param ptr2 pointer two
- * @param n a pointer to the size_t containing the third parameter for memcmp
- * @return the result of memcmp(ptr1, ptr2, *n)
- */
-int ucx_cmp_mem(const void *ptr1, const void *ptr2, void *n);
-
-/**
- * A <code>printf()</code> like function which writes the output to a stream by
- * using a write_func().
- * @param stream the stream the data is written to
- * @param wfc the write function
- * @param fmt format string
- * @param ... additional arguments
- * @return the total number of bytes written
- */
-int ucx_fprintf(void *stream, write_func wfc, const char *fmt, ...);
-
-/**
- * <code>va_list</code> version of ucx_fprintf().
- * @param stream the stream the data is written to
- * @param wfc the write function
- * @param fmt format string
- * @param ap argument list
- * @return the total number of bytes written
- * @see ucx_fprintf()
- */
-int ucx_vfprintf(void *stream, write_func wfc, const char *fmt, va_list ap);
-
-/**
- * A <code>printf()</code> like function which allocates space for a sstr_t
- * the result is written to.
- * 
- * <b>Attention</b>: The sstr_t data is allocated with the allocators
- * ucx_allocator_malloc() function. So it is implementation dependent, if
- * the returned sstr_t.ptr pointer must be passed to the allocators
- * ucx_allocator_free() function manually.
- * 
- * <b>Note</b>: The sstr_t.ptr of the return value will <i>always</i> be
- * <code>NULL</code>-terminated.
- * 
- * @param allocator the UcxAllocator used for allocating the result sstr_t
- * @param fmt format string
- * @param ... additional arguments
- * @return a sstr_t containing the formatted string
- */
-sstr_t ucx_asprintf(UcxAllocator *allocator, const char *fmt, ...);
-
-/**
- * <code>va_list</code> version of ucx_asprintf().
- * 
- * @param allocator the UcxAllocator used for allocating the result sstr_t
- * @param fmt format string
- * @param ap argument list
- * @return a sstr_t containing the formatted string
- * @see ucx_asprintf()
- */
-sstr_t ucx_vasprintf(UcxAllocator *allocator, const char *fmt, va_list ap);
-
-/** Shortcut for ucx_asprintf() with default allocator. */
-#define ucx_sprintf(...) \
-    ucx_asprintf(ucx_default_allocator(), __VA_ARGS__)
-
-/**
- * A <code>printf()</code> like function which writes the output to a
- * UcxBuffer.
- * 
- * @param buffer the buffer the data is written to
- * @param ... format string and additional arguments
- * @return the total number of bytes written
- * @see ucx_fprintf()
- */
-#define ucx_bprintf(buffer, ...) ucx_fprintf((UcxBuffer*)buffer, \
-        (write_func)ucx_buffer_write, __VA_ARGS__)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* UCX_UTILS_H */
-
--- a/ucx/utils.c	Sat Apr 15 15:42:31 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,448 +0,0 @@
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright
- *      notice, this list of conditions and the following disclaimer in the
- *      documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ucx/utils.h"
-
-#include <math.h>
-#include <stdio.h>
-#include <limits.h>
-#include <errno.h>
-
-/* COPY FUCNTIONS */
-void* ucx_strcpy(const void* s, void* data) {
-    const char *str = (const char*) s;
-    size_t n = 1+strlen(str);
-    char *cpy = (char*) malloc(n);
-    memcpy(cpy, str, n);
-    return cpy;
-}
-
-void* ucx_memcpy(const void* m, void* n) {
-    size_t k = *((size_t*)n);
-    void *cpy = malloc(k);
-    memcpy(cpy, m, k);
-    return cpy;
-}
-
-size_t ucx_stream_bncopy(void *src, void *dest, read_func readfnc,
-        write_func writefnc, char* buf, size_t bufsize, size_t n) {
-    if(n == 0 || bufsize == 0) {
-        return 0;
-    }
-    
-    char *lbuf;    
-    size_t ncp = 0;
-    
-    if(buf) {
-        lbuf = buf;
-    } else {
-        lbuf = (char*)malloc(bufsize);
-        if(lbuf == NULL) {
-            return 0;
-        }
-    }
-    
-    size_t r;
-    size_t rn = bufsize > n ? n : bufsize;
-    while((r = readfnc(lbuf, 1, rn, src)) != 0) {
-        r = writefnc(lbuf, 1, r, dest);
-        ncp += r;
-        n -= r;
-        rn = bufsize > n ? n : bufsize;
-        if(r == 0 || n == 0) {
-            break;
-        }
-    }
-    
-    if (lbuf != buf) {
-        free(lbuf);
-    }
-    
-    return ncp;
-}
-
-/* COMPARE FUNCTIONS */
-
-int ucx_cmp_str(const void *s1, const void *s2, void *data) {
-    return strcmp((const char*)s1, (const char*)s2);
-}
-
-int ucx_cmp_strn(const void *s1, const void *s2, void *n) {
-    return strncmp((const char*)s1, (const char*)s2, *((size_t*) n));
-}
-
-int ucx_cmp_sstr(const void *s1, const void *s2, void *data) {
-    sstr_t a = *(const sstr_t*) s1;
-    sstr_t b = *(const sstr_t*) s2;
-    return sstrcmp(a, b);
-}
-
-int ucx_cmp_int(const void *i1, const void *i2, void *data) {
-   int a = *((const int*) i1);
-   int b = *((const int*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_longint(const void *i1, const void *i2, void *data) {
-   long int a = *((const long int*) i1);
-   long int b = *((const long int*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_longlong(const void *i1, const void *i2, void *data) {
-   long long a = *((const long long*) i1);
-   long long b = *((const long long*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_int16(const void *i1, const void *i2, void *data) {
-   int16_t a = *((const int16_t*) i1);
-   int16_t b = *((const int16_t*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_int32(const void *i1, const void *i2, void *data) {
-   int32_t a = *((const int32_t*) i1);
-   int32_t b = *((const int32_t*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_int64(const void *i1, const void *i2, void *data) {
-   int64_t a = *((const int64_t*) i1);
-   int64_t b = *((const int64_t*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_uint(const void *i1, const void *i2, void *data) {
-   unsigned int a = *((const unsigned int*) i1);
-   unsigned int b = *((const unsigned int*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_ulongint(const void *i1, const void *i2, void *data) {
-   unsigned long int a = *((const unsigned long int*) i1);
-   unsigned long int b = *((const unsigned long int*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_ulonglong(const void *i1, const void *i2, void *data) {
-   unsigned long long a = *((const unsigned long long*) i1);
-   unsigned long long b = *((const unsigned long long*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_uint16(const void *i1, const void *i2, void *data) {
-   uint16_t a = *((const uint16_t*) i1);
-   uint16_t b = *((const uint16_t*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_uint32(const void *i1, const void *i2, void *data) {
-   uint32_t a = *((const uint32_t*) i1);
-   uint32_t b = *((const uint32_t*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_uint64(const void *i1, const void *i2, void *data) {
-   uint64_t a = *((const uint64_t*) i1);
-   uint64_t b = *((const uint64_t*) i2);
-   if (a == b) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-intmax_t ucx_dist_int(const void *i1, const void *i2, void *data) {
-   intmax_t a = *((const int*) i1);
-   intmax_t b = *((const int*) i2);
-   return a - b;
-}
-
-intmax_t ucx_dist_longint(const void *i1, const void *i2, void *data) {
-   intmax_t a = *((const long int*) i1);
-   intmax_t b = *((const long int*) i2);
-   return a - b;
-}
-
-intmax_t ucx_dist_longlong(const void *i1, const void *i2, void *data) {
-   intmax_t a = *((const long long*) i1);
-   intmax_t b = *((const long long*) i2);
-   return a - b;
-}
-
-intmax_t ucx_dist_int16(const void *i1, const void *i2, void *data) {
-   intmax_t a = *((const int16_t*) i1);
-   intmax_t b = *((const int16_t*) i2);
-   return a - b;
-}
-
-intmax_t ucx_dist_int32(const void *i1, const void *i2, void *data) {
-   intmax_t a = *((const int32_t*) i1);
-   intmax_t b = *((const int32_t*) i2);
-   return a - b;
-}
-
-intmax_t ucx_dist_int64(const void *i1, const void *i2, void *data) {
-   intmax_t a = *((const int64_t*) i1);
-   intmax_t b = *((const int64_t*) i2);
-   return a - b;
-}
-
-intmax_t ucx_dist_uint(const void *i1, const void *i2, void *data) {
-   uintmax_t a = *((const unsigned int*) i1);
-   uintmax_t b = *((const unsigned int*) i2);
-   return a > b ? (intmax_t)(a - b) : -(intmax_t)(b - a);
-}
-
-intmax_t ucx_dist_ulongint(const void *i1, const void *i2, void *data) {
-   uintmax_t a = *((const unsigned long int*) i1);
-   uintmax_t b = *((const unsigned long int*) i2);
-   return a > b ? (intmax_t)(a - b) : -(intmax_t)(b - a);
-}
-
-intmax_t ucx_dist_ulonglong(const void *i1, const void *i2, void *data) {
-   uintmax_t a = *((const unsigned long long*) i1);
-   uintmax_t b = *((const unsigned long long*) i2);
-   return a > b ? (intmax_t)(a - b) : -(intmax_t)(b - a);
-}
-
-intmax_t ucx_dist_uint16(const void *i1, const void *i2, void *data) {
-   uintmax_t a = *((const uint16_t*) i1);
-   uintmax_t b = *((const uint16_t*) i2);
-   return a > b ? (intmax_t)(a - b) : -(intmax_t)(b - a);
-}
-
-intmax_t ucx_dist_uint32(const void *i1, const void *i2, void *data) {
-   uintmax_t a = *((const uint32_t*) i1);
-   uintmax_t b = *((const uint32_t*) i2);
-   return a > b ? (intmax_t)(a - b) : -(intmax_t)(b - a);
-}
-
-intmax_t ucx_dist_uint64(const void *i1, const void *i2, void *data) {
-   uintmax_t a = *((const uint64_t*) i1);
-   uintmax_t b = *((const uint64_t*) i2);
-   return a > b ? (intmax_t)(a - b) : -(intmax_t)(b - a);
-}
-
-int ucx_cmp_float(const void *f1, const void *f2, void *epsilon) {
-   float a = *((const float*) f1);
-   float b = *((const float*) f2);
-   float e = !epsilon ? 1e-6f : *((float*)epsilon);
-   if (fabsf(a - b) < e) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_double(const void *d1, const void *d2, void *epsilon) {
-   double a = *((const double*) d1);
-   double b = *((const double*) d2);
-   double e = !epsilon ? 1e-14 : *((double*)epsilon);
-   if (fabs(a - b) < e) {
-       return 0;
-   } else {
-       return a < b ? -1 : 1;
-   }
-}
-
-int ucx_cmp_ptr(const void *ptr1, const void *ptr2, void *data) {
-    const intptr_t p1 = (const intptr_t) ptr1;
-    const intptr_t p2 = (const intptr_t) ptr2;
-    if (p1 == p2) {
-        return 0;
-    } else {
-        return p1  < p2 ? -1 : 1;
-    }
-}
-
-int ucx_cmp_mem(const void *ptr1, const void *ptr2, void *n) {
-    return memcmp(ptr1, ptr2, *((size_t*)n));
-}
-
-/* PRINTF FUNCTIONS */
-
-#ifdef va_copy
-#define UCX_PRINTF_BUFSIZE 256
-#else
-#pragma message("WARNING: C99 va_copy macro not supported by this platform" \
-                " - limiting ucx_*printf to 2 KiB")
-#define UCX_PRINTF_BUFSIZE 0x800
-#endif
-
-int ucx_fprintf(void *stream, write_func wfc, const char *fmt, ...) {
-    int ret;
-    va_list ap;
-    va_start(ap, fmt);
-    ret = ucx_vfprintf(stream, wfc, fmt, ap);
-    va_end(ap);
-    return ret;
-}
-
-int ucx_vfprintf(void *stream, write_func wfc, const char *fmt, va_list ap) {
-    char buf[UCX_PRINTF_BUFSIZE];
-#ifdef va_copy
-    va_list ap2;
-    va_copy(ap2, ap);
-    int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
-    if (ret < 0) {
-        return ret;
-    } else if (ret < UCX_PRINTF_BUFSIZE) {
-        return (int)wfc(buf, 1, ret, stream);
-    } else {
-        if (ret == INT_MAX) {
-            errno = ENOMEM;
-            return -1;
-        }
-        
-        int len = ret + 1;
-        char *newbuf = (char*)malloc(len);
-        if (!newbuf) {
-            return -1;
-        }
-        
-        ret = vsnprintf(newbuf, len, fmt, ap2);
-        if (ret > 0) {
-            ret = (int)wfc(newbuf, 1, ret, stream);
-        }
-        free(newbuf);
-    }
-    return ret;
-#else
-    int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
-    if (ret < 0) {
-        return ret;
-    } else if (ret < UCX_PRINTF_BUFSIZE) {
-        return (int)wfc(buf, 1, ret, stream);
-    } else {
-        errno = ENOMEM;
-        return -1;
-    }
-#endif
-}
-
-sstr_t ucx_asprintf(UcxAllocator *allocator, const char *fmt, ...) {
-    va_list ap;
-    sstr_t ret;
-    va_start(ap, fmt);
-    ret = ucx_vasprintf(allocator, fmt, ap);
-    va_end(ap);
-    return ret;
-}
-
-sstr_t ucx_vasprintf(UcxAllocator *a, const char *fmt, va_list ap) {
-    sstr_t s;
-    s.ptr = NULL;
-    s.length = 0;
-    char buf[UCX_PRINTF_BUFSIZE];
-#ifdef va_copy
-    va_list ap2;
-    va_copy(ap2, ap);
-    int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
-    if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) {
-        s.ptr = (char*)almalloc(a, ret + 1);
-        if (s.ptr) {
-            s.length = (size_t)ret;
-            memcpy(s.ptr, buf, ret);
-            s.ptr[s.length] = '\0';
-        }
-    } else if (ret == INT_MAX) {
-        errno = ENOMEM;
-    } else  {
-        int len = ret + 1;
-        s.ptr = (char*)almalloc(a, len);
-        if (s.ptr) {
-            ret = vsnprintf(s.ptr, len, fmt, ap2);
-            if (ret < 0) {
-                free(s.ptr);
-                s.ptr = NULL;
-            } else {
-                s.length = (size_t)ret;
-            }
-        }
-    }
-#else
-    int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap);
-    if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) {
-        s.ptr = (char*)almalloc(a, ret + 1);
-        if (s.ptr) {
-            s.length = (size_t)ret;
-            memcpy(s.ptr, buf, ret);
-            s.ptr[s.length] = '\0';
-        }
-    } else {
-        errno = ENOMEM;
-    }
-#endif
-    return s;
-}
--- a/ui/Makefile	Sat Apr 15 15:42:31 2023 +0200
+++ b/ui/Makefile	Sat Apr 15 15:45:42 2023 +0200
@@ -43,5 +43,5 @@
 include $(TOOLKIT)/Makefile
 
 $(COMMON_OBJPRE)%.o: common/%.c
-	$(CC) -o $@ -c -I../ucx $(CFLAGS) $(TK_CFLAGS) $<
+	$(CC) -o $@ -c $(CFLAGS) $(TK_CFLAGS) $<
 

mercurial