# HG changeset patch # User Mike Becker # Date 1374236232 -7200 # Node ID baa839a7633fb8805e96230e6bd80597f19e85da # Parent 151f5345f3034b3980aa05b8a9e8fef53269f457 completed documentation on sstr_t + sstrsplit overhaul + allocator version of sstrsplit diff -r 151f5345f303 -r baa839a7633f ucx/string.c --- a/ucx/string.c Wed Jul 17 20:03:01 2013 +0200 +++ b/ucx/string.c Fri Jul 19 14:17:12 2013 +0200 @@ -73,7 +73,7 @@ memcpy(ptr, c1.ptr, cplen); len -= cplen; ptr += cplen; - for (size_t i = 0 ; i < n-1 ; i++) { + for (size_t i = 1 ; i < n ; i++) { sstr_t str = va_arg (ap, sstr_t); cplen = str.length > len ? len : str.length; if(cplen <= 0) { @@ -120,7 +120,12 @@ } sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n) { - if (d.length == 0) { + return sstrsplita(s, d, n, ucx_default_allocator()); +} + +sstr_t* sstrsplita(sstr_t s, sstr_t d, size_t *n, UcxAllocator *allocator) { + if (s.length == 0 || d.length == 0) { + *n = -1; return NULL; } @@ -129,11 +134,15 @@ *n = 1; /* special case: exact match - no processing needed */ - if (s.length == d.length && strncmp(s.ptr, d.ptr, s.length) == 0) { + if (sstrcmp(s, d) == 0) { *n = 0; return NULL; } sstr_t sv = sstrdup(s); + if (sv.length == 0) { + *n = -2; + return NULL; + } for (size_t i = 0 ; i < s.length ; i++) { if (sv.ptr[i] == d.ptr[0]) { @@ -156,19 +165,23 @@ } if ((*n) == nmax) break; } - result = (sstr_t*) malloc(sizeof(sstr_t) * (*n)); + result = (sstr_t*) allocator->malloc(sizeof(sstr_t) * (*n)); - char *pptr = sv.ptr; - for (size_t i = 0 ; i < *n ; i++) { - size_t l = strlen(pptr); - char* ptr = (char*) malloc(l + 1); - memcpy(ptr, pptr, l); - ptr[l] = 0; + if (result) { + char *pptr = sv.ptr; + for (size_t i = 0 ; i < *n ; i++) { + size_t l = strlen(pptr); + char* ptr = (char*) allocator->malloc(l + 1); + 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 { + *n = -2; } - + free(sv.ptr); return result; diff -r 151f5345f303 -r baa839a7633f ucx/string.h --- a/ucx/string.h Wed Jul 17 20:03:01 2013 +0200 +++ b/ucx/string.h Fri Jul 19 14:17:12 2013 +0200 @@ -119,48 +119,157 @@ size_t sstrnlen(size_t count, sstr_t string, ...); -/* - * concatenates n strings +/** + * 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. + * + * Attention: + * + * + * @param count the total number of strings to concatenate + * @param dest new sstr_t with capacity information and allocated memory + * @param src the first string + * @param ... all other strings + * @return the argument for dest is returned + */ +sstr_t sstrncat(size_t count, sstr_t dest, sstr_t src, ...); + + +/** + * Returns a substring starting at the specified location. + * + * Attention: the new string references the same memory area as the + * input string and will NOT be NULL-terminated. + * Use sstrdup() to get a copy. + * + * @param string input string + * @param start start location of the substring + * @return a substring of string starting at start + * + * @see sstrsubsl() + * @see sstrchr() + */ +sstr_t sstrsubs(sstr_t string, size_t start); + +/** + * Returns a substring with a maximum length starting at the specified location. + * + * Attention: the new string references the same memory area as the + * input string and will NOT be NULL-terminated. + * Use sstrdup() to get a copy. + * + * @param string input string + * @param start start location of the substring + * @param length the maximum length of the substring + * @return a substring of string starting at start + * with a maximum length of length + * + * @see sstrsubs() + * @see sstrchr() + */ +sstr_t sstrsubsl(sstr_t string, size_t start, size_t length); + +/** + * Returns a substring starting at the location of the first occurrence of the + * specified character. + * + * If the string does not contain the character, an empty string is returned. + * + * @param string the string where to locate the character + * @param chr the character to locate + * @return a substring starting at the least location of chr + * + * @see sstrsubs() + */ +sstr_t sstrchr(sstr_t string, int chr); + +/** + * Splits a string into parts by using a delimiter string. + * + * This function will return NULL, if one of the following happens: + * + * + * 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 + * perform + 1. + * + * The integer referenced by count is also used as output and is + * set to + * + * + * If the string starts with the delimiter, the first item of the resulting + * list 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. + * + * Attention: All list items AND all sstr_t.ptr of the list + * items must be manually passed to free(). Use sstrsplita() with + * an allocator to managed memory, to avoid this. * - * n number of strings - * s new string with enough memory allocated - * ... strings + * @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 + * NULL on error + * + * @see sstrsplita() */ -sstr_t sstrncat(size_t n, sstr_t s, sstr_t c1, ...); +sstr_t* sstrsplit(sstr_t string, sstr_t delim, size_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 sstr_t array itself are allocated by using the UcxAllocator.malloc() + * function. + * + * Note: the allocator is not used for memory that is freed within the + * same call of this function (locally scoped variables). + * + * @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 + * @param allocator the UcxAllocator used for allocating memory + * @return a list of the split strings as sstr_t array or + * NULL on error + * + * @see sstrsplit() */ -sstr_t sstrsubs(sstr_t s, size_t start); - -/* - * - */ -sstr_t sstrsubsl(sstr_t s, size_t start, size_t length); - -/* - * - */ -sstr_t sstrchr(sstr_t s, int c); - -/* - * splits s into n parts - * - * s the string to split - * d the delimiter string - * n the maximum size of the resulting list - * a size of 0 indicates an unbounded list size - * the actual size of the list will be stored here - * - * Hint: use this value to avoid dynamic reallocation of the result list - * - * Returns a list of the split strings - * NOTE: this list needs to be freed manually after usage - * - * Returns NULL on error - */ -sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n); +sstr_t* sstrsplita(sstr_t string, sstr_t delim, size_t *count, + UcxAllocator *allocator); /** * Compares two UCX strings with standard memcmp(). @@ -188,6 +297,7 @@ * * @param string the string to duplicate * @return a duplicate of the string + * @see sstrdupa() */ sstr_t sstrdup(sstr_t string); @@ -205,6 +315,7 @@ * @param allocator a valid instance of an UcxAllocator * @param string the string to duplicate * @return a duplicate of the string + * @see sstrdup() */ sstr_t sstrdupa(UcxAllocator *allocator, sstr_t string);