Mon, 20 Feb 2017 16:57:09 +0100
reimplementation of sstrsplit
test/string_tests.c | file | annotate | diff | comparison | revisions | |
ucx/string.c | file | annotate | diff | comparison | revisions | |
ucx/string.h | file | annotate | diff | comparison | revisions |
--- a/test/string_tests.c Mon Feb 20 16:04:14 2017 +0100 +++ b/test/string_tests.c Mon Feb 20 16:57:09 2017 +0100 @@ -299,7 +299,7 @@ UCX_TEST_ASSERT(n == 3, "ewdeb, list length must be 3"); UCX_TEST_ASSERT(strcmp(list[0].ptr, "a") == 0, "ewdeb, fst item corrupt"); UCX_TEST_ASSERT(strcmp(list[1].ptr, "b") == 0, "ewdeb, snd item corrupt"); - UCX_TEST_ASSERT(strcmp(list[2].ptr, "c") == 0, "ewdeb, trd item corrupt"); + UCX_TEST_ASSERT(strcmp(list[2].ptr, "c,") == 0, "ewdeb, trd item corrupt"); for(int i=0;i<n;i++) { free(list[i].ptr); }
--- a/ucx/string.c Mon Feb 20 16:04:14 2017 +0100 +++ b/ucx/string.c Mon Feb 20 16:57:09 2017 +0100 @@ -212,62 +212,58 @@ } else /* no match possible */ { *n = 1; sstr_t *result = (sstr_t*) almalloc(allocator, sizeof(sstr_t)); - result->ptr = (char*) almalloc(allocator, 1+s.length); - memcpy(result->ptr, s.ptr, s.length); - result->ptr[s.length] = '\0'; - result->length = s.length; + *result = sstrdup_a(allocator, s); return result; } } - sstr_t* result; ssize_t nmax = *n; - *n = 1; - - sstr_t sv = sstrdup(s); - if (sv.length == 0) { - *n = -2; - return NULL; - } - - for (size_t i = 0 ; i < s.length ; i++) { - 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; - } - i += d.length - 1; // -1, because the loop will do a i++ - } - if ((*n) == nmax) break; - } - result = (sstr_t*) almalloc(allocator, sizeof(sstr_t)*(*n)); + sstr_t* result = (sstr_t*) almalloc(allocator, sizeof(sstr_t)); if (result) { - char *pptr = sv.ptr; - for (ssize_t i = 0 ; i < *n ; i++) { - size_t l = strlen(pptr); - char* ptr = (char*) almalloc(allocator, l + 1); - if (ptr) { - memcpy(ptr, pptr, l); - ptr[l] = '\0'; + sstr_t curpos = s; + ssize_t j = 1; + while (1) { + sstr_t match = sstrstr(curpos, d); + if (match.length > 0) { + /* is this our last try? */ + if (nmax == 0 || j < nmax) { + /* copy the current string to the array */ + sstr_t item = sstrn(curpos.ptr, match.ptr - curpos.ptr); + result[j-1] = sstrdup_a(allocator, item); + size_t processed = item.length + d.length; + curpos.ptr += processed; + curpos.length -= processed; - result[i] = sstrn(ptr, l); - pptr += l + d.length; + /* allocate memory for the next string */ + j++; + sstr_t* reallocated = (sstr_t*) + alrealloc(allocator, result, j*sizeof(sstr_t)); + if (reallocated) { + result = reallocated; + } else { + for (ssize_t i = 0 ; i < j-1 ; i++) { + alfree(allocator, result[i].ptr); + } + alfree(allocator, result); + *n = -2; + return NULL; + } + } else { + /* nmax reached, copy the _full_ remaining string */ + result[j-1] = sstrdup_a(allocator, curpos); + break; + } } else { - for (ssize_t j = i-1 ; j >= 0 ; j--) { - alfree(allocator, result[j].ptr); - } - alfree(allocator, result); - *n = -2; + /* no more matches, copy last string */ + result[j-1] = sstrdup_a(allocator, curpos); break; } } + *n = j; } else { *n = -2; } - - free(sv.ptr); return result; }
--- a/ucx/string.h Mon Feb 20 16:04:14 2017 +0100 +++ b/ucx/string.h Mon Feb 20 16:57:09 2017 +0100 @@ -260,6 +260,9 @@ * * If the string ends with the delimiter and the maximum list size is not * exceeded, the last array item will be an empty string. + * In case the list size would be exceeded, the last array item will be the + * remaining string after the last split, <i>including</i> the terminating + * delimiter. * * <b>Attention:</b> The array pointer <b>AND</b> all sstr_t.ptr of the array * items must be manually passed to <code>free()</code>. Use sstrsplit_a() with