Sun, 01 Apr 2018 09:51:01 +0200
adapts sstrtrim, sstrsplit, sstrcmp and sstrstr to new const string API
src/string.c | file | annotate | diff | comparison | revisions | |
src/ucx/string.h | file | annotate | diff | comparison | revisions |
1.1 --- a/src/string.c Sun Mar 11 13:43:07 2018 +0100 1.2 +++ b/src/string.c Sun Apr 01 09:51:01 2018 +0200 1.3 @@ -217,13 +217,21 @@ 1.4 else ((size_t*)ptable)[index] = src;\ 1.5 } while (0); 1.6 1.7 -sstr_t sstrstr(sstr_t string, sstr_t match) { 1.8 - if (match.length == 0) { 1.9 - return string; 1.10 + 1.11 +const char* ucx_strstr( 1.12 + const char *str, 1.13 + size_t length, 1.14 + const char *match, 1.15 + size_t matchlen, 1.16 + size_t *newlen) 1.17 +{ 1.18 + *newlen = length; 1.19 + if (matchlen == 0) { 1.20 + return str; 1.21 } 1.22 1.23 - /* prepare default return value in case of no match */ 1.24 - sstr_t result = sstrn(NULL, 0); 1.25 + const char *result = NULL; 1.26 + size_t resultlen = 0; 1.27 1.28 /* 1.29 * IMPORTANT: 1.30 @@ -238,9 +246,9 @@ 1.31 1.32 /* check pattern length and use appropriate prefix table */ 1.33 /* if the pattern exceeds static prefix table, allocate on the heap */ 1.34 - register int useheap = match.length > 255; 1.35 + register int useheap = matchlen > 255; 1.36 register void* ptable = useheap ? 1.37 - calloc(match.length+1, sizeof(size_t)): s_prefix_table; 1.38 + calloc(matchlen+1, sizeof(size_t)): s_prefix_table; 1.39 1.40 /* keep counter in registers */ 1.41 register size_t i, j; 1.42 @@ -248,8 +256,8 @@ 1.43 /* fill prefix table */ 1.44 i = 0; j = 0; 1.45 ptable_w(useheap, ptable, i, j); 1.46 - while (i < match.length) { 1.47 - while (j >= 1 && match.ptr[j-1] != match.ptr[i]) { 1.48 + while (i < matchlen) { 1.49 + while (j >= 1 && match[j-1] != match[i]) { 1.50 ptable_r(j, useheap, ptable, j-1); 1.51 } 1.52 i++; j++; 1.53 @@ -258,15 +266,15 @@ 1.54 1.55 /* search */ 1.56 i = 0; j = 1; 1.57 - while (i < string.length) { 1.58 - while (j >= 1 && string.ptr[i] != match.ptr[j-1]) { 1.59 + while (i < length) { 1.60 + while (j >= 1 && str[i] != match[j-1]) { 1.61 ptable_r(j, useheap, ptable, j-1); 1.62 } 1.63 i++; j++; 1.64 - if (j-1 == match.length) { 1.65 - size_t start = i - match.length; 1.66 - result.ptr = string.ptr + start; 1.67 - result.length = string.length - start; 1.68 + if (j-1 == matchlen) { 1.69 + size_t start = i - matchlen; 1.70 + result = str + start; 1.71 + resultlen = length - start; 1.72 break; 1.73 } 1.74 } 1.75 @@ -276,17 +284,54 @@ 1.76 free(ptable); 1.77 } 1.78 1.79 + *newlen = resultlen; 1.80 + return result; 1.81 +} 1.82 + 1.83 +sstr_t ucx_sstrstr(sstr_t string, scstr_t match) { 1.84 + sstr_t result; 1.85 + 1.86 + size_t reslen; 1.87 + const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen); 1.88 + if(!resstr) { 1.89 + result.ptr = NULL; 1.90 + result.length = 0; 1.91 + return result; 1.92 + } 1.93 + 1.94 + size_t pos = resstr - string.ptr; 1.95 + result.ptr = string.ptr + pos; 1.96 + result.length = reslen; 1.97 + 1.98 + return result; 1.99 +} 1.100 + 1.101 +scstr_t ucx_scstrstr(scstr_t string, scstr_t match) { 1.102 + scstr_t result; 1.103 + 1.104 + size_t reslen; 1.105 + const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen); 1.106 + if(!resstr) { 1.107 + result.ptr = NULL; 1.108 + result.length = 0; 1.109 + return result; 1.110 + } 1.111 + 1.112 + size_t pos = resstr - string.ptr; 1.113 + result.ptr = string.ptr + pos; 1.114 + result.length = reslen; 1.115 + 1.116 return result; 1.117 } 1.118 1.119 #undef ptable_r 1.120 #undef ptable_w 1.121 1.122 -sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { 1.123 - return sstrsplit_a(ucx_default_allocator(), s, d, n); 1.124 +sstr_t* ucx_strsplit(scstr_t s, scstr_t d, ssize_t *n) { 1.125 + return ucx_strsplit_a(ucx_default_allocator(), s, d, n); 1.126 } 1.127 1.128 -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, ssize_t *n) { 1.129 +sstr_t* ucx_strsplit_a(UcxAllocator *allocator, scstr_t s, scstr_t d, ssize_t *n) { 1.130 if (s.length == 0 || d.length == 0) { 1.131 *n = -1; 1.132 return NULL; 1.133 @@ -315,10 +360,10 @@ 1.134 sstr_t* result = (sstr_t*) alcalloc(allocator, arrlen, sizeof(sstr_t)); 1.135 1.136 if (result) { 1.137 - sstr_t curpos = s; 1.138 + scstr_t curpos = s; 1.139 ssize_t j = 1; 1.140 while (1) { 1.141 - sstr_t match; 1.142 + scstr_t match; 1.143 /* optimize for one byte delimiters */ 1.144 if (d.length == 1) { 1.145 match = curpos; 1.146 @@ -330,13 +375,13 @@ 1.147 match.length--; 1.148 } 1.149 } else { 1.150 - match = sstrstr(curpos, d); 1.151 + match = scstrstr(curpos, d); 1.152 } 1.153 if (match.length > 0) { 1.154 /* is this our last try? */ 1.155 if (nmax == 0 || j < nmax) { 1.156 /* copy the current string to the array */ 1.157 - sstr_t item = sstrn(curpos.ptr, match.ptr - curpos.ptr); 1.158 + scstr_t item = scstrn(curpos.ptr, match.ptr - curpos.ptr); 1.159 result[j-1] = sstrdup_a(allocator, item); 1.160 size_t processed = item.length + d.length; 1.161 curpos.ptr += processed; 1.162 @@ -382,7 +427,7 @@ 1.163 return result; 1.164 } 1.165 1.166 -int sstrcmp(sstr_t s1, sstr_t s2) { 1.167 +int ucx_str_cmp(scstr_t s1, scstr_t s2) { 1.168 if (s1.length == s2.length) { 1.169 return memcmp(s1.ptr, s2.ptr, s1.length); 1.170 } else if (s1.length > s2.length) { 1.171 @@ -392,7 +437,7 @@ 1.172 } 1.173 } 1.174 1.175 -int sstrcasecmp(sstr_t s1, sstr_t s2) { 1.176 +int ucx_str_casecmp(scstr_t s1, scstr_t s2) { 1.177 if (s1.length == s2.length) { 1.178 #ifdef _WIN32 1.179 return _strnicmp(s1.ptr, s2.ptr, s1.length); 1.180 @@ -425,17 +470,34 @@ 1.181 return newstring; 1.182 } 1.183 1.184 -sstr_t sstrtrim(sstr_t string) { 1.185 - sstr_t newstr = string; 1.186 + 1.187 +size_t ucx_strtrim(const char *s, size_t len, size_t *newlen) { 1.188 + const char *newptr = s; 1.189 + size_t length = len; 1.190 1.191 - while (newstr.length > 0 && isspace(*newstr.ptr)) { 1.192 - newstr.ptr++; 1.193 - newstr.length--; 1.194 + while(length > 0 && isspace(*newptr)) { 1.195 + newptr++; 1.196 + length--; 1.197 } 1.198 - while (newstr.length > 0 && isspace(newstr.ptr[newstr.length-1])) { 1.199 - newstr.length--; 1.200 + while(length > 0 && isspace(newptr[length-1])) { 1.201 + length--; 1.202 } 1.203 1.204 + *newlen = length; 1.205 + return newptr - s; 1.206 +} 1.207 + 1.208 +sstr_t sstrtrim(sstr_t string) { 1.209 + sstr_t newstr; 1.210 + newstr.ptr = string.ptr 1.211 + + ucx_strtrim(string.ptr, string.length, &newstr.length); 1.212 + return newstr; 1.213 +} 1.214 + 1.215 +scstr_t scstrtrim(scstr_t string) { 1.216 + scstr_t newstr; 1.217 + newstr.ptr = string.ptr 1.218 + + ucx_strtrim(string.ptr, string.length, &newstr.length); 1.219 return newstr; 1.220 } 1.221
2.1 --- a/src/ucx/string.h Sun Mar 11 13:43:07 2018 +0100 2.2 +++ b/src/ucx/string.h Sun Apr 01 09:51:01 2018 +0200 2.3 @@ -264,6 +264,14 @@ 2.4 */ 2.5 sstr_t sstrrchr(sstr_t string, int chr); 2.6 2.7 + 2.8 +const char* ucx_strstr( 2.9 + const char *str, 2.10 + size_t length, 2.11 + const char *match, 2.12 + size_t matchlen, 2.13 + size_t *newlen); 2.14 + 2.15 /** 2.16 * Returns a substring starting at the location of the first occurrence of the 2.17 * specified string. 2.18 @@ -279,7 +287,11 @@ 2.19 * <code>match</code>, or an empty string, if the sequence is not 2.20 * present in <code>string</code> 2.21 */ 2.22 -sstr_t sstrstr(sstr_t string, sstr_t match); 2.23 +sstr_t ucx_sstrstr(sstr_t string, scstr_t match); 2.24 +#define sstrstr(string, match) ucx_sstrstr(string, SCSTR(match)) 2.25 + 2.26 +scstr_t ucx_scstrstr(scstr_t string, scstr_t match); 2.27 +#define scstrstr(string, match) ucx_scstrstr(string, SCSTR(match)) 2.28 2.29 /** 2.30 * Splits a string into parts by using a delimiter string. 2.31 @@ -328,7 +340,9 @@ 2.32 * 2.33 * @see sstrsplit_a() 2.34 */ 2.35 -sstr_t* sstrsplit(sstr_t string, sstr_t delim, ssize_t *count); 2.36 +sstr_t* ucx_strsplit(scstr_t string, scstr_t delim, ssize_t *count); 2.37 + 2.38 +#define sstrsplit(s, delim, count) ucx_strsplit(SCSTR(s), SCSTR(delim), count) 2.39 2.40 /** 2.41 * Performing sstrsplit() using a UcxAllocator. 2.42 @@ -352,9 +366,11 @@ 2.43 * 2.44 * @see sstrsplit() 2.45 */ 2.46 -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t string, sstr_t delim, 2.47 +sstr_t* ucx_strsplit_a(UcxAllocator *allocator, scstr_t string, scstr_t delim, 2.48 ssize_t *count); 2.49 2.50 +#define sstrsplit_a(a, s, d, c) ucx_strsplit_a(a, SCSTR(s), SCSTR(d, c)) 2.51 + 2.52 /** 2.53 * Compares two UCX strings with standard <code>memcmp()</code>. 2.54 * 2.55 @@ -367,7 +383,9 @@ 2.56 * length of s1 is greater than the length of s2 or the result of 2.57 * <code>memcmp()</code> otherwise (i.e. 0 if the strings match) 2.58 */ 2.59 -int sstrcmp(sstr_t s1, sstr_t s2); 2.60 +int ucx_str_cmp(scstr_t s1, scstr_t s2); 2.61 + 2.62 +#define sstrcmp(s1, s2) ucx_str_cmp(SCSTR(s1), SCSTR(s2)) 2.63 2.64 /** 2.65 * Compares two UCX strings ignoring the case. 2.66 @@ -383,7 +401,9 @@ 2.67 * first two differing characters otherwise (i.e. 0 if the strings match and 2.68 * no characters differ) 2.69 */ 2.70 -int sstrcasecmp(sstr_t s1, sstr_t s2); 2.71 +int ucx_str_casecmp(scstr_t s1, scstr_t s2); 2.72 + 2.73 +#define sstrcasecmp(s1, s2) ucx_str_casecmp(SCSTR(s1), SCSTR(s2)) 2.74 2.75 /** 2.76 * Creates a duplicate of the specified string. 2.77 @@ -423,6 +443,9 @@ 2.78 2.79 #define sstrdup_a(allocator, s) scstrdup_a(allocator, SCSTR(s)) 2.80 2.81 + 2.82 +size_t ucx_strtrim(const char *str, size_t length, size_t *newlen); 2.83 + 2.84 /** 2.85 * Omits leading and trailing spaces. 2.86 * 2.87 @@ -442,6 +465,8 @@ 2.88 */ 2.89 sstr_t sstrtrim(sstr_t string); 2.90 2.91 +scstr_t scstrtrim(scstr_t string); 2.92 + 2.93 /** 2.94 * Checks, if a string has a specific prefix. 2.95 * @param string the string to check