Mon, 14 May 2018 17:56:03 +0200
merges constsstr branch
configure.ac | file | annotate | diff | comparison | revisions | |
src/string.c | file | annotate | diff | comparison | revisions | |
src/ucx/string.h | file | annotate | diff | comparison | revisions | |
src/ucx/ucx.h | file | annotate | diff | comparison | revisions | |
test/string_tests.c | file | annotate | diff | comparison | revisions |
1.1 --- a/configure.ac Mon May 14 15:58:51 2018 +0200 1.2 +++ b/configure.ac Mon May 14 17:56:03 2018 +0200 1.3 @@ -27,8 +27,9 @@ 1.4 # 1.5 1.6 # the package version must match the macros in ucx.h 1.7 -AC_INIT([ucx], [1.1.0], [olaf.wintermann@gmail.com]) 1.8 -AC_SUBST([UCX_LIB_VERSION], [2:0:1]) 1.9 +# the lib version must follow the libtool versioning convention 1.10 +AC_INIT([ucx], [2.0.0], [olaf.wintermann@gmail.com]) 1.11 +AC_SUBST([UCX_LIB_VERSION], [3:0:0]) 1.12 1.13 # don't place everything in the project root 1.14 AC_CONFIG_AUX_DIR([build-aux])
2.1 --- a/src/string.c Mon May 14 15:58:51 2018 +0200 2.2 +++ b/src/string.c Mon May 14 17:56:03 2018 +0200 2.3 @@ -50,13 +50,29 @@ 2.4 return string; 2.5 } 2.6 2.7 -size_t sstrnlen(size_t n, sstr_t s, ...) { 2.8 +scstr_t scstr(const char *cstring) { 2.9 + scstr_t string; 2.10 + string.ptr = cstring; 2.11 + string.length = strlen(cstring); 2.12 + return string; 2.13 +} 2.14 + 2.15 +scstr_t scstrn(const char *cstring, size_t length) { 2.16 + scstr_t string; 2.17 + string.ptr = cstring; 2.18 + string.length = length; 2.19 + return string; 2.20 +} 2.21 + 2.22 + 2.23 +size_t ucx_strnlen(size_t n, ...) { 2.24 va_list ap; 2.25 - size_t size = s.length; 2.26 - va_start(ap, s); 2.27 + va_start(ap, n); 2.28 + 2.29 + size_t size = 0; 2.30 2.31 - for (size_t i = 1 ; i < n ; i++) { 2.32 - sstr_t str = va_arg(ap, sstr_t); 2.33 + for (size_t i = 0 ; i < n ; i++) { 2.34 + scstr_t str = va_arg(ap, scstr_t); 2.35 if(((size_t)-1) - str.length < size) { 2.36 size = 0; 2.37 break; 2.38 @@ -71,8 +87,7 @@ 2.39 static sstr_t sstrvcat_a( 2.40 UcxAllocator *a, 2.41 size_t count, 2.42 - sstr_t s1, 2.43 - sstr_t s2, 2.44 + scstr_t s1, 2.45 va_list ap) { 2.46 sstr_t str; 2.47 str.ptr = NULL; 2.48 @@ -81,11 +96,13 @@ 2.49 return str; 2.50 } 2.51 2.52 + scstr_t s2 = va_arg (ap, scstr_t); 2.53 + 2.54 if(((size_t)-1) - s1.length < s2.length) { 2.55 return str; 2.56 } 2.57 2.58 - sstr_t *strings = (sstr_t*) calloc(count, sizeof(sstr_t)); 2.59 + scstr_t *strings = (scstr_t*) calloc(count, sizeof(scstr_t)); 2.60 if(!strings) { 2.61 return str; 2.62 } 2.63 @@ -96,7 +113,7 @@ 2.64 size_t slen = s1.length + s2.length; 2.65 int error = 0; 2.66 for (size_t i=2;i<count;i++) { 2.67 - sstr_t s = va_arg (ap, sstr_t); 2.68 + scstr_t s = va_arg (ap, scstr_t); 2.69 strings[i] = s; 2.70 if(((size_t)-1) - s.length < slen) { 2.71 error = 1; 2.72 @@ -121,7 +138,7 @@ 2.73 // concatenate strings 2.74 size_t pos = 0; 2.75 for (size_t i=0;i<count;i++) { 2.76 - sstr_t s = strings[i]; 2.77 + scstr_t s = strings[i]; 2.78 memcpy(str.ptr + pos, s.ptr, s.length); 2.79 pos += s.length; 2.80 } 2.81 @@ -133,65 +150,123 @@ 2.82 return str; 2.83 } 2.84 2.85 -sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...) { 2.86 +sstr_t ucx_strcat(size_t count, scstr_t s1, ...) { 2.87 va_list ap; 2.88 - va_start(ap, s2); 2.89 - sstr_t s = sstrvcat_a(ucx_default_allocator(), count, s1, s2, ap); 2.90 + va_start(ap, s1); 2.91 + sstr_t s = sstrvcat_a(ucx_default_allocator(), count, s1, ap); 2.92 va_end(ap); 2.93 return s; 2.94 } 2.95 2.96 -sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...) { 2.97 +sstr_t ucx_strcat_a(UcxAllocator *a, size_t count, scstr_t s1, ...) { 2.98 va_list ap; 2.99 - va_start(ap, s2); 2.100 - sstr_t s = sstrvcat_a(a, count, s1, s2, ap); 2.101 + va_start(ap, s1); 2.102 + sstr_t s = sstrvcat_a(a, count, s1, ap); 2.103 va_end(ap); 2.104 return s; 2.105 } 2.106 2.107 +static int ucx_substring( 2.108 + size_t str_length, 2.109 + size_t start, 2.110 + size_t length, 2.111 + size_t *newlen, 2.112 + size_t *newpos) 2.113 +{ 2.114 + *newlen = 0; 2.115 + *newpos = 0; 2.116 + 2.117 + if(start > str_length) { 2.118 + return 0; 2.119 + } 2.120 + 2.121 + if(length > str_length - start) { 2.122 + length = str_length - start; 2.123 + } 2.124 + *newlen = length; 2.125 + *newpos = start; 2.126 + return 1; 2.127 +} 2.128 + 2.129 sstr_t sstrsubs(sstr_t s, size_t start) { 2.130 return sstrsubsl (s, start, s.length-start); 2.131 } 2.132 2.133 sstr_t sstrsubsl(sstr_t s, size_t start, size_t length) { 2.134 - sstr_t new_sstr; 2.135 - if (start >= s.length) { 2.136 - new_sstr.ptr = NULL; 2.137 - new_sstr.length = 0; 2.138 - } else { 2.139 - if (length > s.length-start) { 2.140 - length = s.length-start; 2.141 + size_t pos; 2.142 + sstr_t ret = { NULL, 0 }; 2.143 + if(ucx_substring(s.length, start, length, &ret.length, &pos)) { 2.144 + ret.ptr = s.ptr + pos; 2.145 + } 2.146 + return ret; 2.147 +} 2.148 + 2.149 +scstr_t scstrsubs(scstr_t s, size_t start) { 2.150 + return scstrsubsl (s, start, s.length-start); 2.151 +} 2.152 + 2.153 +scstr_t scstrsubsl(scstr_t s, size_t start, size_t length) { 2.154 + size_t pos; 2.155 + scstr_t ret = { NULL, 0 }; 2.156 + if(ucx_substring(s.length, start, length, &ret.length, &pos)) { 2.157 + ret.ptr = s.ptr + pos; 2.158 + } 2.159 + return ret; 2.160 +} 2.161 + 2.162 + 2.163 +int ucx_strchr(const char *string, size_t length, int chr, size_t *pos) { 2.164 + for(size_t i=0;i<length;i++) { 2.165 + if(string[i] == chr) { 2.166 + *pos = i; 2.167 + return 1; 2.168 } 2.169 - new_sstr.ptr = &s.ptr[start]; 2.170 - new_sstr.length = length; 2.171 } 2.172 - return new_sstr; 2.173 + return 0; 2.174 +} 2.175 + 2.176 +int ucx_strrchr(const char *string, size_t length, int chr, size_t *pos) { 2.177 + if(length > 0) { 2.178 + for(size_t i=length ; i>0 ; i--) { 2.179 + if(string[i-1] == chr) { 2.180 + *pos = i-1; 2.181 + return 1; 2.182 + } 2.183 + } 2.184 + } 2.185 + return 0; 2.186 } 2.187 2.188 sstr_t sstrchr(sstr_t s, int c) { 2.189 - for(size_t i=0;i<s.length;i++) { 2.190 - if(s.ptr[i] == c) { 2.191 - return sstrsubs(s, i); 2.192 - } 2.193 + size_t pos = 0; 2.194 + if(ucx_strchr(s.ptr, s.length, c, &pos)) { 2.195 + return sstrsubs(s, pos); 2.196 } 2.197 - sstr_t n; 2.198 - n.ptr = NULL; 2.199 - n.length = 0; 2.200 - return n; 2.201 + return sstrn(NULL, 0); 2.202 } 2.203 2.204 sstr_t sstrrchr(sstr_t s, int c) { 2.205 - if (s.length > 0) { 2.206 - for(size_t i=s.length;i>0;i--) { 2.207 - if(s.ptr[i-1] == c) { 2.208 - return sstrsubs(s, i-1); 2.209 - } 2.210 - } 2.211 + size_t pos = 0; 2.212 + if(ucx_strrchr(s.ptr, s.length, c, &pos)) { 2.213 + return sstrsubs(s, pos); 2.214 } 2.215 - sstr_t n; 2.216 - n.ptr = NULL; 2.217 - n.length = 0; 2.218 - return n; 2.219 + return sstrn(NULL, 0); 2.220 +} 2.221 + 2.222 +scstr_t scstrchr(scstr_t s, int c) { 2.223 + size_t pos = 0; 2.224 + if(ucx_strchr(s.ptr, s.length, c, &pos)) { 2.225 + return scstrsubs(s, pos); 2.226 + } 2.227 + return scstrn(NULL, 0); 2.228 +} 2.229 + 2.230 +scstr_t scstrrchr(scstr_t s, int c) { 2.231 + size_t pos = 0; 2.232 + if(ucx_strrchr(s.ptr, s.length, c, &pos)) { 2.233 + return scstrsubs(s, pos); 2.234 + } 2.235 + return scstrn(NULL, 0); 2.236 } 2.237 2.238 #define ptable_r(dest, useheap, ptable, index) (dest = useheap ? \ 2.239 @@ -202,13 +277,21 @@ 2.240 else ((size_t*)ptable)[index] = src;\ 2.241 } while (0); 2.242 2.243 -sstr_t sstrstr(sstr_t string, sstr_t match) { 2.244 - if (match.length == 0) { 2.245 - return string; 2.246 + 2.247 +const char* ucx_strstr( 2.248 + const char *str, 2.249 + size_t length, 2.250 + const char *match, 2.251 + size_t matchlen, 2.252 + size_t *newlen) 2.253 +{ 2.254 + *newlen = length; 2.255 + if (matchlen == 0) { 2.256 + return str; 2.257 } 2.258 2.259 - /* prepare default return value in case of no match */ 2.260 - sstr_t result = sstrn(NULL, 0); 2.261 + const char *result = NULL; 2.262 + size_t resultlen = 0; 2.263 2.264 /* 2.265 * IMPORTANT: 2.266 @@ -223,9 +306,9 @@ 2.267 2.268 /* check pattern length and use appropriate prefix table */ 2.269 /* if the pattern exceeds static prefix table, allocate on the heap */ 2.270 - register int useheap = match.length > 255; 2.271 + register int useheap = matchlen > 255; 2.272 register void* ptable = useheap ? 2.273 - calloc(match.length+1, sizeof(size_t)): s_prefix_table; 2.274 + calloc(matchlen+1, sizeof(size_t)): s_prefix_table; 2.275 2.276 /* keep counter in registers */ 2.277 register size_t i, j; 2.278 @@ -233,8 +316,8 @@ 2.279 /* fill prefix table */ 2.280 i = 0; j = 0; 2.281 ptable_w(useheap, ptable, i, j); 2.282 - while (i < match.length) { 2.283 - while (j >= 1 && match.ptr[j-1] != match.ptr[i]) { 2.284 + while (i < matchlen) { 2.285 + while (j >= 1 && match[j-1] != match[i]) { 2.286 ptable_r(j, useheap, ptable, j-1); 2.287 } 2.288 i++; j++; 2.289 @@ -243,15 +326,15 @@ 2.290 2.291 /* search */ 2.292 i = 0; j = 1; 2.293 - while (i < string.length) { 2.294 - while (j >= 1 && string.ptr[i] != match.ptr[j-1]) { 2.295 + while (i < length) { 2.296 + while (j >= 1 && str[i] != match[j-1]) { 2.297 ptable_r(j, useheap, ptable, j-1); 2.298 } 2.299 i++; j++; 2.300 - if (j-1 == match.length) { 2.301 - size_t start = i - match.length; 2.302 - result.ptr = string.ptr + start; 2.303 - result.length = string.length - start; 2.304 + if (j-1 == matchlen) { 2.305 + size_t start = i - matchlen; 2.306 + result = str + start; 2.307 + resultlen = length - start; 2.308 break; 2.309 } 2.310 } 2.311 @@ -261,17 +344,54 @@ 2.312 free(ptable); 2.313 } 2.314 2.315 + *newlen = resultlen; 2.316 + return result; 2.317 +} 2.318 + 2.319 +sstr_t ucx_sstrstr(sstr_t string, scstr_t match) { 2.320 + sstr_t result; 2.321 + 2.322 + size_t reslen; 2.323 + const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen); 2.324 + if(!resstr) { 2.325 + result.ptr = NULL; 2.326 + result.length = 0; 2.327 + return result; 2.328 + } 2.329 + 2.330 + size_t pos = resstr - string.ptr; 2.331 + result.ptr = string.ptr + pos; 2.332 + result.length = reslen; 2.333 + 2.334 + return result; 2.335 +} 2.336 + 2.337 +scstr_t ucx_scstrstr(scstr_t string, scstr_t match) { 2.338 + scstr_t result; 2.339 + 2.340 + size_t reslen; 2.341 + const char *resstr = ucx_strstr(string.ptr, string.length, match.ptr, match.length, &reslen); 2.342 + if(!resstr) { 2.343 + result.ptr = NULL; 2.344 + result.length = 0; 2.345 + return result; 2.346 + } 2.347 + 2.348 + size_t pos = resstr - string.ptr; 2.349 + result.ptr = string.ptr + pos; 2.350 + result.length = reslen; 2.351 + 2.352 return result; 2.353 } 2.354 2.355 #undef ptable_r 2.356 #undef ptable_w 2.357 2.358 -sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { 2.359 - return sstrsplit_a(ucx_default_allocator(), s, d, n); 2.360 +sstr_t* ucx_strsplit(scstr_t s, scstr_t d, ssize_t *n) { 2.361 + return ucx_strsplit_a(ucx_default_allocator(), s, d, n); 2.362 } 2.363 2.364 -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, ssize_t *n) { 2.365 +sstr_t* ucx_strsplit_a(UcxAllocator *allocator, scstr_t s, scstr_t d, ssize_t *n) { 2.366 if (s.length == 0 || d.length == 0) { 2.367 *n = -1; 2.368 return NULL; 2.369 @@ -300,10 +420,10 @@ 2.370 sstr_t* result = (sstr_t*) alcalloc(allocator, arrlen, sizeof(sstr_t)); 2.371 2.372 if (result) { 2.373 - sstr_t curpos = s; 2.374 + scstr_t curpos = s; 2.375 ssize_t j = 1; 2.376 while (1) { 2.377 - sstr_t match; 2.378 + scstr_t match; 2.379 /* optimize for one byte delimiters */ 2.380 if (d.length == 1) { 2.381 match = curpos; 2.382 @@ -315,13 +435,13 @@ 2.383 match.length--; 2.384 } 2.385 } else { 2.386 - match = sstrstr(curpos, d); 2.387 + match = scstrstr(curpos, d); 2.388 } 2.389 if (match.length > 0) { 2.390 /* is this our last try? */ 2.391 if (nmax == 0 || j < nmax) { 2.392 /* copy the current string to the array */ 2.393 - sstr_t item = sstrn(curpos.ptr, match.ptr - curpos.ptr); 2.394 + scstr_t item = scstrn(curpos.ptr, match.ptr - curpos.ptr); 2.395 result[j-1] = sstrdup_a(allocator, item); 2.396 size_t processed = item.length + d.length; 2.397 curpos.ptr += processed; 2.398 @@ -367,7 +487,7 @@ 2.399 return result; 2.400 } 2.401 2.402 -int sstrcmp(sstr_t s1, sstr_t s2) { 2.403 +int ucx_str_cmp(scstr_t s1, scstr_t s2) { 2.404 if (s1.length == s2.length) { 2.405 return memcmp(s1.ptr, s2.ptr, s1.length); 2.406 } else if (s1.length > s2.length) { 2.407 @@ -377,7 +497,7 @@ 2.408 } 2.409 } 2.410 2.411 -int sstrcasecmp(sstr_t s1, sstr_t s2) { 2.412 +int ucx_str_casecmp(scstr_t s1, scstr_t s2) { 2.413 if (s1.length == s2.length) { 2.414 #ifdef _WIN32 2.415 return _strnicmp(s1.ptr, s2.ptr, s1.length); 2.416 @@ -391,11 +511,11 @@ 2.417 } 2.418 } 2.419 2.420 -sstr_t sstrdup(sstr_t s) { 2.421 +sstr_t scstrdup(scstr_t s) { 2.422 return sstrdup_a(ucx_default_allocator(), s); 2.423 } 2.424 2.425 -sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t s) { 2.426 +sstr_t scstrdup_a(UcxAllocator *allocator, scstr_t s) { 2.427 sstr_t newstring; 2.428 newstring.ptr = (char*)almalloc(allocator, s.length + 1); 2.429 if (newstring.ptr) { 2.430 @@ -410,21 +530,38 @@ 2.431 return newstring; 2.432 } 2.433 2.434 -sstr_t sstrtrim(sstr_t string) { 2.435 - sstr_t newstr = string; 2.436 + 2.437 +size_t ucx_strtrim(const char *s, size_t len, size_t *newlen) { 2.438 + const char *newptr = s; 2.439 + size_t length = len; 2.440 2.441 - while (newstr.length > 0 && isspace(*newstr.ptr)) { 2.442 - newstr.ptr++; 2.443 - newstr.length--; 2.444 + while(length > 0 && isspace(*newptr)) { 2.445 + newptr++; 2.446 + length--; 2.447 } 2.448 - while (newstr.length > 0 && isspace(newstr.ptr[newstr.length-1])) { 2.449 - newstr.length--; 2.450 + while(length > 0 && isspace(newptr[length-1])) { 2.451 + length--; 2.452 } 2.453 2.454 + *newlen = length; 2.455 + return newptr - s; 2.456 +} 2.457 + 2.458 +sstr_t sstrtrim(sstr_t string) { 2.459 + sstr_t newstr; 2.460 + newstr.ptr = string.ptr 2.461 + + ucx_strtrim(string.ptr, string.length, &newstr.length); 2.462 return newstr; 2.463 } 2.464 2.465 -int sstrprefix(sstr_t string, sstr_t prefix) { 2.466 +scstr_t scstrtrim(scstr_t string) { 2.467 + scstr_t newstr; 2.468 + newstr.ptr = string.ptr 2.469 + + ucx_strtrim(string.ptr, string.length, &newstr.length); 2.470 + return newstr; 2.471 +} 2.472 + 2.473 +int ucx_strprefix(scstr_t string, scstr_t prefix) { 2.474 if (string.length == 0) { 2.475 return prefix.length == 0; 2.476 } 2.477 @@ -439,7 +576,7 @@ 2.478 } 2.479 } 2.480 2.481 -int sstrsuffix(sstr_t string, sstr_t suffix) { 2.482 +int ucx_strsuffix(scstr_t string, scstr_t suffix) { 2.483 if (string.length == 0) { 2.484 return suffix.length == 0; 2.485 } 2.486 @@ -455,7 +592,7 @@ 2.487 } 2.488 } 2.489 2.490 -sstr_t sstrlower(sstr_t string) { 2.491 +sstr_t ucx_strlower(scstr_t string) { 2.492 sstr_t ret = sstrdup(string); 2.493 for (size_t i = 0; i < ret.length ; i++) { 2.494 ret.ptr[i] = tolower(ret.ptr[i]); 2.495 @@ -463,7 +600,7 @@ 2.496 return ret; 2.497 } 2.498 2.499 -sstr_t sstrlower_a(UcxAllocator *allocator, sstr_t string) { 2.500 +sstr_t ucx_strlower_a(UcxAllocator *allocator, scstr_t string) { 2.501 sstr_t ret = sstrdup_a(allocator, string); 2.502 for (size_t i = 0; i < ret.length ; i++) { 2.503 ret.ptr[i] = tolower(ret.ptr[i]); 2.504 @@ -471,7 +608,7 @@ 2.505 return ret; 2.506 } 2.507 2.508 -sstr_t sstrupper(sstr_t string) { 2.509 +sstr_t ucx_strupper(scstr_t string) { 2.510 sstr_t ret = sstrdup(string); 2.511 for (size_t i = 0; i < ret.length ; i++) { 2.512 ret.ptr[i] = toupper(ret.ptr[i]); 2.513 @@ -479,10 +616,24 @@ 2.514 return ret; 2.515 } 2.516 2.517 -sstr_t sstrupper_a(UcxAllocator *allocator, sstr_t string) { 2.518 +sstr_t ucx_strupper_a(UcxAllocator *allocator, scstr_t string) { 2.519 sstr_t ret = sstrdup_a(allocator, string); 2.520 for (size_t i = 0; i < ret.length ; i++) { 2.521 ret.ptr[i] = toupper(ret.ptr[i]); 2.522 } 2.523 return ret; 2.524 } 2.525 + 2.526 +// private string conversion functions 2.527 +scstr_t ucx_sc2sc(scstr_t c) { 2.528 + return c; 2.529 +} 2.530 +scstr_t ucx_ss2sc(sstr_t str) { 2.531 + scstr_t cs; 2.532 + cs.ptr = str.ptr; 2.533 + cs.length = str.length; 2.534 + return cs; 2.535 +} 2.536 +scstr_t ucx_ss2c_s(scstr_t c) { 2.537 + return c; 2.538 +}
3.1 --- a/src/ucx/string.h Mon May 14 15:58:51 2018 +0200 3.2 +++ b/src/ucx/string.h Mon May 14 17:56:03 2018 +0200 3.3 @@ -67,7 +67,6 @@ 3.4 #ifdef __cplusplus 3.5 extern "C" { 3.6 #endif 3.7 - 3.8 /** 3.9 * The UCX string structure. 3.10 */ 3.11 @@ -79,6 +78,56 @@ 3.12 size_t length; 3.13 } sstr_t; 3.14 3.15 +typedef struct { 3.16 + const char *ptr; 3.17 + size_t length; 3.18 +} scstr_t; 3.19 + 3.20 +#ifdef __cplusplus 3.21 +} 3.22 +#endif 3.23 + 3.24 + 3.25 +#ifdef __cplusplus 3.26 +inline scstr_t s2scstr(sstr_t s) { 3.27 + scstr_t c; 3.28 + c.ptr = s.ptr; 3.29 + c.length = s.ptr; 3.30 + return c; 3.31 +} 3.32 +inline scstr_t s2scstr(scstr_t c) { 3.33 + return c; 3.34 +} 3.35 +#define SCSTR s2scstr 3.36 +#else 3.37 + 3.38 +scstr_t ucx_sc2sc(scstr_t c); 3.39 +scstr_t ucx_ss2sc(sstr_t str); 3.40 +#if __STDC_VERSION__ >= 201112L 3.41 +#define SCSTR(str) _Generic(str, sstr_t: ucx_ss2sc, scstr_t: ucx_sc2sc)(str) 3.42 +#elif defined(__GNUC__) || defined(__clang__) 3.43 +#define SCSTR(str) __builtin_choose_expr( \ 3.44 + __builtin_types_compatible_p(typeof(str), sstr_t), \ 3.45 + ucx_ss2sc, \ 3.46 + ucx_sc2sc)(str) 3.47 +#elif defined(__sun) 3.48 +#define SCSTR(str) ({typeof(str) ucx_tmp_var_str = str; \ 3.49 + scstr_t ucx_tmp_var_c; \ 3.50 + ucx_tmp_var_c.ptr = ucx_tmp_var_str.ptr;\ 3.51 + ucx_tmp_var_c.length = ucx_tmp_var_str.length;\ 3.52 + ucx_tmp_var_c; }) 3.53 +#else 3.54 +scstr_t ucx_ss2c_s(); 3.55 +#define SCSTR ucx_ss2c_s 3.56 +#endif /* C11 feature test */ 3.57 + 3.58 +#endif /* C++ */ 3.59 + 3.60 +#ifdef __cplusplus 3.61 +extern "C" { 3.62 +#endif 3.63 + 3.64 + 3.65 /** 3.66 * Creates a new sstr_t based on a C string. 3.67 * 3.68 @@ -110,6 +159,9 @@ 3.69 sstr_t sstrn(char *cstring, size_t length); 3.70 3.71 3.72 +scstr_t scstr(const char *cstring); 3.73 +scstr_t scstrn(const char *cstring, size_t length); 3.74 + 3.75 /** 3.76 * Returns the cumulated length of all specified strings. 3.77 * 3.78 @@ -123,7 +175,9 @@ 3.79 * @param ... all other strings 3.80 * @return the cumulated length of all strings 3.81 */ 3.82 -size_t sstrnlen(size_t count, sstr_t string, ...); 3.83 +size_t ucx_strnlen(size_t count, ...); 3.84 + 3.85 +#define sstrnlen(count, ...) ucx_strnlen(count, __VA_ARGS__) 3.86 3.87 /** 3.88 * Concatenates two or more strings. 3.89 @@ -136,11 +190,12 @@ 3.90 * 3.91 * @param count the total number of strings to concatenate 3.92 * @param s1 first string 3.93 - * @param s2 second string 3.94 * @param ... all remaining strings 3.95 * @return the concatenated string 3.96 */ 3.97 -sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...); 3.98 +sstr_t ucx_strcat(size_t count, scstr_t s1, ...); 3.99 + 3.100 +#define sstrcat(count, s1, ...) ucx_strcat(count, SCSTR(s1), __VA_ARGS__) 3.101 3.102 /** 3.103 * Concatenates two or more strings using a UcxAllocator. 3.104 @@ -150,12 +205,12 @@ 3.105 * @param a the allocator to use 3.106 * @param count the total number of strings to concatenate 3.107 * @param s1 first string 3.108 - * @param s2 second string 3.109 * @param ... all remaining strings 3.110 * @return the concatenated string 3.111 */ 3.112 -sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...); 3.113 +sstr_t ucx_strcat_a(UcxAllocator *a, size_t count, scstr_t s1, ...); 3.114 3.115 +#define sstrcat_a(count, s1, ...) ucx_strcat_a(count, SCSTR(s1), __VA_ARGS__) 3.116 3.117 /** 3.118 * Returns a substring starting at the specified location. 3.119 @@ -191,6 +246,13 @@ 3.120 */ 3.121 sstr_t sstrsubsl(sstr_t string, size_t start, size_t length); 3.122 3.123 +scstr_t scstrsubs(scstr_t s, size_t start); 3.124 +scstr_t scstrsubsl(scstr_t string, size_t start, size_t length); 3.125 + 3.126 + 3.127 +int ucx_strchr(const char *string, size_t length, int chr, size_t *pos); 3.128 +int ucx_strrchr(const char *string, size_t length, int chr, size_t *pos); 3.129 + 3.130 /** 3.131 * Returns a substring starting at the location of the first occurrence of the 3.132 * specified character. 3.133 @@ -219,6 +281,17 @@ 3.134 */ 3.135 sstr_t sstrrchr(sstr_t string, int chr); 3.136 3.137 + 3.138 +scstr_t scstrchr(scstr_t string, int chr); 3.139 +scstr_t scstrrchr(scstr_t string, int chr); 3.140 + 3.141 +const char* ucx_strstr( 3.142 + const char *str, 3.143 + size_t length, 3.144 + const char *match, 3.145 + size_t matchlen, 3.146 + size_t *newlen); 3.147 + 3.148 /** 3.149 * Returns a substring starting at the location of the first occurrence of the 3.150 * specified string. 3.151 @@ -234,7 +307,11 @@ 3.152 * <code>match</code>, or an empty string, if the sequence is not 3.153 * present in <code>string</code> 3.154 */ 3.155 -sstr_t sstrstr(sstr_t string, sstr_t match); 3.156 +sstr_t ucx_sstrstr(sstr_t string, scstr_t match); 3.157 +#define sstrstr(string, match) ucx_sstrstr(string, SCSTR(match)) 3.158 + 3.159 +scstr_t ucx_scstrstr(scstr_t string, scstr_t match); 3.160 +#define scstrstr(string, match) ucx_scstrstr(string, SCSTR(match)) 3.161 3.162 /** 3.163 * Splits a string into parts by using a delimiter string. 3.164 @@ -283,7 +360,9 @@ 3.165 * 3.166 * @see sstrsplit_a() 3.167 */ 3.168 -sstr_t* sstrsplit(sstr_t string, sstr_t delim, ssize_t *count); 3.169 +sstr_t* ucx_strsplit(scstr_t string, scstr_t delim, ssize_t *count); 3.170 + 3.171 +#define sstrsplit(s, delim, count) ucx_strsplit(SCSTR(s), SCSTR(delim), count) 3.172 3.173 /** 3.174 * Performing sstrsplit() using a UcxAllocator. 3.175 @@ -307,9 +386,11 @@ 3.176 * 3.177 * @see sstrsplit() 3.178 */ 3.179 -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t string, sstr_t delim, 3.180 +sstr_t* ucx_strsplit_a(UcxAllocator *allocator, scstr_t string, scstr_t delim, 3.181 ssize_t *count); 3.182 3.183 +#define sstrsplit_a(a, s, d, c) ucx_strsplit_a(a, SCSTR(s), SCSTR(d, c)) 3.184 + 3.185 /** 3.186 * Compares two UCX strings with standard <code>memcmp()</code>. 3.187 * 3.188 @@ -322,7 +403,9 @@ 3.189 * length of s1 is greater than the length of s2 or the result of 3.190 * <code>memcmp()</code> otherwise (i.e. 0 if the strings match) 3.191 */ 3.192 -int sstrcmp(sstr_t s1, sstr_t s2); 3.193 +int ucx_str_cmp(scstr_t s1, scstr_t s2); 3.194 + 3.195 +#define sstrcmp(s1, s2) ucx_str_cmp(SCSTR(s1), SCSTR(s2)) 3.196 3.197 /** 3.198 * Compares two UCX strings ignoring the case. 3.199 @@ -338,7 +421,9 @@ 3.200 * first two differing characters otherwise (i.e. 0 if the strings match and 3.201 * no characters differ) 3.202 */ 3.203 -int sstrcasecmp(sstr_t s1, sstr_t s2); 3.204 +int ucx_str_casecmp(scstr_t s1, scstr_t s2); 3.205 + 3.206 +#define sstrcasecmp(s1, s2) ucx_str_casecmp(SCSTR(s1), SCSTR(s2)) 3.207 3.208 /** 3.209 * Creates a duplicate of the specified string. 3.210 @@ -354,7 +439,9 @@ 3.211 * @return a duplicate of the string 3.212 * @see sstrdup_a() 3.213 */ 3.214 -sstr_t sstrdup(sstr_t string); 3.215 +sstr_t scstrdup(scstr_t string); 3.216 + 3.217 +#define sstrdup(s) scstrdup(SCSTR(s)) 3.218 3.219 /** 3.220 * Creates a duplicate of the specified string using a UcxAllocator. 3.221 @@ -372,7 +459,12 @@ 3.222 * @return a duplicate of the string 3.223 * @see sstrdup() 3.224 */ 3.225 -sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t string); 3.226 +sstr_t scstrdup_a(UcxAllocator *allocator, scstr_t string); 3.227 + 3.228 +#define sstrdup_a(allocator, s) scstrdup_a(allocator, SCSTR(s)) 3.229 + 3.230 + 3.231 +size_t ucx_strtrim(const char *str, size_t length, size_t *newlen); 3.232 3.233 /** 3.234 * Omits leading and trailing spaces. 3.235 @@ -393,13 +485,17 @@ 3.236 */ 3.237 sstr_t sstrtrim(sstr_t string); 3.238 3.239 +scstr_t scstrtrim(scstr_t string); 3.240 + 3.241 /** 3.242 * Checks, if a string has a specific prefix. 3.243 * @param string the string to check 3.244 * @param prefix the prefix the string should have 3.245 * @return 1, if and only if the string has the specified prefix, 0 otherwise 3.246 */ 3.247 -int sstrprefix(sstr_t string, sstr_t prefix); 3.248 +int ucx_strprefix(scstr_t string, scstr_t prefix); 3.249 + 3.250 +#define sstrprefix(string, prefix) ucx_strprefix(SCSTR(string), SCSTR(prefix)) 3.251 3.252 /** 3.253 * Checks, if a string has a specific suffix. 3.254 @@ -407,7 +503,9 @@ 3.255 * @param suffix the suffix the string should have 3.256 * @return 1, if and only if the string has the specified suffix, 0 otherwise 3.257 */ 3.258 -int sstrsuffix(sstr_t string, sstr_t suffix); 3.259 +int ucx_strsuffix(scstr_t string, scstr_t suffix); 3.260 + 3.261 +#define sstrsuffix(string, prefix) ucx_strsuffix(SCSTR(string), SCSTR(prefix)) 3.262 3.263 /** 3.264 * Returns a lower case version of a string. 3.265 @@ -419,7 +517,9 @@ 3.266 * @return the resulting lower case string 3.267 * @see sstrdup() 3.268 */ 3.269 -sstr_t sstrlower(sstr_t string); 3.270 +sstr_t ucx_strlower(scstr_t string); 3.271 + 3.272 +#define sstrlower(string) ucx_strlower(SCSTR(string)) 3.273 3.274 /** 3.275 * Returns a lower case version of a string. 3.276 @@ -432,7 +532,9 @@ 3.277 * @return the resulting lower case string 3.278 * @see sstrdup_a() 3.279 */ 3.280 -sstr_t sstrlower_a(UcxAllocator *allocator, sstr_t string); 3.281 +sstr_t ucx_strlower_a(UcxAllocator *allocator, scstr_t string); 3.282 + 3.283 +#define sstrlower_a(allocator, string) ucx_strlower_a(allocator, SCSTR(string)) 3.284 3.285 /** 3.286 * Returns a upper case version of a string. 3.287 @@ -444,7 +546,9 @@ 3.288 * @return the resulting upper case string 3.289 * @see sstrdup() 3.290 */ 3.291 -sstr_t sstrupper(sstr_t string); 3.292 +sstr_t ucx_strupper(scstr_t string); 3.293 + 3.294 +#define sstrupper(string) ucx_strupper(SCSTR(string)) 3.295 3.296 /** 3.297 * Returns a upper case version of a string. 3.298 @@ -457,7 +561,9 @@ 3.299 * @return the resulting upper case string 3.300 * @see sstrdup_a() 3.301 */ 3.302 -sstr_t sstrupper_a(UcxAllocator *allocator, sstr_t string); 3.303 +sstr_t ucx_strupper_a(UcxAllocator *allocator, scstr_t string); 3.304 + 3.305 +#define sstrupper_a(allocator, string) ucx_strupper_a(allocator, string) 3.306 3.307 #ifdef __cplusplus 3.308 }
4.1 --- a/src/ucx/ucx.h Mon May 14 15:58:51 2018 +0200 4.2 +++ b/src/ucx/ucx.h Mon May 14 17:56:03 2018 +0200 4.3 @@ -37,10 +37,10 @@ 4.4 #define UCX_H 4.5 4.6 /** Major UCX version as integer constant. */ 4.7 -#define UCX_VERSION_MAJOR 1 4.8 +#define UCX_VERSION_MAJOR 2 4.9 4.10 /** Minor UCX version as integer constant. */ 4.11 -#define UCX_VERSION_MINOR 1 4.12 +#define UCX_VERSION_MINOR 0 4.13 4.14 /** Version constant which ensures to increase monotonically. */ 4.15 #define UCX_VERSION (((UCX_VERSION_MAJOR)<<16)|UCX_VERSION_MINOR)
5.1 --- a/test/string_tests.c Mon May 14 15:58:51 2018 +0200 5.2 +++ b/test/string_tests.c Mon May 14 17:56:03 2018 +0200 5.3 @@ -77,7 +77,12 @@ 5.4 UCX_TEST_BEGIN 5.5 5.6 sstr_t notfound = sstrchr(str, 'x'); 5.7 - UCX_TEST_ASSERT(notfound.length == 0, "string length not 0"); 5.8 + UCX_TEST_ASSERT(notfound.length == 0, 5.9 + "string length not 0 after forward search w/o result"); 5.10 + 5.11 + notfound = sstrrchr(str, 'x'); 5.12 + UCX_TEST_ASSERT(notfound.length == 0, 5.13 + "string length not 0 after reverse search w/o result"); 5.14 5.15 sstr_t result = sstrchr(str, 'w'); 5.16 UCX_TEST_ASSERT(result.length == 35, "sstrchr returned wrong length");