# HG changeset patch # User Olaf Wintermann # Date 1522569061 -7200 # Node ID f1b2146d48053db1435f00d4da088895d2778286 # Parent 96f643d30ff140cada6ff7d9bfe7a3009a7d5e03 adapts sstrtrim, sstrsplit, sstrcmp and sstrstr to new const string API diff -r 96f643d30ff1 -r f1b2146d4805 src/string.c --- a/src/string.c Sun Mar 11 13:43:07 2018 +0100 +++ b/src/string.c Sun Apr 01 09:51:01 2018 +0200 @@ -217,13 +217,21 @@ else ((size_t*)ptable)[index] = src;\ } while (0); -sstr_t sstrstr(sstr_t string, sstr_t match) { - if (match.length == 0) { - return string; + +const char* ucx_strstr( + const char *str, + size_t length, + const char *match, + size_t matchlen, + size_t *newlen) +{ + *newlen = length; + if (matchlen == 0) { + return str; } - /* prepare default return value in case of no match */ - sstr_t result = sstrn(NULL, 0); + const char *result = NULL; + size_t resultlen = 0; /* * IMPORTANT: @@ -238,9 +246,9 @@ /* check pattern length and use appropriate prefix table */ /* if the pattern exceeds static prefix table, allocate on the heap */ - register int useheap = match.length > 255; + register int useheap = matchlen > 255; register void* ptable = useheap ? - calloc(match.length+1, sizeof(size_t)): s_prefix_table; + calloc(matchlen+1, sizeof(size_t)): s_prefix_table; /* keep counter in registers */ register size_t i, j; @@ -248,8 +256,8 @@ /* fill prefix table */ i = 0; j = 0; ptable_w(useheap, ptable, i, j); - while (i < match.length) { - while (j >= 1 && match.ptr[j-1] != match.ptr[i]) { + while (i < matchlen) { + while (j >= 1 && match[j-1] != match[i]) { ptable_r(j, useheap, ptable, j-1); } i++; j++; @@ -258,15 +266,15 @@ /* search */ i = 0; j = 1; - while (i < string.length) { - while (j >= 1 && string.ptr[i] != match.ptr[j-1]) { + while (i < length) { + while (j >= 1 && str[i] != match[j-1]) { ptable_r(j, useheap, ptable, j-1); } i++; j++; - if (j-1 == match.length) { - size_t start = i - match.length; - result.ptr = string.ptr + start; - result.length = string.length - start; + if (j-1 == matchlen) { + size_t start = i - matchlen; + result = str + start; + resultlen = length - start; break; } } @@ -276,17 +284,54 @@ free(ptable); } + *newlen = resultlen; + return result; +} + +sstr_t ucx_sstrstr(sstr_t string, scstr_t match) { + sstr_t result; + + size_t reslen; + const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen); + if(!resstr) { + result.ptr = NULL; + result.length = 0; + return result; + } + + size_t pos = resstr - string.ptr; + result.ptr = string.ptr + pos; + result.length = reslen; + + return result; +} + +scstr_t ucx_scstrstr(scstr_t string, scstr_t match) { + scstr_t result; + + size_t reslen; + const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen); + if(!resstr) { + result.ptr = NULL; + result.length = 0; + return result; + } + + size_t pos = resstr - string.ptr; + result.ptr = string.ptr + pos; + result.length = reslen; + return result; } #undef ptable_r #undef ptable_w -sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { - return sstrsplit_a(ucx_default_allocator(), s, d, n); +sstr_t* ucx_strsplit(scstr_t s, scstr_t d, ssize_t *n) { + return ucx_strsplit_a(ucx_default_allocator(), s, d, n); } -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, ssize_t *n) { +sstr_t* ucx_strsplit_a(UcxAllocator *allocator, scstr_t s, scstr_t d, ssize_t *n) { if (s.length == 0 || d.length == 0) { *n = -1; return NULL; @@ -315,10 +360,10 @@ sstr_t* result = (sstr_t*) alcalloc(allocator, arrlen, sizeof(sstr_t)); if (result) { - sstr_t curpos = s; + scstr_t curpos = s; ssize_t j = 1; while (1) { - sstr_t match; + scstr_t match; /* optimize for one byte delimiters */ if (d.length == 1) { match = curpos; @@ -330,13 +375,13 @@ match.length--; } } else { - match = sstrstr(curpos, d); + match = scstrstr(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); + scstr_t item = scstrn(curpos.ptr, match.ptr - curpos.ptr); result[j-1] = sstrdup_a(allocator, item); size_t processed = item.length + d.length; curpos.ptr += processed; @@ -382,7 +427,7 @@ return result; } -int sstrcmp(sstr_t s1, sstr_t s2) { +int ucx_str_cmp(scstr_t s1, scstr_t s2) { if (s1.length == s2.length) { return memcmp(s1.ptr, s2.ptr, s1.length); } else if (s1.length > s2.length) { @@ -392,7 +437,7 @@ } } -int sstrcasecmp(sstr_t s1, sstr_t s2) { +int ucx_str_casecmp(scstr_t s1, scstr_t s2) { if (s1.length == s2.length) { #ifdef _WIN32 return _strnicmp(s1.ptr, s2.ptr, s1.length); @@ -425,17 +470,34 @@ return newstring; } -sstr_t sstrtrim(sstr_t string) { - sstr_t newstr = string; + +size_t ucx_strtrim(const char *s, size_t len, size_t *newlen) { + const char *newptr = s; + size_t length = len; - while (newstr.length > 0 && isspace(*newstr.ptr)) { - newstr.ptr++; - newstr.length--; + while(length > 0 && isspace(*newptr)) { + newptr++; + length--; } - while (newstr.length > 0 && isspace(newstr.ptr[newstr.length-1])) { - newstr.length--; + while(length > 0 && isspace(newptr[length-1])) { + length--; } + *newlen = length; + return newptr - s; +} + +sstr_t sstrtrim(sstr_t string) { + sstr_t newstr; + newstr.ptr = string.ptr + + ucx_strtrim(string.ptr, string.length, &newstr.length); + return newstr; +} + +scstr_t scstrtrim(scstr_t string) { + scstr_t newstr; + newstr.ptr = string.ptr + + ucx_strtrim(string.ptr, string.length, &newstr.length); return newstr; } diff -r 96f643d30ff1 -r f1b2146d4805 src/ucx/string.h --- a/src/ucx/string.h Sun Mar 11 13:43:07 2018 +0100 +++ b/src/ucx/string.h Sun Apr 01 09:51:01 2018 +0200 @@ -264,6 +264,14 @@ */ sstr_t sstrrchr(sstr_t string, int chr); + +const char* ucx_strstr( + const char *str, + size_t length, + const char *match, + size_t matchlen, + size_t *newlen); + /** * Returns a substring starting at the location of the first occurrence of the * specified string. @@ -279,7 +287,11 @@ * match, or an empty string, if the sequence is not * present in string */ -sstr_t sstrstr(sstr_t string, sstr_t match); +sstr_t ucx_sstrstr(sstr_t string, scstr_t match); +#define sstrstr(string, match) ucx_sstrstr(string, SCSTR(match)) + +scstr_t ucx_scstrstr(scstr_t string, scstr_t match); +#define scstrstr(string, match) ucx_scstrstr(string, SCSTR(match)) /** * Splits a string into parts by using a delimiter string. @@ -328,7 +340,9 @@ * * @see sstrsplit_a() */ -sstr_t* sstrsplit(sstr_t string, sstr_t delim, ssize_t *count); +sstr_t* ucx_strsplit(scstr_t string, scstr_t delim, ssize_t *count); + +#define sstrsplit(s, delim, count) ucx_strsplit(SCSTR(s), SCSTR(delim), count) /** * Performing sstrsplit() using a UcxAllocator. @@ -352,9 +366,11 @@ * * @see sstrsplit() */ -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t string, sstr_t delim, +sstr_t* ucx_strsplit_a(UcxAllocator *allocator, scstr_t string, scstr_t delim, ssize_t *count); +#define sstrsplit_a(a, s, d, c) ucx_strsplit_a(a, SCSTR(s), SCSTR(d, c)) + /** * Compares two UCX strings with standard memcmp(). * @@ -367,7 +383,9 @@ * length of s1 is greater than the length of s2 or the result of * memcmp() otherwise (i.e. 0 if the strings match) */ -int sstrcmp(sstr_t s1, sstr_t s2); +int ucx_str_cmp(scstr_t s1, scstr_t s2); + +#define sstrcmp(s1, s2) ucx_str_cmp(SCSTR(s1), SCSTR(s2)) /** * Compares two UCX strings ignoring the case. @@ -383,7 +401,9 @@ * first two differing characters otherwise (i.e. 0 if the strings match and * no characters differ) */ -int sstrcasecmp(sstr_t s1, sstr_t s2); +int ucx_str_casecmp(scstr_t s1, scstr_t s2); + +#define sstrcasecmp(s1, s2) ucx_str_casecmp(SCSTR(s1), SCSTR(s2)) /** * Creates a duplicate of the specified string. @@ -423,6 +443,9 @@ #define sstrdup_a(allocator, s) scstrdup_a(allocator, SCSTR(s)) + +size_t ucx_strtrim(const char *str, size_t length, size_t *newlen); + /** * Omits leading and trailing spaces. * @@ -442,6 +465,8 @@ */ sstr_t sstrtrim(sstr_t string); +scstr_t scstrtrim(scstr_t string); + /** * Checks, if a string has a specific prefix. * @param string the string to check