# HG changeset patch # User Olaf Wintermann # Date 1418633855 -3600 # Node ID 88092b88ec000bb80b78a405d1b82729af6e4c18 # Parent 0dbdd7e8c1fcd09c5c1c632842b5dd503eddfeb3 ucx update diff -r 0dbdd7e8c1fc -r 88092b88ec00 dav/main.c --- a/dav/main.c Fri Dec 12 15:48:54 2014 +0100 +++ b/dav/main.c Mon Dec 15 09:57:35 2014 +0100 @@ -221,10 +221,16 @@ *path = sstrdup(p).ptr; } else { repo = calloc(1, sizeof(Repository)); - repo->name = ""; - repo->url = strdup(url); + repo->name = strdup(""); repo->decrypt_content = true; - *path = strdup("/"); + if(url[ulen-1] == '/') { + repo->url = strdup(url); + *path = strdup("/"); + } else { + repo->url = util_parent_path(url); + // TODO: check/fix + *path = strdup(util_resource_name(url)-1); + } } return repo; diff -r 0dbdd7e8c1fc -r 88092b88ec00 libidav/resource.c --- a/libidav/resource.c Fri Dec 12 15:48:54 2014 +0100 +++ b/libidav/resource.c Mon Dec 15 09:57:35 2014 +0100 @@ -245,9 +245,7 @@ sstr_t name_str = sstr(name); sstr_t key; - key.length = ns_str.length + name_str.length + 1; - key.ptr = malloc(key.length + 1); - key = sstrncat(key, 3, ns_str, S(" "), name_str); + key = sstrcat(3, ns_str, S(" "), name_str); return ucx_key(key.ptr, key.length); } diff -r 0dbdd7e8c1fc -r 88092b88ec00 libidav/utils.c --- a/libidav/utils.c Fri Dec 12 15:48:54 2014 +0100 +++ b/libidav/utils.c Mon Dec 15 09:57:35 2014 +0100 @@ -172,14 +172,10 @@ } sstr_t url; - url.length = base.length + path.length + add_separator; - url.ptr = malloc(url.length + 1); - url.ptr[url.length] = '\0'; - if(add_separator) { - url = sstrncat(url, 3, base, sstr("/"), path); + url = sstrcat(3, base, sstr("/"), path); } else { - url = sstrncat(url, 2, base, path); + url = sstrcat(2, base, path); } return url.ptr; @@ -192,11 +188,7 @@ char *base_path = util_url_path(sn->base_url); base.length -= strlen(base_path); - sstr_t url; - url.length = base.length + href_str.length; - url.ptr = malloc(url.length + 1); - url.ptr[url.length] = '\0'; - url = sstrncat(url, 2, base, href_str); + sstr_t url = sstrcat(2, base, href_str); curl_easy_setopt(sn->handle, CURLOPT_URL, url); free(url.ptr); diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/Makefile --- a/ucx/Makefile Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/Makefile Mon Dec 15 09:57:35 2014 +0100 @@ -39,6 +39,7 @@ SRC += allocator.c SRC += logging.c SRC += buffer.c +SRC += stack.c OBJ = $(SRC:%.c=../build/ucx/%$(OBJ_EXT)) diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/allocator.c --- a/ucx/allocator.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/allocator.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/allocator.h --- a/ucx/allocator.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/allocator.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -157,6 +157,41 @@ 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 struct definition. */ #define UCX_ALLOCATOR_DEFAULT {NULL, \ diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/buffer.c --- a/ucx/buffer.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/buffer.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -31,22 +31,22 @@ #include #include -UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags) { +UcxBuffer *ucx_buffer_new(void *space, size_t capacity, int flags) { UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer)); if (buffer) { buffer->flags = flags; if (!space) { - buffer->space = (char*)malloc(size); + buffer->space = (char*)malloc(capacity); if (!buffer->space) { free(buffer); return NULL; } - memset(buffer->space, 0, size); + memset(buffer->space, 0, capacity); buffer->flags |= UCX_BUFFER_AUTOFREE; } else { buffer->space = (char*)space; } - buffer->capacity = size; + buffer->capacity = capacity; buffer->size = 0; buffer->pos = 0; @@ -64,13 +64,8 @@ UcxBuffer* ucx_buffer_extract( UcxBuffer *src, size_t start, size_t length, int flags) { - if(src->size == 0) { - return NULL; - } - if (length == 0) { - length = src->size - start; - } - if (start+length > src->size) { + + if (src->size == 0 || length == 0 || start+length > src->capacity) { return NULL; } @@ -99,13 +94,21 @@ case SEEK_END: npos = buffer->size; break; + case SEEK_SET: + npos = 0; + break; default: - npos = 0; + return -1; } + size_t opos = npos; npos += offset; - if (npos > buffer->size) { + if ((offset > 0 && npos < opos) || (offset < 0 && npos > opos)) { + return -1; + } + + if (npos >= buffer->size) { return -1; } else { buffer->pos = npos; @@ -120,7 +123,17 @@ int ucx_buffer_extend(UcxBuffer *buffer, size_t len) { size_t newcap = buffer->capacity; - while (buffer->pos + len > newcap) newcap <<= 1; + + if (buffer->capacity + len < buffer->capacity) { + return -1; + } + + while (buffer->capacity + len > newcap) { + newcap <<= 1; + if (newcap < buffer->capacity) { + return -1; + } + } char *newspace = (char*)realloc(buffer->space, newcap); if (newspace) { @@ -137,18 +150,25 @@ size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems, UcxBuffer *buffer) { size_t len = size * nitems; - if (buffer->pos + len > buffer->capacity) { + size_t required = buffer->pos + len; + if (buffer->pos > required) { + return 0; + } + + if (required > buffer->capacity) { if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) { - if(ucx_buffer_extend(buffer, len)) { - return -1; + if (ucx_buffer_extend(buffer, required - buffer->capacity)) { + return 0; } } else { len = buffer->capacity - buffer->pos; - if (size > 1) len -= len%size; + if (size > 1) { + len -= len%size; + } } } - if (len <= 0) { + if (len == 0) { return len; } diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/buffer.h --- a/ucx/buffer.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/buffer.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -97,11 +97,11 @@ * * @param space pointer to the memory area, or NULL to allocate * new memory - * @param size the size of the buffer + * @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 size, int flags); +UcxBuffer *ucx_buffer_new(void *space, size_t capacity, int flags); /** * Destroys a buffer. @@ -120,10 +120,9 @@ * * @param src the source buffer * @param start the start position of extraction - * @param length the count of bytes to extract or 0 if all of the remaining - * bytes shall be extracted + * @param length the count of bytes to extract (must not be zero) * @param flags feature mask for the new buffer - * @return + * @return a new buffer containing the extraction */ UcxBuffer* ucx_buffer_extract(UcxBuffer *src, size_t start, size_t length, int flags); @@ -136,7 +135,7 @@ * @return a new buffer with the extracted content */ #define ucx_buffer_clone(src,flags) \ - ucx_buffer_extract(src, 0, 0, flags) + ucx_buffer_extract(src, 0, (src)->capacity, flags) /** * Moves the position of the buffer. @@ -145,7 +144,11 @@ * * SEEK_SET marks the start of the buffer. * SEEK_CUR marks the current position. - * SEEK_END marks the first 0-byte in the buffer. + * 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 whence @@ -182,12 +185,12 @@ * the buffer capacity is doubled, as long as it would not hold the current * content plus the additional required bytes. * - * Attention: the argument provided is the count of additional - * bytes the buffer shall hold. It is NOT the total count of bytes the + * Attention: the argument provided is the number of additional + * bytes the buffer shall hold. It is NOT the total number of bytes the * buffer shall hold. * * @param buffer the buffer to extend - * @param additional_bytes the count of additional bytes the buffer shall + * @param additional_bytes the number of additional bytes the buffer shall * at least hold * @return 0 on success or a non-zero value on failure */ @@ -216,7 +219,7 @@ * @param size the length of one element * @param nitems the element count * @param buffer the UcxBuffer to read from - * @return the total count of bytes read + * @return the total number of elements read */ size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems, UcxBuffer *buffer); diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/list.c --- a/ucx/list.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/list.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -72,7 +72,7 @@ while (e != NULL) { f = e; e = e->next; - alloc->free(alloc->pool, f); + alfree(alloc, f); } } @@ -81,7 +81,7 @@ } UcxList *ucx_list_append_a(UcxAllocator *alloc, UcxList *l, void *data) { - UcxList *nl = (UcxList*) alloc->malloc(alloc->pool, sizeof(UcxList)); + UcxList *nl = (UcxList*) almalloc(alloc, sizeof(UcxList)); if (!nl) { return NULL; } @@ -121,7 +121,9 @@ if (l1) { UcxList *last = ucx_list_last(l1); last->next = l2; - l2->prev = last; + if (l2) { + l2->prev = last; + } return l1; } else { return l2; @@ -150,7 +152,7 @@ return -1; } -UcxList *ucx_list_get(const UcxList *l, int index) { +UcxList *ucx_list_get(const UcxList *l, size_t index) { if (l == NULL) return NULL; const UcxList *e = l; @@ -196,7 +198,7 @@ return s; } -UcxList *ucx_list_sort_merge(int length, +static UcxList *ucx_list_sort_merge(int length, UcxList* restrict ls, UcxList* restrict le, UcxList* restrict re, cmp_func fnc, void* data) { @@ -248,6 +250,8 @@ int ln = 1; UcxList *restrict ls = l, *restrict le, *restrict re; + + // check how many elements are already sorted lc = ls; while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) { lc = lc->next; @@ -261,27 +265,30 @@ UcxList *rc; int rn = 1; rc = le; + // skip already sorted elements while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) { rc = rc->next; rn++; } re = rc->next; - // Something left? Sort it! - UcxList *remainder = re; - size_t remainder_length = ucx_list_size(remainder); - if (remainder != NULL) { - remainder = ucx_list_sort(remainder, fnc, data); - } - // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them UcxList *sorted = ucx_list_sort_merge(ln+rn, ls, le, re, fnc, data); + + // Something left? Sort it! + size_t remainder_length = ucx_list_size(re); + if (remainder_length > 0) { + UcxList *remainder = ucx_list_sort(re, fnc, data); - // merge sorted list with (also sorted) remainder - l = ucx_list_sort_merge(ln+rn+remainder_length, - sorted, remainder, NULL, fnc, data); + // merge sorted list with (also sorted) remainder + l = ucx_list_sort_merge(ln+rn+remainder_length, + sorted, remainder, NULL, fnc, data); + } else { + // no remainder - we've got our sorted list + l = sorted; + } return l; } @@ -304,18 +311,18 @@ } UcxList *ucx_list_remove_a(UcxAllocator *alloc, UcxList *l, UcxList *e) { - if (e->prev == NULL) { - if(e->next != NULL) { - e->next->prev = NULL; - l = e->next; - } else { - l = NULL; - } - - } else { - e->prev->next = e->next; + if (l == e) { + l = e->next; + } + + if (e->next) { e->next->prev = e->prev; } - alloc->free(alloc->pool, e); + + if (e->prev) { + e->prev->next = e->next; + } + + alfree(alloc, e); return l; } diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/list.h --- a/ucx/list.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/list.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -169,7 +169,7 @@ /** * Inserts an element at the end of the list. * - * This is generally an O(n) operation, as the end of the list is seeked with + * 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 NULL to @@ -273,7 +273,7 @@ * @return the element at the specified index or NULL, if the * index is greater than the list size */ -UcxList *ucx_list_get(const UcxList *list, int index); +UcxList *ucx_list_get(const UcxList *list, size_t index); /** * Returns the index of an element. @@ -350,7 +350,7 @@ * mylist = ucx_list_remove(mylist, myelem);. * * @param list the list from which the element shall be removed - * @param element the element to removed + * @param element the element to remove * @return returns the updated list pointer or NULL, if the list * is now empty */ @@ -363,7 +363,7 @@ * * @param allocator the allocator to use * @param list the list from which the element shall be removed - * @param element the element to removed + * @param element the element to remove * @return returns the updated list pointer or NULL, if the list * @see ucx_list_remove() */ diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/logging.c --- a/ucx/logging.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/logging.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -75,6 +75,7 @@ if ((logger->mask & UCX_LOGGER_LEVEL) > 0) { text = (char*) ucx_map_int_get(logger->levels, level); n = strlen(text); + n = n > 256 ? 256 : n; memcpy(msg+k, text, n); k += n; msg[k++] = ' '; @@ -87,11 +88,7 @@ n = strlen(file); memcpy(msg+k, file, n); k += n; -#ifdef _WIN32 - k += _snprintf(msg+k, UCX_LOGGER_MSGMAX-k, ":%d ", line); -#else - k += snprintf(msg+k, UCX_LOGGER_MSGMAX-k, ":%d ", line); -#endif /* _WIN32 */ + k += sprintf(msg+k, ":%u ", line); } msg[k++] = '-'; msg[k++] = ' '; diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/logging.h --- a/ucx/logging.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/logging.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -97,7 +97,7 @@ write_func writer; /** - * The date format for timestamp outputs + * The date format for timestamp outputs including the delimiter * (default: "%F %T %z "). * @see UCX_LOGGER_TIMESTAMP */ @@ -162,7 +162,8 @@ * [LEVEL] [TIMESTAMP] [SOURCEFILE]:[LINENO] message * * Attention: the message (including automatically generated information) - * MUST NOT exceed the size of 4 KB. + * 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 diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/map.c --- a/ucx/map.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/map.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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,18 +44,16 @@ allocator = ucx_default_allocator(); } - UcxMap *map = (UcxMap*)allocator->malloc(allocator->pool, sizeof(UcxMap)); + UcxMap *map = (UcxMap*)almalloc(allocator, sizeof(UcxMap)); if (!map) { return NULL; } map->allocator = allocator; - map->map = (UcxMapElement**)allocator->calloc( - allocator->pool, - size, - sizeof(UcxMapElement*)); + map->map = (UcxMapElement**)alcalloc( + allocator, size, sizeof(UcxMapElement*)); if(map->map == NULL) { - allocator->free(allocator->pool, map); + alfree(allocator, map); return NULL; } map->size = size; @@ -70,18 +68,18 @@ if (elem != NULL) { do { UcxMapElement *next = elem->next; - map->allocator->free(map->allocator->pool, elem->key.data); - map->allocator->free(map->allocator->pool, elem); + alfree(map->allocator, elem->key.data); + alfree(map->allocator, elem); elem = next; } while (elem != NULL); } } - map->allocator->free(map->allocator->pool, map->map); + alfree(map->allocator, map->map); } void ucx_map_free(UcxMap *map) { ucx_map_free_elmlist(map); - map->allocator->free(map->allocator->pool, map); + alfree(map->allocator, map); } int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to, @@ -116,10 +114,8 @@ oldmap.allocator = map->allocator; map->size = (map->count * 5) >> 1; - map->map = (UcxMapElement**)map->allocator->calloc( - map->allocator->pool, - map->size, - sizeof(UcxMapElement*)); + map->map = (UcxMapElement**)alcalloc( + map->allocator, map->size, sizeof(UcxMapElement*)); if (!map->map) { *map = oldmap; return 1; @@ -150,9 +146,8 @@ } if (!elm || elm->key.hash != key.hash) { - UcxMapElement *e = (UcxMapElement*)allocator->malloc( - allocator->pool, - sizeof(UcxMapElement)); + UcxMapElement *e = (UcxMapElement*)almalloc( + allocator, sizeof(UcxMapElement)); if (!e) { return -1; } @@ -167,7 +162,7 @@ } if (!elm->key.data) { - void *kd = allocator->malloc(allocator->pool, key.len); + void *kd = almalloc(allocator, key.len); if (!kd) { return -1; } @@ -200,8 +195,8 @@ } else { map->map[slot] = elm->next; } - map->allocator->free(map->allocator->pool, elm->key.data); - map->allocator->free(map->allocator->pool, elm); + alfree(map->allocator, elm->key.data); + alfree(map->allocator, elm); map->count--; } diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/map.h --- a/ucx/map.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/map.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/mempool.c --- a/ucx/mempool.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/mempool.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/mempool.h --- a/ucx/mempool.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/mempool.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -121,7 +121,7 @@ /** * Allocates a pooled memory array. * - * The contents of the allocated memory is set to zero. + * The content of the allocated memory is set to zero. * * @param pool the memory pool * @param nelem amount of elements to allocate @@ -142,7 +142,7 @@ * @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 the location 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); diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/properties.c --- a/ucx/properties.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/properties.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -206,7 +206,7 @@ return 1; } if(ucx_map_sstr_put(map, name, value.ptr)) { - map->allocator->free(map->allocator->pool, value.ptr); + alfree(map->allocator, value.ptr); return 1; } } diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/properties.h --- a/ucx/properties.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/properties.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/stack.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/stack.c Mon Dec 15 09:57:35 2014 +0100 @@ -0,0 +1,143 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stack.h" +#include + +static size_t ucx_stack_align(size_t n) { + int align = n % sizeof(void*); + if (align) { + n += sizeof(void*) - align; + } + return n; +} + +void ucx_stack_init(UcxStack *stack, char* space, size_t size) { + stack->size = size - size % sizeof(void*); + stack->space = space; + stack->top = NULL; + + stack->allocator.pool = stack; + stack->allocator.malloc = (ucx_allocator_malloc) ucx_stack_malloc; + stack->allocator.calloc = (ucx_allocator_calloc) ucx_stack_calloc; + stack->allocator.realloc = (ucx_allocator_realloc) ucx_stack_realloc; + stack->allocator.free = (ucx_allocator_free) ucx_stack_free; +} + +void *ucx_stack_malloc(UcxStack *stack, size_t n) { + + if (ucx_stack_avail(stack) < ucx_stack_align(n)) { + return NULL; + } else { + char *prev = stack->top; + if (stack->top) { + stack->top += ucx_stack_align(ucx_stack_topsize(stack)); + } else { + stack->top = stack->space; + } + + ((struct ucx_stack_metadata*)stack->top)->prev = prev; + ((struct ucx_stack_metadata*)stack->top)->size = n; + stack->top += sizeof(struct ucx_stack_metadata); + + return stack->top; + } +} + +void *ucx_stack_calloc(UcxStack *stack, size_t nelem, size_t elsize) { + void *mem = ucx_stack_malloc(stack, nelem*elsize); + memset(mem, 0, nelem*elsize); + return mem; +} + +void *ucx_stack_realloc(UcxStack *stack, void *ptr, size_t n) { + if (ptr == stack->top) { + if (stack->size - (stack->top - stack->space) < ucx_stack_align(n)) { + return NULL; + } else { + ((struct ucx_stack_metadata*)stack->top - 1)->size = n; + return ptr; + } + } else { + if (ucx_stack_align(((struct ucx_stack_metadata*)ptr - 1)->size) < + ucx_stack_align(n)) { + void *nptr = ucx_stack_malloc(stack, n); + if (nptr) { + memcpy(nptr, ptr, n); + ucx_stack_free(stack, ptr); + + return nptr; + } else { + return NULL; + } + } else { + ((struct ucx_stack_metadata*)ptr - 1)->size = n; + return ptr; + } + } +} + +void ucx_stack_free(UcxStack *stack, void *ptr) { + if (ptr == stack->top) { + stack->top = ((struct ucx_stack_metadata*) stack->top - 1)->prev; + } else { + struct ucx_stack_metadata *next = (struct ucx_stack_metadata*)( + (char*)ptr + + ucx_stack_align(((struct ucx_stack_metadata*) ptr - 1)->size) + ); + next->prev = ((struct ucx_stack_metadata*) ptr - 1)->prev; + } +} + +void ucx_stack_popn(UcxStack *stack, void *dest, size_t n) { + if (ucx_stack_empty(stack)) { + return; + } + + size_t len = ucx_stack_topsize(stack); + if (len > n) { + len = n; + } + + memcpy(dest, stack->top, len); + + ucx_stack_free(stack, stack->top); +} + +size_t ucx_stack_avail(UcxStack *stack) { + size_t avail = ((stack->top ? (stack->size + - (stack->top - stack->space) + - ucx_stack_align(ucx_stack_topsize(stack))) + : stack->size)); + + if (avail > sizeof(struct ucx_stack_metadata)) { + return avail - sizeof(struct ucx_stack_metadata); + } else { + return 0; + } +} diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/stack.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/stack.h Mon Dec 15 09:57:35 2014 +0100 @@ -0,0 +1,233 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 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 +#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 (NULL 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 + * dest, if specified. + * + * Use #ucx_stack_topsize()# to get the amount of memory that must be available + * at the location of dest. + * + * @param stack a pointer to the stack + * @param dest the location where the contents shall be written to, or + * NULL, 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_MAX) + +/** + * Removes the top most element from the stack and copies the content to + * dest. + * + * In contrast to #ucx_stack_pop() the dest pointer MUST + * NOT be NULL. + * + * @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 dest + * @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 */ + diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/string.c --- a/ucx/string.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/string.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -61,32 +61,71 @@ return size; } -sstr_t sstrncat(sstr_t s, size_t n, sstr_t c1, ...) { - va_list ap; - va_start(ap, c1); - s.ptr[0] = 0; +static sstr_t sstrvcat_a( + UcxAllocator *a, + size_t count, + sstr_t s1, + sstr_t s2, + va_list ap) { + sstr_t str; + str.ptr = NULL; + str.length = 0; + if(count < 2) { + return str; + } - size_t len = s.length; - size_t cplen = c1.length > len ? len : c1.length; - char *ptr = s.ptr; + sstr_t *strings = (sstr_t*) calloc(count, sizeof(sstr_t)); + if(!strings) { + return str; + } + + // get all args and overall length + strings[0] = s1; + strings[1] = s2; + size_t strlen = s1.length + s2.length; + for (size_t i=2;i len ? len : str.length; - if(cplen <= 0) { - va_end(ap); - return s; - } - memcpy(ptr, str.ptr, cplen); - len -= cplen; - ptr += cplen; + // create new string + str.ptr = (char*) almalloc(a, strlen + 1); + str.length = strlen; + if(!str.ptr) { + free(strings); + str.length = 0; + return str; + } + + // concatenate strings + size_t pos = 0; + for (size_t i=0;i= s.length) { - //return s; new_sstr.ptr = NULL; new_sstr.length = 0; - return new_sstr; + } else { + if (length > s.length-start) { + length = s.length-start; + } + new_sstr.ptr = &s.ptr[start]; + new_sstr.length = length; } - if (length > s.length-start) { - length = s.length-start; - } - new_sstr.ptr = &s.ptr[start]; - new_sstr.length = length; return new_sstr; } @@ -136,18 +174,18 @@ return n; } -sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n) { +sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { return sstrsplit_a(ucx_default_allocator(), s, d, n); } -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, size_t *n) { +sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, ssize_t *n) { if (s.length == 0 || d.length == 0) { - *n = 0; + *n = -1; return NULL; } sstr_t* result; - size_t nmax = *n; + ssize_t nmax = *n; *n = 1; /* special case: exact match - no processing needed */ @@ -182,18 +220,27 @@ } if ((*n) == nmax) break; } - result = (sstr_t*) allocator->malloc(allocator->pool, sizeof(sstr_t)*(*n)); + result = (sstr_t*) almalloc(allocator, sizeof(sstr_t)*(*n)); if (result) { char *pptr = sv.ptr; - for (size_t i = 0 ; i < *n ; i++) { + for (ssize_t i = 0 ; i < *n ; i++) { size_t l = strlen(pptr); - char* ptr = (char*) allocator->malloc(allocator->pool, l + 1); - memcpy(ptr, pptr, l); - ptr[l] = 0; + char* ptr = (char*) almalloc(allocator, l + 1); + if (ptr) { + memcpy(ptr, pptr, l); + ptr[l] = 0; - result[i] = sstrn(ptr, l); - pptr += l + d.length; + result[i] = sstrn(ptr, l); + pptr += l + d.length; + } else { + for (ssize_t j = i-1 ; j >= 0 ; j--) { + alfree(allocator, result[j].ptr); + } + alfree(allocator, result); + *n = -2; + break; + } } } else { *n = -2; @@ -234,7 +281,7 @@ sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t s) { sstr_t newstring; - newstring.ptr = (char*)allocator->malloc(allocator->pool, s.length + 1); + newstring.ptr = (char*)almalloc(allocator, s.length + 1); if (newstring.ptr) { newstring.length = s.length; newstring.ptr[newstring.length] = 0; diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/string.h --- a/ucx/string.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/string.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -119,38 +119,36 @@ */ size_t sstrnlen(size_t count, sstr_t string, ...); +/** + * Concatenates two or more strings. + * + * The resulting string will be allocated by standard malloc(). + * So developers MUST pass the sstr_t.ptr to free(). + * + * The sstr_t.ptr of the return value will always be NULL- + * 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 strings. - * - * At least one string must be specified and there must be enough memory - * available referenced by the destination sstr_t.ptr for this function to - * successfully concatenate all specified strings. - * - * The sstr_t.length of the destination string specifies the capacity and - * should match the total memory available referenced by the destination - * sstr_t.ptr. This function never copies data beyond the capacity and - * does not modify any of the source strings. + * Concatenates two or more strings using an UcxAllocator. * - * Attention: - *
    - *
  • Any content in the destination string will be overwritten
  • - *
  • The destination sstr_t.ptr is NOT - * NULL-terminated
  • - *
  • The destination sstr_t.length is set to the total length of the - * concatenated strings
  • - *
  • Hint: get a NULL-terminated string by performing - * mystring.ptr[mystring.length]='\0' after calling this - * function
  • - *
