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 -}