Sat, 28 Oct 2017 16:50:03 +0200
updates ucx to version 1.0
--- a/dav/Makefile Sat Oct 28 15:25:17 2017 +0200 +++ b/dav/Makefile Sat Oct 28 16:50:03 2017 +0200 @@ -62,8 +62,8 @@ $(LDFLAGS) $(DAV_LDFLAGS) ../build/tool/%$(OBJ_EXT): %.c - $(CC) $(CFLAGS) $(DAV_CFLAGS) -I../ -o $@ $< + $(CC) $(CFLAGS) $(DAV_CFLAGS) -I../ -I../ucx -o $@ $< cppcheck: $(DAV_SRC) $(SYNC_SRC) - $(CPPCHECK) $(CPPCHECK_CONFIG) $(CPPCHECK_FLAGS) -I../ $+ 2>> ../$(CPPCHECK_LOG) + $(CPPCHECK) $(CPPCHECK_CONFIG) $(CPPCHECK_FLAGS) -I../ucx -I../ $+ 2>> ../$(CPPCHECK_LOG)
--- a/libidav/Makefile Sat Oct 28 15:25:17 2017 +0200 +++ b/libidav/Makefile Sat Oct 28 16:50:03 2017 +0200 @@ -49,8 +49,8 @@ $(AR) $(ARFLAGS) $(AOFLAGS)../build/libidav$(LIB_EXT) $(OBJ) ../build/libidav/%$(OBJ_EXT): %.c - $(CC) $(CFLAGS) $(DAV_CFLAGS) -I../ $(COFLAGS)$@ $< + $(CC) $(CFLAGS) $(DAV_CFLAGS) -I.. -I../ucx $(COFLAGS)$@ $< cppcheck: $(SRC) - $(CPPCHECK) $(CPPCHECK_CONFIG) $(CPPCHECK_FLAGS) -I../ $+ 2>> ../$(CPPCHECK_LOG) + $(CPPCHECK) $(CPPCHECK_CONFIG) $(CPPCHECK_FLAGS) -I../ucx $+ 2>> ../$(CPPCHECK_LOG)
--- a/test/Makefile Sat Oct 28 15:25:17 2017 +0200 +++ b/test/Makefile Sat Oct 28 16:50:03 2017 +0200 @@ -45,5 +45,5 @@ $(LDFLAGS) $(DAV_LDFLAGS) ../build/test/%$(OBJ_EXT): %.c - $(CC) $(CFLAGS) $(DAV_CFLAGS) -I../ -o $@ $< + $(CC) $(CFLAGS) $(DAV_CFLAGS) -I../ucx -I../ -o $@ $<
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/README Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,4 @@ +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 Oct 28 15:25:17 2017 +0200 +++ b/ucx/allocator.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,8 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "ucx/allocator.h" + #include <stdlib.h> -#include "allocator.h" UcxAllocator default_allocator = { NULL,
--- a/ucx/allocator.h Sat Oct 28 15:25:17 2017 +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 2016 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/avl.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/avl.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,9 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <limits.h> +#include "ucx/avl.h" -#include "avl.h" +#include <limits.h> #define ptrcast(ptr) ((void*)(ptr)) #define alloc_tree(al) (UcxAVLTree*) almalloc((al), sizeof(UcxAVLTree))
--- a/ucx/avl.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,327 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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_strcmp() 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. - * @param tree the tree to destroy - */ -void ucx_avl_free(UcxAVLTree *tree); - -/** - * Macro for initializing a new UcxAVLTree with the default allocator and a - * ucx_ptrcmp() compare function. - * - * @return a new default UcxAVLTree object - */ -#define ucx_avl_default_new() ucx_avl_new_a(ucx_ptrcmp, 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/buffer.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/buffer.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,7 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "buffer.h" +#include "ucx/buffer.h" + #include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -64,8 +65,9 @@ UcxBuffer* ucx_buffer_extract( UcxBuffer *src, size_t start, size_t length, int flags) { - - if (src->size == 0 || length == 0 || start+length > src->capacity) { + if (src->size == 0 || length == 0 || + ((size_t)-1) - start < length || start+length > src->capacity) + { return NULL; } @@ -150,7 +152,6 @@ size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems, UcxBuffer *buffer) { size_t len = size * nitems; - const char *string = ptr; size_t required = buffer->pos + len; if (buffer->pos > required) { return 0;
--- a/ucx/buffer.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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) - -/** - * 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, char *str); - -#ifdef __cplusplus -} -#endif - -#endif /* UCX_BUFFER_H */ -
--- a/ucx/list.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/list.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,7 +26,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "list.h" +#include "ucx/list.h" UcxList *ucx_list_clone(UcxList *l, copy_func fnc, void *data) { return ucx_list_clone_a(ucx_default_allocator(), l, fnc, data); @@ -241,7 +241,7 @@ } static UcxList *ucx_list_sort_merge(int length, - UcxList* restrict ls, UcxList* restrict le, UcxList* restrict re, + UcxList* ls, UcxList* le, UcxList* re, cmp_func fnc, void* data) { UcxList** sorted = (UcxList**) malloc(sizeof(UcxList*)*length); @@ -291,7 +291,7 @@ UcxList *lc; int ln = 1; - UcxList *restrict ls = l, *restrict le, *restrict re; + UcxList *ls = l, *le, *re; // check how many elements are already sorted lc = ls;
--- a/ucx/list.h Sat Oct 28 15:25:17 2017 +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 2016 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 = 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(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, 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(). - * - * @param list the list for which the contents shall be freed - * @param destr the destructor function (e.g. stdlib free()) - * @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 end of the list, if it is not present in the list. - * - * - * @param list the list where to append the data, or <code>NULL</code> to - * create a new list - * @param data the data to insert - * @param cmpfnc the compare function - * @param cmpdata additional data for the compare function - * @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_once(UcxList *list, void *data, - cmp_func cmpfnc, void *cmpdata); - -/** - * Inserts an element at the end of the list, if it is not present in 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 - * @param cmpfnc the compare function - * @param cmpdata additional data for the compare function - * @return <code>list</code>, if it is not <code>NULL</code> or a pointer to - * the newly created list otherwise - * @see ucx_list_append_a() - */ -UcxList *ucx_list_append_once_a(UcxAllocator *allocator, - UcxList *list, void *data, cmp_func cmpfnc, void *cmpdata); - -/** - * 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(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(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); - -#ifdef __cplusplus -} -#endif - -#endif /* UCX_LIST_H */ -
--- a/ucx/logging.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/logging.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,7 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "logging.h" +#include "ucx/logging.h" + #include <stdlib.h> #include <string.h> #include <stdarg.h>
--- a/ucx/logging.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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> - * - * <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, ...); - -/** - * 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/map.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/map.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,11 +26,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "ucx/map.h" + #include <stdlib.h> #include <string.h> -#include "map.h" - UcxMap *ucx_map_new(size_t size) { return ucx_map_new_a(NULL, size); } @@ -99,8 +99,7 @@ map->count = 0; } -int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to, - copy_func fnc, void *data) { +int ucx_map_copy(UcxMap *from, UcxMap *to, copy_func fnc, void *data) { UcxMapIterator i = ucx_map_iterator(from); void *value; UCX_MAP_FOREACH(key, value, i) { @@ -155,8 +154,8 @@ } size_t slot = key.hash%map->size; - UcxMapElement *restrict elm = map->map[slot]; - UcxMapElement *restrict prev = NULL; + UcxMapElement *elm = map->map[slot]; + UcxMapElement *prev = NULL; while (elm && elm->key.hash < key.hash) { prev = elm; @@ -194,14 +193,14 @@ return 0; } -void* ucx_map_get_and_remove(UcxMap *map, UcxKey key, _Bool remove) { +static void* ucx_map_get_and_remove(UcxMap *map, UcxKey key, int remove) { if(key.hash == 0) { key.hash = ucx_hash((char*)key.data, key.len); } size_t slot = key.hash%map->size; - UcxMapElement *restrict elm = map->map[slot]; - UcxMapElement *restrict pelm = NULL; + 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;
--- a/ucx/map.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,423 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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 for a key of a UcxMap. */ -struct UcxKey { - /** 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. */ - UcxKey key; -}; - -/** Structure for an iterator over a UcxMap. */ -struct UcxMapIterator { - /** The map to iterate over. */ - UcxMap *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 (e.g. stdlib free()). - * - * 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 pointer to the 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 *restrict from, UcxMap *restrict 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 *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 *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((void*)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((void*)&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((void*)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((void*)&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((void*)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((void*)&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(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 *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); - - -#ifdef __cplusplus -} -#endif - -#endif /* UCX_MAP_H */ -
--- a/ucx/mempool.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/mempool.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,6 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "ucx/mempool.h" + #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -34,8 +36,6 @@ #endif #include <inttypes.h> -#include "mempool.h" - /** Capsule for destructible memory chunks. */ typedef struct { /** The destructor for the memory chunk. */ @@ -56,7 +56,10 @@ void *ptr; } ucx_regdestr; -UCX_EXTERN void ucx_mempool_shared_destr(void* ptr) { +#ifdef __cplusplus +extern "C" +#endif +void ucx_mempool_shared_destr(void* ptr) { ucx_regdestr *rd = (ucx_regdestr*)ptr; rd->destructor(rd->ptr); }
--- a/ucx/mempool.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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 <stddef.h> -#include "allocator.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. - * - * 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. - * - * @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/properties.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/properties.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,12 +26,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "ucx/properties.h" + #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "properties.h" - UcxProperties *ucx_properties_new() { UcxProperties *parser = (UcxProperties*)malloc( sizeof(UcxProperties));
--- a/ucx/properties.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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. - * - * @param prop the UcxProperties object - * @param map the target map - * @return The UcxProperties.error code (i.e. 0 on success). - * @see ucx_properties_fill() - */ -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/stack.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/stack.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,7 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "stack.h" +#include "ucx/stack.h" + #include <string.h> static size_t ucx_stack_align(size_t n) {
--- a/ucx/stack.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,232 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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 - * @see ucx_allocator_malloc() - */ -void *ucx_stack_malloc(UcxStack *stack, size_t n); - -/** - * Alias for #ucx_stack_malloc(). - * @param stack a pointer to the stack - * @param n amount of memory to allocate - * @return a pointer to the allocated memory - * @see ucx_stack_malloc - */ -#define ucx_stack_push(stack, n) ucx_stack_malloc(stack, n) - -/** - * 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); - -/** - * Alias for #ucx_stack_calloc(). - * - * @param stack a pointer to the stack - * @param n amount of elements to allocate - * @param elsize amount of memory per element - * @return a pointer to the allocated memory - * @see ucx_stack_calloc - */ -#define ucx_stack_pusharr(stack,n,elsize) ucx_stack_calloc(stack,n,elssize) - -/** - * 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>. - * - * In contrast to #ucx_stack_pop() the <code>dest</code> pointer <code>MUST - * NOT</code> be <code>NULL</code>. - * - * @param stack a pointer to the stack - * @param dest the location where the contents shall be written to - * @param n copies at most n elements 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/string.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/string.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,15 +26,16 @@ * 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> -#include "string.h" -#include "allocator.h" - sstr_t sstr(char *cstring) { sstr_t string; string.ptr = cstring;
--- a/ucx/string.h Sat Oct 28 15:25:17 2017 +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 2016 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> - -/** Shortcut for a <code>sstr_t struct</code> literal. */ -#define ST(s) { (char*)s, sizeof(s)-1 } - -/** Shortcut for the conversion of a C string to a <code>sstr_t</code>. */ -#define S(s) sstrn((char*)s, sizeof(s)-1) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * The UCX string structure. - */ -typedef struct { - /** A reference to the string (<b>not necessarily <code>NULL</code> - * -terminated</b>) */ - char *ptr; - /** The length of the string */ - size_t length; -} sstr_t; - -/** - * 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 hold a <i>reference</i> to the C string. If you - * do want a copy, use sstrdup() on the return value of this function. - * - * @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 hold a <i>reference</i> to the C string. If you - * do want a copy, use sstrdup() on the return value of this function. - * - * @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); - - -/** - * Returns the cumulated length of all specified strings. - * - * At least one string must be specified. - * - * <b>Attention:</b> if the count argument does not match the count of the - * specified strings, the behavior is undefined. - * - * @param count the total number of specified strings (so at least 1) - * @param string the first string - * @param ... all other strings - * @return the cumulated length of all strings - */ -size_t sstrnlen(size_t count, sstr_t string, ...); - -/** - * 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 s2 second string - * @param ... all remaining strings - * @return the concatenated string - */ -sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...); - -/** - * Concatenates two or more strings using a UcxAllocator. - * - * See sstrcat() for details. - * - * @param a the allocator to use - * @param count the total number of strings to concatenate - * @param s1 first string - * @param s2 second string - * @param ... all remaining strings - * @return the concatenated string - */ -sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...); - - -/** - * Returns a substring starting at the specified location. - * - * <b>Attention:</b> the new string references the same memory area as the - * input string and will <b>NOT</b> 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 a maximum length starting at the specified location. - * - * <b>Attention:</b> the new string references the same memory area as the - * input string and will <b>NOT</b> 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 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 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 sstrstr(sstr_t string, sstr_t 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 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() - */ -sstr_t* sstrsplit(sstr_t string, sstr_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. - * - * <b>Note:</b> the allocator is not used for memory that is freed within the - * same call of this function (locally scoped variables). - * - * @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() - */ -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t string, sstr_t delim, - ssize_t *count); - -/** - * 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) - */ -int sstrcmp(sstr_t s1, sstr_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 difference between the - * first two differing characters otherwise (i.e. 0 if the strings match and - * no characters differ) - */ -int sstrcasecmp(sstr_t s1, sstr_t 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. - * - * @param string the string to duplicate - * @return a duplicate of the string - * @see sstrdup_a() - */ -sstr_t sstrdup(sstr_t string); - -/** - * Creates a duplicate of the specified string using a UcxAllocator. - * - * The new sstr_t will contain a copy allocated by the allocators - * ucx_allocator_malloc function. So it is implementation depended, whether the - * returned sstr_t.ptr pointer must be passed to the allocators - * ucx_allocator_free function manually. - * - * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>- - * terminated. - * - * @param allocator a valid instance of a UcxAllocator - * @param string the string to duplicate - * @return a duplicate of the string - * @see sstrdup() - */ -sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t 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); - -/** - * 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 sstrprefix(sstr_t string, sstr_t 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 sstrsuffix(sstr_t string, sstr_t suffix); - -/** - * Returns a lower case version of a string. - * - * This function creates a duplicate of the input string, first. See the - * documentation of sstrdup() for the implications. - * - * @param string the input string - * @return the resulting lower case string - * @see sstrdup() - */ -sstr_t sstrlower(sstr_t string); - -/** - * Returns a lower case version of a string. - * - * This function creates a duplicate of the input string, first. See the - * documentation of sstrdup_a() for the implications. - * - * @param allocator the allocator used for duplicating the string - * @param string the input string - * @return the resulting lower case string - * @see sstrdup_a() - */ -sstr_t sstrlower_a(UcxAllocator *allocator, sstr_t string); - -/** - * Returns a upper case version of a string. - * - * This function creates a duplicate of the input string, first. See the - * documentation of sstrdup() for the implications. - * - * @param string the input string - * @return the resulting upper case string - * @see sstrdup() - */ -sstr_t sstrupper(sstr_t string); - -/** - * Returns a upper case version of a string. - * - * This function creates a duplicate of the input string, first. See the - * documentation of sstrdup_a() for the implications. - * - * @param allocator the allocator used for duplicating the string - * @param string the input string - * @return the resulting upper case string - * @see sstrdup_a() - */ -sstr_t sstrupper_a(UcxAllocator *allocator, sstr_t string); - -#ifdef __cplusplus -} -#endif - -#endif /* UCX_STRING_H */
--- a/ucx/test.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/test.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,7 +26,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "test.h" +#include "ucx/test.h" UcxTestSuite* ucx_test_suite_new() { UcxTestSuite* suite = (UcxTestSuite*) malloc(sizeof(UcxTestSuite));
--- a/ucx/test.h Sat Oct 28 15:25:17 2017 +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 2016 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.c Sat Oct 28 15:25:17 2017 +0200 +++ b/ucx/ucx.c Sat Oct 28 16:50:03 2017 +0200 @@ -2,14 +2,23 @@ * @mainpage UAP Common Extensions * Library with common and useful functions, macros and data structures. * <p> - * Latest available source:<br/> + * 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> + * - or - * <a href="https://develop.uap-core.de/hg/ucx"> * https://develop.uap-core.de/hg/ucx</a> * </p> * * <h2>LICENCE</h2> * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -34,4 +43,4 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "ucx.h" +#include "ucx/ucx.h"
--- a/ucx/ucx.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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 0 - -/** Minor UCX version as integer constant. */ -#define UCX_VERSION_MINOR 12 - -#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 -#ifndef _Bool -#define _Bool bool -#define restrict -#endif -/** Use C naming even when compiling with C++. */ -#define UCX_EXTERN extern "C" -extern "C" { -#else -/** Pointless in C. */ -#define UCX_EXTERN -#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*); - -#ifdef __cplusplus -} -#endif - -#endif /* UCX_H */ -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/allocator.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,206 @@ +/* + * 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 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/avl.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,327 @@ +/* + * 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_strcmp() 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. + * @param tree the tree to destroy + */ +void ucx_avl_free(UcxAVLTree *tree); + +/** + * Macro for initializing a new UcxAVLTree with the default allocator and a + * ucx_ptrcmp() compare function. + * + * @return a new default UcxAVLTree object + */ +#define ucx_avl_default_new() ucx_avl_new_a(ucx_ptrcmp, 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 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/buffer.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,270 @@ +/* + * 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) + +/** + * 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, char *str); + +#ifdef __cplusplus +} +#endif + +#endif /* UCX_BUFFER_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/list.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,428 @@ +/* + * 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 = 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(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, 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(). + * + * @param list the list for which the contents shall be freed + * @param destr the destructor function (e.g. stdlib free()) + * @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 end of the list, if it is not present in the list. + * + * + * @param list the list where to append the data, or <code>NULL</code> to + * create a new list + * @param data the data to insert + * @param cmpfnc the compare function + * @param cmpdata additional data for the compare function + * @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_once(UcxList *list, void *data, + cmp_func cmpfnc, void *cmpdata); + +/** + * Inserts an element at the end of the list, if it is not present in 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 + * @param cmpfnc the compare function + * @param cmpdata additional data for the compare function + * @return <code>list</code>, if it is not <code>NULL</code> or a pointer to + * the newly created list otherwise + * @see ucx_list_append_a() + */ +UcxList *ucx_list_append_once_a(UcxAllocator *allocator, + UcxList *list, void *data, cmp_func cmpfnc, void *cmpdata); + +/** + * 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(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(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); + +#ifdef __cplusplus +} +#endif + +#endif /* UCX_LIST_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/logging.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,238 @@ +/* + * 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> + * + * <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, ...); + +/** + * 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/map.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,422 @@ +/* + * 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 for a key of a UcxMap. */ +struct UcxKey { + /** 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. */ + UcxKey key; +}; + +/** Structure for an iterator over a UcxMap. */ +struct UcxMapIterator { + /** The map to iterate over. */ + UcxMap *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 (e.g. stdlib free()). + * + * 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 pointer to the 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 *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 *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 *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((void*)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((void*)&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((void*)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((void*)&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((void*)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((void*)&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(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 *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); + + +#ifdef __cplusplus +} +#endif + +#endif /* UCX_MAP_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/mempool.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,200 @@ +/* + * 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. + * + * 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. + * + * @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 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/properties.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,218 @@ +/* + * 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. + * + * @param prop the UcxProperties object + * @param map the target map + * @return The UcxProperties.error code (i.e. 0 on success). + * @see ucx_properties_fill() + */ +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 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/stack.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,232 @@ +/* + * 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 + * @see ucx_allocator_malloc() + */ +void *ucx_stack_malloc(UcxStack *stack, size_t n); + +/** + * Alias for #ucx_stack_malloc(). + * @param stack a pointer to the stack + * @param n amount of memory to allocate + * @return a pointer to the allocated memory + * @see ucx_stack_malloc + */ +#define ucx_stack_push(stack, n) ucx_stack_malloc(stack, n) + +/** + * 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); + +/** + * Alias for #ucx_stack_calloc(). + * + * @param stack a pointer to the stack + * @param n amount of elements to allocate + * @param elsize amount of memory per element + * @return a pointer to the allocated memory + * @see ucx_stack_calloc + */ +#define ucx_stack_pusharr(stack,n,elsize) ucx_stack_calloc(stack,n,elssize) + +/** + * 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>. + * + * In contrast to #ucx_stack_pop() the <code>dest</code> pointer <code>MUST + * NOT</code> be <code>NULL</code>. + * + * @param stack a pointer to the stack + * @param dest the location where the contents shall be written to + * @param n copies at most n elements 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 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/string.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,460 @@ +/* + * 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> + +/** Shortcut for a <code>sstr_t struct</code> literal. */ +#define ST(s) { (char*)s, sizeof(s)-1 } + +/** Shortcut for the conversion of a C string to a <code>sstr_t</code>. */ +#define S(s) sstrn((char*)s, sizeof(s)-1) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The UCX string structure. + */ +typedef struct { + /** A reference to the string (<b>not necessarily <code>NULL</code> + * -terminated</b>) */ + char *ptr; + /** The length of the string */ + size_t length; +} sstr_t; + +/** + * 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 hold a <i>reference</i> to the C string. If you + * do want a copy, use sstrdup() on the return value of this function. + * + * @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 hold a <i>reference</i> to the C string. If you + * do want a copy, use sstrdup() on the return value of this function. + * + * @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); + + +/** + * Returns the cumulated length of all specified strings. + * + * At least one string must be specified. + * + * <b>Attention:</b> if the count argument does not match the count of the + * specified strings, the behavior is undefined. + * + * @param count the total number of specified strings (so at least 1) + * @param string the first string + * @param ... all other strings + * @return the cumulated length of all strings + */ +size_t sstrnlen(size_t count, sstr_t string, ...); + +/** + * 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 s2 second string + * @param ... all remaining strings + * @return the concatenated string + */ +sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...); + +/** + * Concatenates two or more strings using a UcxAllocator. + * + * See sstrcat() for details. + * + * @param a the allocator to use + * @param count the total number of strings to concatenate + * @param s1 first string + * @param s2 second string + * @param ... all remaining strings + * @return the concatenated string + */ +sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...); + + +/** + * Returns a substring starting at the specified location. + * + * <b>Attention:</b> the new string references the same memory area as the + * input string and will <b>NOT</b> 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 a maximum length starting at the specified location. + * + * <b>Attention:</b> the new string references the same memory area as the + * input string and will <b>NOT</b> 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 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 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 sstrstr(sstr_t string, sstr_t 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 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() + */ +sstr_t* sstrsplit(sstr_t string, sstr_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. + * + * <b>Note:</b> the allocator is not used for memory that is freed within the + * same call of this function (locally scoped variables). + * + * @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() + */ +sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t string, sstr_t delim, + ssize_t *count); + +/** + * 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) + */ +int sstrcmp(sstr_t s1, sstr_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 difference between the + * first two differing characters otherwise (i.e. 0 if the strings match and + * no characters differ) + */ +int sstrcasecmp(sstr_t s1, sstr_t 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. + * + * @param string the string to duplicate + * @return a duplicate of the string + * @see sstrdup_a() + */ +sstr_t sstrdup(sstr_t string); + +/** + * Creates a duplicate of the specified string using a UcxAllocator. + * + * The new sstr_t will contain a copy allocated by the allocators + * ucx_allocator_malloc function. So it is implementation depended, whether the + * returned sstr_t.ptr pointer must be passed to the allocators + * ucx_allocator_free function manually. + * + * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>- + * terminated. + * + * @param allocator a valid instance of a UcxAllocator + * @param string the string to duplicate + * @return a duplicate of the string + * @see sstrdup() + */ +sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t 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); + +/** + * 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 sstrprefix(sstr_t string, sstr_t 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 sstrsuffix(sstr_t string, sstr_t suffix); + +/** + * Returns a lower case version of a string. + * + * This function creates a duplicate of the input string, first. See the + * documentation of sstrdup() for the implications. + * + * @param string the input string + * @return the resulting lower case string + * @see sstrdup() + */ +sstr_t sstrlower(sstr_t string); + +/** + * Returns a lower case version of a string. + * + * This function creates a duplicate of the input string, first. See the + * documentation of sstrdup_a() for the implications. + * + * @param allocator the allocator used for duplicating the string + * @param string the input string + * @return the resulting lower case string + * @see sstrdup_a() + */ +sstr_t sstrlower_a(UcxAllocator *allocator, sstr_t string); + +/** + * Returns a upper case version of a string. + * + * This function creates a duplicate of the input string, first. See the + * documentation of sstrdup() for the implications. + * + * @param string the input string + * @return the resulting upper case string + * @see sstrdup() + */ +sstr_t sstrupper(sstr_t string); + +/** + * Returns a upper case version of a string. + * + * This function creates a duplicate of the input string, first. See the + * documentation of sstrdup_a() for the implications. + * + * @param allocator the allocator used for duplicating the string + * @param string the input string + * @return the resulting upper case string + * @see sstrdup_a() + */ +sstr_t sstrupper_a(UcxAllocator *allocator, sstr_t string); + +#ifdef __cplusplus +} +#endif + +#endif /* UCX_STRING_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/test.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,241 @@ +/* + * 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 */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/ucx.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,139 @@ +/* + * 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 1 + +/** Minor UCX version as integer constant. */ +#define UCX_VERSION_MINOR 0 + +/** 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*); + +#ifdef __cplusplus +} +#endif + +#endif /* UCX_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/ucx/utils.h Sat Oct 28 16:50:03 2017 +0200 @@ -0,0 +1,281 @@ +/* + * 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 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ucx.h" +#include "string.h" +#include "allocator.h" +#include <inttypes.h> +#include <string.h> +#include <stdarg.h> + +/** + * 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_strcmp(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_strncmp(const void *s1, const void *s2, void *n); + +/** + * 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_intcmp(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_floatcmp(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_doublecmp(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_ptrcmp(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_memcmp(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 Oct 28 15:25:17 2017 +0200 +++ b/ucx/utils.c Sat Oct 28 16:50:03 2017 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * 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: @@ -26,7 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "utils.h" +#include "ucx/utils.h" + #include <math.h> #include <stdio.h> #include <limits.h>
--- a/ucx/utils.h Sat Oct 28 15:25:17 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,281 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2016 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 - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ucx.h" -#include "string.h" -#include "allocator.h" -#include <inttypes.h> -#include <string.h> -#include <stdarg.h> - -/** - * 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_strcmp(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_strncmp(const void *s1, const void *s2, void *n); - -/** - * 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_intcmp(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_floatcmp(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_doublecmp(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_ptrcmp(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_memcmp(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 */ -