Fri, 19 Jul 2013 14:17:12 +0200
completed documentation on sstr_t + sstrsplit overhaul + allocator version of sstrsplit
ucx/string.c | file | annotate | diff | comparison | revisions | |
ucx/string.h | file | annotate | diff | comparison | revisions |
1.1 --- a/ucx/string.c Wed Jul 17 20:03:01 2013 +0200 1.2 +++ b/ucx/string.c Fri Jul 19 14:17:12 2013 +0200 1.3 @@ -73,7 +73,7 @@ 1.4 memcpy(ptr, c1.ptr, cplen); 1.5 len -= cplen; 1.6 ptr += cplen; 1.7 - for (size_t i = 0 ; i < n-1 ; i++) { 1.8 + for (size_t i = 1 ; i < n ; i++) { 1.9 sstr_t str = va_arg (ap, sstr_t); 1.10 cplen = str.length > len ? len : str.length; 1.11 if(cplen <= 0) { 1.12 @@ -120,7 +120,12 @@ 1.13 } 1.14 1.15 sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n) { 1.16 - if (d.length == 0) { 1.17 + return sstrsplita(s, d, n, ucx_default_allocator()); 1.18 +} 1.19 + 1.20 +sstr_t* sstrsplita(sstr_t s, sstr_t d, size_t *n, UcxAllocator *allocator) { 1.21 + if (s.length == 0 || d.length == 0) { 1.22 + *n = -1; 1.23 return NULL; 1.24 } 1.25 1.26 @@ -129,11 +134,15 @@ 1.27 *n = 1; 1.28 1.29 /* special case: exact match - no processing needed */ 1.30 - if (s.length == d.length && strncmp(s.ptr, d.ptr, s.length) == 0) { 1.31 + if (sstrcmp(s, d) == 0) { 1.32 *n = 0; 1.33 return NULL; 1.34 } 1.35 sstr_t sv = sstrdup(s); 1.36 + if (sv.length == 0) { 1.37 + *n = -2; 1.38 + return NULL; 1.39 + } 1.40 1.41 for (size_t i = 0 ; i < s.length ; i++) { 1.42 if (sv.ptr[i] == d.ptr[0]) { 1.43 @@ -156,19 +165,23 @@ 1.44 } 1.45 if ((*n) == nmax) break; 1.46 } 1.47 - result = (sstr_t*) malloc(sizeof(sstr_t) * (*n)); 1.48 + result = (sstr_t*) allocator->malloc(sizeof(sstr_t) * (*n)); 1.49 1.50 - char *pptr = sv.ptr; 1.51 - for (size_t i = 0 ; i < *n ; i++) { 1.52 - size_t l = strlen(pptr); 1.53 - char* ptr = (char*) malloc(l + 1); 1.54 - memcpy(ptr, pptr, l); 1.55 - ptr[l] = 0; 1.56 + if (result) { 1.57 + char *pptr = sv.ptr; 1.58 + for (size_t i = 0 ; i < *n ; i++) { 1.59 + size_t l = strlen(pptr); 1.60 + char* ptr = (char*) allocator->malloc(l + 1); 1.61 + memcpy(ptr, pptr, l); 1.62 + ptr[l] = 0; 1.63 1.64 - result[i] = sstrn(ptr, l); 1.65 - pptr += l + d.length; 1.66 + result[i] = sstrn(ptr, l); 1.67 + pptr += l + d.length; 1.68 + } 1.69 + } else { 1.70 + *n = -2; 1.71 } 1.72 - 1.73 + 1.74 free(sv.ptr); 1.75 1.76 return result;
2.1 --- a/ucx/string.h Wed Jul 17 20:03:01 2013 +0200 2.2 +++ b/ucx/string.h Fri Jul 19 14:17:12 2013 +0200 2.3 @@ -119,48 +119,157 @@ 2.4 size_t sstrnlen(size_t count, sstr_t string, ...); 2.5 2.6 2.7 -/* 2.8 - * concatenates n strings 2.9 +/** 2.10 + * Concatenates strings. 2.11 + * 2.12 + * At least one string must be specified and there must be enough memory 2.13 + * available referenced by the destination sstr_t.ptr for this function to 2.14 + * successfully concatenate all specified strings. 2.15 + * 2.16 + * The sstr_t.length of the destination string specifies the capacity and 2.17 + * should match the total memory available referenced by the destination 2.18 + * sstr_t.ptr. This function <i>never</i> copies data beyond the capacity and 2.19 + * does not modify any of the source strings. 2.20 + * 2.21 + * <b>Attention:</b> 2.22 + * <ul> 2.23 + * <li>Any content in the destination string will be overwritten</li> 2.24 + * <li>The destination sstr_t.ptr is <b>NOT</b> 2.25 + * <code>NULL</code>-terminated</li> 2.26 + * <li>The destination sstr_t.length is set to the total length of the 2.27 + * concatenated strings</li> 2.28 + * <li><i>Hint:</i> get a <code>NULL</code>-terminated string by performing 2.29 + * <code>mystring.ptr[mystring.length]='\0'</code> after calling this 2.30 + * function</li> 2.31 + * </ul> 2.32 + * 2.33 + * @param count the total number of strings to concatenate 2.34 + * @param dest new sstr_t with capacity information and allocated memory 2.35 + * @param src the first string 2.36 + * @param ... all other strings 2.37 + * @return the argument for <code>dest</code> is returned 2.38 + */ 2.39 +sstr_t sstrncat(size_t count, sstr_t dest, sstr_t src, ...); 2.40 + 2.41 + 2.42 +/** 2.43 + * Returns a substring starting at the specified location. 2.44 + * 2.45 + * <b>Attention:</b> the new string references the same memory area as the 2.46 + * input string and will <b>NOT</b> be <code>NULL</code>-terminated. 2.47 + * Use sstrdup() to get a copy. 2.48 + * 2.49 + * @param string input string 2.50 + * @param start start location of the substring 2.51 + * @return a substring of <code>string</code> starting at <code>start</code> 2.52 + * 2.53 + * @see sstrsubsl() 2.54 + * @see sstrchr() 2.55 + */ 2.56 +sstr_t sstrsubs(sstr_t string, size_t start); 2.57 + 2.58 +/** 2.59 + * Returns a substring with a maximum length starting at the specified location. 2.60 + * 2.61 + * <b>Attention:</b> the new string references the same memory area as the 2.62 + * input string and will <b>NOT</b> be <code>NULL</code>-terminated. 2.63 + * Use sstrdup() to get a copy. 2.64 + * 2.65 + * @param string input string 2.66 + * @param start start location of the substring 2.67 + * @param length the maximum length of the substring 2.68 + * @return a substring of <code>string</code> starting at <code>start</code> 2.69 + * with a maximum length of <code>length</code> 2.70 + * 2.71 + * @see sstrsubs() 2.72 + * @see sstrchr() 2.73 + */ 2.74 +sstr_t sstrsubsl(sstr_t string, size_t start, size_t length); 2.75 + 2.76 +/** 2.77 + * Returns a substring starting at the location of the first occurrence of the 2.78 + * specified character. 2.79 + * 2.80 + * If the string does not contain the character, an empty string is returned. 2.81 + * 2.82 + * @param string the string where to locate the character 2.83 + * @param chr the character to locate 2.84 + * @return a substring starting at the least location of <code>chr</code> 2.85 + * 2.86 + * @see sstrsubs() 2.87 + */ 2.88 +sstr_t sstrchr(sstr_t string, int chr); 2.89 + 2.90 +/** 2.91 + * Splits a string into parts by using a delimiter string. 2.92 + * 2.93 + * This function will return <code>NULL</code>, if one of the following happens: 2.94 + * <ul> 2.95 + * <li>the string length is zero</li> 2.96 + * <li>the delimeter length is zero</li> 2.97 + * <li>the string equals the delimeter</li> 2.98 + * <li>memory allocation fails</li> 2.99 + * </ul> 2.100 + * 2.101 + * The integer referenced by <code>count</code> is used as input and determines 2.102 + * the maximum size of the resulting list, i.e. the maximum count of splits to 2.103 + * perform + 1. 2.104 + * 2.105 + * The integer referenced by <code>count</code> is also used as output and is 2.106 + * set to 2.107 + * <ul> 2.108 + * <li>-2, on memory allocation errors</li> 2.109 + * <li>-1, if either the string or the delimiter is an empty string</li> 2.110 + * <li>0, if the string equals the delimiter</li> 2.111 + * <li>1, if the string does not contain the delimiter</li> 2.112 + * <li>the count of list items, otherwise</li> 2.113 + * </ul> 2.114 + * 2.115 + * If the string starts with the delimiter, the first item of the resulting 2.116 + * list will be an empty string. 2.117 + * 2.118 + * If the string ends with the delimiter and the maximum list size is not 2.119 + * exceeded, the last list item will be an empty string. 2.120 + * 2.121 + * <b>Attention:</b> All list items <b>AND</b> all sstr_t.ptr of the list 2.122 + * items must be manually passed to <code>free()</code>. Use sstrsplita() with 2.123 + * an allocator to managed memory, to avoid this. 2.124 * 2.125 - * n number of strings 2.126 - * s new string with enough memory allocated 2.127 - * ... strings 2.128 + * @param string the string to split 2.129 + * @param delim the delimiter string 2.130 + * @param count IN: the maximum size of the resulting list (0 for an 2.131 + * unbounded list), OUT: the actual size of the list 2.132 + * @return a list of the split strings as sstr_t array or 2.133 + * <code>NULL</code> on error 2.134 + * 2.135 + * @see sstrsplita() 2.136 */ 2.137 -sstr_t sstrncat(size_t n, sstr_t s, sstr_t c1, ...); 2.138 +sstr_t* sstrsplit(sstr_t string, sstr_t delim, size_t *count); 2.139 2.140 - 2.141 -/* 2.142 - * 2.143 +/** 2.144 + * Performing sstrsplit() using an UcxAllocator. 2.145 + * 2.146 + * <i>Read the description of sstrsplit() for details.</i> 2.147 + * 2.148 + * The memory for the sstr_t.ptr pointers of the list items and the memory for 2.149 + * the sstr_t array itself are allocated by using the UcxAllocator.malloc() 2.150 + * function. 2.151 + * 2.152 + * <b>Note:</b> the allocator is not used for memory that is freed within the 2.153 + * same call of this function (locally scoped variables). 2.154 + * 2.155 + * @param string the string to split 2.156 + * @param delim the delimiter string 2.157 + * @param count IN: the maximum size of the resulting list (0 for an 2.158 + * unbounded list), OUT: the actual size of the list 2.159 + * @param allocator the UcxAllocator used for allocating memory 2.160 + * @return a list of the split strings as sstr_t array or 2.161 + * <code>NULL</code> on error 2.162 + * 2.163 + * @see sstrsplit() 2.164 */ 2.165 -sstr_t sstrsubs(sstr_t s, size_t start); 2.166 - 2.167 -/* 2.168 - * 2.169 - */ 2.170 -sstr_t sstrsubsl(sstr_t s, size_t start, size_t length); 2.171 - 2.172 -/* 2.173 - * 2.174 - */ 2.175 -sstr_t sstrchr(sstr_t s, int c); 2.176 - 2.177 -/* 2.178 - * splits s into n parts 2.179 - * 2.180 - * s the string to split 2.181 - * d the delimiter string 2.182 - * n the maximum size of the resulting list 2.183 - * a size of 0 indicates an unbounded list size 2.184 - * the actual size of the list will be stored here 2.185 - * 2.186 - * Hint: use this value to avoid dynamic reallocation of the result list 2.187 - * 2.188 - * Returns a list of the split strings 2.189 - * NOTE: this list needs to be freed manually after usage 2.190 - * 2.191 - * Returns NULL on error 2.192 - */ 2.193 -sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n); 2.194 +sstr_t* sstrsplita(sstr_t string, sstr_t delim, size_t *count, 2.195 + UcxAllocator *allocator); 2.196 2.197 /** 2.198 * Compares two UCX strings with standard <code>memcmp()</code>. 2.199 @@ -188,6 +297,7 @@ 2.200 * 2.201 * @param string the string to duplicate 2.202 * @return a duplicate of the string 2.203 + * @see sstrdupa() 2.204 */ 2.205 sstr_t sstrdup(sstr_t string); 2.206 2.207 @@ -205,6 +315,7 @@ 2.208 * @param allocator a valid instance of an UcxAllocator 2.209 * @param string the string to duplicate 2.210 * @return a duplicate of the string 2.211 + * @see sstrdup() 2.212 */ 2.213 sstr_t sstrdupa(UcxAllocator *allocator, sstr_t string); 2.214