# HG changeset patch # User Mike Becker # Date 1405349650 -7200 # Node ID 998bf7c643b4c16be52d5e1422949f3abb9a9f8b # Parent 1e9012ad8215c97e4b941a474276d2c8647f7968# Parent 2185f19dcc45b45f0f70550059ddc6952845fd8e merged sstrcat function diff -r 2185f19dcc45 -r 998bf7c643b4 ucx/Makefile --- a/ucx/Makefile Mon Jul 14 13:51:02 2014 +0200 +++ b/ucx/Makefile Mon Jul 14 16:54:10 2014 +0200 @@ -39,6 +39,7 @@ SRC += allocator.c SRC += logging.c SRC += buffer.c +SRC += stack.c OBJ = $(SRC:%.c=../build/release/ucx/%$(OBJ_EXT)) OBJ_D = $(SRC:%.c=../build/debug/ucx/%$(OBJ_EXT)) diff -r 2185f19dcc45 -r 998bf7c643b4 ucx/mempool.h --- a/ucx/mempool.h Mon Jul 14 13:51:02 2014 +0200 +++ b/ucx/mempool.h Mon Jul 14 16:54:10 2014 +0200 @@ -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 2185f19dcc45 -r 998bf7c643b4 ucx/stack.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/stack.c Mon Jul 14 16:54:10 2014 +0200 @@ -0,0 +1,108 @@ +/* + * 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 + +UcxStack ucx_stack_new(char* space, size_t size) { + UcxStack stack; + stack.size = size; + stack.space = stack.top = space; + + UcxAllocator alloc; + alloc.pool = &stack; + alloc.malloc = (ucx_allocator_malloc) ucx_stack_malloc; + alloc.calloc = (ucx_allocator_calloc) ucx_stack_calloc; + alloc.realloc = (ucx_allocator_realloc) ucx_stack_realloc; + alloc.free = (ucx_allocator_free) ucx_stack_free; + + stack.allocator = alloc; + + return stack; +} + +void *ucx_stack_malloc(UcxStack *stack, size_t n) { + n += n % sizeof(void*); + + if (stack->top + n + sizeof(size_t) > stack->space + stack->size) { + return NULL; + } else { + void *ptr = stack->top; + + *((size_t*) (stack->top + n)) = n; + stack->top += n + sizeof(size_t); + + return ptr; + } +} + +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 - sizeof(size_t) - *((size_t*) stack->top - 1)) { + + stack->top = (char*)ptr + n; + *((size_t*)stack->top) = n; + stack->top += sizeof(size_t); + + return ptr; + } else { + size_t* sptr = (size_t*) (((char*) ptr)-sizeof(size_t)); + if (*sptr < n) { + void *nptr = ucx_stack_malloc(stack, n); + if (nptr) { + memcpy(nptr, ptr, *sptr); + ucx_stack_free(stack, ptr); + return nptr; + } else { + return NULL; + } + } else { + *sptr = n; + return ptr; + } + } +} + +void ucx_stack_free(UcxStack *stack, void *ptr) { + if (ptr == stack->top+sizeof(size_t)) { + + } else { + + } +} + +void ucx_stack_pop(UcxStack *stack, void *dest) { +} + +void ucx_stack_popn(UcxStack *stack, void *dest, size_t n) { +} diff -r 2185f19dcc45 -r 998bf7c643b4 ucx/stack.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ucx/stack.h Mon Jul 14 16:54:10 2014 +0200 @@ -0,0 +1,198 @@ +/* + * 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; + +/** + * Wraps memory in a new UcxStack structure. + * + * @param space the memory area that shall be managed + * @param size size of the memory area + * @return a new UcxStack structure + */ +UcxStack ucx_stack_new(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(s, n) ucx_stack_malloc(s, 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 nelem 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(st,n,es) ucx_stack_calloc(st,n,es) + +/** + * 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) (*(((size_t*)stack->top - 1)) + +/** + * 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 + */ +void ucx_stack_pop(UcxStack *stack, void *dest); + +/** + * 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 + */ +#define ucx_stack_avail(stack) ((stack->size) - (s.top - s.space)\ + - sizeof(size_t)) + + +#ifdef __cplusplus +} +#endif + +#endif /* UCX_STACK_H */ + diff -r 2185f19dcc45 -r 998bf7c643b4 ucx/string.c --- a/ucx/string.c Mon Jul 14 13:51:02 2014 +0200 +++ b/ucx/string.c Mon Jul 14 16:54:10 2014 +0200 @@ -90,7 +90,7 @@ } // create new string - str.ptr = malloc(strlen + 1); + str.ptr = almalloc(a, strlen + 1); str.length = strlen; if(!str.ptr) { free(strings); diff -r 2185f19dcc45 -r 998bf7c643b4 ucx/utils.c --- a/ucx/utils.c Mon Jul 14 13:51:02 2014 +0200 +++ b/ucx/utils.c Mon Jul 14 16:54:10 2014 +0200 @@ -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; }