+ * See sstrcat() for details. * - * @param dest new sstr_t with capacity information and allocated memory + * @param a the allocator to use * @param count the total number of strings to concatenate - * @param src the first string - * @param ... all other strings - * @return the argument for dest is returned + * @param s1 first string + * @param s2 second string + * @param ... all remaining strings + * @return the concatenated string */ -sstr_t sstrncat(sstr_t dest, size_t count, sstr_t src, ...); +sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...); /** @@ -227,7 +225,7 @@ * * * The integer referenced by count is used as input and determines - * the maximum size of the resulting list, i.e. the maximum count of splits to + * the maximum size of the resulting array, i.e. the maximum count of splits to * perform + 1. * * The integer referenced by count is also used as output and is @@ -237,36 +235,36 @@ *
  • -1, if either the string or the delimiter is an empty string
  • *
  • 0, if the string equals the delimiter
  • *
  • 1, if the string does not contain the delimiter
  • - *
  • the count of list items, otherwise
  • + *
  • the count of array items, otherwise
  • * * * If the string starts with the delimiter, the first item of the resulting - * list will be an empty string. + * array will be an empty string. * * If the string ends with the delimiter and the maximum list size is not - * exceeded, the last list item will be an empty string. + * exceeded, the last array item will be an empty string. * - * Attention: All list items AND all sstr_t.ptr of the list + * Attention: The array pointer AND all sstr_t.ptr of the array * items must be manually passed to free(). 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 list (0 for an - * unbounded list), OUT: the actual size of the list - * @return a list of the split strings as sstr_t array or + * @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 * NULL on error * * @see sstrsplit_a() */ -sstr_t* sstrsplit(sstr_t string, sstr_t delim, size_t *count); +sstr_t* sstrsplit(sstr_t string, sstr_t delim, ssize_t *count); /** * Performing sstrsplit() using an UcxAllocator. * * Read the description of sstrsplit() for details. * - * The memory for the sstr_t.ptr pointers of the list items and the memory for + * 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. * @@ -276,15 +274,15 @@ * @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 list (0 for an - * unbounded list), OUT: the actual size of the list - * @return a list of the split strings as sstr_t array or + * @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 * NULL on error * * @see sstrsplit() */ sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t string, sstr_t delim, - size_t *count); + ssize_t *count); /** * Compares two UCX strings with standard memcmp(). diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/test.c --- a/ucx/test.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/test.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/test.h --- a/ucx/test.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/test.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -84,8 +84,8 @@ /** * Alias for the __func__ preprocessor macro. - * Some compilers use __func__ and others use __FUNC__. - * We use __FUNC__ so we define it for those compilers which use + * Some compilers use __func__ and others use __FUNCTION__. + * We use __FUNCTION__ so we define it for those compilers which use * __func__. */ #define __FUNCTION__ __func__ diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/ucx.c --- a/ucx/ucx.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/ucx.c Mon Dec 15 09:57:35 2014 +0100 @@ -9,7 +9,7 @@ * *

    LICENCE

    * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/ucx.h --- a/ucx/ucx.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/ucx.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -37,10 +37,10 @@ #define UCX_H /** Major UCX version as integer constant. */ -#define UCX_VERSION_MAJOR 1 +#define UCX_VERSION_MAJOR 0 /** Minor UCX version as integer constant. */ -#define UCX_VERSION_MINOR 0 +#define UCX_VERSION_MINOR 9 /** The UCX version in format [major].[minor] */ #define UCX_VERSION UCX_VERSION_MAJOR.UCX_VERSION_MINOR diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/utils.c --- a/ucx/utils.c Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/utils.c Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: @@ -54,18 +54,22 @@ return 0; } + char *lbuf; size_t ncp = 0; - if (!buf) { - buf = (char*)malloc(bufsize); - if(buf == NULL) { + + if(buf) { + lbuf = buf; + } else { + lbuf = (char*)malloc(bufsize); + if(lbuf == NULL) { return 0; } } size_t r; size_t rn = bufsize > n ? n : bufsize; - while((r = readfnc(buf, 1, rn, src)) != 0) { - r = writefnc(buf, 1, r, dest); + while((r = readfnc(lbuf, 1, rn, src)) != 0) { + r = writefnc(lbuf, 1, r, dest); ncp += r; n -= r; rn = bufsize > n ? n : bufsize; @@ -74,7 +78,10 @@ } } - free(buf); + if (lbuf != buf) { + free(lbuf); + } + return ncp; } @@ -212,30 +219,36 @@ va_copy(ap2, ap); int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap); if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) { - s.ptr = (char*)a->malloc(a->pool, ret + 1); - s.length = (size_t)ret; - memcpy(s.ptr, buf, ret); - s.ptr[s.length] = '\0'; + s.ptr = (char*)almalloc(a, ret + 1); + if (s.ptr) { + s.length = (size_t)ret; + memcpy(s.ptr, buf, ret); + s.ptr[s.length] = '\0'; + } } else if (ret == INT_MAX) { errno = ENOMEM; } else { int len = ret + 1; - s.ptr = (char*)a->malloc(a->pool, len); - ret = vsnprintf(s.ptr, len, fmt, ap2); - if (ret < 0) { - free(s.ptr); - s.ptr = NULL; - } else { - s.length = (size_t)ret; + s.ptr = (char*)almalloc(a, len); + if (s.ptr) { + ret = vsnprintf(s.ptr, len, fmt, ap2); + if (ret < 0) { + free(s.ptr); + s.ptr = NULL; + } else { + s.length = (size_t)ret; + } } } #else int ret = vsnprintf(buf, UCX_PRINTF_BUFSIZE, fmt, ap); if (ret > 0 && ret < UCX_PRINTF_BUFSIZE) { - s.ptr = (char*)a->malloc(a->pool, ret + 1); - s.length = (size_t)ret; - memcpy(s.ptr, buf, ret); - s.ptr[s.length] = '\0'; + s.ptr = (char*)almalloc(a, ret + 1); + if (s.ptr) { + s.length = (size_t)ret; + memcpy(s.ptr, buf, ret); + s.ptr[s.length] = '\0'; + } } else { errno = ENOMEM; } diff -r 0dbdd7e8c1fc -r 88092b88ec00 ucx/utils.h --- a/ucx/utils.h Fri Dec 12 15:48:54 2014 +0100 +++ b/ucx/utils.h Mon Dec 15 09:57:35 2014 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2014 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: