Fri, 18 Nov 2016 15:27:45 +0100
updates UCX to version 0.11
--- a/ucx/Makefile Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/Makefile Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. # -# Copyright 2015 Olaf Wintermann. All rights reserved. +# 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: @@ -32,15 +32,15 @@ SRC = utils.c SRC += list.c SRC += map.c +SRC += avl.c SRC += properties.c SRC += mempool.c SRC += string.c SRC += test.c SRC += allocator.c +SRC += logging.c SRC += buffer.c -SRC += logging.c SRC += stack.c -SRC += avl.c OBJ = $(SRC:%.c=../build/ucx/%$(OBJ_EXT))
--- a/ucx/allocator.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/allocator.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/allocator.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/allocator.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -28,7 +28,7 @@ /** * Allocator for custom memory management. * - * An UCX allocator consists of a pointer to the memory area / pool and four + * 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>. @@ -38,7 +38,7 @@ * 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. An UcxMempool is just + * can be provided to the memory management functions. A UcxMempool is just * one example. * * @see mempool.h @@ -116,7 +116,7 @@ * 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 an UcxAllocator as argument. Note that using + * 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. *
--- a/ucx/avl.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/avl.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -29,6 +29,8 @@ #include "avl.h" #define ptrcast(ptr) ((void*)(ptr)) +#define alloc_tree(al) (UcxAVLTree*) almalloc((al), sizeof(UcxAVLTree)) +#define alloc_node(al) (UcxAVLNode*) almalloc((al), sizeof(UcxAVLNode)) static void ucx_avl_connect(UcxAVLTree *tree, UcxAVLNode *node, UcxAVLNode *child, intptr_t nullkey) { @@ -107,7 +109,7 @@ } UcxAVLTree *ucx_avl_new_a(cmp_func cmpfunc, UcxAllocator *allocator) { - UcxAVLTree *tree = almalloc(allocator, sizeof(UcxAVLTree)); + UcxAVLTree* tree = alloc_tree(allocator); if (tree) { tree->allocator = allocator; tree->cmpfunc = cmpfunc; @@ -167,7 +169,7 @@ } if (cmpresult) { - UcxAVLNode *e = almalloc(tree->allocator, sizeof(UcxAVLNode)); + UcxAVLNode* e = alloc_node(tree->allocator); if (e) { e->key = key; e->value = value; e->height = 1; e->parent = e->left = e->right = NULL; @@ -185,7 +187,7 @@ return 0; } } else { - tree->root = almalloc(tree->allocator, sizeof(UcxAVLNode)); + tree->root = alloc_node(tree->allocator); if (tree->root) { tree->root->key = key; tree->root->value = value; tree->root->height = 1;
--- a/ucx/avl.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/avl.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -44,7 +44,7 @@ #include "ucx.h" #include "allocator.h" -#include <stdint.h> +#include <inttypes.h> #ifdef __cplusplus extern "C" { @@ -134,7 +134,7 @@ UcxAVLTree *ucx_avl_new_a(cmp_func cmpfunc, UcxAllocator *allocator); /** - * Destroys an UcxAVLTree. + * Destroys a UcxAVLTree. * @param tree the tree to destroy */ void ucx_avl_free(UcxAVLTree *tree);
--- a/ucx/buffer.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/buffer.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/buffer.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/buffer.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -197,9 +197,9 @@ int ucx_buffer_extend(UcxBuffer *buffer, size_t additional_bytes); /** - * Writes data to an UcxBuffer. + * Writes data to a UcxBuffer. * - * The position of the buffer is increased by the number of bytes read. + * 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 @@ -211,7 +211,7 @@ UcxBuffer *buffer); /** - * Reads data from an UcxBuffer. + * Reads data from a UcxBuffer. * * The position of the buffer is increased by the number of bytes read. *
--- a/ucx/list.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/list.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -76,6 +76,13 @@ } } +void ucx_list_free_content(UcxList* list, ucx_destructor destr) { + while (list != NULL) { + destr(list->data); + list = list->next; + } +} + UcxList *ucx_list_append(UcxList *l, void *data) { return ucx_list_append_a(ucx_default_allocator(), l, data); } @@ -99,6 +106,41 @@ } } +UcxList *ucx_list_append_once(UcxList *l, void *data, + cmp_func cmpfnc, void *cmpdata) { + return ucx_list_append_once_a(ucx_default_allocator(), l, + data, cmpfnc, cmpdata); +} + +UcxList *ucx_list_append_once_a(UcxAllocator *alloc, UcxList *l, void *data, + cmp_func cmpfnc, void *cmpdata) { + + UcxList *last = NULL; + { + UcxList *e = l; + while (e) { + if (cmpfnc(e->data, data, cmpdata) == 0) { + return l; + } + last = e; + e = e->next; + } + } + + UcxList *nl = ucx_list_append_a(alloc, NULL, data); + if (!nl) { + return NULL; + } + + if (last == NULL) { + return nl; + } else { + nl->prev = last; + last->next = nl; + return l; + } +} + UcxList *ucx_list_prepend(UcxList *l, void *data) { return ucx_list_prepend_a(ucx_default_allocator(), l, data); } @@ -117,6 +159,40 @@ return nl; } +UcxList *ucx_list_prepend_once(UcxList *l, void *data, + cmp_func cmpfnc, void* cmpdata) { + return ucx_list_prepend_once_a(ucx_default_allocator(), l, + data, cmpfnc, cmpdata); +} + +UcxList *ucx_list_prepend_once_a(UcxAllocator *alloc, UcxList *l, void *data, + cmp_func cmpfnc, void *cmpdata) { + + if (l) { + int found = 0; + UcxList *first; + { + UcxList *e = l; + while (e) { + found |= (cmpfnc(e->data, data, cmpdata) == 0); + first = e; + e = e->prev; + } + } + + if (found) { + return first; + } else { + UcxList *nl = ucx_list_append_a(alloc, NULL, data); + nl->next = first; + first->prev = nl; + return nl; + } + } else { + return ucx_list_append_a(alloc, NULL, data); + } +} + UcxList *ucx_list_concat(UcxList *l1, UcxList *l2) { if (l1) { UcxList *last = ucx_list_last(l1);
--- a/ucx/list.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/list.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -46,13 +46,13 @@ /** * Loop statement for UCX lists. * - * The first argument is a pointer to the list. In most cases this will be the + * 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. * - * The second argument is the name of the iteration variable. The scope of - * this variable is limited to the <code>UCX_FOREACH</code> statement. - * * @param list The first element of the list * @param elem The variable name of the element */ @@ -102,13 +102,12 @@ UcxList *ucx_list_clone(UcxList *list, copy_func cpyfnc, void* data); /** - * Creates an element-wise copy of a list using an UcxAllocator. + * Creates an element-wise copy of a list using a UcxAllocator. * * See ucx_list_clone() for details. * - * Keep in mind, that you might want to pass the allocator as an (part of the) - * argument for the <code>data</code> parameter, if you want the copy_func() to - * make use of the allocator. + * 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 @@ -146,17 +145,19 @@ * Destroys the entire list. * * The members of the list are not automatically freed, so ensure they are - * otherwise referenced or a memory leak will occur. + * 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 an UcxAllocator. + * Destroys the entire list using a UcxAllocator. * * See ucx_list_free() for details. * @@ -167,6 +168,20 @@ 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 @@ -181,7 +196,7 @@ UcxList *ucx_list_append(UcxList *list, void *data); /** - * Inserts an element at the end of the list using an UcxAllocator. + * Inserts an element at the end of the list using a UcxAllocator. * * See ucx_list_append() for details. * @@ -196,6 +211,41 @@ 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 @@ -212,7 +262,7 @@ UcxList *ucx_list_prepend(UcxList *list, void *data); /** - * Inserts an element at the beginning of the list using an UcxAllocator. + * Inserts an element at the beginning of the list using a UcxAllocator. * * See ucx_list_prepend() for details. * @@ -226,6 +276,37 @@ UcxList *ucx_list_prepend_a(UcxAllocator *allocator, UcxList *list, void *data); /** + * Inserts an element at the beginning of the list, if it is not present + * in the list. + * + * @param list the list where to insert 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 a pointer to the new list head + * @see ucx_list_prepend() + */ +UcxList *ucx_list_prepend_once(UcxList *list, void *data, + cmp_func cmpfnc, void *cmpdata); + +/** + * Inserts an element at the beginning of the list, if it is not present in + * the list, using a UcxAllocator. + * + * @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 + * @param cmpfnc the compare function + * @param cmpdata additional data for the compare function + * @return a pointer to the new list head + * @see ucx_list_prepend_a() + */ +UcxList *ucx_list_prepend_once_a(UcxAllocator *allocator, + UcxList *list, void *data, cmp_func cmpfnc, void *cmpdata); + +/** * Concatenates two lists. * * Either of the two arguments may be <code>NULL</code>. @@ -327,7 +408,7 @@ int ucx_list_contains(UcxList *list, void *elem, cmp_func cmpfnc, void *data); /** - * Sorts an UcxList with natural merge sort. + * 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. @@ -357,7 +438,7 @@ UcxList *ucx_list_remove(UcxList *list, UcxList *element); /** - * Removes an element from the list using an UcxAllocator. + * Removes an element from the list using a UcxAllocator. * * See ucx_list_remove() for details. *
--- a/ucx/logging.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/logging.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/logging.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/logging.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/map.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/map.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/map.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/map.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -59,7 +59,7 @@ * * @param key the variable name for the key * @param value the variable name for the value - * @param iter an UcxMapIterator + * @param iter a UcxMapIterator * @see ucx_map_iterator() */ #define UCX_MAP_FOREACH(key,value,iter) \ @@ -68,13 +68,13 @@ /** Type for the UCX map. @see UcxMap */ typedef struct UcxMap UcxMap; -/** Type for a key of an UcxMap. @see UcxKey */ +/** Type for a key of a UcxMap. @see UcxKey */ typedef struct UcxKey UcxKey; -/** Type for an element of an UcxMap. @see UcxMapElement */ +/** Type for an element of a UcxMap. @see UcxMapElement */ typedef struct UcxMapElement UcxMapElement; -/** Type for an iterator over an UcxMap. @see UcxMapIterator */ +/** Type for an iterator over a UcxMap. @see UcxMapIterator */ typedef struct UcxMapIterator UcxMapIterator; /** Structure for the UCX map. */ @@ -89,7 +89,7 @@ size_t count; }; -/** Structure for a key of an UcxMap. */ +/** Structure for a key of a UcxMap. */ struct UcxKey { /** The key data. */ void *data; @@ -99,7 +99,7 @@ int hash; }; -/** Structure for an element of an UcxMap. */ +/** Structure for an element of a UcxMap. */ struct UcxMapElement { /** The value data. */ void *data; @@ -111,7 +111,7 @@ UcxKey key; }; -/** Structure for an iterator over an UcxMap. */ +/** Structure for an iterator over a UcxMap. */ struct UcxMapIterator { /** The map to iterate over. */ UcxMap *map; @@ -136,7 +136,7 @@ UcxMap *ucx_map_new(size_t size); /** - * Creates a new hash map with the specified size using an UcxAllocator. + * 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 @@ -357,13 +357,13 @@ ucx_map_remove(map, ucx_key((void*)&key, sizeof(key))) /** - * Creates an UcxKey based on the given data. + * 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 an UcxKey with implicitly computed hash + * @return a UcxKey with implicitly computed hash * @see ucx_hash() */ UcxKey ucx_key(void *data, size_t len); @@ -380,14 +380,14 @@ /** * Creates an iterator for a map. * - * <b>Note:</b> An UcxMapIterator iterates over all elements in all element + * <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 an UcxMapIterator directly. + * 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
--- a/ucx/mempool.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/mempool.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/mempool.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/mempool.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -127,10 +127,8 @@ /** * Reallocates pooled memory. * - * If the memory to be reallocated is not contained by the specified pool, this - * function will possibly fail. In case the memory had to be moved to another - * location, this function will print out a message to <code>stderr</code> - * and exit the program with error code <code>EXIT_FAILURE</code>. + * 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 @@ -146,10 +144,8 @@ * 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, this - * is considered as a severe error and an error message is written to - * <code>stderr</code> and the application is shut down with code - * <code>EXIT_FAILURE</code>. + * If you specify memory, that is not pooled by the specified memory pool, the + * behavior is undefined. * * @param pool the memory pool * @param ptr a pointer to the memory that shall be freed @@ -180,7 +176,7 @@ * pool is destroyed. * * The only requirement for the specified memory is, that it <b>MUST</b> be - * pooled memory by an UcxMempool or an element-compatible mempool. The pointer + * 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. *
--- a/ucx/properties.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/properties.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/properties.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/properties.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -127,7 +127,7 @@ UcxProperties *ucx_properties_new(); /** - * Destroys an UcxProperties object. + * Destroys a UcxProperties object. * @param prop the UcxProperties object to destroy */ void ucx_properties_free(UcxProperties *prop); @@ -137,8 +137,8 @@ * * 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 performs these successive calls of - * ucx_properties_next() within a while loop and puts the properties to a map. + * is a convenience function that reads as much data as possible by using this + * function. * * * @param prop the UcxProperties object @@ -170,7 +170,7 @@ int ucx_properties_next(UcxProperties *prop, sstr_t *name, sstr_t *value); /** - * Retrieves all available key/value-pairs and puts them into an UcxMap. + * 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. @@ -183,13 +183,11 @@ int ucx_properties2map(UcxProperties *prop, UcxMap *map); /** - * Loads a properties file to an UcxMap. + * Loads a properties file to a UcxMap. * - * This is a convenience function that reads chunks of 1 KB from an input + * This is a convenience function that reads data from an input * stream until the end of the stream is reached. * - * An UcxProperties object is implicitly created and destroyed. - * * @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 @@ -200,7 +198,7 @@ int ucx_properties_load(UcxMap *map, FILE *file); /** - * Stores an UcxMap to a file. + * Stores a UcxMap to a file. * * The key/value-pairs are written by using the following format: *
--- a/ucx/stack.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/stack.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/stack.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/stack.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -39,7 +39,6 @@ #define UCX_STACK_H #include "ucx.h" -#include <stdint.h> #include "allocator.h" #ifdef __cplusplus @@ -179,7 +178,7 @@ * @see ucx_stack_free * @see ucx_stack_popn */ -#define ucx_stack_pop(stack, dest) ucx_stack_popn(stack, dest, SIZE_MAX) +#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>
--- a/ucx/string.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/string.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -175,6 +175,24 @@ return n; } +sstr_t sstrstr(sstr_t string, sstr_t match) { + if (match.length == 0) { + return string; + } + + for (size_t i = 0 ; i < string.length ; i++) { + sstr_t substr = sstrsubs(string, i); + if (sstrprefix(substr, match)) { + return substr; + } + } + + sstr_t emptystr; + emptystr.length = 0; + emptystr.ptr = NULL; + return emptystr; +} + sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { return sstrsplit_a(ucx_default_allocator(), s, d, n); } @@ -201,23 +219,13 @@ } for (size_t i = 0 ; i < s.length ; i++) { - if (sv.ptr[i] == d.ptr[0]) { - _Bool match = 1; - for (size_t j = 1 ; j < d.length ; j++) { - if (j+i < s.length) { - match &= (sv.ptr[i+j] == d.ptr[j]); - } else { - match = 0; - break; - } + sstr_t substr = sstrsubs(sv, i); + if (sstrprefix(substr, d)) { + (*n)++; + for (size_t j = 0 ; j < d.length ; j++) { + sv.ptr[i+j] = 0; } - if (match) { - (*n)++; - for (size_t j = 0 ; j < d.length ; j++) { - sv.ptr[i+j] = 0; - } - i += d.length; - } + i += d.length - 1; // -1, because the loop will do a i++ } if ((*n) == nmax) break; }
--- a/ucx/string.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/string.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -137,7 +137,7 @@ sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...); /** - * Concatenates two or more strings using an UcxAllocator. + * Concatenates two or more strings using a UcxAllocator. * * See sstrcat() for details. * @@ -214,6 +214,23 @@ 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: @@ -260,7 +277,7 @@ sstr_t* sstrsplit(sstr_t string, sstr_t delim, ssize_t *count); /** - * Performing sstrsplit() using an UcxAllocator. + * Performing sstrsplit() using a UcxAllocator. * * <i>Read the description of sstrsplit() for details.</i> * @@ -331,7 +348,7 @@ sstr_t sstrdup(sstr_t string); /** - * Creates a duplicate of the specified string using an UcxAllocator. + * 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 @@ -341,7 +358,7 @@ * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>- * terminated. * - * @param allocator a valid instance of an UcxAllocator + * @param allocator a valid instance of a UcxAllocator * @param string the string to duplicate * @return a duplicate of the string * @see sstrdup()
--- a/ucx/test.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/test.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/test.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/test.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -160,7 +160,7 @@ /** * Macro for a #UcxTest function header. * - * Use this macro to declare and/or define an #UcxTest function. + * Use this macro to declare and/or define a #UcxTest function. * * @param name the name of the test function */ @@ -196,7 +196,7 @@ /** * Macro for a test subroutine function header. * - * Use this to declare and/or define an subroutine that can be called by using + * 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
--- a/ucx/ucx.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/ucx.c Fri Nov 18 15:27:45 2016 +0100 @@ -9,7 +9,7 @@ * * <h2>LICENCE</h2> * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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:
--- a/ucx/ucx.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/ucx.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -40,10 +40,7 @@ #define UCX_VERSION_MAJOR 0 /** Minor UCX version as integer constant. */ -#define UCX_VERSION_MINOR 9 - -/** The UCX version in format [major].[minor] */ -#define UCX_VERSION UCX_VERSION_MAJOR.UCX_VERSION_MINOR +#define UCX_VERSION_MINOR 11 #include <stdlib.h>
--- a/ucx/utils.c Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/utils.c Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -48,7 +48,7 @@ return cpy; } -size_t ucx_stream_copy(void *src, void *dest, read_func readfnc, +size_t ucx_stream_bncopy(void *src, void *dest, read_func readfnc, write_func writefnc, char* buf, size_t bufsize, size_t n) { if(n == 0 || bufsize == 0) { return 0;
--- a/ucx/utils.h Fri Nov 18 13:39:20 2016 +0100 +++ b/ucx/utils.h Fri Nov 18 15:27:45 2016 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * 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: @@ -45,11 +45,16 @@ #include "ucx.h" #include "string.h" #include "allocator.h" -#include <stdint.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 @@ -82,23 +87,26 @@ * @param n the maximum number of bytes that shall be copied * @return the total number of bytes copied */ -size_t ucx_stream_copy(void *src, void *dest, read_func rfnc, write_func wfnc, +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 ucx_stream_copy using the default copy buffer. + * 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_hcopy(src,dest,rfnc,wfnc) ucx_stream_copy(\ - src, dest, (read_func)rfnc, (write_func)wfnc, NULL, 0x100, SIZE_MAX) +#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_copy using the default copy buffer and a copy limit. + * Shorthand for ucx_stream_bncopy using a default copy buffer. * * @param src the source stream * @param dest the destination stream @@ -107,8 +115,27 @@ * @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_copy(\ - src, dest, (read_func)rfnc, (write_func)wfnc, NULL, 0x100, n) +#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. @@ -219,10 +246,6 @@ */ sstr_t ucx_asprintf(UcxAllocator *allocator, const char *fmt, ...); -/** Shortcut for ucx_asprintf() with default allocator. */ -#define ucx_sprintf(fmt, ...) \ - ucx_asprintf(ucx_default_allocator(), fmt, __VA_ARGS__) - /** * <code>va_list</code> version of ucx_asprintf(). * @@ -234,8 +257,12 @@ */ 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 an + * A <code>printf()</code> like function which writes the output to a * UcxBuffer. * * @param buffer the buffer the data is written to