Thu, 28 Dec 2023 20:37:53 +0100
migrate string tests - relates to #342
tests/Makefile | file | annotate | diff | comparison | revisions | |
tests/test_string.c | file | annotate | diff | comparison | revisions | |
tests/test_string.cpp | file | annotate | diff | comparison | revisions | |
tests/ucxtest.c | file | annotate | diff | comparison | revisions |
1.1 --- a/tests/Makefile Thu Dec 28 19:17:45 2023 +0100 1.2 +++ b/tests/Makefile Thu Dec 28 20:37:53 2023 +0100 1.3 @@ -23,11 +23,11 @@ 1.4 1.5 include ../config.mk 1.6 1.7 -CFLAGS += -I../src 1.8 +CFLAGS += -I../src -Wno-clobbered 1.9 1.10 TEST_DIR=$(build_dir)/tests 1.11 1.12 -SRC = util_allocator.c test_utils.c test_hash_key.c ucxtest.c 1.13 +SRC = util_allocator.c test_utils.c test_hash_key.c test_string.c ucxtest.c 1.14 1.15 OBJ_EXT=.o 1.16 OBJ=$(SRC:%.c=$(TEST_DIR)/%$(OBJ_EXT)) 1.17 @@ -59,6 +59,10 @@ 1.18 @echo "Compiling $<" 1.19 $(CC) -o $@ $(CFLAGS) -c $< 1.20 1.21 +$(TEST_DIR)/test_string$(OBJ_EXT): test_string.c 1.22 + @echo "Compiling $<" 1.23 + $(CC) -o $@ $(CFLAGS) -c $< 1.24 + 1.25 $(TEST_DIR)/test_utils$(OBJ_EXT): test_utils.c ../src/cx/test.h \ 1.26 ../src/cx/utils.h ../src/cx/common.h ../src/cx/buffer.h \ 1.27 ../src/cx/allocator.h ../src/szmul.c
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/tests/test_string.c Thu Dec 28 20:37:53 2023 +0100 2.3 @@ -0,0 +1,986 @@ 2.4 +/* 2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2.6 + * 2.7 + * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved. 2.8 + * 2.9 + * Redistribution and use in source and binary forms, with or without 2.10 + * modification, are permitted provided that the following conditions are met: 2.11 + * 2.12 + * 1. Redistributions of source code must retain the above copyright 2.13 + * notice, this list of conditions and the following disclaimer. 2.14 + * 2.15 + * 2. Redistributions in binary form must reproduce the above copyright 2.16 + * notice, this list of conditions and the following disclaimer in the 2.17 + * documentation and/or other materials provided with the distribution. 2.18 + * 2.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2.29 + * POSSIBILITY OF SUCH DAMAGE. 2.30 + */ 2.31 + 2.32 +#include "cx/test.h" 2.33 +#include "util_allocator.h" 2.34 + 2.35 +#include "cx/string.h" 2.36 + 2.37 +#define ASSERT_ZERO_TERMINATED(str) CX_TEST_ASSERTM((str).ptr[(str).length] == '\0', \ 2.38 + #str " is not zero terminated") 2.39 + 2.40 +CX_TEST(test_string_construct) { 2.41 + cxstring s1 = CX_STR("1234"); 2.42 + cxstring s2 = cx_strn("abcd", 2); 2.43 + cxmutstr s3 = cx_mutstr((char *) "1234"); 2.44 + cxmutstr s4 = cx_mutstrn((char *) "abcd", 2); 2.45 + CX_TEST_DO { 2.46 + CX_TEST_ASSERT(s1.length == 4); 2.47 + CX_TEST_ASSERT(strncmp(s1.ptr, "1234", 4) == 0); 2.48 + CX_TEST_ASSERT(s2.length == 2); 2.49 + CX_TEST_ASSERT(strncmp(s2.ptr, "ab", 2) == 0); 2.50 + CX_TEST_ASSERT(s3.length == 4); 2.51 + CX_TEST_ASSERT(strncmp(s3.ptr, "1234", 4) == 0); 2.52 + CX_TEST_ASSERT(s4.length == 2); 2.53 + CX_TEST_ASSERT(strncmp(s4.ptr, "ab", 2) == 0); 2.54 + } 2.55 +} 2.56 + 2.57 +CX_TEST(test_strfree) { 2.58 + CxTestingAllocator talloc; 2.59 + cx_testing_allocator_init(&talloc); 2.60 + CxAllocator *alloc = &talloc.base; 2.61 + CX_TEST_DO { 2.62 + char *test = cxMalloc(alloc, 16); 2.63 + cxmutstr str = cx_mutstrn(test, 16); 2.64 + CX_TEST_ASSERT(str.ptr == test); 2.65 + CX_TEST_ASSERT(str.length == 16); 2.66 + cx_strfree_a(alloc, &str); 2.67 + CX_TEST_ASSERT(str.ptr == NULL); 2.68 + CX_TEST_ASSERT(str.length == 0); 2.69 + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 2.70 + } 2.71 + cx_testing_allocator_destroy(&talloc); 2.72 +} 2.73 + 2.74 +CX_TEST(test_strdup) { 2.75 + cxstring str = CX_STR("test"); 2.76 + cxmutstr dup = cx_strdup(str); 2.77 + CX_TEST_DO { 2.78 + CX_TEST_ASSERT(dup.length == str.length); 2.79 + CX_TEST_ASSERT(0 == strcmp(dup.ptr, str.ptr)); 2.80 + ASSERT_ZERO_TERMINATED(dup); 2.81 + } 2.82 + cx_strfree(&dup); 2.83 +} 2.84 + 2.85 +CX_TEST(test_strdup_shortened) { 2.86 + cxstring str = CX_STR("test"); 2.87 + str.length = 2; 2.88 + cxmutstr dup = cx_strdup(str); 2.89 + CX_TEST_DO { 2.90 + CX_TEST_ASSERT(dup.length == str.length); 2.91 + CX_TEST_ASSERT(0 == strcmp(dup.ptr, "te")); 2.92 + ASSERT_ZERO_TERMINATED(dup); 2.93 + } 2.94 + cx_strfree(&dup); 2.95 +} 2.96 + 2.97 +CX_TEST(test_strlen) { 2.98 + cxstring s1 = CX_STR("1234"); 2.99 + cxstring s2 = CX_STR(".:.:."); 2.100 + cxstring s3 = CX_STR("X"); 2.101 + CX_TEST_DO { 2.102 + size_t len0 = cx_strlen(0); 2.103 + size_t len1 = cx_strlen(1, s1); 2.104 + size_t len2 = cx_strlen(2, s1, s2); 2.105 + size_t len3 = cx_strlen(3, s1, s2, s3); 2.106 + 2.107 + CX_TEST_ASSERT(len0 == 0); 2.108 + CX_TEST_ASSERT(len1 == 4); 2.109 + CX_TEST_ASSERT(len2 == 9); 2.110 + CX_TEST_ASSERT(len3 == 10); 2.111 + } 2.112 +} 2.113 + 2.114 +CX_TEST(test_strsubs) { 2.115 + cxstring str = CX_STR("A test string"); 2.116 + 2.117 + CX_TEST_DO { 2.118 + cxstring sub = cx_strsubs(str, 0); 2.119 + CX_TEST_ASSERT(0 == cx_strcmp(sub, str)); 2.120 + 2.121 + sub = cx_strsubs(str, 2); 2.122 + CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("test string"))); 2.123 + 2.124 + sub = cx_strsubs(str, 7); 2.125 + CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("string"))); 2.126 + 2.127 + sub = cx_strsubs(str, 15); 2.128 + CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR(""))); 2.129 + 2.130 + sub = cx_strsubsl(str, 2, 4); 2.131 + CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("test"))); 2.132 + 2.133 + sub = cx_strsubsl(str, 7, 3); 2.134 + CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("str"))); 2.135 + 2.136 + sub = cx_strsubsl(str, 7, 20); 2.137 + CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("string"))); 2.138 + 2.139 + // just for coverage, call the _m variant 2.140 + cxmutstr m = cx_strsubs_m(cx_mutstrn(NULL, 0), 0); 2.141 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m), CX_STR(""))); 2.142 + } 2.143 +} 2.144 + 2.145 +CX_TEST(test_strchr) { 2.146 + cxstring str = CX_STR("I will find you - and I will kill you"); 2.147 + 2.148 + CX_TEST_DO { 2.149 + cxstring notfound = cx_strchr(str, 'x'); 2.150 + CX_TEST_ASSERT(notfound.length == 0); 2.151 + 2.152 + cxstring result = cx_strchr(str, 'w'); 2.153 + CX_TEST_ASSERT(result.length == 35); 2.154 + CX_TEST_ASSERT(0 == strcmp(result.ptr, "will find you - and I will kill you")); 2.155 + 2.156 + // just for coverage, call the _m variant 2.157 + cxmutstr m = cx_strchr_m(cx_mutstrn(NULL, 0), 'a'); 2.158 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m), CX_STR(""))); 2.159 + } 2.160 +} 2.161 + 2.162 +CX_TEST(test_strrchr) { 2.163 + cxstring str = CX_STR("I will find you - and I will kill you"); 2.164 + 2.165 + CX_TEST_DO { 2.166 + cxstring notfound = cx_strrchr(str, 'x'); 2.167 + CX_TEST_ASSERT(notfound.length == 0); 2.168 + 2.169 + cxstring result = cx_strrchr(str, 'w'); 2.170 + CX_TEST_ASSERT(result.length == 13); 2.171 + CX_TEST_ASSERT(0 == strcmp(result.ptr, "will kill you")); 2.172 + 2.173 + // just for coverage, call the _m variant 2.174 + cxmutstr m = cx_strrchr_m(cx_mutstrn(NULL, 0), 'a'); 2.175 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m), CX_STR(""))); 2.176 + } 2.177 +} 2.178 + 2.179 +CX_TEST(test_strstr) { 2.180 + cxstring str = CX_STR("find the match in this string"); 2.181 + cxstring longstr = CX_STR( 2.182 + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl" 2.183 + "mnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx" 2.184 + "yzabcdeababababnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij" 2.185 + "klmnopqrstuvwxyzaababababababababrstuvwxyzabcdefghijklmnopqrstuv" 2.186 + "abababababababababababababababababababababababababababababababab" 2.187 + "abababababababababababababababababababababababababababababababab" 2.188 + "abababababababababababababababababababababababababababababababab" 2.189 + "abababababababababababababababababababababababababababababababab" 2.190 + "abababababababababababababababababababababababababababababababab" 2.191 + "abababababababababababababababababababababababababababababababab" 2.192 + "wxyz1234567890"); 2.193 + cxstring longstrpattern = CX_STR( 2.194 + "abababababababababababababababababababababababababababababababab" 2.195 + "abababababababababababababababababababababababababababababababab" 2.196 + "abababababababababababababababababababababababababababababababab" 2.197 + "abababababababababababababababababababababababababababababababab" 2.198 + "abababababababababababababababababababababababababababababababab" 2.199 + ); 2.200 + cxstring longstrresult = CX_STR( 2.201 + "abababababababababababababababababababababababababababababababab" 2.202 + "abababababababababababababababababababababababababababababababab" 2.203 + "abababababababababababababababababababababababababababababababab" 2.204 + "abababababababababababababababababababababababababababababababab" 2.205 + "abababababababababababababababababababababababababababababababab" 2.206 + "abababababababababababababababababababababababababababababababab" 2.207 + "wxyz1234567890" 2.208 + ); 2.209 + 2.210 + CX_TEST_DO { 2.211 + cxstring notfound = cx_strstr(str, CX_STR("no match")); 2.212 + CX_TEST_ASSERT(notfound.length == 0); 2.213 + 2.214 + cxstring result = cx_strstr(str, CX_STR("match")); 2.215 + CX_TEST_ASSERT(result.length == 20); 2.216 + CX_TEST_ASSERT(0 == strcmp(result.ptr, "match in this string")); 2.217 + 2.218 + result = cx_strstr(str, CX_STR("")); 2.219 + CX_TEST_ASSERT(result.length == str.length); 2.220 + CX_TEST_ASSERT(0 == strcmp(result.ptr, str.ptr)); 2.221 + 2.222 + result = cx_strstr(longstr, longstrpattern); 2.223 + CX_TEST_ASSERT(result.length == longstrresult.length); 2.224 + CX_TEST_ASSERT(0 == strcmp(result.ptr, longstrresult.ptr)); 2.225 + 2.226 + // just for coverage, call the _m variant 2.227 + cxmutstr mstr = cx_strdup(longstr); 2.228 + cxmutstr m = cx_strstr_m(mstr, longstrpattern); 2.229 + CX_TEST_ASSERT(m.length == longstrresult.length); 2.230 + CX_TEST_ASSERT(0 == strcmp(m.ptr, longstrresult.ptr)); 2.231 + cx_strfree(&mstr); 2.232 + } 2.233 +} 2.234 + 2.235 +CX_TEST(test_strcmp) { 2.236 + cxstring str = CX_STR("compare this"); 2.237 + CX_TEST_DO { 2.238 + CX_TEST_ASSERT(0 == cx_strcmp(CX_STR(""), CX_STR(""))); 2.239 + CX_TEST_ASSERT(0 < cx_strcmp(str, CX_STR(""))); 2.240 + CX_TEST_ASSERT(0 == cx_strcmp(str, CX_STR("compare this"))); 2.241 + CX_TEST_ASSERT(0 != cx_strcmp(str, CX_STR("Compare This"))); 2.242 + CX_TEST_ASSERT(0 > cx_strcmp(str, CX_STR("compare tool"))); 2.243 + CX_TEST_ASSERT(0 < cx_strcmp(str, CX_STR("compare shit"))); 2.244 + CX_TEST_ASSERT(0 > cx_strcmp(str, CX_STR("compare this not"))); 2.245 + CX_TEST_ASSERT(0 < cx_strcmp(str, CX_STR("compare"))); 2.246 + 2.247 + cxstring str2 = CX_STR("Compare This"); 2.248 + CX_TEST_ASSERT(0 != cx_strcmp_p(&str, &str2)); 2.249 + str2 = CX_STR("compare this"); 2.250 + CX_TEST_ASSERT(0 == cx_strcmp_p(&str, &str2)); 2.251 + } 2.252 +} 2.253 + 2.254 +CX_TEST(test_strcasecmp) { 2.255 + cxstring str = CX_STR("compare this"); 2.256 + CX_TEST_DO { 2.257 + CX_TEST_ASSERT(0 == cx_strcasecmp(CX_STR(""), CX_STR(""))); 2.258 + CX_TEST_ASSERT(0 < cx_strcasecmp(str, CX_STR(""))); 2.259 + CX_TEST_ASSERT(0 == cx_strcasecmp(str, CX_STR("compare this"))); 2.260 + CX_TEST_ASSERT(0 == cx_strcasecmp(str, CX_STR("Compare This"))); 2.261 + CX_TEST_ASSERT(0 > cx_strcasecmp(str, CX_STR("compare tool"))); 2.262 + CX_TEST_ASSERT(0 < cx_strcasecmp(str, CX_STR("compare shit"))); 2.263 + CX_TEST_ASSERT(0 > cx_strcasecmp(str, CX_STR("compare this not"))); 2.264 + CX_TEST_ASSERT(0 < cx_strcasecmp(str, CX_STR("compare"))); 2.265 + 2.266 + cxstring str2 = CX_STR("Compare This"); 2.267 + CX_TEST_ASSERT(0 == cx_strcasecmp_p(&str, &str2)); 2.268 + str2 = CX_STR("Compare Tool"); 2.269 + CX_TEST_ASSERT(0 > cx_strcasecmp_p(&str, &str2)); 2.270 + } 2.271 +} 2.272 + 2.273 +CX_TEST(test_strcat) { 2.274 + cxstring s1 = CX_STR("12"); 2.275 + cxstring s2 = CX_STR("34"); 2.276 + cxstring s3 = CX_STR("56"); 2.277 + cxstring sn = {NULL, 0}; 2.278 + 2.279 + CxTestingAllocator talloc; 2.280 + cx_testing_allocator_init(&talloc); 2.281 + CxAllocator *alloc = &talloc.base; 2.282 + 2.283 + CX_TEST_DO { 2.284 + cxmutstr t1 = cx_strcat_a(alloc, 2, s1, s2); 2.285 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t1), CX_STR("1234"))); 2.286 + ASSERT_ZERO_TERMINATED(t1); 2.287 + cx_strfree_a(alloc, &t1); 2.288 + 2.289 + cxmutstr t2 = cx_strcat_a(alloc, 3, s1, s2, s3); 2.290 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t2), CX_STR("123456"))); 2.291 + ASSERT_ZERO_TERMINATED(t2); 2.292 + cx_strfree_a(alloc, &t2); 2.293 + 2.294 + cxmutstr t3 = cx_strcat_a(alloc, 6, s1, sn, s2, sn, s3, sn); 2.295 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t3), CX_STR("123456"))); 2.296 + ASSERT_ZERO_TERMINATED(t3); 2.297 + cx_strfree_a(alloc, &t3); 2.298 + 2.299 + cxmutstr t4 = cx_strcat_a(alloc, 2, sn, sn); 2.300 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t4), CX_STR(""))); 2.301 + ASSERT_ZERO_TERMINATED(t4); 2.302 + cx_strfree_a(alloc, &t4); 2.303 + 2.304 + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 2.305 + 2.306 + // use the macro 2.307 + cxmutstr t5 = cx_strcat(3, s3, s1, s2); 2.308 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t5), CX_STR("561234"))); 2.309 + ASSERT_ZERO_TERMINATED(t5); 2.310 + cx_strfree(&t5); 2.311 + 2.312 + // use an initial string 2.313 + cxmutstr t6 = cx_strdup(CX_STR("Hello")); 2.314 + t6 = cx_strcat_m(t6, 2, CX_STR(", "), CX_STR("World!")); 2.315 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t6), CX_STR("Hello, World!"))); 2.316 + ASSERT_ZERO_TERMINATED(t6); 2.317 + cx_strfree(&t6); 2.318 + } 2.319 + cx_testing_allocator_destroy(&talloc); 2.320 +} 2.321 + 2.322 +CX_TEST(test_strsplit) { 2.323 + cxstring test = CX_STR("this,is,a,csv,string"); 2.324 + size_t capa = 8; 2.325 + cxstring list[8]; 2.326 + size_t n; 2.327 + CX_TEST_DO { 2.328 + // special case: empty string 2.329 + n = cx_strsplit(test, CX_STR(""), capa, list); 2.330 + CX_TEST_ASSERT(n == 1); 2.331 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], test)); 2.332 + 2.333 + // no delimiter occurrence 2.334 + n = cx_strsplit(test, CX_STR("z"), capa, list); 2.335 + CX_TEST_ASSERT(n == 1); 2.336 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], test)); 2.337 + 2.338 + // partially matching delimiter 2.339 + n = cx_strsplit(test, CX_STR("is,not"), capa, list); 2.340 + CX_TEST_ASSERT(n == 1); 2.341 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], test)); 2.342 + 2.343 + // matching single-char delimiter 2.344 + n = cx_strsplit(test, CX_STR(","), capa, list); 2.345 + CX_TEST_ASSERT(n == 5); 2.346 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this"))); 2.347 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("is"))); 2.348 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a"))); 2.349 + CX_TEST_ASSERT(0 == cx_strcmp(list[3], CX_STR("csv"))); 2.350 + CX_TEST_ASSERT(0 == cx_strcmp(list[4], CX_STR("string"))); 2.351 + 2.352 + // matching multi-char delimiter 2.353 + n = cx_strsplit(test, CX_STR("is"), capa, list); 2.354 + CX_TEST_ASSERT(n == 3); 2.355 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th"))); 2.356 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(","))); 2.357 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR(",a,csv,string"))); 2.358 + 2.359 + // bounded list using single-char delimiter 2.360 + n = cx_strsplit(test, CX_STR(","), 3, list); 2.361 + CX_TEST_ASSERT(n == 3); 2.362 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this"))); 2.363 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("is"))); 2.364 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a,csv,string"))); 2.365 + 2.366 + // bounded list using multi-char delimiter 2.367 + n = cx_strsplit(test, CX_STR("is"), 2, list); 2.368 + CX_TEST_ASSERT(n == 2); 2.369 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th"))); 2.370 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",is,a,csv,string"))); 2.371 + 2.372 + // start with delimiter 2.373 + n = cx_strsplit(test, CX_STR("this"), capa, list); 2.374 + CX_TEST_ASSERT(n == 2); 2.375 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR(""))); 2.376 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",is,a,csv,string"))); 2.377 + 2.378 + // end with delimiter 2.379 + n = cx_strsplit(test, CX_STR("string"), capa, list); 2.380 + CX_TEST_ASSERT(n == 2); 2.381 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this,is,a,csv,"))); 2.382 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(""))); 2.383 + 2.384 + 2.385 + // end with delimiter exceed bound 2.386 + n = cx_strsplit(CX_STR("a,b,c,"), CX_STR(","), 3, list); 2.387 + CX_TEST_ASSERT(n == 3); 2.388 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("a"))); 2.389 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("b"))); 2.390 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("c,"))); 2.391 + 2.392 + // exact match 2.393 + n = cx_strsplit(test, CX_STR("this,is,a,csv,string"), capa, list); 2.394 + CX_TEST_ASSERT(n == 2); 2.395 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR(""))); 2.396 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(""))); 2.397 + 2.398 + // string to be split is only substring 2.399 + n = cx_strsplit(test, CX_STR("this,is,a,csv,string,with,extension"), capa, list); 2.400 + CX_TEST_ASSERT(n == 1); 2.401 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], test)); 2.402 + 2.403 + // subsequent encounter of delimiter (the string between is empty) 2.404 + n = cx_strsplit(test, CX_STR("is,"), capa, list); 2.405 + CX_TEST_ASSERT(n == 3); 2.406 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th"))); 2.407 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(""))); 2.408 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a,csv,string"))); 2.409 + 2.410 + // call the _m variant just for coverage 2.411 + cxmutstr mtest = cx_strdup(test); 2.412 + cxmutstr mlist[4]; 2.413 + n = cx_strsplit_m(mtest, CX_STR("is,"), 4, mlist); 2.414 + CX_TEST_ASSERT(n == 3); 2.415 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[0]), CX_STR("th"))); 2.416 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[1]), CX_STR(""))); 2.417 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[2]), CX_STR("a,csv,string"))); 2.418 + cx_strfree(&mtest); 2.419 + } 2.420 +} 2.421 + 2.422 +CX_TEST(test_strsplit_a) { 2.423 + CxTestingAllocator talloc; 2.424 + cx_testing_allocator_init(&talloc); 2.425 + CxAllocator *alloc = &talloc.base; 2.426 + 2.427 + cxstring test = CX_STR("this,is,a,csv,string"); 2.428 + size_t capa = 8; 2.429 + cxstring *list; 2.430 + size_t n; 2.431 + CX_TEST_DO { 2.432 + // special case: empty string 2.433 + n = cx_strsplit_a(alloc, test, CX_STR(""), capa, &list); 2.434 + CX_TEST_ASSERT(n == 1); 2.435 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], test)); 2.436 + cxFree(alloc, list); 2.437 + 2.438 + // no delimiter occurrence 2.439 + n = cx_strsplit_a(alloc, test, CX_STR("z"), capa, &list); 2.440 + CX_TEST_ASSERT(n == 1); 2.441 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], test)); 2.442 + cxFree(alloc, list); 2.443 + 2.444 + // partially matching delimiter 2.445 + n = cx_strsplit_a(alloc, test, CX_STR("is,not"), capa, &list); 2.446 + CX_TEST_ASSERT(n == 1); 2.447 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], test)); 2.448 + cxFree(alloc, list); 2.449 + 2.450 + // matching single-char delimiter 2.451 + n = cx_strsplit_a(alloc, test, CX_STR(","), capa, &list); 2.452 + CX_TEST_ASSERT(n == 5); 2.453 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this"))); 2.454 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("is"))); 2.455 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a"))); 2.456 + CX_TEST_ASSERT(0 == cx_strcmp(list[3], CX_STR("csv"))); 2.457 + CX_TEST_ASSERT(0 == cx_strcmp(list[4], CX_STR("string"))); 2.458 + cxFree(alloc, list); 2.459 + 2.460 + // matching multi-char delimiter 2.461 + n = cx_strsplit_a(alloc, test, CX_STR("is"), capa, &list); 2.462 + CX_TEST_ASSERT(n == 3); 2.463 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th"))); 2.464 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(","))); 2.465 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR(",a,csv,string"))); 2.466 + cxFree(alloc, list); 2.467 + 2.468 + // bounded list using single-char delimiter 2.469 + n = cx_strsplit_a(alloc, test, CX_STR(","), 3, &list); 2.470 + CX_TEST_ASSERT(n == 3); 2.471 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this"))); 2.472 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("is"))); 2.473 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a,csv,string"))); 2.474 + cxFree(alloc, list); 2.475 + 2.476 + // bounded list using multi-char delimiter 2.477 + n = cx_strsplit_a(alloc, test, CX_STR("is"), 2, &list); 2.478 + CX_TEST_ASSERT(n == 2); 2.479 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th"))); 2.480 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",is,a,csv,string"))); 2.481 + cxFree(alloc, list); 2.482 + 2.483 + // start with delimiter 2.484 + n = cx_strsplit_a(alloc, test, CX_STR("this"), capa, &list); 2.485 + CX_TEST_ASSERT(n == 2); 2.486 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR(""))); 2.487 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",is,a,csv,string"))); 2.488 + cxFree(alloc, list); 2.489 + 2.490 + // end with delimiter 2.491 + n = cx_strsplit_a(alloc, test, CX_STR("string"), capa, &list); 2.492 + CX_TEST_ASSERT(n == 2); 2.493 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this,is,a,csv,"))); 2.494 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(""))); 2.495 + cxFree(alloc, list); 2.496 + 2.497 + // end with delimiter exceed bound 2.498 + n = cx_strsplit_a(alloc, CX_STR("a,b,c,"), CX_STR(","), 3, &list); 2.499 + CX_TEST_ASSERT(n == 3); 2.500 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("a"))); 2.501 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("b"))); 2.502 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("c,"))); 2.503 + cxFree(alloc, list); 2.504 + 2.505 + // exact match 2.506 + n = cx_strsplit_a(alloc, test, CX_STR("this,is,a,csv,string"), capa, &list); 2.507 + CX_TEST_ASSERT(n == 2); 2.508 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR(""))); 2.509 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(""))); 2.510 + cxFree(alloc, list); 2.511 + 2.512 + // string to be split is only substring 2.513 + n = cx_strsplit_a(alloc, test, CX_STR("this,is,a,csv,string,with,extension"), capa, &list); 2.514 + CX_TEST_ASSERT(n == 1); 2.515 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], test)); 2.516 + cxFree(alloc, list); 2.517 + 2.518 + // subsequent encounter of delimiter (the string between is empty) 2.519 + n = cx_strsplit_a(alloc, test, CX_STR("is,"), capa, &list); 2.520 + CX_TEST_ASSERT(n == 3); 2.521 + CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th"))); 2.522 + CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(""))); 2.523 + CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a,csv,string"))); 2.524 + cxFree(alloc, list); 2.525 + 2.526 + // call the _m variant just for coverage 2.527 + cxmutstr mtest = cx_strdup(test); 2.528 + cxmutstr *mlist; 2.529 + n = cx_strsplit_ma(alloc, mtest, CX_STR("is,"), 4, &mlist); 2.530 + CX_TEST_ASSERT(n == 3); 2.531 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[0]), CX_STR("th"))); 2.532 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[1]), CX_STR(""))); 2.533 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[2]), CX_STR("a,csv,string"))); 2.534 + cxFree(alloc, mlist); 2.535 + cx_strfree(&mtest); 2.536 + 2.537 + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 2.538 + } 2.539 + cx_testing_allocator_destroy(&talloc); 2.540 +} 2.541 + 2.542 +CX_TEST(test_strtrim) { 2.543 + cxstring t1 = cx_strtrim(CX_STR(" ein test \t ")); 2.544 + cxstring t2 = cx_strtrim(CX_STR("abc")); 2.545 + cxstring t3 = cx_strtrim(CX_STR(" 123")); 2.546 + cxstring t4 = cx_strtrim(CX_STR("xyz ")); 2.547 + cxstring t5 = cx_strtrim(CX_STR(" ")); 2.548 + cxstring empty = cx_strtrim(CX_STR("")); 2.549 + 2.550 + CX_TEST_DO { 2.551 + CX_TEST_ASSERT(0 == cx_strcmp(t1, CX_STR("ein test"))); 2.552 + CX_TEST_ASSERT(0 == cx_strcmp(t2, CX_STR("abc"))); 2.553 + CX_TEST_ASSERT(0 == cx_strcmp(t3, CX_STR("123"))); 2.554 + CX_TEST_ASSERT(0 == cx_strcmp(t4, CX_STR("xyz"))); 2.555 + CX_TEST_ASSERT(0 == cx_strcmp(t5, CX_STR(""))); 2.556 + CX_TEST_ASSERT(0 == cx_strcmp(empty, CX_STR(""))); 2.557 + 2.558 + // call the _m variant just for coverage 2.559 + cxmutstr m1 = cx_strtrim_m(cx_mutstr((char *) " ein test \t ")); 2.560 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m1), CX_STR("ein test"))); 2.561 + } 2.562 +} 2.563 + 2.564 +CX_TEST(test_strprefix) { 2.565 + cxstring str = CX_STR("test my prefix and my suffix"); 2.566 + cxstring empty = CX_STR(""); 2.567 + CX_TEST_DO { 2.568 + CX_TEST_ASSERT(!cx_strprefix(empty, CX_STR("pref"))); 2.569 + CX_TEST_ASSERT(cx_strprefix(str, empty)); 2.570 + CX_TEST_ASSERT(cx_strprefix(empty, empty)); 2.571 + CX_TEST_ASSERT(cx_strprefix(str, CX_STR("test "))); 2.572 + CX_TEST_ASSERT(!cx_strprefix(str, CX_STR("8-) fsck "))); 2.573 + } 2.574 +} 2.575 + 2.576 +CX_TEST(test_strsuffix) { 2.577 + cxstring str = CX_STR("test my prefix and my suffix"); 2.578 + cxstring empty = CX_STR(""); 2.579 + CX_TEST_DO { 2.580 + CX_TEST_ASSERT(!cx_strsuffix(empty, CX_STR("suf"))); 2.581 + CX_TEST_ASSERT(cx_strsuffix(str, empty)); 2.582 + CX_TEST_ASSERT(cx_strsuffix(empty, empty)); 2.583 + CX_TEST_ASSERT(cx_strsuffix(str, CX_STR("fix"))); 2.584 + CX_TEST_ASSERT(!cx_strsuffix(str, CX_STR("fox"))); 2.585 + } 2.586 +} 2.587 + 2.588 +CX_TEST(test_strcaseprefix) { 2.589 + cxstring str = CX_STR("test my prefix and my suffix"); 2.590 + cxstring empty = CX_STR(""); 2.591 + CX_TEST_DO { 2.592 + CX_TEST_ASSERT(!cx_strcaseprefix(empty, CX_STR("pREf"))); 2.593 + CX_TEST_ASSERT(cx_strcaseprefix(str, empty)); 2.594 + CX_TEST_ASSERT(cx_strcaseprefix(empty, empty)); 2.595 + CX_TEST_ASSERT(cx_strcaseprefix(str, CX_STR("TEST "))); 2.596 + CX_TEST_ASSERT(!cx_strcaseprefix(str, CX_STR("8-) fsck "))); 2.597 + } 2.598 +} 2.599 + 2.600 +CX_TEST(test_strcasesuffix) { 2.601 + cxstring str = CX_STR("test my prefix and my suffix"); 2.602 + cxstring empty = CX_STR(""); 2.603 + CX_TEST_DO { 2.604 + CX_TEST_ASSERT(!cx_strcasesuffix(empty, CX_STR("sUf"))); 2.605 + CX_TEST_ASSERT(cx_strcasesuffix(str, empty)); 2.606 + CX_TEST_ASSERT(cx_strcasesuffix(empty, empty)); 2.607 + CX_TEST_ASSERT(cx_strcasesuffix(str, CX_STR("FIX"))); 2.608 + CX_TEST_ASSERT(!cx_strcasesuffix(str, CX_STR("fox"))); 2.609 + } 2.610 +} 2.611 + 2.612 +CX_TEST(test_strreplace) { 2.613 + CxTestingAllocator talloc; 2.614 + cx_testing_allocator_init(&talloc); 2.615 + CxAllocator *alloc = &talloc.base; 2.616 + 2.617 + cxstring str = CX_STR("test ababab string aba"); 2.618 + cxstring longstr = CX_STR( 2.619 + "xyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacd"); 2.620 + cxstring notrail = CX_STR("test abab"); 2.621 + cxstring empty = CX_STR(""); 2.622 + cxstring astr = CX_STR("aaaaaaaaaa"); 2.623 + cxstring csstr = CX_STR("test AB ab TEST xyz"); 2.624 + 2.625 + cxmutstr repl = cx_strreplace(str, CX_STR("abab"), CX_STR("muchlonger")); 2.626 + char const *expected = "test muchlongerab string aba"; 2.627 + 2.628 + cxmutstr repln = cx_strreplacen(str, CX_STR("ab"), CX_STR("c"), 2); 2.629 + char const *expectedn = "test ccab string aba"; 2.630 + 2.631 + cxmutstr longrepl = cx_strreplace(longstr, CX_STR("a"), CX_STR("z")); 2.632 + char const *longexpect = "xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzcd"; 2.633 + 2.634 + cxmutstr replnotrail = cx_strreplace(notrail, CX_STR("ab"), CX_STR("z")); 2.635 + char const *notrailexpect = "test zz"; 2.636 + 2.637 + cxmutstr repleq = cx_strreplace(str, str, CX_STR("hello")); 2.638 + char const *eqexpect = "hello"; 2.639 + 2.640 + cxmutstr replempty1 = cx_strreplace(empty, CX_STR("ab"), CX_STR("c")); // expect: empty 2.641 + cxmutstr replempty2 = cx_strreplace(str, CX_STR("abab"), empty); 2.642 + char const *emptyexpect2 = "test ab string aba"; 2.643 + 2.644 + cxmutstr replpre = cx_strreplace(str, CX_STR("test "), CX_STR("TEST ")); 2.645 + char const *preexpected = "TEST ababab string aba"; 2.646 + 2.647 + cxmutstr replan1 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 1); 2.648 + char const *an1expected = "xaaaaaaaaa"; 2.649 + 2.650 + cxmutstr replan4 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 4); 2.651 + char const *an4expected = "xxxxaaaaaa"; 2.652 + 2.653 + cxmutstr replan9 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 9); 2.654 + char const *an9expected = "xxxxxxxxxa"; 2.655 + 2.656 + cxmutstr replan10 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 10); 2.657 + char const *an10expected = "xxxxxxxxxx"; 2.658 + 2.659 + CX_TEST_DO { 2.660 + cxmutstr repl1_a = cx_strreplace_a(alloc, csstr, CX_STR("AB"), CX_STR("*")); 2.661 + char const *expeced1_a = "test * ab TEST xyz"; 2.662 + 2.663 + cxmutstr repl2_a = cx_strreplace_a(alloc, csstr, CX_STR("test"), CX_STR("TEST")); 2.664 + char const *expected2_a = "TEST AB ab TEST xyz"; 2.665 + 2.666 + CX_TEST_ASSERT(repl.ptr != str.ptr); 2.667 + ASSERT_ZERO_TERMINATED(repl); 2.668 + CX_TEST_ASSERT(0 == strcmp(repl.ptr, expected)); 2.669 + ASSERT_ZERO_TERMINATED(repln); 2.670 + CX_TEST_ASSERT(0 == strcmp(repln.ptr, expectedn)); 2.671 + ASSERT_ZERO_TERMINATED(longrepl); 2.672 + CX_TEST_ASSERT(0 == strcmp(longrepl.ptr, longexpect)); 2.673 + ASSERT_ZERO_TERMINATED(replnotrail); 2.674 + CX_TEST_ASSERT(0 == strcmp(replnotrail.ptr, notrailexpect)); 2.675 + ASSERT_ZERO_TERMINATED(repleq); 2.676 + CX_TEST_ASSERT(0 == strcmp(repleq.ptr, eqexpect)); 2.677 + ASSERT_ZERO_TERMINATED(replempty1); 2.678 + CX_TEST_ASSERT(0 == strcmp(replempty1.ptr, "")); 2.679 + ASSERT_ZERO_TERMINATED(replempty2); 2.680 + CX_TEST_ASSERT(0 == strcmp(replempty2.ptr, emptyexpect2)); 2.681 + ASSERT_ZERO_TERMINATED(replpre); 2.682 + CX_TEST_ASSERT(0 == strcmp(replpre.ptr, preexpected)); 2.683 + ASSERT_ZERO_TERMINATED(replan1); 2.684 + CX_TEST_ASSERT(0 == strcmp(replan1.ptr, an1expected)); 2.685 + ASSERT_ZERO_TERMINATED(replan4); 2.686 + CX_TEST_ASSERT(0 == strcmp(replan4.ptr, an4expected)); 2.687 + ASSERT_ZERO_TERMINATED(replan9); 2.688 + CX_TEST_ASSERT(0 == strcmp(replan9.ptr, an9expected)); 2.689 + ASSERT_ZERO_TERMINATED(replan10); 2.690 + CX_TEST_ASSERT(0 == strcmp(replan10.ptr, an10expected)); 2.691 + ASSERT_ZERO_TERMINATED(repl1_a); 2.692 + CX_TEST_ASSERT(0 == strcmp(repl1_a.ptr, expeced1_a)); 2.693 + ASSERT_ZERO_TERMINATED(repl2_a); 2.694 + CX_TEST_ASSERT(0 == strcmp(repl2_a.ptr, expected2_a)); 2.695 + 2.696 + cx_strfree_a(alloc, &repl1_a); 2.697 + cx_strfree_a(alloc, &repl2_a); 2.698 + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 2.699 + } 2.700 + 2.701 + cx_strfree(&repl); 2.702 + cx_strfree(&repln); 2.703 + cx_strfree(&longrepl); 2.704 + cx_strfree(&replnotrail); 2.705 + cx_strfree(&repleq); 2.706 + cx_strfree(&replempty1); 2.707 + cx_strfree(&replempty2); 2.708 + cx_strfree(&replpre); 2.709 + cx_strfree(&replan1); 2.710 + cx_strfree(&replan4); 2.711 + cx_strfree(&replan9); 2.712 + cx_strfree(&replan10); 2.713 + cx_testing_allocator_destroy(&talloc); 2.714 +} 2.715 + 2.716 +CX_TEST(test_strupper) { 2.717 + cxmutstr str = cx_strdup(CX_STR("thIs 1s @ Te$t")); 2.718 + CX_TEST_DO { 2.719 + cx_strupper(str); 2.720 + CX_TEST_ASSERT(0 == strcmp(str.ptr, "THIS 1S @ TE$T")); 2.721 + } 2.722 + cx_strfree(&str); 2.723 +} 2.724 + 2.725 +CX_TEST(test_strlower) { 2.726 + cxmutstr str = cx_strdup(CX_STR("thIs 1s @ Te$t")); 2.727 + CX_TEST_DO { 2.728 + cx_strlower(str); 2.729 + CX_TEST_ASSERT(0 == strcmp(str.ptr, "this 1s @ te$t")); 2.730 + } 2.731 + cx_strfree(&str); 2.732 +} 2.733 + 2.734 +CX_TEST(test_strtok) { 2.735 + cxstring str = CX_STR("a,comma,separated,string"); 2.736 + cxstring delim = CX_STR(","); 2.737 + CX_TEST_DO { 2.738 + CxStrtokCtx ctx = cx_strtok(str, delim, 3); 2.739 + CX_TEST_ASSERT(ctx.str.ptr == str.ptr); 2.740 + CX_TEST_ASSERT(ctx.str.length == str.length); 2.741 + CX_TEST_ASSERT(ctx.delim.ptr == delim.ptr); 2.742 + CX_TEST_ASSERT(ctx.delim.length == delim.length); 2.743 + CX_TEST_ASSERT(ctx.limit == 3); 2.744 + CX_TEST_ASSERT(ctx.found == 0); 2.745 + CX_TEST_ASSERT(ctx.pos == 0); 2.746 + CX_TEST_ASSERT(ctx.next_pos == 0); 2.747 + CX_TEST_ASSERT(ctx.delim_more == NULL); 2.748 + CX_TEST_ASSERT(ctx.delim_more_count == 0); 2.749 + } 2.750 +} 2.751 + 2.752 +CX_TEST(test_strtok_m) { 2.753 + cxmutstr str = cx_strdup(CX_STR("a,comma,separated,string")); 2.754 + cxstring delim = CX_STR(","); 2.755 + CX_TEST_DO { 2.756 + CxStrtokCtx ctx = cx_strtok_m(str, delim, 3); 2.757 + CX_TEST_ASSERT(ctx.str.ptr == str.ptr); 2.758 + CX_TEST_ASSERT(ctx.str.length == str.length); 2.759 + CX_TEST_ASSERT(ctx.delim.ptr == delim.ptr); 2.760 + CX_TEST_ASSERT(ctx.delim.length == delim.length); 2.761 + CX_TEST_ASSERT(ctx.limit == 3); 2.762 + CX_TEST_ASSERT(ctx.found == 0); 2.763 + CX_TEST_ASSERT(ctx.pos == 0); 2.764 + CX_TEST_ASSERT(ctx.next_pos == 0); 2.765 + CX_TEST_ASSERT(ctx.delim_more == NULL); 2.766 + CX_TEST_ASSERT(ctx.delim_more_count == 0); 2.767 + } 2.768 + cx_strfree(&str); 2.769 +} 2.770 + 2.771 +CX_TEST(test_strtok_delim) { 2.772 + cxstring str = CX_STR("an,arbitrarily|separated;string"); 2.773 + cxstring delim = CX_STR(","); 2.774 + cxstring delim_more[2] = {CX_STR("|"), CX_STR(";")}; 2.775 + CX_TEST_DO { 2.776 + CxStrtokCtx ctx = cx_strtok(str, delim, 3); 2.777 + cx_strtok_delim(&ctx, delim_more, 2); 2.778 + CX_TEST_ASSERT(ctx.str.ptr == str.ptr); 2.779 + CX_TEST_ASSERT(ctx.str.length == str.length); 2.780 + CX_TEST_ASSERT(ctx.delim.ptr == delim.ptr); 2.781 + CX_TEST_ASSERT(ctx.delim.length == delim.length); 2.782 + CX_TEST_ASSERT(ctx.limit == 3); 2.783 + CX_TEST_ASSERT(ctx.found == 0); 2.784 + CX_TEST_ASSERT(ctx.pos == 0); 2.785 + CX_TEST_ASSERT(ctx.next_pos == 0); 2.786 + CX_TEST_ASSERT(ctx.delim_more == delim_more); 2.787 + CX_TEST_ASSERT(ctx.delim_more_count == 2); 2.788 + } 2.789 +} 2.790 + 2.791 +CX_TEST(test_strtok_next_easy) { 2.792 + cxstring str = CX_STR("a,comma,separated,string"); 2.793 + cxstring delim = CX_STR(","); 2.794 + CX_TEST_DO { 2.795 + CxStrtokCtx ctx = cx_strtok(str, delim, 3); 2.796 + bool ret; 2.797 + cxstring tok; 2.798 + 2.799 + ret = cx_strtok_next(&ctx, &tok); 2.800 + CX_TEST_ASSERT(ret); 2.801 + CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("a"))); 2.802 + CX_TEST_ASSERT(ctx.pos == 0); 2.803 + CX_TEST_ASSERT(ctx.next_pos == 2); 2.804 + CX_TEST_ASSERT(ctx.delim_pos == 1); 2.805 + CX_TEST_ASSERT(ctx.found == 1); 2.806 + 2.807 + ret = cx_strtok_next(&ctx, &tok); 2.808 + CX_TEST_ASSERT(ret); 2.809 + CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("comma"))); 2.810 + CX_TEST_ASSERT(ctx.pos == 2); 2.811 + CX_TEST_ASSERT(ctx.next_pos == 8); 2.812 + CX_TEST_ASSERT(ctx.delim_pos == 7); 2.813 + CX_TEST_ASSERT(ctx.found == 2); 2.814 + 2.815 + ret = cx_strtok_next(&ctx, &tok); 2.816 + CX_TEST_ASSERT(ret); 2.817 + CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("separated"))); 2.818 + CX_TEST_ASSERT(ctx.pos == 8); 2.819 + CX_TEST_ASSERT(ctx.next_pos == 18); 2.820 + CX_TEST_ASSERT(ctx.delim_pos == 17); 2.821 + CX_TEST_ASSERT(ctx.found == 3); 2.822 + 2.823 + ret = cx_strtok_next(&ctx, &tok); 2.824 + CX_TEST_ASSERT(!ret); 2.825 + CX_TEST_ASSERT(ctx.pos == 8); 2.826 + CX_TEST_ASSERT(ctx.next_pos == 18); 2.827 + CX_TEST_ASSERT(ctx.delim_pos == 17); 2.828 + CX_TEST_ASSERT(ctx.found == 3); 2.829 + } 2.830 +} 2.831 + 2.832 +CX_TEST(test_strtok_next_unlimited) { 2.833 + cxstring str = CX_STR("some;-;otherwise;-;separated;-;string;-;"); 2.834 + cxstring delim = CX_STR(";-;"); 2.835 + CX_TEST_DO { 2.836 + CxStrtokCtx ctx = cx_strtok(str, delim, SIZE_MAX); 2.837 + bool ret; 2.838 + cxstring tok; 2.839 + 2.840 + ret = cx_strtok_next(&ctx, &tok); 2.841 + CX_TEST_ASSERT(ret); 2.842 + CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("some"))); 2.843 + CX_TEST_ASSERT(ctx.pos == 0); 2.844 + CX_TEST_ASSERT(ctx.next_pos == 7); 2.845 + CX_TEST_ASSERT(ctx.delim_pos == 4); 2.846 + CX_TEST_ASSERT(ctx.found == 1); 2.847 + 2.848 + ret = cx_strtok_next(&ctx, &tok); 2.849 + CX_TEST_ASSERT(ret); 2.850 + CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("otherwise"))); 2.851 + CX_TEST_ASSERT(ctx.pos == 7); 2.852 + CX_TEST_ASSERT(ctx.next_pos == 19); 2.853 + CX_TEST_ASSERT(ctx.delim_pos == 16); 2.854 + CX_TEST_ASSERT(ctx.found == 2); 2.855 + 2.856 + ret = cx_strtok_next(&ctx, &tok); 2.857 + CX_TEST_ASSERT(ret); 2.858 + CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("separated"))); 2.859 + CX_TEST_ASSERT(ctx.pos == 19); 2.860 + CX_TEST_ASSERT(ctx.next_pos == 31); 2.861 + CX_TEST_ASSERT(ctx.delim_pos == 28); 2.862 + CX_TEST_ASSERT(ctx.found == 3); 2.863 + 2.864 + ret = cx_strtok_next(&ctx, &tok); 2.865 + CX_TEST_ASSERT(ret); 2.866 + CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("string"))); 2.867 + CX_TEST_ASSERT(ctx.pos == 31); 2.868 + CX_TEST_ASSERT(ctx.next_pos == 40); 2.869 + CX_TEST_ASSERT(ctx.delim_pos == 37); 2.870 + CX_TEST_ASSERT(ctx.found == 4); 2.871 + 2.872 + ret = cx_strtok_next(&ctx, &tok); 2.873 + CX_TEST_ASSERT(ret); 2.874 + CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR(""))); 2.875 + CX_TEST_ASSERT(ctx.pos == 40); 2.876 + CX_TEST_ASSERT(ctx.next_pos == 40); 2.877 + CX_TEST_ASSERT(ctx.delim_pos == 40); 2.878 + CX_TEST_ASSERT(ctx.found == 5); 2.879 + 2.880 + ret = cx_strtok_next(&ctx, &tok); 2.881 + CX_TEST_ASSERT(!ret); 2.882 + CX_TEST_ASSERT(ctx.pos == 40); 2.883 + CX_TEST_ASSERT(ctx.delim_pos == 40); 2.884 + CX_TEST_ASSERT(ctx.found == 5); 2.885 + } 2.886 +} 2.887 + 2.888 +CX_TEST(test_strtok_next_advanced) { 2.889 + cxmutstr str = cx_strdup(CX_STR("an,arbitrarily;||separated;string")); 2.890 + cxstring delim = CX_STR(","); 2.891 + cxstring delim_more[2] = {CX_STR("||"), CX_STR(";")}; 2.892 + CX_TEST_DO { 2.893 + CxStrtokCtx ctx = cx_strtok_m(str, delim, 10); 2.894 + cx_strtok_delim(&ctx, delim_more, 2); 2.895 + bool ret; 2.896 + cxmutstr tok; 2.897 + 2.898 + ret = cx_strtok_next_m(&ctx, &tok); 2.899 + CX_TEST_ASSERT(ret); 2.900 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("an"))); 2.901 + CX_TEST_ASSERT(ctx.pos == 0); 2.902 + CX_TEST_ASSERT(ctx.next_pos == 3); 2.903 + CX_TEST_ASSERT(ctx.delim_pos == 2); 2.904 + CX_TEST_ASSERT(ctx.found == 1); 2.905 + cx_strupper(tok); 2.906 + 2.907 + ret = cx_strtok_next_m(&ctx, &tok); 2.908 + CX_TEST_ASSERT(ret); 2.909 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("arbitrarily"))); 2.910 + CX_TEST_ASSERT(ctx.pos == 3); 2.911 + CX_TEST_ASSERT(ctx.next_pos == 15); 2.912 + CX_TEST_ASSERT(ctx.delim_pos == 14); 2.913 + CX_TEST_ASSERT(ctx.found == 2); 2.914 + cx_strupper(tok); 2.915 + 2.916 + ret = cx_strtok_next_m(&ctx, &tok); 2.917 + CX_TEST_ASSERT(ret); 2.918 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR(""))); 2.919 + CX_TEST_ASSERT(ctx.pos == 15); 2.920 + CX_TEST_ASSERT(ctx.next_pos == 17); 2.921 + CX_TEST_ASSERT(ctx.delim_pos == 15); 2.922 + CX_TEST_ASSERT(ctx.found == 3); 2.923 + cx_strupper(tok); 2.924 + 2.925 + ret = cx_strtok_next_m(&ctx, &tok); 2.926 + CX_TEST_ASSERT(ret); 2.927 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("separated"))); 2.928 + CX_TEST_ASSERT(ctx.pos == 17); 2.929 + CX_TEST_ASSERT(ctx.next_pos == 27); 2.930 + CX_TEST_ASSERT(ctx.delim_pos == 26); 2.931 + CX_TEST_ASSERT(ctx.found == 4); 2.932 + cx_strupper(tok); 2.933 + 2.934 + ret = cx_strtok_next_m(&ctx, &tok); 2.935 + CX_TEST_ASSERT(ret); 2.936 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("string"))); 2.937 + CX_TEST_ASSERT(ctx.pos == 27); 2.938 + CX_TEST_ASSERT(ctx.next_pos == 33); 2.939 + CX_TEST_ASSERT(ctx.delim_pos == 33); 2.940 + CX_TEST_ASSERT(ctx.found == 5); 2.941 + cx_strupper(tok); 2.942 + 2.943 + ret = cx_strtok_next_m(&ctx, &tok); 2.944 + CX_TEST_ASSERT(!ret); 2.945 + CX_TEST_ASSERT(ctx.pos == 27); 2.946 + CX_TEST_ASSERT(ctx.next_pos == 33); 2.947 + CX_TEST_ASSERT(ctx.delim_pos == 33); 2.948 + CX_TEST_ASSERT(ctx.found == 5); 2.949 + 2.950 + CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(str), CX_STR("AN,ARBITRARILY;||SEPARATED;STRING"))); 2.951 + } 2.952 + cx_strfree(&str); 2.953 +} 2.954 + 2.955 + 2.956 +CxTestSuite *cx_test_suite_string(void) { 2.957 + CxTestSuite *suite = cx_test_suite_new("string"); 2.958 + 2.959 + cx_test_register(suite, test_string_construct); 2.960 + cx_test_register(suite, test_strfree); 2.961 + cx_test_register(suite, test_strdup); 2.962 + cx_test_register(suite, test_strdup_shortened); 2.963 + cx_test_register(suite, test_strlen); 2.964 + cx_test_register(suite, test_strsubs); 2.965 + cx_test_register(suite, test_strchr); 2.966 + cx_test_register(suite, test_strrchr); 2.967 + cx_test_register(suite, test_strstr); 2.968 + cx_test_register(suite, test_strcmp); 2.969 + cx_test_register(suite, test_strcasecmp); 2.970 + cx_test_register(suite, test_strcat); 2.971 + cx_test_register(suite, test_strsplit); 2.972 + cx_test_register(suite, test_strsplit_a); 2.973 + cx_test_register(suite, test_strtrim); 2.974 + cx_test_register(suite, test_strprefix); 2.975 + cx_test_register(suite, test_strsuffix); 2.976 + cx_test_register(suite, test_strcaseprefix); 2.977 + cx_test_register(suite, test_strcasesuffix); 2.978 + cx_test_register(suite, test_strreplace); 2.979 + cx_test_register(suite, test_strupper); 2.980 + cx_test_register(suite, test_strlower); 2.981 + cx_test_register(suite, test_strtok); 2.982 + cx_test_register(suite, test_strtok_m); 2.983 + cx_test_register(suite, test_strtok_delim); 2.984 + cx_test_register(suite, test_strtok_next_easy); 2.985 + cx_test_register(suite, test_strtok_next_unlimited); 2.986 + cx_test_register(suite, test_strtok_next_advanced); 2.987 + 2.988 + return suite; 2.989 +}
3.1 --- a/tests/test_string.cpp Thu Dec 28 19:17:45 2023 +0100 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,882 +0,0 @@ 3.4 -/* 3.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3.6 - * 3.7 - * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 3.8 - * 3.9 - * Redistribution and use in source and binary forms, with or without 3.10 - * modification, are permitted provided that the following conditions are met: 3.11 - * 3.12 - * 1. Redistributions of source code must retain the above copyright 3.13 - * notice, this list of conditions and the following disclaimer. 3.14 - * 3.15 - * 2. Redistributions in binary form must reproduce the above copyright 3.16 - * notice, this list of conditions and the following disclaimer in the 3.17 - * documentation and/or other materials provided with the distribution. 3.18 - * 3.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 3.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 3.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3.29 - * POSSIBILITY OF SUCH DAMAGE. 3.30 - */ 3.31 - 3.32 -#include "cx/string.h" 3.33 -#include "util_allocator.h" 3.34 - 3.35 -#include <gtest/gtest.h> 3.36 - 3.37 -#define EXPECT_ZERO_TERMINATED(str) EXPECT_EQ((str).ptr[(str).length], '\0') 3.38 - 3.39 -TEST(String, construct) { 3.40 - cxstring s1 = CX_STR("1234"); 3.41 - cxstring s2 = cx_strn("abcd", 2); 3.42 - cxmutstr s3 = cx_mutstr((char *) "1234"); 3.43 - cxmutstr s4 = cx_mutstrn((char *) "abcd", 2); 3.44 - 3.45 - EXPECT_EQ(s1.length, 4); 3.46 - EXPECT_EQ(s2.length, 2); 3.47 - EXPECT_EQ(s3.length, 4); 3.48 - EXPECT_EQ(s4.length, 2); 3.49 -} 3.50 - 3.51 -TEST(String, strfree) { 3.52 - CxTestingAllocator alloc; 3.53 - auto test = (char *) cxMalloc(&alloc, 16); 3.54 - cxmutstr str = cx_mutstrn(test, 16); 3.55 - ASSERT_EQ(str.ptr, test); 3.56 - EXPECT_EQ(str.length, 16); 3.57 - cx_strfree_a(&alloc, &str); 3.58 - EXPECT_EQ(str.ptr, nullptr); 3.59 - EXPECT_EQ(str.length, 0); 3.60 - EXPECT_TRUE(alloc.verify()); 3.61 -} 3.62 - 3.63 -TEST(String, strdup) { 3.64 - cxstring str = CX_STR("test"); 3.65 - cxmutstr dup = cx_strdup(str); 3.66 - ASSERT_EQ(dup.length, str.length); 3.67 - EXPECT_STREQ(dup.ptr, str.ptr); 3.68 - EXPECT_ZERO_TERMINATED(dup); 3.69 - cx_strfree(&dup); 3.70 - 3.71 - str.length = 2; 3.72 - dup = cx_strdup(str); 3.73 - ASSERT_EQ(dup.length, str.length); 3.74 - EXPECT_STREQ(dup.ptr, "te"); 3.75 - EXPECT_ZERO_TERMINATED(dup); 3.76 - cx_strfree(&dup); 3.77 -} 3.78 - 3.79 -TEST(String, strlen) { 3.80 - cxstring s1 = CX_STR("1234"); 3.81 - cxstring s2 = CX_STR(".:.:."); 3.82 - cxstring s3 = CX_STR("X"); 3.83 - 3.84 - size_t len0 = cx_strlen(0); 3.85 - size_t len1 = cx_strlen(1, s1); 3.86 - size_t len2 = cx_strlen(2, s1, s2); 3.87 - size_t len3 = cx_strlen(3, s1, s2, s3); 3.88 - 3.89 - EXPECT_EQ(len0, 0); 3.90 - EXPECT_EQ(len1, 4); 3.91 - EXPECT_EQ(len2, 9); 3.92 - EXPECT_EQ(len3, 10); 3.93 -} 3.94 - 3.95 -TEST(String, strsubs) { 3.96 - cxstring str = CX_STR("A test string"); 3.97 - 3.98 - cxstring sub = cx_strsubs(str, 0); 3.99 - EXPECT_EQ(cx_strcmp(sub, str), 0); 3.100 - 3.101 - sub = cx_strsubs(str, 2); 3.102 - EXPECT_EQ(cx_strcmp(sub, CX_STR("test string")), 0); 3.103 - 3.104 - sub = cx_strsubs(str, 7); 3.105 - EXPECT_EQ(cx_strcmp(sub, CX_STR("string")), 0); 3.106 - 3.107 - sub = cx_strsubs(str, 15); 3.108 - EXPECT_EQ(cx_strcmp(sub, CX_STR("")), 0); 3.109 - 3.110 - sub = cx_strsubsl(str, 2, 4); 3.111 - EXPECT_EQ(cx_strcmp(sub, CX_STR("test")), 0); 3.112 - 3.113 - sub = cx_strsubsl(str, 7, 3); 3.114 - EXPECT_EQ(cx_strcmp(sub, CX_STR("str")), 0); 3.115 - 3.116 - sub = cx_strsubsl(str, 7, 20); 3.117 - EXPECT_EQ(cx_strcmp(sub, CX_STR("string")), 0); 3.118 - 3.119 - // just for coverage, call the _m variant 3.120 - auto m = cx_strsubs_m(cx_mutstrn(nullptr, 0), 0); 3.121 - EXPECT_EQ(cx_strcmp(cx_strcast(m), CX_STR("")), 0); 3.122 -} 3.123 - 3.124 -TEST(String, strchr) { 3.125 - cxstring str = CX_STR("I will find you - and I will kill you"); 3.126 - 3.127 - cxstring notfound = cx_strchr(str, 'x'); 3.128 - EXPECT_EQ(notfound.length, 0); 3.129 - 3.130 - cxstring result = cx_strchr(str, 'w'); 3.131 - EXPECT_EQ(result.length, 35); 3.132 - EXPECT_STREQ(result.ptr, "will find you - and I will kill you"); 3.133 - 3.134 - // just for coverage, call the _m variant 3.135 - auto m = cx_strchr_m(cx_mutstrn(nullptr, 0), 'a'); 3.136 - EXPECT_EQ(cx_strcmp(cx_strcast(m), CX_STR("")), 0); 3.137 -} 3.138 - 3.139 -TEST(String, strrchr) { 3.140 - cxstring str = CX_STR("I will find you - and I will kill you"); 3.141 - 3.142 - cxstring notfound = cx_strrchr(str, 'x'); 3.143 - EXPECT_EQ(notfound.length, 0); 3.144 - 3.145 - cxstring result = cx_strrchr(str, 'w'); 3.146 - EXPECT_EQ(result.length, 13); 3.147 - EXPECT_STREQ(result.ptr, "will kill you"); 3.148 - 3.149 - // just for coverage, call the _m variant 3.150 - auto m = cx_strrchr_m(cx_mutstrn(nullptr, 0), 'a'); 3.151 - EXPECT_EQ(cx_strcmp(cx_strcast(m), CX_STR("")), 0); 3.152 -} 3.153 - 3.154 -TEST(String, strstr) { 3.155 - cxstring str = CX_STR("find the match in this string"); 3.156 - cxstring longstr = CX_STR( 3.157 - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl" 3.158 - "mnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx" 3.159 - "yzabcdeababababnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij" 3.160 - "klmnopqrstuvwxyzaababababababababrstuvwxyzabcdefghijklmnopqrstuv" 3.161 - "abababababababababababababababababababababababababababababababab" 3.162 - "abababababababababababababababababababababababababababababababab" 3.163 - "abababababababababababababababababababababababababababababababab" 3.164 - "abababababababababababababababababababababababababababababababab" 3.165 - "abababababababababababababababababababababababababababababababab" 3.166 - "abababababababababababababababababababababababababababababababab" 3.167 - "wxyz1234567890"); 3.168 - cxstring longstrpattern = CX_STR( 3.169 - "abababababababababababababababababababababababababababababababab" 3.170 - "abababababababababababababababababababababababababababababababab" 3.171 - "abababababababababababababababababababababababababababababababab" 3.172 - "abababababababababababababababababababababababababababababababab" 3.173 - "abababababababababababababababababababababababababababababababab" 3.174 - ); 3.175 - cxstring longstrresult = CX_STR( 3.176 - "abababababababababababababababababababababababababababababababab" 3.177 - "abababababababababababababababababababababababababababababababab" 3.178 - "abababababababababababababababababababababababababababababababab" 3.179 - "abababababababababababababababababababababababababababababababab" 3.180 - "abababababababababababababababababababababababababababababababab" 3.181 - "abababababababababababababababababababababababababababababababab" 3.182 - "wxyz1234567890" 3.183 - ); 3.184 - 3.185 - cxstring notfound = cx_strstr(str, CX_STR("no match")); 3.186 - EXPECT_EQ(notfound.length, 0); 3.187 - 3.188 - cxstring result = cx_strstr(str, CX_STR("match")); 3.189 - EXPECT_EQ(result.length, 20); 3.190 - EXPECT_STREQ(result.ptr, "match in this string"); 3.191 - 3.192 - result = cx_strstr(str, CX_STR("")); 3.193 - EXPECT_EQ(result.length, str.length); 3.194 - EXPECT_STREQ(result.ptr, str.ptr); 3.195 - 3.196 - result = cx_strstr(longstr, longstrpattern); 3.197 - EXPECT_EQ(result.length, longstrresult.length); 3.198 - EXPECT_STREQ(result.ptr, longstrresult.ptr); 3.199 - 3.200 - // just for coverage, call the _m variant 3.201 - auto mstr = cx_strdup(longstr); 3.202 - auto m = cx_strstr_m(mstr, longstrpattern); 3.203 - EXPECT_EQ(m.length, longstrresult.length); 3.204 - EXPECT_STREQ(m.ptr, longstrresult.ptr); 3.205 - cx_strfree(&mstr); 3.206 -} 3.207 - 3.208 -TEST(String, strcmp) { 3.209 - cxstring str = CX_STR("compare this"); 3.210 - 3.211 - EXPECT_EQ(cx_strcmp(CX_STR(""), CX_STR("")), 0); 3.212 - EXPECT_GT(cx_strcmp(str, CX_STR("")), 0); 3.213 - EXPECT_EQ(cx_strcmp(str, CX_STR("compare this")), 0); 3.214 - EXPECT_NE(cx_strcmp(str, CX_STR("Compare This")), 0); 3.215 - EXPECT_LT(cx_strcmp(str, CX_STR("compare tool")), 0); 3.216 - EXPECT_GT(cx_strcmp(str, CX_STR("compare shit")), 0); 3.217 - EXPECT_LT(cx_strcmp(str, CX_STR("compare this not")), 0); 3.218 - EXPECT_GT(cx_strcmp(str, CX_STR("compare")), 0); 3.219 - 3.220 - cxstring str2 = CX_STR("Compare This"); 3.221 - EXPECT_NE(cx_strcmp_p(&str, &str2), 0); 3.222 - str2 = CX_STR("compare this"); 3.223 - EXPECT_EQ(cx_strcmp_p(&str, &str2), 0); 3.224 -} 3.225 - 3.226 -TEST(String, strcasecmp) { 3.227 - cxstring str = CX_STR("compare this"); 3.228 - 3.229 - EXPECT_EQ(cx_strcasecmp(CX_STR(""), CX_STR("")), 0); 3.230 - EXPECT_GT(cx_strcasecmp(str, CX_STR("")), 0); 3.231 - EXPECT_EQ(cx_strcasecmp(str, CX_STR("compare this")), 0); 3.232 - EXPECT_EQ(cx_strcasecmp(str, CX_STR("Compare This")), 0); 3.233 - EXPECT_LT(cx_strcasecmp(str, CX_STR("compare tool")), 0); 3.234 - EXPECT_GT(cx_strcasecmp(str, CX_STR("compare shit")), 0); 3.235 - EXPECT_LT(cx_strcasecmp(str, CX_STR("compare this not")), 0); 3.236 - EXPECT_GT(cx_strcasecmp(str, CX_STR("compare")), 0); 3.237 - 3.238 - cxstring str2 = CX_STR("Compare This"); 3.239 - EXPECT_EQ(cx_strcasecmp_p(&str, &str2), 0); 3.240 - str2 = CX_STR("Compare Tool"); 3.241 - EXPECT_LT(cx_strcasecmp_p(&str, &str2), 0); 3.242 -} 3.243 - 3.244 -TEST(String, strcat) { 3.245 - cxstring s1 = CX_STR("12"); 3.246 - cxstring s2 = CX_STR("34"); 3.247 - cxstring s3 = CX_STR("56"); 3.248 - cxstring sn = {nullptr, 0}; 3.249 - 3.250 - CxTestingAllocator alloc; 3.251 - 3.252 - cxmutstr t1 = cx_strcat_a(&alloc, 2, s1, s2); 3.253 - EXPECT_EQ(cx_strcmp(cx_strcast(t1), CX_STR("1234")), 0); 3.254 - EXPECT_ZERO_TERMINATED(t1); 3.255 - cx_strfree_a(&alloc, &t1); 3.256 - 3.257 - cxmutstr t2 = cx_strcat_a(&alloc, 3, s1, s2, s3); 3.258 - EXPECT_EQ(cx_strcmp(cx_strcast(t2), CX_STR("123456")), 0); 3.259 - EXPECT_ZERO_TERMINATED(t2); 3.260 - cx_strfree_a(&alloc, &t2); 3.261 - 3.262 - cxmutstr t3 = cx_strcat_a(&alloc, 6, s1, sn, s2, sn, s3, sn); 3.263 - EXPECT_EQ(cx_strcmp(cx_strcast(t3), CX_STR("123456")), 0); 3.264 - EXPECT_ZERO_TERMINATED(t3); 3.265 - cx_strfree_a(&alloc, &t3); 3.266 - 3.267 - cxmutstr t4 = cx_strcat_a(&alloc, 2, sn, sn); 3.268 - EXPECT_EQ(cx_strcmp(cx_strcast(t4), CX_STR("")), 0); 3.269 - EXPECT_ZERO_TERMINATED(t4); 3.270 - cx_strfree_a(&alloc, &t4); 3.271 - 3.272 - EXPECT_TRUE(alloc.verify()); 3.273 - 3.274 - // use the macro 3.275 - cxmutstr t5 = cx_strcat(3, s3, s1, s2); 3.276 - EXPECT_EQ(cx_strcmp(cx_strcast(t5), CX_STR("561234")), 0); 3.277 - EXPECT_ZERO_TERMINATED(t5); 3.278 - cx_strfree(&t5); 3.279 - 3.280 - // use an initial string 3.281 - cxmutstr t6 = cx_strdup(CX_STR("Hello")); 3.282 - t6 = cx_strcat_m(t6, 2, CX_STR(", "), CX_STR("World!")); 3.283 - EXPECT_EQ(cx_strcmp(cx_strcast(t6), CX_STR("Hello, World!")), 0); 3.284 - EXPECT_ZERO_TERMINATED(t6); 3.285 - cx_strfree(&t6); 3.286 -} 3.287 - 3.288 -TEST(String, strsplit) { 3.289 - 3.290 - cxstring test = CX_STR("this,is,a,csv,string"); 3.291 - size_t capa = 8; 3.292 - cxstring list[8]; 3.293 - size_t n; 3.294 - 3.295 - // special case: empty string 3.296 - n = cx_strsplit(test, CX_STR(""), capa, list); 3.297 - ASSERT_EQ(n, 1); 3.298 - EXPECT_EQ(cx_strcmp(list[0], test), 0); 3.299 - 3.300 - // no delimiter occurrence 3.301 - n = cx_strsplit(test, CX_STR("z"), capa, list); 3.302 - ASSERT_EQ(n, 1); 3.303 - EXPECT_EQ(cx_strcmp(list[0], test), 0); 3.304 - 3.305 - // partially matching delimiter 3.306 - n = cx_strsplit(test, CX_STR("is,not"), capa, list); 3.307 - ASSERT_EQ(n, 1); 3.308 - EXPECT_EQ(cx_strcmp(list[0], test), 0); 3.309 - 3.310 - // matching single-char delimiter 3.311 - n = cx_strsplit(test, CX_STR(","), capa, list); 3.312 - ASSERT_EQ(n, 5); 3.313 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("this")), 0); 3.314 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("is")), 0); 3.315 - EXPECT_EQ(cx_strcmp(list[2], CX_STR("a")), 0); 3.316 - EXPECT_EQ(cx_strcmp(list[3], CX_STR("csv")), 0); 3.317 - EXPECT_EQ(cx_strcmp(list[4], CX_STR("string")), 0); 3.318 - 3.319 - // matching multi-char delimiter 3.320 - n = cx_strsplit(test, CX_STR("is"), capa, list); 3.321 - ASSERT_EQ(n, 3); 3.322 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("th")), 0); 3.323 - EXPECT_EQ(cx_strcmp(list[1], CX_STR(",")), 0); 3.324 - EXPECT_EQ(cx_strcmp(list[2], CX_STR(",a,csv,string")), 0); 3.325 - 3.326 - // bounded list using single-char delimiter 3.327 - n = cx_strsplit(test, CX_STR(","), 3, list); 3.328 - ASSERT_EQ(n, 3); 3.329 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("this")), 0); 3.330 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("is")), 0); 3.331 - EXPECT_EQ(cx_strcmp(list[2], CX_STR("a,csv,string")), 0); 3.332 - 3.333 - // bounded list using multi-char delimiter 3.334 - n = cx_strsplit(test, CX_STR("is"), 2, list); 3.335 - ASSERT_EQ(n, 2); 3.336 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("th")), 0); 3.337 - EXPECT_EQ(cx_strcmp(list[1], CX_STR(",is,a,csv,string")), 0); 3.338 - 3.339 - // start with delimiter 3.340 - n = cx_strsplit(test, CX_STR("this"), capa, list); 3.341 - ASSERT_EQ(n, 2); 3.342 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("")), 0); 3.343 - EXPECT_EQ(cx_strcmp(list[1], CX_STR(",is,a,csv,string")), 0); 3.344 - 3.345 - // end with delimiter 3.346 - n = cx_strsplit(test, CX_STR("string"), capa, list); 3.347 - ASSERT_EQ(n, 2); 3.348 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("this,is,a,csv,")), 0); 3.349 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("")), 0); 3.350 - 3.351 - 3.352 - // end with delimiter exceed bound 3.353 - n = cx_strsplit(CX_STR("a,b,c,"), CX_STR(","), 3, list); 3.354 - ASSERT_EQ(n, 3); 3.355 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("a")), 0); 3.356 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("b")), 0); 3.357 - EXPECT_EQ(cx_strcmp(list[2], CX_STR("c,")), 0); 3.358 - 3.359 - // exact match 3.360 - n = cx_strsplit(test, CX_STR("this,is,a,csv,string"), capa, list); 3.361 - ASSERT_EQ(n, 2); 3.362 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("")), 0); 3.363 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("")), 0); 3.364 - 3.365 - // string to be split is only substring 3.366 - n = cx_strsplit(test, CX_STR("this,is,a,csv,string,with,extension"), capa, list); 3.367 - ASSERT_EQ(n, 1); 3.368 - EXPECT_EQ(cx_strcmp(list[0], test), 0); 3.369 - 3.370 - // subsequent encounter of delimiter (the string between is empty) 3.371 - n = cx_strsplit(test, CX_STR("is,"), capa, list); 3.372 - ASSERT_EQ(n, 3); 3.373 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("th")), 0); 3.374 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("")), 0); 3.375 - EXPECT_EQ(cx_strcmp(list[2], CX_STR("a,csv,string")), 0); 3.376 - 3.377 - // call the _m variant just for coverage 3.378 - auto mtest = cx_strdup(test); 3.379 - cxmutstr mlist[4]; 3.380 - n = cx_strsplit_m(mtest, CX_STR("is,"), 4, mlist); 3.381 - ASSERT_EQ(n, 3); 3.382 - EXPECT_EQ(cx_strcmp(cx_strcast(mlist[0]), CX_STR("th")), 0); 3.383 - EXPECT_EQ(cx_strcmp(cx_strcast(mlist[1]), CX_STR("")), 0); 3.384 - EXPECT_EQ(cx_strcmp(cx_strcast(mlist[2]), CX_STR("a,csv,string")), 0); 3.385 - cx_strfree(&mtest); 3.386 -} 3.387 - 3.388 -TEST(String, strsplit_a) { 3.389 - CxTestingAllocator alloc; 3.390 - 3.391 - cxstring test = CX_STR("this,is,a,csv,string"); 3.392 - size_t capa = 8; 3.393 - cxstring *list; 3.394 - size_t n; 3.395 - 3.396 - // special case: empty string 3.397 - n = cx_strsplit_a(&alloc, test, CX_STR(""), capa, &list); 3.398 - ASSERT_EQ(n, 1); 3.399 - EXPECT_EQ(cx_strcmp(list[0], test), 0); 3.400 - cxFree(&alloc, list); 3.401 - 3.402 - // no delimiter occurrence 3.403 - n = cx_strsplit_a(&alloc, test, CX_STR("z"), capa, &list); 3.404 - ASSERT_EQ(n, 1); 3.405 - EXPECT_EQ(cx_strcmp(list[0], test), 0); 3.406 - cxFree(&alloc, list); 3.407 - 3.408 - // partially matching delimiter 3.409 - n = cx_strsplit_a(&alloc, test, CX_STR("is,not"), capa, &list); 3.410 - ASSERT_EQ(n, 1); 3.411 - EXPECT_EQ(cx_strcmp(list[0], test), 0); 3.412 - cxFree(&alloc, list); 3.413 - 3.414 - // matching single-char delimiter 3.415 - n = cx_strsplit_a(&alloc, test, CX_STR(","), capa, &list); 3.416 - ASSERT_EQ(n, 5); 3.417 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("this")), 0); 3.418 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("is")), 0); 3.419 - EXPECT_EQ(cx_strcmp(list[2], CX_STR("a")), 0); 3.420 - EXPECT_EQ(cx_strcmp(list[3], CX_STR("csv")), 0); 3.421 - EXPECT_EQ(cx_strcmp(list[4], CX_STR("string")), 0); 3.422 - cxFree(&alloc, list); 3.423 - 3.424 - // matching multi-char delimiter 3.425 - n = cx_strsplit_a(&alloc, test, CX_STR("is"), capa, &list); 3.426 - ASSERT_EQ(n, 3); 3.427 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("th")), 0); 3.428 - EXPECT_EQ(cx_strcmp(list[1], CX_STR(",")), 0); 3.429 - EXPECT_EQ(cx_strcmp(list[2], CX_STR(",a,csv,string")), 0); 3.430 - cxFree(&alloc, list); 3.431 - 3.432 - // bounded list using single-char delimiter 3.433 - n = cx_strsplit_a(&alloc, test, CX_STR(","), 3, &list); 3.434 - ASSERT_EQ(n, 3); 3.435 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("this")), 0); 3.436 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("is")), 0); 3.437 - EXPECT_EQ(cx_strcmp(list[2], CX_STR("a,csv,string")), 0); 3.438 - cxFree(&alloc, list); 3.439 - 3.440 - // bounded list using multi-char delimiter 3.441 - n = cx_strsplit_a(&alloc, test, CX_STR("is"), 2, &list); 3.442 - ASSERT_EQ(n, 2); 3.443 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("th")), 0); 3.444 - EXPECT_EQ(cx_strcmp(list[1], CX_STR(",is,a,csv,string")), 0); 3.445 - cxFree(&alloc, list); 3.446 - 3.447 - // start with delimiter 3.448 - n = cx_strsplit_a(&alloc, test, CX_STR("this"), capa, &list); 3.449 - ASSERT_EQ(n, 2); 3.450 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("")), 0); 3.451 - EXPECT_EQ(cx_strcmp(list[1], CX_STR(",is,a,csv,string")), 0); 3.452 - cxFree(&alloc, list); 3.453 - 3.454 - // end with delimiter 3.455 - n = cx_strsplit_a(&alloc, test, CX_STR("string"), capa, &list); 3.456 - ASSERT_EQ(n, 2); 3.457 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("this,is,a,csv,")), 0); 3.458 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("")), 0); 3.459 - cxFree(&alloc, list); 3.460 - 3.461 - // end with delimiter exceed bound 3.462 - n = cx_strsplit_a(&alloc, CX_STR("a,b,c,"), CX_STR(","), 3, &list); 3.463 - ASSERT_EQ(n, 3); 3.464 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("a")), 0); 3.465 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("b")), 0); 3.466 - EXPECT_EQ(cx_strcmp(list[2], CX_STR("c,")), 0); 3.467 - cxFree(&alloc, list); 3.468 - 3.469 - // exact match 3.470 - n = cx_strsplit_a(&alloc, test, CX_STR("this,is,a,csv,string"), capa, &list); 3.471 - ASSERT_EQ(n, 2); 3.472 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("")), 0); 3.473 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("")), 0); 3.474 - cxFree(&alloc, list); 3.475 - 3.476 - // string to be split is only substring 3.477 - n = cx_strsplit_a(&alloc, test, CX_STR("this,is,a,csv,string,with,extension"), capa, &list); 3.478 - ASSERT_EQ(n, 1); 3.479 - EXPECT_EQ(cx_strcmp(list[0], test), 0); 3.480 - cxFree(&alloc, list); 3.481 - 3.482 - // subsequent encounter of delimiter (the string between is empty) 3.483 - n = cx_strsplit_a(&alloc, test, CX_STR("is,"), capa, &list); 3.484 - ASSERT_EQ(n, 3); 3.485 - EXPECT_EQ(cx_strcmp(list[0], CX_STR("th")), 0); 3.486 - EXPECT_EQ(cx_strcmp(list[1], CX_STR("")), 0); 3.487 - EXPECT_EQ(cx_strcmp(list[2], CX_STR("a,csv,string")), 0); 3.488 - cxFree(&alloc, list); 3.489 - 3.490 - // call the _m variant just for coverage 3.491 - auto mtest = cx_strdup(test); 3.492 - cxmutstr *mlist; 3.493 - n = cx_strsplit_ma(&alloc, mtest, CX_STR("is,"), 4, &mlist); 3.494 - ASSERT_EQ(n, 3); 3.495 - EXPECT_EQ(cx_strcmp(cx_strcast(mlist[0]), CX_STR("th")), 0); 3.496 - EXPECT_EQ(cx_strcmp(cx_strcast(mlist[1]), CX_STR("")), 0); 3.497 - EXPECT_EQ(cx_strcmp(cx_strcast(mlist[2]), CX_STR("a,csv,string")), 0); 3.498 - cxFree(&alloc, mlist); 3.499 - cx_strfree(&mtest); 3.500 - 3.501 - EXPECT_TRUE(alloc.verify()); 3.502 -} 3.503 - 3.504 -TEST(String, strtrim) { 3.505 - cxstring t1 = cx_strtrim(CX_STR(" ein test \t ")); 3.506 - cxstring t2 = cx_strtrim(CX_STR("abc")); 3.507 - cxstring t3 = cx_strtrim(CX_STR(" 123")); 3.508 - cxstring t4 = cx_strtrim(CX_STR("xyz ")); 3.509 - cxstring t5 = cx_strtrim(CX_STR(" ")); 3.510 - cxstring empty = cx_strtrim(CX_STR("")); 3.511 - 3.512 - EXPECT_EQ(cx_strcmp(t1, CX_STR("ein test")), 0); 3.513 - EXPECT_EQ(cx_strcmp(t2, CX_STR("abc")), 0); 3.514 - EXPECT_EQ(cx_strcmp(t3, CX_STR("123")), 0); 3.515 - EXPECT_EQ(cx_strcmp(t4, CX_STR("xyz")), 0); 3.516 - EXPECT_EQ(cx_strcmp(t5, CX_STR("")), 0); 3.517 - EXPECT_EQ(cx_strcmp(empty, CX_STR("")), 0); 3.518 - 3.519 - // call the _m variant just for coverage 3.520 - cxmutstr m1 = cx_strtrim_m(cx_mutstr((char *) " ein test \t ")); 3.521 - EXPECT_EQ(cx_strcmp(cx_strcast(m1), CX_STR("ein test")), 0); 3.522 -} 3.523 - 3.524 -TEST(String, strprefix) { 3.525 - cxstring str = CX_STR("test my prefix and my suffix"); 3.526 - cxstring empty = CX_STR(""); 3.527 - EXPECT_FALSE(cx_strprefix(empty, CX_STR("pref"))); 3.528 - EXPECT_TRUE(cx_strprefix(str, empty)); 3.529 - EXPECT_TRUE(cx_strprefix(empty, empty)); 3.530 - EXPECT_TRUE(cx_strprefix(str, CX_STR("test "))); 3.531 - EXPECT_FALSE(cx_strprefix(str, CX_STR("8-) fsck "))); 3.532 -} 3.533 - 3.534 -TEST(String, strsuffix) { 3.535 - cxstring str = CX_STR("test my prefix and my suffix"); 3.536 - cxstring empty = CX_STR(""); 3.537 - EXPECT_FALSE(cx_strsuffix(empty, CX_STR("suf"))); 3.538 - EXPECT_TRUE(cx_strsuffix(str, empty)); 3.539 - EXPECT_TRUE(cx_strsuffix(empty, empty)); 3.540 - EXPECT_TRUE(cx_strsuffix(str, CX_STR("fix"))); 3.541 - EXPECT_FALSE(cx_strsuffix(str, CX_STR("fox"))); 3.542 -} 3.543 - 3.544 -TEST(String, strcaseprefix) { 3.545 - cxstring str = CX_STR("test my prefix and my suffix"); 3.546 - cxstring empty = CX_STR(""); 3.547 - EXPECT_FALSE(cx_strcaseprefix(empty, CX_STR("pREf"))); 3.548 - EXPECT_TRUE(cx_strcaseprefix(str, empty)); 3.549 - EXPECT_TRUE(cx_strcaseprefix(empty, empty)); 3.550 - EXPECT_TRUE(cx_strcaseprefix(str, CX_STR("TEST "))); 3.551 - EXPECT_FALSE(cx_strcaseprefix(str, CX_STR("8-) fsck "))); 3.552 -} 3.553 - 3.554 -TEST(String, strcasesuffix) { 3.555 - cxstring str = CX_STR("test my prefix and my suffix"); 3.556 - cxstring empty = CX_STR(""); 3.557 - EXPECT_FALSE(cx_strcasesuffix(empty, CX_STR("sUf"))); 3.558 - EXPECT_TRUE(cx_strcasesuffix(str, empty)); 3.559 - EXPECT_TRUE(cx_strcasesuffix(empty, empty)); 3.560 - EXPECT_TRUE(cx_strcasesuffix(str, CX_STR("FIX"))); 3.561 - EXPECT_FALSE(cx_strcasesuffix(str, CX_STR("fox"))); 3.562 -} 3.563 - 3.564 -TEST(String, strreplace) { 3.565 - CxTestingAllocator alloc; 3.566 - cxstring str = CX_STR("test ababab string aba"); 3.567 - cxstring longstr = CX_STR( 3.568 - "xyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacd"); 3.569 - cxstring notrail = CX_STR("test abab"); 3.570 - cxstring empty = CX_STR(""); 3.571 - cxstring astr = CX_STR("aaaaaaaaaa"); 3.572 - cxstring csstr = CX_STR("test AB ab TEST xyz"); 3.573 - 3.574 - cxmutstr repl = cx_strreplace(str, CX_STR("abab"), CX_STR("muchlonger")); 3.575 - auto expected = "test muchlongerab string aba"; 3.576 - 3.577 - cxmutstr repln = cx_strreplacen(str, CX_STR("ab"), CX_STR("c"), 2); 3.578 - auto expectedn = "test ccab string aba"; 3.579 - 3.580 - cxmutstr longrepl = cx_strreplace(longstr, CX_STR("a"), CX_STR("z")); 3.581 - auto longexpect = "xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzcd"; 3.582 - 3.583 - cxmutstr replnotrail = cx_strreplace(notrail, CX_STR("ab"), CX_STR("z")); 3.584 - auto notrailexpect = "test zz"; 3.585 - 3.586 - cxmutstr repleq = cx_strreplace(str, str, CX_STR("hello")); 3.587 - auto eqexpect = "hello"; 3.588 - 3.589 - cxmutstr replempty1 = cx_strreplace(empty, CX_STR("ab"), CX_STR("c")); // expect: empty 3.590 - cxmutstr replempty2 = cx_strreplace(str, CX_STR("abab"), empty); 3.591 - auto emptyexpect2 = "test ab string aba"; 3.592 - 3.593 - cxmutstr replpre = cx_strreplace(str, CX_STR("test "), CX_STR("TEST ")); 3.594 - auto preexpected = "TEST ababab string aba"; 3.595 - 3.596 - cxmutstr replan1 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 1); 3.597 - auto an1expected = "xaaaaaaaaa"; 3.598 - 3.599 - cxmutstr replan4 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 4); 3.600 - auto an4expected = "xxxxaaaaaa"; 3.601 - 3.602 - cxmutstr replan9 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 9); 3.603 - auto an9expected = "xxxxxxxxxa"; 3.604 - 3.605 - cxmutstr replan10 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 10); 3.606 - auto an10expected = "xxxxxxxxxx"; 3.607 - 3.608 - cxmutstr repl1_a = cx_strreplace_a(&alloc, csstr, CX_STR("AB"), CX_STR("*")); 3.609 - auto expeced1_a = "test * ab TEST xyz"; 3.610 - 3.611 - cxmutstr repl2_a = cx_strreplace_a(&alloc, csstr, CX_STR("test"), CX_STR("TEST")); 3.612 - auto expected2_a = "TEST AB ab TEST xyz"; 3.613 - 3.614 - 3.615 - EXPECT_NE(repl.ptr, str.ptr); 3.616 - EXPECT_ZERO_TERMINATED(repl); 3.617 - EXPECT_STREQ(repl.ptr, expected); 3.618 - EXPECT_ZERO_TERMINATED(repln); 3.619 - EXPECT_STREQ(repln.ptr, expectedn); 3.620 - EXPECT_ZERO_TERMINATED(longrepl); 3.621 - EXPECT_STREQ(longrepl.ptr, longexpect); 3.622 - EXPECT_ZERO_TERMINATED(replnotrail); 3.623 - EXPECT_STREQ(replnotrail.ptr, notrailexpect); 3.624 - EXPECT_ZERO_TERMINATED(repleq); 3.625 - EXPECT_STREQ(repleq.ptr, eqexpect); 3.626 - EXPECT_ZERO_TERMINATED(replempty1); 3.627 - EXPECT_STREQ(replempty1.ptr, ""); 3.628 - EXPECT_ZERO_TERMINATED(replempty2); 3.629 - EXPECT_STREQ(replempty2.ptr, emptyexpect2); 3.630 - EXPECT_ZERO_TERMINATED(replpre); 3.631 - EXPECT_STREQ(replpre.ptr, preexpected); 3.632 - EXPECT_ZERO_TERMINATED(replan1); 3.633 - EXPECT_STREQ(replan1.ptr, an1expected); 3.634 - EXPECT_ZERO_TERMINATED(replan4); 3.635 - EXPECT_STREQ(replan4.ptr, an4expected); 3.636 - EXPECT_ZERO_TERMINATED(replan9); 3.637 - EXPECT_STREQ(replan9.ptr, an9expected); 3.638 - EXPECT_ZERO_TERMINATED(replan10); 3.639 - EXPECT_STREQ(replan10.ptr, an10expected); 3.640 - EXPECT_ZERO_TERMINATED(repl1_a); 3.641 - EXPECT_STREQ(repl1_a.ptr, expeced1_a); 3.642 - EXPECT_ZERO_TERMINATED(repl2_a); 3.643 - EXPECT_STREQ(repl2_a.ptr, expected2_a); 3.644 - 3.645 - cx_strfree(&repl); 3.646 - cx_strfree(&repln); 3.647 - cx_strfree(&longrepl); 3.648 - cx_strfree(&replnotrail); 3.649 - cx_strfree(&repleq); 3.650 - cx_strfree(&replempty1); 3.651 - cx_strfree(&replempty2); 3.652 - cx_strfree(&replpre); 3.653 - cx_strfree(&replan1); 3.654 - cx_strfree(&replan4); 3.655 - cx_strfree(&replan9); 3.656 - cx_strfree(&replan10); 3.657 - 3.658 - cx_strfree_a(&alloc, &repl1_a); 3.659 - cx_strfree_a(&alloc, &repl2_a); 3.660 - EXPECT_TRUE(alloc.verify()); 3.661 -} 3.662 - 3.663 -TEST(String, strupper) { 3.664 - cxmutstr str = cx_strdup(CX_STR("thIs 1s @ Te$t")); 3.665 - cx_strupper(str); 3.666 - EXPECT_STREQ(str.ptr, "THIS 1S @ TE$T"); 3.667 - cx_strfree(&str); 3.668 -} 3.669 - 3.670 -TEST(String, strlower) { 3.671 - cxmutstr str = cx_strdup(CX_STR("thIs 1s @ Te$t")); 3.672 - cx_strlower(str); 3.673 - EXPECT_STREQ(str.ptr, "this 1s @ te$t"); 3.674 - cx_strfree(&str); 3.675 -} 3.676 - 3.677 -TEST(String, strtok) { 3.678 - cxstring str = CX_STR("a,comma,separated,string"); 3.679 - cxstring delim = CX_STR(","); 3.680 - CxStrtokCtx ctx = cx_strtok(str, delim, 3); 3.681 - EXPECT_EQ(ctx.str.ptr, str.ptr); 3.682 - EXPECT_EQ(ctx.str.length, str.length); 3.683 - EXPECT_EQ(ctx.delim.ptr, delim.ptr); 3.684 - EXPECT_EQ(ctx.delim.length, delim.length); 3.685 - EXPECT_EQ(ctx.limit, 3); 3.686 - EXPECT_EQ(ctx.found, 0); 3.687 - EXPECT_EQ(ctx.pos, 0); 3.688 - EXPECT_EQ(ctx.next_pos, 0); 3.689 - EXPECT_EQ(ctx.delim_more, nullptr); 3.690 - EXPECT_EQ(ctx.delim_more_count, 0); 3.691 -} 3.692 - 3.693 -TEST(String, strtok_m) { 3.694 - cxmutstr str = cx_strdup(CX_STR("a,comma,separated,string")); 3.695 - cxstring delim = CX_STR(","); 3.696 - CxStrtokCtx ctx = cx_strtok_m(str, delim, 3); 3.697 - EXPECT_EQ(ctx.str.ptr, str.ptr); 3.698 - EXPECT_EQ(ctx.str.length, str.length); 3.699 - EXPECT_EQ(ctx.delim.ptr, delim.ptr); 3.700 - EXPECT_EQ(ctx.delim.length, delim.length); 3.701 - EXPECT_EQ(ctx.limit, 3); 3.702 - EXPECT_EQ(ctx.found, 0); 3.703 - EXPECT_EQ(ctx.pos, 0); 3.704 - EXPECT_EQ(ctx.next_pos, 0); 3.705 - EXPECT_EQ(ctx.delim_more, nullptr); 3.706 - EXPECT_EQ(ctx.delim_more_count, 0); 3.707 - cx_strfree(&str); 3.708 -} 3.709 - 3.710 -TEST(String, strtok_delim) { 3.711 - cxstring str = CX_STR("an,arbitrarily|separated;string"); 3.712 - cxstring delim = CX_STR(","); 3.713 - cxstring delim_more[2] = {CX_STR("|"), CX_STR(";")}; 3.714 - CxStrtokCtx ctx = cx_strtok(str, delim, 3); 3.715 - cx_strtok_delim(&ctx, delim_more, 2); 3.716 - EXPECT_EQ(ctx.str.ptr, str.ptr); 3.717 - EXPECT_EQ(ctx.str.length, str.length); 3.718 - EXPECT_EQ(ctx.delim.ptr, delim.ptr); 3.719 - EXPECT_EQ(ctx.delim.length, delim.length); 3.720 - EXPECT_EQ(ctx.limit, 3); 3.721 - EXPECT_EQ(ctx.found, 0); 3.722 - EXPECT_EQ(ctx.pos, 0); 3.723 - EXPECT_EQ(ctx.next_pos, 0); 3.724 - EXPECT_EQ(ctx.delim_more, delim_more); 3.725 - EXPECT_EQ(ctx.delim_more_count, 2); 3.726 -} 3.727 - 3.728 -TEST(String, strtok_next_easy) { 3.729 - cxstring str = CX_STR("a,comma,separated,string"); 3.730 - cxstring delim = CX_STR(","); 3.731 - CxStrtokCtx ctx = cx_strtok(str, delim, 3); 3.732 - bool ret; 3.733 - cxstring tok; 3.734 - 3.735 - ret = cx_strtok_next(&ctx, &tok); 3.736 - ASSERT_TRUE(ret); 3.737 - EXPECT_EQ(cx_strcmp(tok, CX_STR("a")), 0); 3.738 - EXPECT_EQ(ctx.pos, 0); 3.739 - EXPECT_EQ(ctx.next_pos, 2); 3.740 - EXPECT_EQ(ctx.delim_pos, 1); 3.741 - EXPECT_EQ(ctx.found, 1); 3.742 - 3.743 - ret = cx_strtok_next(&ctx, &tok); 3.744 - ASSERT_TRUE(ret); 3.745 - EXPECT_EQ(cx_strcmp(tok, CX_STR("comma")), 0); 3.746 - EXPECT_EQ(ctx.pos, 2); 3.747 - EXPECT_EQ(ctx.next_pos, 8); 3.748 - EXPECT_EQ(ctx.delim_pos, 7); 3.749 - EXPECT_EQ(ctx.found, 2); 3.750 - 3.751 - ret = cx_strtok_next(&ctx, &tok); 3.752 - ASSERT_TRUE(ret); 3.753 - EXPECT_EQ(cx_strcmp(tok, CX_STR("separated")), 0); 3.754 - EXPECT_EQ(ctx.pos, 8); 3.755 - EXPECT_EQ(ctx.next_pos, 18); 3.756 - EXPECT_EQ(ctx.delim_pos, 17); 3.757 - EXPECT_EQ(ctx.found, 3); 3.758 - 3.759 - ret = cx_strtok_next(&ctx, &tok); 3.760 - ASSERT_FALSE(ret); 3.761 - EXPECT_EQ(ctx.pos, 8); 3.762 - EXPECT_EQ(ctx.next_pos, 18); 3.763 - EXPECT_EQ(ctx.delim_pos, 17); 3.764 - EXPECT_EQ(ctx.found, 3); 3.765 -} 3.766 - 3.767 -TEST(String, strtok_next_unlimited) { 3.768 - cxstring str = CX_STR("some;-;otherwise;-;separated;-;string;-;"); 3.769 - cxstring delim = CX_STR(";-;"); 3.770 - CxStrtokCtx ctx = cx_strtok(str, delim, SIZE_MAX); 3.771 - bool ret; 3.772 - cxstring tok; 3.773 - 3.774 - ret = cx_strtok_next(&ctx, &tok); 3.775 - ASSERT_TRUE(ret); 3.776 - EXPECT_EQ(cx_strcmp(tok, CX_STR("some")), 0); 3.777 - EXPECT_EQ(ctx.pos, 0); 3.778 - EXPECT_EQ(ctx.next_pos, 7); 3.779 - EXPECT_EQ(ctx.delim_pos, 4); 3.780 - EXPECT_EQ(ctx.found, 1); 3.781 - 3.782 - ret = cx_strtok_next(&ctx, &tok); 3.783 - ASSERT_TRUE(ret); 3.784 - EXPECT_EQ(cx_strcmp(tok, CX_STR("otherwise")), 0); 3.785 - EXPECT_EQ(ctx.pos, 7); 3.786 - EXPECT_EQ(ctx.next_pos, 19); 3.787 - EXPECT_EQ(ctx.delim_pos, 16); 3.788 - EXPECT_EQ(ctx.found, 2); 3.789 - 3.790 - ret = cx_strtok_next(&ctx, &tok); 3.791 - ASSERT_TRUE(ret); 3.792 - EXPECT_EQ(cx_strcmp(tok, CX_STR("separated")), 0); 3.793 - EXPECT_EQ(ctx.pos, 19); 3.794 - EXPECT_EQ(ctx.next_pos, 31); 3.795 - EXPECT_EQ(ctx.delim_pos, 28); 3.796 - EXPECT_EQ(ctx.found, 3); 3.797 - 3.798 - ret = cx_strtok_next(&ctx, &tok); 3.799 - ASSERT_TRUE(ret); 3.800 - EXPECT_EQ(cx_strcmp(tok, CX_STR("string")), 0); 3.801 - EXPECT_EQ(ctx.pos, 31); 3.802 - EXPECT_EQ(ctx.next_pos, 40); 3.803 - EXPECT_EQ(ctx.delim_pos, 37); 3.804 - EXPECT_EQ(ctx.found, 4); 3.805 - 3.806 - ret = cx_strtok_next(&ctx, &tok); 3.807 - ASSERT_TRUE(ret); 3.808 - EXPECT_EQ(cx_strcmp(tok, CX_STR("")), 0); 3.809 - EXPECT_EQ(ctx.pos, 40); 3.810 - EXPECT_EQ(ctx.next_pos, 40); 3.811 - EXPECT_EQ(ctx.delim_pos, 40); 3.812 - EXPECT_EQ(ctx.found, 5); 3.813 - 3.814 - ret = cx_strtok_next(&ctx, &tok); 3.815 - ASSERT_FALSE(ret); 3.816 - EXPECT_EQ(ctx.pos, 40); 3.817 - EXPECT_EQ(ctx.delim_pos, 40); 3.818 - EXPECT_EQ(ctx.found, 5); 3.819 -} 3.820 - 3.821 -TEST(String, strtok_next_advanced) { 3.822 - cxmutstr str = cx_strdup(CX_STR("an,arbitrarily;||separated;string")); 3.823 - cxstring delim = CX_STR(","); 3.824 - cxstring delim_more[2] = {CX_STR("||"), CX_STR(";")}; 3.825 - CxStrtokCtx ctx = cx_strtok_m(str, delim, 10); 3.826 - cx_strtok_delim(&ctx, delim_more, 2); 3.827 - bool ret; 3.828 - cxmutstr tok; 3.829 - 3.830 - ret = cx_strtok_next_m(&ctx, &tok); 3.831 - ASSERT_TRUE(ret); 3.832 - EXPECT_EQ(cx_strcmp(cx_strcast(tok), CX_STR("an")), 0); 3.833 - EXPECT_EQ(ctx.pos, 0); 3.834 - EXPECT_EQ(ctx.next_pos, 3); 3.835 - EXPECT_EQ(ctx.delim_pos, 2); 3.836 - EXPECT_EQ(ctx.found, 1); 3.837 - cx_strupper(tok); 3.838 - 3.839 - ret = cx_strtok_next_m(&ctx, &tok); 3.840 - ASSERT_TRUE(ret); 3.841 - EXPECT_EQ(cx_strcmp(cx_strcast(tok), CX_STR("arbitrarily")), 0); 3.842 - EXPECT_EQ(ctx.pos, 3); 3.843 - EXPECT_EQ(ctx.next_pos, 15); 3.844 - EXPECT_EQ(ctx.delim_pos, 14); 3.845 - EXPECT_EQ(ctx.found, 2); 3.846 - cx_strupper(tok); 3.847 - 3.848 - ret = cx_strtok_next_m(&ctx, &tok); 3.849 - ASSERT_TRUE(ret); 3.850 - EXPECT_EQ(cx_strcmp(cx_strcast(tok), CX_STR("")), 0); 3.851 - EXPECT_EQ(ctx.pos, 15); 3.852 - EXPECT_EQ(ctx.next_pos, 17); 3.853 - EXPECT_EQ(ctx.delim_pos, 15); 3.854 - EXPECT_EQ(ctx.found, 3); 3.855 - cx_strupper(tok); 3.856 - 3.857 - ret = cx_strtok_next_m(&ctx, &tok); 3.858 - ASSERT_TRUE(ret); 3.859 - EXPECT_EQ(cx_strcmp(cx_strcast(tok), CX_STR("separated")), 0); 3.860 - EXPECT_EQ(ctx.pos, 17); 3.861 - EXPECT_EQ(ctx.next_pos, 27); 3.862 - EXPECT_EQ(ctx.delim_pos, 26); 3.863 - EXPECT_EQ(ctx.found, 4); 3.864 - cx_strupper(tok); 3.865 - 3.866 - ret = cx_strtok_next_m(&ctx, &tok); 3.867 - ASSERT_TRUE(ret); 3.868 - EXPECT_EQ(cx_strcmp(cx_strcast(tok), CX_STR("string")), 0); 3.869 - EXPECT_EQ(ctx.pos, 27); 3.870 - EXPECT_EQ(ctx.next_pos, 33); 3.871 - EXPECT_EQ(ctx.delim_pos, 33); 3.872 - EXPECT_EQ(ctx.found, 5); 3.873 - cx_strupper(tok); 3.874 - 3.875 - ret = cx_strtok_next_m(&ctx, &tok); 3.876 - ASSERT_FALSE(ret); 3.877 - EXPECT_EQ(ctx.pos, 27); 3.878 - EXPECT_EQ(ctx.next_pos, 33); 3.879 - EXPECT_EQ(ctx.delim_pos, 33); 3.880 - EXPECT_EQ(ctx.found, 5); 3.881 - 3.882 - EXPECT_EQ(cx_strcmp(cx_strcast(str), CX_STR("AN,ARBITRARILY;||SEPARATED;STRING")), 0); 3.883 - 3.884 - cx_strfree(&str); 3.885 -}
4.1 --- a/tests/ucxtest.c Thu Dec 28 19:17:45 2023 +0100 4.2 +++ b/tests/ucxtest.c Thu Dec 28 20:37:53 2023 +0100 4.3 @@ -32,6 +32,8 @@ 4.4 CxTestSuite *cx_test_suite_utils(void); 4.5 CxTestSuite *cx_test_suite_hash_key(void); 4.6 4.7 +CxTestSuite *cx_test_suite_string(void); 4.8 + 4.9 #define run_tests(suite) cx_test_run_stdout(suite); success += (suite)->success; failure += (suite)->failure 4.10 #define execute_test_suites(...) unsigned success = 0, failure = 0; CxTestSuite* test_suites[] = {__VA_ARGS__}; \ 4.11 for (size_t i = 0; i < sizeof(test_suites)/sizeof(void*) ; i++) {run_tests(test_suites[i]);} (void)0 4.12 @@ -43,7 +45,8 @@ 4.13 execute_test_suites( 4.14 cx_test_suite_testing_allocator(), 4.15 cx_test_suite_utils(), 4.16 - cx_test_suite_hash_key() 4.17 + cx_test_suite_hash_key(), 4.18 + cx_test_suite_string() 4.19 ); 4.20 printf("=== OVERALL RESULT ===\n"); 4.21 printf(" Total: %u\n Success: %u\n Failure: %u\n",