src/ucx/string.c

changeset 61
47a5fc33590a
parent 60
9f25df78925e
child 62
3fff4c364ffc
     1.1 --- a/src/ucx/string.c	Thu Nov 10 18:44:48 2016 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,381 +0,0 @@
     1.4 -/*
     1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     1.6 - *
     1.7 - * Copyright 2015 Olaf Wintermann. All rights reserved.
     1.8 - *
     1.9 - * Redistribution and use in source and binary forms, with or without
    1.10 - * modification, are permitted provided that the following conditions are met:
    1.11 - *
    1.12 - *   1. Redistributions of source code must retain the above copyright
    1.13 - *      notice, this list of conditions and the following disclaimer.
    1.14 - *
    1.15 - *   2. Redistributions in binary form must reproduce the above copyright
    1.16 - *      notice, this list of conditions and the following disclaimer in the
    1.17 - *      documentation and/or other materials provided with the distribution.
    1.18 - *
    1.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    1.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    1.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    1.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    1.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    1.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    1.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1.29 - * POSSIBILITY OF SUCH DAMAGE.
    1.30 - */
    1.31 -
    1.32 -#include <stdlib.h>
    1.33 -#include <string.h>
    1.34 -#include <stdarg.h>
    1.35 -#include <ctype.h>
    1.36 -
    1.37 -#include "string.h"
    1.38 -#include "allocator.h"
    1.39 -
    1.40 -sstr_t sstr(char *cstring) {
    1.41 -    sstr_t string;
    1.42 -    string.ptr = cstring;
    1.43 -    string.length = strlen(cstring);
    1.44 -    return string;
    1.45 -}
    1.46 -
    1.47 -sstr_t sstrn(char *cstring, size_t length) {
    1.48 -    sstr_t string;
    1.49 -    string.ptr = cstring;
    1.50 -    string.length = length;
    1.51 -    return string;
    1.52 -}
    1.53 -
    1.54 -size_t sstrnlen(size_t n, sstr_t s, ...) {
    1.55 -    va_list ap;
    1.56 -    size_t size = s.length;
    1.57 -    va_start(ap, s);
    1.58 -
    1.59 -    for (size_t i = 1 ; i < n ; i++) {
    1.60 -        sstr_t str = va_arg(ap, sstr_t);
    1.61 -        size += str.length;
    1.62 -    }
    1.63 -    va_end(ap);
    1.64 -
    1.65 -    return size;
    1.66 -}
    1.67 -
    1.68 -static sstr_t sstrvcat_a(
    1.69 -        UcxAllocator *a,
    1.70 -        size_t count,
    1.71 -        sstr_t s1,
    1.72 -        sstr_t s2,
    1.73 -        va_list ap) {
    1.74 -    sstr_t str;
    1.75 -    str.ptr = NULL;
    1.76 -    str.length = 0;
    1.77 -    if(count < 2) {
    1.78 -        return str;
    1.79 -    }
    1.80 -    
    1.81 -    sstr_t *strings = (sstr_t*) calloc(count, sizeof(sstr_t));
    1.82 -    if(!strings) {
    1.83 -        return str;
    1.84 -    }
    1.85 -    
    1.86 -    // get all args and overall length
    1.87 -    strings[0] = s1;
    1.88 -    strings[1] = s2;
    1.89 -    size_t strlen = s1.length + s2.length;
    1.90 -    for (size_t i=2;i<count;i++) {
    1.91 -        sstr_t s = va_arg (ap, sstr_t);
    1.92 -        strings[i] = s;
    1.93 -        strlen += s.length;
    1.94 -    }
    1.95 -    
    1.96 -    // create new string
    1.97 -    str.ptr = (char*) almalloc(a, strlen + 1);
    1.98 -    str.length = strlen;
    1.99 -    if(!str.ptr) {
   1.100 -        free(strings);
   1.101 -        str.length = 0;
   1.102 -        return str;
   1.103 -    }
   1.104 -    
   1.105 -    // concatenate strings
   1.106 -    size_t pos = 0;
   1.107 -    for (size_t i=0;i<count;i++) {
   1.108 -        sstr_t s = strings[i];
   1.109 -        memcpy(str.ptr + pos, s.ptr, s.length);
   1.110 -        pos += s.length;
   1.111 -    }
   1.112 -    
   1.113 -    str.ptr[str.length] = '\0';
   1.114 -    
   1.115 -    free(strings);
   1.116 -    
   1.117 -    return str;
   1.118 -}
   1.119 -
   1.120 -sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...) {
   1.121 -    va_list ap;
   1.122 -    va_start(ap, s2);
   1.123 -    sstr_t s = sstrvcat_a(ucx_default_allocator(), count, s1, s2, ap);
   1.124 -    va_end(ap);
   1.125 -    return s;
   1.126 -}
   1.127 -
   1.128 -sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...) {
   1.129 -    va_list ap;
   1.130 -    va_start(ap, s2);
   1.131 -    sstr_t s = sstrvcat_a(a, count, s1, s2, ap);
   1.132 -    va_end(ap);
   1.133 -    return s;
   1.134 -}
   1.135 -
   1.136 -sstr_t sstrsubs(sstr_t s, size_t start) {
   1.137 -    return sstrsubsl (s, start, s.length-start);
   1.138 -}
   1.139 -
   1.140 -sstr_t sstrsubsl(sstr_t s, size_t start, size_t length) {
   1.141 -    sstr_t new_sstr;
   1.142 -    if (start >= s.length) {
   1.143 -        new_sstr.ptr = NULL;
   1.144 -        new_sstr.length = 0;
   1.145 -    } else {
   1.146 -        if (length > s.length-start) {
   1.147 -            length = s.length-start;
   1.148 -        }
   1.149 -        new_sstr.ptr = &s.ptr[start];
   1.150 -        new_sstr.length = length;
   1.151 -    }
   1.152 -    return new_sstr;
   1.153 -}
   1.154 -
   1.155 -sstr_t sstrchr(sstr_t s, int c) {
   1.156 -    for(size_t i=0;i<s.length;i++) {
   1.157 -        if(s.ptr[i] == c) {
   1.158 -            return sstrsubs(s, i);
   1.159 -        }
   1.160 -    }
   1.161 -    sstr_t n;
   1.162 -    n.ptr = NULL;
   1.163 -    n.length = 0;
   1.164 -    return n;
   1.165 -}
   1.166 -
   1.167 -sstr_t sstrrchr(sstr_t s, int c) {
   1.168 -    if (s.length > 0) {
   1.169 -        for(size_t i=s.length;i>0;i--) {
   1.170 -            if(s.ptr[i-1] == c) {
   1.171 -                return sstrsubs(s, i-1);
   1.172 -            }
   1.173 -        }
   1.174 -    }
   1.175 -    sstr_t n;
   1.176 -    n.ptr = NULL;
   1.177 -    n.length = 0;
   1.178 -    return n;
   1.179 -}
   1.180 -
   1.181 -sstr_t sstrstr(sstr_t string, sstr_t match) {
   1.182 -    if (match.length == 0) {
   1.183 -        return string;
   1.184 -    }
   1.185 -    
   1.186 -    for (size_t i = 0 ; i < string.length ; i++) {
   1.187 -        sstr_t substr = sstrsubs(string, i);
   1.188 -        if (sstrprefix(substr, match)) {
   1.189 -            return substr;
   1.190 -        }
   1.191 -    }
   1.192 -    
   1.193 -    sstr_t emptystr;
   1.194 -    emptystr.length = 0;
   1.195 -    emptystr.ptr = NULL;
   1.196 -    return emptystr;
   1.197 -}
   1.198 -
   1.199 -sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) {
   1.200 -    return sstrsplit_a(ucx_default_allocator(), s, d, n);
   1.201 -}
   1.202 -
   1.203 -sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, ssize_t *n) {
   1.204 -    if (s.length == 0 || d.length == 0) {
   1.205 -        *n = -1;
   1.206 -        return NULL;
   1.207 -    }
   1.208 -
   1.209 -    sstr_t* result;
   1.210 -    ssize_t nmax = *n;
   1.211 -    *n = 1;
   1.212 -
   1.213 -    /* special case: exact match - no processing needed */
   1.214 -    if (sstrcmp(s, d) == 0) {
   1.215 -        *n = 0;
   1.216 -        return NULL;
   1.217 -    }
   1.218 -    sstr_t sv = sstrdup(s);
   1.219 -    if (sv.length == 0) {
   1.220 -        *n = -2;
   1.221 -        return NULL;
   1.222 -    }
   1.223 -
   1.224 -    for (size_t i = 0 ; i < s.length ; i++) {
   1.225 -        sstr_t substr = sstrsubs(sv, i);
   1.226 -        if (sstrprefix(substr, d)) {
   1.227 -            (*n)++;
   1.228 -            for (size_t j = 0 ; j < d.length ; j++) {
   1.229 -                sv.ptr[i+j] = 0;
   1.230 -            }
   1.231 -            i += d.length - 1; // -1, because the loop will do a i++
   1.232 -        }
   1.233 -        if ((*n) == nmax) break;
   1.234 -    }
   1.235 -    result = (sstr_t*) almalloc(allocator, sizeof(sstr_t)*(*n));
   1.236 -
   1.237 -    if (result) {
   1.238 -        char *pptr = sv.ptr;
   1.239 -        for (ssize_t i = 0 ; i < *n ; i++) {
   1.240 -            size_t l = strlen(pptr);
   1.241 -            char* ptr = (char*) almalloc(allocator, l + 1);
   1.242 -            if (ptr) {
   1.243 -                memcpy(ptr, pptr, l);
   1.244 -                ptr[l] = 0;
   1.245 -
   1.246 -                result[i] = sstrn(ptr, l);
   1.247 -                pptr += l + d.length;
   1.248 -            } else {
   1.249 -                for (ssize_t j = i-1 ; j >= 0 ; j--) {
   1.250 -                    alfree(allocator, result[j].ptr);
   1.251 -                }
   1.252 -                alfree(allocator, result);
   1.253 -                *n = -2;
   1.254 -                break;
   1.255 -            }
   1.256 -        }
   1.257 -    } else {
   1.258 -        *n = -2;
   1.259 -    }
   1.260 -    
   1.261 -    free(sv.ptr);
   1.262 -
   1.263 -    return result;
   1.264 -}
   1.265 -
   1.266 -int sstrcmp(sstr_t s1, sstr_t s2) {
   1.267 -    if (s1.length == s2.length) {
   1.268 -        return memcmp(s1.ptr, s2.ptr, s1.length);
   1.269 -    } else if (s1.length > s2.length) {
   1.270 -        return 1;
   1.271 -    } else {
   1.272 -        return -1;
   1.273 -    }
   1.274 -}
   1.275 -
   1.276 -int sstrcasecmp(sstr_t s1, sstr_t s2) {
   1.277 -    if (s1.length == s2.length) {
   1.278 -#ifdef _WIN32
   1.279 -        return _strnicmp(s1.ptr, s2.ptr, s1.length);
   1.280 -#else
   1.281 -        return strncasecmp(s1.ptr, s2.ptr, s1.length);
   1.282 -#endif
   1.283 -    } else if (s1.length > s2.length) {
   1.284 -        return 1;
   1.285 -    } else {
   1.286 -        return -1;
   1.287 -    }
   1.288 -}
   1.289 -
   1.290 -sstr_t sstrdup(sstr_t s) {
   1.291 -    return sstrdup_a(ucx_default_allocator(), s);
   1.292 -}
   1.293 -
   1.294 -sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t s) {
   1.295 -    sstr_t newstring;
   1.296 -    newstring.ptr = (char*)almalloc(allocator, s.length + 1);
   1.297 -    if (newstring.ptr) {
   1.298 -        newstring.length = s.length;
   1.299 -        newstring.ptr[newstring.length] = 0;
   1.300 -        
   1.301 -        memcpy(newstring.ptr, s.ptr, s.length);
   1.302 -    } else {
   1.303 -        newstring.length = 0;
   1.304 -    }
   1.305 -    
   1.306 -    return newstring;
   1.307 -}
   1.308 -
   1.309 -sstr_t sstrtrim(sstr_t string) {
   1.310 -    sstr_t newstr = string;
   1.311 -    
   1.312 -    while (newstr.length > 0 && isspace(*newstr.ptr)) {
   1.313 -        newstr.ptr++;
   1.314 -        newstr.length--;
   1.315 -    }
   1.316 -    while (newstr.length > 0 && isspace(newstr.ptr[newstr.length-1])) {
   1.317 -        newstr.length--;
   1.318 -    }
   1.319 -    
   1.320 -    return newstr;
   1.321 -}
   1.322 -
   1.323 -int sstrprefix(sstr_t string, sstr_t prefix) {
   1.324 -    if (string.length == 0) {
   1.325 -        return prefix.length == 0;
   1.326 -    }
   1.327 -    if (prefix.length == 0) {
   1.328 -        return 1;
   1.329 -    }
   1.330 -    
   1.331 -    if (prefix.length > string.length) {
   1.332 -        return 0;
   1.333 -    } else {
   1.334 -        return memcmp(string.ptr, prefix.ptr, prefix.length) == 0;
   1.335 -    }
   1.336 -}
   1.337 -
   1.338 -int sstrsuffix(sstr_t string, sstr_t suffix) {
   1.339 -    if (string.length == 0) {
   1.340 -        return suffix.length == 0;
   1.341 -    }
   1.342 -    if (suffix.length == 0) {
   1.343 -        return 1;
   1.344 -    }
   1.345 -    
   1.346 -    if (suffix.length > string.length) {
   1.347 -        return 0;
   1.348 -    } else {
   1.349 -        return memcmp(string.ptr+string.length-suffix.length,
   1.350 -            suffix.ptr, suffix.length) == 0;
   1.351 -    }
   1.352 -}
   1.353 -
   1.354 -sstr_t sstrlower(sstr_t string) {
   1.355 -    sstr_t ret = sstrdup(string);
   1.356 -    for (size_t i = 0; i < ret.length ; i++) {
   1.357 -        ret.ptr[i] = tolower(ret.ptr[i]);
   1.358 -    }
   1.359 -    return ret;
   1.360 -}
   1.361 -
   1.362 -sstr_t sstrlower_a(UcxAllocator *allocator, sstr_t string) {
   1.363 -    sstr_t ret = sstrdup_a(allocator, string);
   1.364 -    for (size_t i = 0; i < ret.length ; i++) {
   1.365 -        ret.ptr[i] = tolower(ret.ptr[i]);
   1.366 -    }
   1.367 -    return ret;
   1.368 -}
   1.369 -
   1.370 -sstr_t sstrupper(sstr_t string) {
   1.371 -    sstr_t ret = sstrdup(string);
   1.372 -    for (size_t i = 0; i < ret.length ; i++) {
   1.373 -        ret.ptr[i] = toupper(ret.ptr[i]);
   1.374 -    }
   1.375 -    return ret;
   1.376 -}
   1.377 -
   1.378 -sstr_t sstrupper_a(UcxAllocator *allocator, sstr_t string) {
   1.379 -    sstr_t ret = sstrdup_a(allocator, string);
   1.380 -    for (size_t i = 0; i < ret.length ; i++) {
   1.381 -        ret.ptr[i] = toupper(ret.ptr[i]);
   1.382 -    }
   1.383 -    return ret;
   1.384 -}

mercurial