merges constsstr branch

Mon, 14 May 2018 17:56:03 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 14 May 2018 17:56:03 +0200
changeset 306
90b6d69bb499
parent 305
353d71349e61 (current diff)
parent 300
d1f814633049 (diff)
child 308
d6f580621512

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");

mercurial