tests/test_string.c

Tue, 16 Jan 2024 23:12:43 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 16 Jan 2024 23:12:43 +0100
changeset 809
b7e2e1d7ed22
parent 806
e06249e09f99
permissions
-rw-r--r--

fix assertion failure depending on possibly uninitialized memory

universe@777 1 /*
universe@777 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@777 3 *
universe@777 4 * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
universe@777 5 *
universe@777 6 * Redistribution and use in source and binary forms, with or without
universe@777 7 * modification, are permitted provided that the following conditions are met:
universe@777 8 *
universe@777 9 * 1. Redistributions of source code must retain the above copyright
universe@777 10 * notice, this list of conditions and the following disclaimer.
universe@777 11 *
universe@777 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@777 13 * notice, this list of conditions and the following disclaimer in the
universe@777 14 * documentation and/or other materials provided with the distribution.
universe@777 15 *
universe@777 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@777 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@777 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@777 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@777 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@777 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@777 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@777 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@777 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@777 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@777 26 * POSSIBILITY OF SUCH DAMAGE.
universe@777 27 */
universe@777 28
universe@777 29 #include "cx/test.h"
universe@777 30 #include "util_allocator.h"
universe@777 31
universe@777 32 #include "cx/string.h"
universe@777 33
universe@777 34 #define ASSERT_ZERO_TERMINATED(str) CX_TEST_ASSERTM((str).ptr[(str).length] == '\0', \
universe@777 35 #str " is not zero terminated")
universe@777 36
universe@777 37 CX_TEST(test_string_construct) {
universe@777 38 cxstring s1 = CX_STR("1234");
universe@777 39 cxstring s2 = cx_strn("abcd", 2);
universe@777 40 cxmutstr s3 = cx_mutstr((char *) "1234");
universe@777 41 cxmutstr s4 = cx_mutstrn((char *) "abcd", 2);
universe@777 42 CX_TEST_DO {
universe@777 43 CX_TEST_ASSERT(s1.length == 4);
universe@777 44 CX_TEST_ASSERT(strncmp(s1.ptr, "1234", 4) == 0);
universe@777 45 CX_TEST_ASSERT(s2.length == 2);
universe@777 46 CX_TEST_ASSERT(strncmp(s2.ptr, "ab", 2) == 0);
universe@777 47 CX_TEST_ASSERT(s3.length == 4);
universe@777 48 CX_TEST_ASSERT(strncmp(s3.ptr, "1234", 4) == 0);
universe@777 49 CX_TEST_ASSERT(s4.length == 2);
universe@777 50 CX_TEST_ASSERT(strncmp(s4.ptr, "ab", 2) == 0);
universe@777 51 }
universe@777 52 }
universe@777 53
universe@777 54 CX_TEST(test_strfree) {
universe@777 55 CxTestingAllocator talloc;
universe@777 56 cx_testing_allocator_init(&talloc);
universe@777 57 CxAllocator *alloc = &talloc.base;
universe@777 58 CX_TEST_DO {
universe@777 59 char *test = cxMalloc(alloc, 16);
universe@777 60 cxmutstr str = cx_mutstrn(test, 16);
universe@777 61 CX_TEST_ASSERT(str.ptr == test);
universe@777 62 CX_TEST_ASSERT(str.length == 16);
universe@777 63 cx_strfree_a(alloc, &str);
universe@777 64 CX_TEST_ASSERT(str.ptr == NULL);
universe@777 65 CX_TEST_ASSERT(str.length == 0);
universe@777 66 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@777 67 }
universe@777 68 cx_testing_allocator_destroy(&talloc);
universe@777 69 }
universe@777 70
universe@777 71 CX_TEST(test_strdup) {
universe@777 72 cxstring str = CX_STR("test");
universe@777 73 cxmutstr dup = cx_strdup(str);
universe@777 74 CX_TEST_DO {
universe@777 75 CX_TEST_ASSERT(dup.length == str.length);
universe@777 76 CX_TEST_ASSERT(0 == strcmp(dup.ptr, str.ptr));
universe@777 77 ASSERT_ZERO_TERMINATED(dup);
universe@777 78 }
universe@777 79 cx_strfree(&dup);
universe@777 80 }
universe@777 81
universe@777 82 CX_TEST(test_strdup_shortened) {
universe@777 83 cxstring str = CX_STR("test");
universe@777 84 str.length = 2;
universe@777 85 cxmutstr dup = cx_strdup(str);
universe@777 86 CX_TEST_DO {
universe@777 87 CX_TEST_ASSERT(dup.length == str.length);
universe@777 88 CX_TEST_ASSERT(0 == strcmp(dup.ptr, "te"));
universe@777 89 ASSERT_ZERO_TERMINATED(dup);
universe@777 90 }
universe@777 91 cx_strfree(&dup);
universe@777 92 }
universe@777 93
universe@777 94 CX_TEST(test_strlen) {
universe@777 95 cxstring s1 = CX_STR("1234");
universe@777 96 cxstring s2 = CX_STR(".:.:.");
universe@777 97 cxstring s3 = CX_STR("X");
universe@777 98 CX_TEST_DO {
universe@777 99 size_t len0 = cx_strlen(0);
universe@777 100 size_t len1 = cx_strlen(1, s1);
universe@777 101 size_t len2 = cx_strlen(2, s1, s2);
universe@777 102 size_t len3 = cx_strlen(3, s1, s2, s3);
universe@777 103
universe@777 104 CX_TEST_ASSERT(len0 == 0);
universe@777 105 CX_TEST_ASSERT(len1 == 4);
universe@777 106 CX_TEST_ASSERT(len2 == 9);
universe@777 107 CX_TEST_ASSERT(len3 == 10);
universe@777 108 }
universe@777 109 }
universe@777 110
universe@777 111 CX_TEST(test_strsubs) {
universe@777 112 cxstring str = CX_STR("A test string");
universe@777 113
universe@777 114 CX_TEST_DO {
universe@777 115 cxstring sub = cx_strsubs(str, 0);
universe@777 116 CX_TEST_ASSERT(0 == cx_strcmp(sub, str));
universe@777 117
universe@777 118 sub = cx_strsubs(str, 2);
universe@777 119 CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("test string")));
universe@777 120
universe@777 121 sub = cx_strsubs(str, 7);
universe@777 122 CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("string")));
universe@777 123
universe@777 124 sub = cx_strsubs(str, 15);
universe@777 125 CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("")));
universe@777 126
universe@777 127 sub = cx_strsubsl(str, 2, 4);
universe@777 128 CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("test")));
universe@777 129
universe@777 130 sub = cx_strsubsl(str, 7, 3);
universe@777 131 CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("str")));
universe@777 132
universe@777 133 sub = cx_strsubsl(str, 7, 20);
universe@777 134 CX_TEST_ASSERT(0 == cx_strcmp(sub, CX_STR("string")));
universe@777 135
universe@777 136 // just for coverage, call the _m variant
universe@777 137 cxmutstr m = cx_strsubs_m(cx_mutstrn(NULL, 0), 0);
universe@777 138 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m), CX_STR("")));
universe@777 139 }
universe@777 140 }
universe@777 141
universe@777 142 CX_TEST(test_strchr) {
universe@777 143 cxstring str = CX_STR("I will find you - and I will kill you");
universe@777 144
universe@777 145 CX_TEST_DO {
universe@777 146 cxstring notfound = cx_strchr(str, 'x');
universe@777 147 CX_TEST_ASSERT(notfound.length == 0);
universe@777 148
universe@777 149 cxstring result = cx_strchr(str, 'w');
universe@777 150 CX_TEST_ASSERT(result.length == 35);
universe@777 151 CX_TEST_ASSERT(0 == strcmp(result.ptr, "will find you - and I will kill you"));
universe@777 152
universe@777 153 // just for coverage, call the _m variant
universe@777 154 cxmutstr m = cx_strchr_m(cx_mutstrn(NULL, 0), 'a');
universe@777 155 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m), CX_STR("")));
universe@777 156 }
universe@777 157 }
universe@777 158
universe@777 159 CX_TEST(test_strrchr) {
universe@777 160 cxstring str = CX_STR("I will find you - and I will kill you");
universe@777 161
universe@777 162 CX_TEST_DO {
universe@777 163 cxstring notfound = cx_strrchr(str, 'x');
universe@777 164 CX_TEST_ASSERT(notfound.length == 0);
universe@777 165
universe@777 166 cxstring result = cx_strrchr(str, 'w');
universe@777 167 CX_TEST_ASSERT(result.length == 13);
universe@777 168 CX_TEST_ASSERT(0 == strcmp(result.ptr, "will kill you"));
universe@777 169
universe@777 170 // just for coverage, call the _m variant
universe@777 171 cxmutstr m = cx_strrchr_m(cx_mutstrn(NULL, 0), 'a');
universe@777 172 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m), CX_STR("")));
universe@777 173 }
universe@777 174 }
universe@777 175
universe@777 176 CX_TEST(test_strstr) {
universe@777 177 cxstring str = CX_STR("find the match in this string");
universe@806 178
universe@806 179 size_t const longstrpatternlen = 64 + cx_strstr_sbo_size;
universe@806 180 size_t const longstrlen = 320 + longstrpatternlen + 14;
universe@806 181
universe@809 182 // it is more expensive to use calloc here, because we will overwrite
universe@809 183 // the memory anyway in the test preparation - but it is more reliable
universe@809 184 // in case we are doing something horribly wrong
universe@809 185 char *longstrc = calloc(longstrlen+1, 1);
universe@809 186 char *longstrpatternc = calloc(longstrpatternlen+1, 1);
universe@806 187
universe@806 188 memcpy(longstrc,
universe@806 189 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl"
universe@806 190 "mnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx"
universe@806 191 "yzabcdeababababnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij"
universe@806 192 "klmnopqrstuvwxyzaababababababababrstuvwxyzabcdefghijklmnopqrstuv"
universe@806 193 "abababababababababababababababababababababababababababababababab",
universe@806 194 320
universe@777 195 );
universe@806 196 memcpy(longstrpatternc,
universe@806 197 "abababababababababababababababababababababababababababababababab",
universe@806 198 64
universe@777 199 );
universe@806 200 char x = 'a', y='b', z;
universe@806 201 for (size_t i = 0; i < cx_strstr_sbo_size ; i++) {
universe@806 202 longstrpatternc[64+i] = x;
universe@806 203 longstrc[320+i] = x;
universe@806 204 z=x; x=y; y=z;
universe@806 205 }
universe@806 206 longstrpatternc[longstrpatternlen] = '\0';
universe@806 207 memcpy(longstrc+longstrlen-14, "wxyz1234567890", 15);
universe@806 208
universe@806 209 cxmutstr longstr = cx_mutstrn(longstrc, longstrlen);
universe@806 210 cxstring longstrpattern = cx_strn(longstrpatternc, longstrpatternlen);
universe@806 211 cxmutstr longstrresult = cx_mutstrn(longstrc+256, longstrlen-256);
universe@777 212
universe@777 213 CX_TEST_DO {
universe@777 214 cxstring notfound = cx_strstr(str, CX_STR("no match"));
universe@777 215 CX_TEST_ASSERT(notfound.length == 0);
universe@777 216
universe@777 217 cxstring result = cx_strstr(str, CX_STR("match"));
universe@777 218 CX_TEST_ASSERT(result.length == 20);
universe@777 219 CX_TEST_ASSERT(0 == strcmp(result.ptr, "match in this string"));
universe@777 220
universe@777 221 result = cx_strstr(str, CX_STR(""));
universe@777 222 CX_TEST_ASSERT(result.length == str.length);
universe@777 223 CX_TEST_ASSERT(0 == strcmp(result.ptr, str.ptr));
universe@777 224
universe@806 225 cxmutstr resultm = cx_strstr_m(longstr, longstrpattern);
universe@806 226 CX_TEST_ASSERT(resultm.length == longstrresult.length);
universe@806 227 CX_TEST_ASSERT(0 == strcmp(resultm.ptr, longstrresult.ptr));
universe@806 228 }
universe@777 229
universe@806 230 free(longstrc);
universe@806 231 free(longstrpatternc);
universe@777 232 }
universe@777 233
universe@777 234 CX_TEST(test_strcmp) {
universe@777 235 cxstring str = CX_STR("compare this");
universe@777 236 CX_TEST_DO {
universe@777 237 CX_TEST_ASSERT(0 == cx_strcmp(CX_STR(""), CX_STR("")));
universe@777 238 CX_TEST_ASSERT(0 < cx_strcmp(str, CX_STR("")));
universe@777 239 CX_TEST_ASSERT(0 == cx_strcmp(str, CX_STR("compare this")));
universe@777 240 CX_TEST_ASSERT(0 != cx_strcmp(str, CX_STR("Compare This")));
universe@777 241 CX_TEST_ASSERT(0 > cx_strcmp(str, CX_STR("compare tool")));
universe@777 242 CX_TEST_ASSERT(0 < cx_strcmp(str, CX_STR("compare shit")));
universe@777 243 CX_TEST_ASSERT(0 > cx_strcmp(str, CX_STR("compare this not")));
universe@777 244 CX_TEST_ASSERT(0 < cx_strcmp(str, CX_STR("compare")));
universe@777 245
universe@777 246 cxstring str2 = CX_STR("Compare This");
universe@777 247 CX_TEST_ASSERT(0 != cx_strcmp_p(&str, &str2));
universe@777 248 str2 = CX_STR("compare this");
universe@777 249 CX_TEST_ASSERT(0 == cx_strcmp_p(&str, &str2));
universe@777 250 }
universe@777 251 }
universe@777 252
universe@777 253 CX_TEST(test_strcasecmp) {
universe@777 254 cxstring str = CX_STR("compare this");
universe@777 255 CX_TEST_DO {
universe@777 256 CX_TEST_ASSERT(0 == cx_strcasecmp(CX_STR(""), CX_STR("")));
universe@777 257 CX_TEST_ASSERT(0 < cx_strcasecmp(str, CX_STR("")));
universe@777 258 CX_TEST_ASSERT(0 == cx_strcasecmp(str, CX_STR("compare this")));
universe@777 259 CX_TEST_ASSERT(0 == cx_strcasecmp(str, CX_STR("Compare This")));
universe@777 260 CX_TEST_ASSERT(0 > cx_strcasecmp(str, CX_STR("compare tool")));
universe@777 261 CX_TEST_ASSERT(0 < cx_strcasecmp(str, CX_STR("compare shit")));
universe@777 262 CX_TEST_ASSERT(0 > cx_strcasecmp(str, CX_STR("compare this not")));
universe@777 263 CX_TEST_ASSERT(0 < cx_strcasecmp(str, CX_STR("compare")));
universe@777 264
universe@777 265 cxstring str2 = CX_STR("Compare This");
universe@777 266 CX_TEST_ASSERT(0 == cx_strcasecmp_p(&str, &str2));
universe@777 267 str2 = CX_STR("Compare Tool");
universe@777 268 CX_TEST_ASSERT(0 > cx_strcasecmp_p(&str, &str2));
universe@777 269 }
universe@777 270 }
universe@777 271
universe@777 272 CX_TEST(test_strcat) {
universe@777 273 cxstring s1 = CX_STR("12");
universe@777 274 cxstring s2 = CX_STR("34");
universe@777 275 cxstring s3 = CX_STR("56");
universe@777 276 cxstring sn = {NULL, 0};
universe@777 277
universe@777 278 CxTestingAllocator talloc;
universe@777 279 cx_testing_allocator_init(&talloc);
universe@777 280 CxAllocator *alloc = &talloc.base;
universe@777 281
universe@777 282 CX_TEST_DO {
universe@777 283 cxmutstr t1 = cx_strcat_a(alloc, 2, s1, s2);
universe@777 284 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t1), CX_STR("1234")));
universe@777 285 ASSERT_ZERO_TERMINATED(t1);
universe@777 286 cx_strfree_a(alloc, &t1);
universe@777 287
universe@777 288 cxmutstr t2 = cx_strcat_a(alloc, 3, s1, s2, s3);
universe@777 289 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t2), CX_STR("123456")));
universe@777 290 ASSERT_ZERO_TERMINATED(t2);
universe@777 291 cx_strfree_a(alloc, &t2);
universe@777 292
universe@777 293 cxmutstr t3 = cx_strcat_a(alloc, 6, s1, sn, s2, sn, s3, sn);
universe@777 294 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t3), CX_STR("123456")));
universe@777 295 ASSERT_ZERO_TERMINATED(t3);
universe@777 296 cx_strfree_a(alloc, &t3);
universe@777 297
universe@777 298 cxmutstr t4 = cx_strcat_a(alloc, 2, sn, sn);
universe@777 299 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t4), CX_STR("")));
universe@777 300 ASSERT_ZERO_TERMINATED(t4);
universe@777 301 cx_strfree_a(alloc, &t4);
universe@777 302
universe@777 303 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@777 304
universe@777 305 // use the macro
universe@777 306 cxmutstr t5 = cx_strcat(3, s3, s1, s2);
universe@777 307 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t5), CX_STR("561234")));
universe@777 308 ASSERT_ZERO_TERMINATED(t5);
universe@777 309 cx_strfree(&t5);
universe@777 310
universe@777 311 // use an initial string
universe@777 312 cxmutstr t6 = cx_strdup(CX_STR("Hello"));
universe@777 313 t6 = cx_strcat_m(t6, 2, CX_STR(", "), CX_STR("World!"));
universe@777 314 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t6), CX_STR("Hello, World!")));
universe@777 315 ASSERT_ZERO_TERMINATED(t6);
universe@777 316 cx_strfree(&t6);
universe@777 317 }
universe@777 318 cx_testing_allocator_destroy(&talloc);
universe@777 319 }
universe@777 320
universe@777 321 CX_TEST(test_strsplit) {
universe@777 322 cxstring test = CX_STR("this,is,a,csv,string");
universe@777 323 size_t capa = 8;
universe@777 324 cxstring list[8];
universe@777 325 size_t n;
universe@777 326 CX_TEST_DO {
universe@777 327 // special case: empty string
universe@777 328 n = cx_strsplit(test, CX_STR(""), capa, list);
universe@777 329 CX_TEST_ASSERT(n == 1);
universe@777 330 CX_TEST_ASSERT(0 == cx_strcmp(list[0], test));
universe@777 331
universe@777 332 // no delimiter occurrence
universe@777 333 n = cx_strsplit(test, CX_STR("z"), capa, list);
universe@777 334 CX_TEST_ASSERT(n == 1);
universe@777 335 CX_TEST_ASSERT(0 == cx_strcmp(list[0], test));
universe@777 336
universe@777 337 // partially matching delimiter
universe@777 338 n = cx_strsplit(test, CX_STR("is,not"), capa, list);
universe@777 339 CX_TEST_ASSERT(n == 1);
universe@777 340 CX_TEST_ASSERT(0 == cx_strcmp(list[0], test));
universe@777 341
universe@777 342 // matching single-char delimiter
universe@777 343 n = cx_strsplit(test, CX_STR(","), capa, list);
universe@777 344 CX_TEST_ASSERT(n == 5);
universe@777 345 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this")));
universe@777 346 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("is")));
universe@777 347 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a")));
universe@777 348 CX_TEST_ASSERT(0 == cx_strcmp(list[3], CX_STR("csv")));
universe@777 349 CX_TEST_ASSERT(0 == cx_strcmp(list[4], CX_STR("string")));
universe@777 350
universe@777 351 // matching multi-char delimiter
universe@777 352 n = cx_strsplit(test, CX_STR("is"), capa, list);
universe@777 353 CX_TEST_ASSERT(n == 3);
universe@777 354 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th")));
universe@777 355 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",")));
universe@777 356 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR(",a,csv,string")));
universe@777 357
universe@777 358 // bounded list using single-char delimiter
universe@777 359 n = cx_strsplit(test, CX_STR(","), 3, list);
universe@777 360 CX_TEST_ASSERT(n == 3);
universe@777 361 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this")));
universe@777 362 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("is")));
universe@777 363 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a,csv,string")));
universe@777 364
universe@777 365 // bounded list using multi-char delimiter
universe@777 366 n = cx_strsplit(test, CX_STR("is"), 2, list);
universe@777 367 CX_TEST_ASSERT(n == 2);
universe@777 368 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th")));
universe@777 369 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",is,a,csv,string")));
universe@777 370
universe@777 371 // start with delimiter
universe@777 372 n = cx_strsplit(test, CX_STR("this"), capa, list);
universe@777 373 CX_TEST_ASSERT(n == 2);
universe@777 374 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("")));
universe@777 375 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",is,a,csv,string")));
universe@777 376
universe@777 377 // end with delimiter
universe@777 378 n = cx_strsplit(test, CX_STR("string"), capa, list);
universe@777 379 CX_TEST_ASSERT(n == 2);
universe@777 380 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this,is,a,csv,")));
universe@777 381 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("")));
universe@777 382
universe@777 383
universe@777 384 // end with delimiter exceed bound
universe@777 385 n = cx_strsplit(CX_STR("a,b,c,"), CX_STR(","), 3, list);
universe@777 386 CX_TEST_ASSERT(n == 3);
universe@777 387 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("a")));
universe@777 388 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("b")));
universe@777 389 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("c,")));
universe@777 390
universe@777 391 // exact match
universe@777 392 n = cx_strsplit(test, CX_STR("this,is,a,csv,string"), capa, list);
universe@777 393 CX_TEST_ASSERT(n == 2);
universe@777 394 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("")));
universe@777 395 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("")));
universe@777 396
universe@777 397 // string to be split is only substring
universe@777 398 n = cx_strsplit(test, CX_STR("this,is,a,csv,string,with,extension"), capa, list);
universe@777 399 CX_TEST_ASSERT(n == 1);
universe@777 400 CX_TEST_ASSERT(0 == cx_strcmp(list[0], test));
universe@777 401
universe@777 402 // subsequent encounter of delimiter (the string between is empty)
universe@777 403 n = cx_strsplit(test, CX_STR("is,"), capa, list);
universe@777 404 CX_TEST_ASSERT(n == 3);
universe@777 405 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th")));
universe@777 406 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("")));
universe@777 407 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a,csv,string")));
universe@777 408
universe@777 409 // call the _m variant just for coverage
universe@777 410 cxmutstr mtest = cx_strdup(test);
universe@777 411 cxmutstr mlist[4];
universe@777 412 n = cx_strsplit_m(mtest, CX_STR("is,"), 4, mlist);
universe@777 413 CX_TEST_ASSERT(n == 3);
universe@777 414 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[0]), CX_STR("th")));
universe@777 415 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[1]), CX_STR("")));
universe@777 416 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[2]), CX_STR("a,csv,string")));
universe@777 417 cx_strfree(&mtest);
universe@777 418 }
universe@777 419 }
universe@777 420
universe@777 421 CX_TEST(test_strsplit_a) {
universe@777 422 CxTestingAllocator talloc;
universe@777 423 cx_testing_allocator_init(&talloc);
universe@777 424 CxAllocator *alloc = &talloc.base;
universe@777 425
universe@777 426 cxstring test = CX_STR("this,is,a,csv,string");
universe@777 427 size_t capa = 8;
universe@777 428 cxstring *list;
universe@777 429 size_t n;
universe@777 430 CX_TEST_DO {
universe@777 431 // special case: empty string
universe@777 432 n = cx_strsplit_a(alloc, test, CX_STR(""), capa, &list);
universe@777 433 CX_TEST_ASSERT(n == 1);
universe@777 434 CX_TEST_ASSERT(0 == cx_strcmp(list[0], test));
universe@777 435 cxFree(alloc, list);
universe@777 436
universe@777 437 // no delimiter occurrence
universe@777 438 n = cx_strsplit_a(alloc, test, CX_STR("z"), capa, &list);
universe@777 439 CX_TEST_ASSERT(n == 1);
universe@777 440 CX_TEST_ASSERT(0 == cx_strcmp(list[0], test));
universe@777 441 cxFree(alloc, list);
universe@777 442
universe@777 443 // partially matching delimiter
universe@777 444 n = cx_strsplit_a(alloc, test, CX_STR("is,not"), capa, &list);
universe@777 445 CX_TEST_ASSERT(n == 1);
universe@777 446 CX_TEST_ASSERT(0 == cx_strcmp(list[0], test));
universe@777 447 cxFree(alloc, list);
universe@777 448
universe@777 449 // matching single-char delimiter
universe@777 450 n = cx_strsplit_a(alloc, test, CX_STR(","), capa, &list);
universe@777 451 CX_TEST_ASSERT(n == 5);
universe@777 452 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this")));
universe@777 453 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("is")));
universe@777 454 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a")));
universe@777 455 CX_TEST_ASSERT(0 == cx_strcmp(list[3], CX_STR("csv")));
universe@777 456 CX_TEST_ASSERT(0 == cx_strcmp(list[4], CX_STR("string")));
universe@777 457 cxFree(alloc, list);
universe@777 458
universe@777 459 // matching multi-char delimiter
universe@777 460 n = cx_strsplit_a(alloc, test, CX_STR("is"), capa, &list);
universe@777 461 CX_TEST_ASSERT(n == 3);
universe@777 462 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th")));
universe@777 463 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",")));
universe@777 464 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR(",a,csv,string")));
universe@777 465 cxFree(alloc, list);
universe@777 466
universe@777 467 // bounded list using single-char delimiter
universe@777 468 n = cx_strsplit_a(alloc, test, CX_STR(","), 3, &list);
universe@777 469 CX_TEST_ASSERT(n == 3);
universe@777 470 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this")));
universe@777 471 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("is")));
universe@777 472 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a,csv,string")));
universe@777 473 cxFree(alloc, list);
universe@777 474
universe@777 475 // bounded list using multi-char delimiter
universe@777 476 n = cx_strsplit_a(alloc, test, CX_STR("is"), 2, &list);
universe@777 477 CX_TEST_ASSERT(n == 2);
universe@777 478 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th")));
universe@777 479 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",is,a,csv,string")));
universe@777 480 cxFree(alloc, list);
universe@777 481
universe@777 482 // start with delimiter
universe@777 483 n = cx_strsplit_a(alloc, test, CX_STR("this"), capa, &list);
universe@777 484 CX_TEST_ASSERT(n == 2);
universe@777 485 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("")));
universe@777 486 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR(",is,a,csv,string")));
universe@777 487 cxFree(alloc, list);
universe@777 488
universe@777 489 // end with delimiter
universe@777 490 n = cx_strsplit_a(alloc, test, CX_STR("string"), capa, &list);
universe@777 491 CX_TEST_ASSERT(n == 2);
universe@777 492 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("this,is,a,csv,")));
universe@777 493 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("")));
universe@777 494 cxFree(alloc, list);
universe@777 495
universe@777 496 // end with delimiter exceed bound
universe@777 497 n = cx_strsplit_a(alloc, CX_STR("a,b,c,"), CX_STR(","), 3, &list);
universe@777 498 CX_TEST_ASSERT(n == 3);
universe@777 499 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("a")));
universe@777 500 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("b")));
universe@777 501 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("c,")));
universe@777 502 cxFree(alloc, list);
universe@777 503
universe@777 504 // exact match
universe@777 505 n = cx_strsplit_a(alloc, test, CX_STR("this,is,a,csv,string"), capa, &list);
universe@777 506 CX_TEST_ASSERT(n == 2);
universe@777 507 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("")));
universe@777 508 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("")));
universe@777 509 cxFree(alloc, list);
universe@777 510
universe@777 511 // string to be split is only substring
universe@777 512 n = cx_strsplit_a(alloc, test, CX_STR("this,is,a,csv,string,with,extension"), capa, &list);
universe@777 513 CX_TEST_ASSERT(n == 1);
universe@777 514 CX_TEST_ASSERT(0 == cx_strcmp(list[0], test));
universe@777 515 cxFree(alloc, list);
universe@777 516
universe@777 517 // subsequent encounter of delimiter (the string between is empty)
universe@777 518 n = cx_strsplit_a(alloc, test, CX_STR("is,"), capa, &list);
universe@777 519 CX_TEST_ASSERT(n == 3);
universe@777 520 CX_TEST_ASSERT(0 == cx_strcmp(list[0], CX_STR("th")));
universe@777 521 CX_TEST_ASSERT(0 == cx_strcmp(list[1], CX_STR("")));
universe@777 522 CX_TEST_ASSERT(0 == cx_strcmp(list[2], CX_STR("a,csv,string")));
universe@777 523 cxFree(alloc, list);
universe@777 524
universe@777 525 // call the _m variant just for coverage
universe@777 526 cxmutstr mtest = cx_strdup(test);
universe@777 527 cxmutstr *mlist;
universe@777 528 n = cx_strsplit_ma(alloc, mtest, CX_STR("is,"), 4, &mlist);
universe@777 529 CX_TEST_ASSERT(n == 3);
universe@777 530 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[0]), CX_STR("th")));
universe@777 531 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[1]), CX_STR("")));
universe@777 532 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(mlist[2]), CX_STR("a,csv,string")));
universe@777 533 cxFree(alloc, mlist);
universe@777 534 cx_strfree(&mtest);
universe@777 535
universe@777 536 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@777 537 }
universe@777 538 cx_testing_allocator_destroy(&talloc);
universe@777 539 }
universe@777 540
universe@777 541 CX_TEST(test_strtrim) {
universe@777 542 cxstring t1 = cx_strtrim(CX_STR(" ein test \t "));
universe@777 543 cxstring t2 = cx_strtrim(CX_STR("abc"));
universe@777 544 cxstring t3 = cx_strtrim(CX_STR(" 123"));
universe@777 545 cxstring t4 = cx_strtrim(CX_STR("xyz "));
universe@777 546 cxstring t5 = cx_strtrim(CX_STR(" "));
universe@777 547 cxstring empty = cx_strtrim(CX_STR(""));
universe@777 548
universe@777 549 CX_TEST_DO {
universe@777 550 CX_TEST_ASSERT(0 == cx_strcmp(t1, CX_STR("ein test")));
universe@777 551 CX_TEST_ASSERT(0 == cx_strcmp(t2, CX_STR("abc")));
universe@777 552 CX_TEST_ASSERT(0 == cx_strcmp(t3, CX_STR("123")));
universe@777 553 CX_TEST_ASSERT(0 == cx_strcmp(t4, CX_STR("xyz")));
universe@777 554 CX_TEST_ASSERT(0 == cx_strcmp(t5, CX_STR("")));
universe@777 555 CX_TEST_ASSERT(0 == cx_strcmp(empty, CX_STR("")));
universe@777 556
universe@777 557 // call the _m variant just for coverage
universe@777 558 cxmutstr m1 = cx_strtrim_m(cx_mutstr((char *) " ein test \t "));
universe@777 559 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(m1), CX_STR("ein test")));
universe@777 560 }
universe@777 561 }
universe@777 562
universe@777 563 CX_TEST(test_strprefix) {
universe@777 564 cxstring str = CX_STR("test my prefix and my suffix");
universe@777 565 cxstring empty = CX_STR("");
universe@777 566 CX_TEST_DO {
universe@777 567 CX_TEST_ASSERT(!cx_strprefix(empty, CX_STR("pref")));
universe@777 568 CX_TEST_ASSERT(cx_strprefix(str, empty));
universe@777 569 CX_TEST_ASSERT(cx_strprefix(empty, empty));
universe@777 570 CX_TEST_ASSERT(cx_strprefix(str, CX_STR("test ")));
universe@777 571 CX_TEST_ASSERT(!cx_strprefix(str, CX_STR("8-) fsck ")));
universe@777 572 }
universe@777 573 }
universe@777 574
universe@777 575 CX_TEST(test_strsuffix) {
universe@777 576 cxstring str = CX_STR("test my prefix and my suffix");
universe@777 577 cxstring empty = CX_STR("");
universe@777 578 CX_TEST_DO {
universe@777 579 CX_TEST_ASSERT(!cx_strsuffix(empty, CX_STR("suf")));
universe@777 580 CX_TEST_ASSERT(cx_strsuffix(str, empty));
universe@777 581 CX_TEST_ASSERT(cx_strsuffix(empty, empty));
universe@777 582 CX_TEST_ASSERT(cx_strsuffix(str, CX_STR("fix")));
universe@777 583 CX_TEST_ASSERT(!cx_strsuffix(str, CX_STR("fox")));
universe@777 584 }
universe@777 585 }
universe@777 586
universe@777 587 CX_TEST(test_strcaseprefix) {
universe@777 588 cxstring str = CX_STR("test my prefix and my suffix");
universe@777 589 cxstring empty = CX_STR("");
universe@777 590 CX_TEST_DO {
universe@777 591 CX_TEST_ASSERT(!cx_strcaseprefix(empty, CX_STR("pREf")));
universe@777 592 CX_TEST_ASSERT(cx_strcaseprefix(str, empty));
universe@777 593 CX_TEST_ASSERT(cx_strcaseprefix(empty, empty));
universe@777 594 CX_TEST_ASSERT(cx_strcaseprefix(str, CX_STR("TEST ")));
universe@777 595 CX_TEST_ASSERT(!cx_strcaseprefix(str, CX_STR("8-) fsck ")));
universe@777 596 }
universe@777 597 }
universe@777 598
universe@777 599 CX_TEST(test_strcasesuffix) {
universe@777 600 cxstring str = CX_STR("test my prefix and my suffix");
universe@777 601 cxstring empty = CX_STR("");
universe@777 602 CX_TEST_DO {
universe@777 603 CX_TEST_ASSERT(!cx_strcasesuffix(empty, CX_STR("sUf")));
universe@777 604 CX_TEST_ASSERT(cx_strcasesuffix(str, empty));
universe@777 605 CX_TEST_ASSERT(cx_strcasesuffix(empty, empty));
universe@777 606 CX_TEST_ASSERT(cx_strcasesuffix(str, CX_STR("FIX")));
universe@777 607 CX_TEST_ASSERT(!cx_strcasesuffix(str, CX_STR("fox")));
universe@777 608 }
universe@777 609 }
universe@777 610
universe@777 611 CX_TEST(test_strreplace) {
universe@777 612 CxTestingAllocator talloc;
universe@777 613 cx_testing_allocator_init(&talloc);
universe@777 614 CxAllocator *alloc = &talloc.base;
universe@777 615
universe@777 616 cxstring str = CX_STR("test ababab string aba");
universe@777 617 cxstring longstr = CX_STR(
universe@777 618 "xyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacd");
universe@777 619 cxstring notrail = CX_STR("test abab");
universe@777 620 cxstring empty = CX_STR("");
universe@777 621 cxstring astr = CX_STR("aaaaaaaaaa");
universe@777 622 cxstring csstr = CX_STR("test AB ab TEST xyz");
universe@777 623
universe@777 624 cxmutstr repl = cx_strreplace(str, CX_STR("abab"), CX_STR("muchlonger"));
universe@777 625 char const *expected = "test muchlongerab string aba";
universe@777 626
universe@777 627 cxmutstr repln = cx_strreplacen(str, CX_STR("ab"), CX_STR("c"), 2);
universe@777 628 char const *expectedn = "test ccab string aba";
universe@777 629
universe@777 630 cxmutstr longrepl = cx_strreplace(longstr, CX_STR("a"), CX_STR("z"));
universe@777 631 char const *longexpect = "xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzcd";
universe@777 632
universe@777 633 cxmutstr replnotrail = cx_strreplace(notrail, CX_STR("ab"), CX_STR("z"));
universe@777 634 char const *notrailexpect = "test zz";
universe@777 635
universe@777 636 cxmutstr repleq = cx_strreplace(str, str, CX_STR("hello"));
universe@777 637 char const *eqexpect = "hello";
universe@777 638
universe@777 639 cxmutstr replempty1 = cx_strreplace(empty, CX_STR("ab"), CX_STR("c")); // expect: empty
universe@777 640 cxmutstr replempty2 = cx_strreplace(str, CX_STR("abab"), empty);
universe@777 641 char const *emptyexpect2 = "test ab string aba";
universe@777 642
universe@777 643 cxmutstr replpre = cx_strreplace(str, CX_STR("test "), CX_STR("TEST "));
universe@777 644 char const *preexpected = "TEST ababab string aba";
universe@777 645
universe@777 646 cxmutstr replan1 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 1);
universe@777 647 char const *an1expected = "xaaaaaaaaa";
universe@777 648
universe@777 649 cxmutstr replan4 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 4);
universe@777 650 char const *an4expected = "xxxxaaaaaa";
universe@777 651
universe@777 652 cxmutstr replan9 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 9);
universe@777 653 char const *an9expected = "xxxxxxxxxa";
universe@777 654
universe@777 655 cxmutstr replan10 = cx_strreplacen(astr, CX_STR("a"), CX_STR("x"), 10);
universe@777 656 char const *an10expected = "xxxxxxxxxx";
universe@777 657
universe@777 658 CX_TEST_DO {
universe@777 659 cxmutstr repl1_a = cx_strreplace_a(alloc, csstr, CX_STR("AB"), CX_STR("*"));
universe@777 660 char const *expeced1_a = "test * ab TEST xyz";
universe@777 661
universe@777 662 cxmutstr repl2_a = cx_strreplace_a(alloc, csstr, CX_STR("test"), CX_STR("TEST"));
universe@777 663 char const *expected2_a = "TEST AB ab TEST xyz";
universe@777 664
universe@777 665 CX_TEST_ASSERT(repl.ptr != str.ptr);
universe@777 666 ASSERT_ZERO_TERMINATED(repl);
universe@777 667 CX_TEST_ASSERT(0 == strcmp(repl.ptr, expected));
universe@777 668 ASSERT_ZERO_TERMINATED(repln);
universe@777 669 CX_TEST_ASSERT(0 == strcmp(repln.ptr, expectedn));
universe@777 670 ASSERT_ZERO_TERMINATED(longrepl);
universe@777 671 CX_TEST_ASSERT(0 == strcmp(longrepl.ptr, longexpect));
universe@777 672 ASSERT_ZERO_TERMINATED(replnotrail);
universe@777 673 CX_TEST_ASSERT(0 == strcmp(replnotrail.ptr, notrailexpect));
universe@777 674 ASSERT_ZERO_TERMINATED(repleq);
universe@777 675 CX_TEST_ASSERT(0 == strcmp(repleq.ptr, eqexpect));
universe@777 676 ASSERT_ZERO_TERMINATED(replempty1);
universe@777 677 CX_TEST_ASSERT(0 == strcmp(replempty1.ptr, ""));
universe@777 678 ASSERT_ZERO_TERMINATED(replempty2);
universe@777 679 CX_TEST_ASSERT(0 == strcmp(replempty2.ptr, emptyexpect2));
universe@777 680 ASSERT_ZERO_TERMINATED(replpre);
universe@777 681 CX_TEST_ASSERT(0 == strcmp(replpre.ptr, preexpected));
universe@777 682 ASSERT_ZERO_TERMINATED(replan1);
universe@777 683 CX_TEST_ASSERT(0 == strcmp(replan1.ptr, an1expected));
universe@777 684 ASSERT_ZERO_TERMINATED(replan4);
universe@777 685 CX_TEST_ASSERT(0 == strcmp(replan4.ptr, an4expected));
universe@777 686 ASSERT_ZERO_TERMINATED(replan9);
universe@777 687 CX_TEST_ASSERT(0 == strcmp(replan9.ptr, an9expected));
universe@777 688 ASSERT_ZERO_TERMINATED(replan10);
universe@777 689 CX_TEST_ASSERT(0 == strcmp(replan10.ptr, an10expected));
universe@777 690 ASSERT_ZERO_TERMINATED(repl1_a);
universe@777 691 CX_TEST_ASSERT(0 == strcmp(repl1_a.ptr, expeced1_a));
universe@777 692 ASSERT_ZERO_TERMINATED(repl2_a);
universe@777 693 CX_TEST_ASSERT(0 == strcmp(repl2_a.ptr, expected2_a));
universe@777 694
universe@777 695 cx_strfree_a(alloc, &repl1_a);
universe@777 696 cx_strfree_a(alloc, &repl2_a);
universe@777 697 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@777 698 }
universe@777 699
universe@777 700 cx_strfree(&repl);
universe@777 701 cx_strfree(&repln);
universe@777 702 cx_strfree(&longrepl);
universe@777 703 cx_strfree(&replnotrail);
universe@777 704 cx_strfree(&repleq);
universe@777 705 cx_strfree(&replempty1);
universe@777 706 cx_strfree(&replempty2);
universe@777 707 cx_strfree(&replpre);
universe@777 708 cx_strfree(&replan1);
universe@777 709 cx_strfree(&replan4);
universe@777 710 cx_strfree(&replan9);
universe@777 711 cx_strfree(&replan10);
universe@777 712 cx_testing_allocator_destroy(&talloc);
universe@777 713 }
universe@777 714
universe@777 715 CX_TEST(test_strupper) {
universe@777 716 cxmutstr str = cx_strdup(CX_STR("thIs 1s @ Te$t"));
universe@777 717 CX_TEST_DO {
universe@777 718 cx_strupper(str);
universe@777 719 CX_TEST_ASSERT(0 == strcmp(str.ptr, "THIS 1S @ TE$T"));
universe@777 720 }
universe@777 721 cx_strfree(&str);
universe@777 722 }
universe@777 723
universe@777 724 CX_TEST(test_strlower) {
universe@777 725 cxmutstr str = cx_strdup(CX_STR("thIs 1s @ Te$t"));
universe@777 726 CX_TEST_DO {
universe@777 727 cx_strlower(str);
universe@777 728 CX_TEST_ASSERT(0 == strcmp(str.ptr, "this 1s @ te$t"));
universe@777 729 }
universe@777 730 cx_strfree(&str);
universe@777 731 }
universe@777 732
universe@777 733 CX_TEST(test_strtok) {
universe@777 734 cxstring str = CX_STR("a,comma,separated,string");
universe@777 735 cxstring delim = CX_STR(",");
universe@777 736 CX_TEST_DO {
universe@777 737 CxStrtokCtx ctx = cx_strtok(str, delim, 3);
universe@777 738 CX_TEST_ASSERT(ctx.str.ptr == str.ptr);
universe@777 739 CX_TEST_ASSERT(ctx.str.length == str.length);
universe@777 740 CX_TEST_ASSERT(ctx.delim.ptr == delim.ptr);
universe@777 741 CX_TEST_ASSERT(ctx.delim.length == delim.length);
universe@777 742 CX_TEST_ASSERT(ctx.limit == 3);
universe@777 743 CX_TEST_ASSERT(ctx.found == 0);
universe@777 744 CX_TEST_ASSERT(ctx.pos == 0);
universe@777 745 CX_TEST_ASSERT(ctx.next_pos == 0);
universe@777 746 CX_TEST_ASSERT(ctx.delim_more == NULL);
universe@777 747 CX_TEST_ASSERT(ctx.delim_more_count == 0);
universe@777 748 }
universe@777 749 }
universe@777 750
universe@777 751 CX_TEST(test_strtok_m) {
universe@777 752 cxmutstr str = cx_strdup(CX_STR("a,comma,separated,string"));
universe@777 753 cxstring delim = CX_STR(",");
universe@777 754 CX_TEST_DO {
universe@777 755 CxStrtokCtx ctx = cx_strtok_m(str, delim, 3);
universe@777 756 CX_TEST_ASSERT(ctx.str.ptr == str.ptr);
universe@777 757 CX_TEST_ASSERT(ctx.str.length == str.length);
universe@777 758 CX_TEST_ASSERT(ctx.delim.ptr == delim.ptr);
universe@777 759 CX_TEST_ASSERT(ctx.delim.length == delim.length);
universe@777 760 CX_TEST_ASSERT(ctx.limit == 3);
universe@777 761 CX_TEST_ASSERT(ctx.found == 0);
universe@777 762 CX_TEST_ASSERT(ctx.pos == 0);
universe@777 763 CX_TEST_ASSERT(ctx.next_pos == 0);
universe@777 764 CX_TEST_ASSERT(ctx.delim_more == NULL);
universe@777 765 CX_TEST_ASSERT(ctx.delim_more_count == 0);
universe@777 766 }
universe@777 767 cx_strfree(&str);
universe@777 768 }
universe@777 769
universe@777 770 CX_TEST(test_strtok_delim) {
universe@777 771 cxstring str = CX_STR("an,arbitrarily|separated;string");
universe@777 772 cxstring delim = CX_STR(",");
universe@777 773 cxstring delim_more[2] = {CX_STR("|"), CX_STR(";")};
universe@777 774 CX_TEST_DO {
universe@777 775 CxStrtokCtx ctx = cx_strtok(str, delim, 3);
universe@777 776 cx_strtok_delim(&ctx, delim_more, 2);
universe@777 777 CX_TEST_ASSERT(ctx.str.ptr == str.ptr);
universe@777 778 CX_TEST_ASSERT(ctx.str.length == str.length);
universe@777 779 CX_TEST_ASSERT(ctx.delim.ptr == delim.ptr);
universe@777 780 CX_TEST_ASSERT(ctx.delim.length == delim.length);
universe@777 781 CX_TEST_ASSERT(ctx.limit == 3);
universe@777 782 CX_TEST_ASSERT(ctx.found == 0);
universe@777 783 CX_TEST_ASSERT(ctx.pos == 0);
universe@777 784 CX_TEST_ASSERT(ctx.next_pos == 0);
universe@777 785 CX_TEST_ASSERT(ctx.delim_more == delim_more);
universe@777 786 CX_TEST_ASSERT(ctx.delim_more_count == 2);
universe@777 787 }
universe@777 788 }
universe@777 789
universe@777 790 CX_TEST(test_strtok_next_easy) {
universe@777 791 cxstring str = CX_STR("a,comma,separated,string");
universe@777 792 cxstring delim = CX_STR(",");
universe@777 793 CX_TEST_DO {
universe@777 794 CxStrtokCtx ctx = cx_strtok(str, delim, 3);
universe@777 795 bool ret;
universe@777 796 cxstring tok;
universe@777 797
universe@777 798 ret = cx_strtok_next(&ctx, &tok);
universe@777 799 CX_TEST_ASSERT(ret);
universe@777 800 CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("a")));
universe@777 801 CX_TEST_ASSERT(ctx.pos == 0);
universe@777 802 CX_TEST_ASSERT(ctx.next_pos == 2);
universe@777 803 CX_TEST_ASSERT(ctx.delim_pos == 1);
universe@777 804 CX_TEST_ASSERT(ctx.found == 1);
universe@777 805
universe@777 806 ret = cx_strtok_next(&ctx, &tok);
universe@777 807 CX_TEST_ASSERT(ret);
universe@777 808 CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("comma")));
universe@777 809 CX_TEST_ASSERT(ctx.pos == 2);
universe@777 810 CX_TEST_ASSERT(ctx.next_pos == 8);
universe@777 811 CX_TEST_ASSERT(ctx.delim_pos == 7);
universe@777 812 CX_TEST_ASSERT(ctx.found == 2);
universe@777 813
universe@777 814 ret = cx_strtok_next(&ctx, &tok);
universe@777 815 CX_TEST_ASSERT(ret);
universe@777 816 CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("separated")));
universe@777 817 CX_TEST_ASSERT(ctx.pos == 8);
universe@777 818 CX_TEST_ASSERT(ctx.next_pos == 18);
universe@777 819 CX_TEST_ASSERT(ctx.delim_pos == 17);
universe@777 820 CX_TEST_ASSERT(ctx.found == 3);
universe@777 821
universe@777 822 ret = cx_strtok_next(&ctx, &tok);
universe@777 823 CX_TEST_ASSERT(!ret);
universe@777 824 CX_TEST_ASSERT(ctx.pos == 8);
universe@777 825 CX_TEST_ASSERT(ctx.next_pos == 18);
universe@777 826 CX_TEST_ASSERT(ctx.delim_pos == 17);
universe@777 827 CX_TEST_ASSERT(ctx.found == 3);
universe@777 828 }
universe@777 829 }
universe@777 830
universe@777 831 CX_TEST(test_strtok_next_unlimited) {
universe@777 832 cxstring str = CX_STR("some;-;otherwise;-;separated;-;string;-;");
universe@777 833 cxstring delim = CX_STR(";-;");
universe@777 834 CX_TEST_DO {
universe@777 835 CxStrtokCtx ctx = cx_strtok(str, delim, SIZE_MAX);
universe@777 836 bool ret;
universe@777 837 cxstring tok;
universe@777 838
universe@777 839 ret = cx_strtok_next(&ctx, &tok);
universe@777 840 CX_TEST_ASSERT(ret);
universe@777 841 CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("some")));
universe@777 842 CX_TEST_ASSERT(ctx.pos == 0);
universe@777 843 CX_TEST_ASSERT(ctx.next_pos == 7);
universe@777 844 CX_TEST_ASSERT(ctx.delim_pos == 4);
universe@777 845 CX_TEST_ASSERT(ctx.found == 1);
universe@777 846
universe@777 847 ret = cx_strtok_next(&ctx, &tok);
universe@777 848 CX_TEST_ASSERT(ret);
universe@777 849 CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("otherwise")));
universe@777 850 CX_TEST_ASSERT(ctx.pos == 7);
universe@777 851 CX_TEST_ASSERT(ctx.next_pos == 19);
universe@777 852 CX_TEST_ASSERT(ctx.delim_pos == 16);
universe@777 853 CX_TEST_ASSERT(ctx.found == 2);
universe@777 854
universe@777 855 ret = cx_strtok_next(&ctx, &tok);
universe@777 856 CX_TEST_ASSERT(ret);
universe@777 857 CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("separated")));
universe@777 858 CX_TEST_ASSERT(ctx.pos == 19);
universe@777 859 CX_TEST_ASSERT(ctx.next_pos == 31);
universe@777 860 CX_TEST_ASSERT(ctx.delim_pos == 28);
universe@777 861 CX_TEST_ASSERT(ctx.found == 3);
universe@777 862
universe@777 863 ret = cx_strtok_next(&ctx, &tok);
universe@777 864 CX_TEST_ASSERT(ret);
universe@777 865 CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("string")));
universe@777 866 CX_TEST_ASSERT(ctx.pos == 31);
universe@777 867 CX_TEST_ASSERT(ctx.next_pos == 40);
universe@777 868 CX_TEST_ASSERT(ctx.delim_pos == 37);
universe@777 869 CX_TEST_ASSERT(ctx.found == 4);
universe@777 870
universe@777 871 ret = cx_strtok_next(&ctx, &tok);
universe@777 872 CX_TEST_ASSERT(ret);
universe@777 873 CX_TEST_ASSERT(0 == cx_strcmp(tok, CX_STR("")));
universe@777 874 CX_TEST_ASSERT(ctx.pos == 40);
universe@777 875 CX_TEST_ASSERT(ctx.next_pos == 40);
universe@777 876 CX_TEST_ASSERT(ctx.delim_pos == 40);
universe@777 877 CX_TEST_ASSERT(ctx.found == 5);
universe@777 878
universe@777 879 ret = cx_strtok_next(&ctx, &tok);
universe@777 880 CX_TEST_ASSERT(!ret);
universe@777 881 CX_TEST_ASSERT(ctx.pos == 40);
universe@777 882 CX_TEST_ASSERT(ctx.delim_pos == 40);
universe@777 883 CX_TEST_ASSERT(ctx.found == 5);
universe@777 884 }
universe@777 885 }
universe@777 886
universe@777 887 CX_TEST(test_strtok_next_advanced) {
universe@777 888 cxmutstr str = cx_strdup(CX_STR("an,arbitrarily;||separated;string"));
universe@777 889 cxstring delim = CX_STR(",");
universe@777 890 cxstring delim_more[2] = {CX_STR("||"), CX_STR(";")};
universe@777 891 CX_TEST_DO {
universe@777 892 CxStrtokCtx ctx = cx_strtok_m(str, delim, 10);
universe@777 893 cx_strtok_delim(&ctx, delim_more, 2);
universe@777 894 bool ret;
universe@777 895 cxmutstr tok;
universe@777 896
universe@777 897 ret = cx_strtok_next_m(&ctx, &tok);
universe@777 898 CX_TEST_ASSERT(ret);
universe@777 899 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("an")));
universe@777 900 CX_TEST_ASSERT(ctx.pos == 0);
universe@777 901 CX_TEST_ASSERT(ctx.next_pos == 3);
universe@777 902 CX_TEST_ASSERT(ctx.delim_pos == 2);
universe@777 903 CX_TEST_ASSERT(ctx.found == 1);
universe@777 904 cx_strupper(tok);
universe@777 905
universe@777 906 ret = cx_strtok_next_m(&ctx, &tok);
universe@777 907 CX_TEST_ASSERT(ret);
universe@777 908 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("arbitrarily")));
universe@777 909 CX_TEST_ASSERT(ctx.pos == 3);
universe@777 910 CX_TEST_ASSERT(ctx.next_pos == 15);
universe@777 911 CX_TEST_ASSERT(ctx.delim_pos == 14);
universe@777 912 CX_TEST_ASSERT(ctx.found == 2);
universe@777 913 cx_strupper(tok);
universe@777 914
universe@777 915 ret = cx_strtok_next_m(&ctx, &tok);
universe@777 916 CX_TEST_ASSERT(ret);
universe@777 917 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("")));
universe@777 918 CX_TEST_ASSERT(ctx.pos == 15);
universe@777 919 CX_TEST_ASSERT(ctx.next_pos == 17);
universe@777 920 CX_TEST_ASSERT(ctx.delim_pos == 15);
universe@777 921 CX_TEST_ASSERT(ctx.found == 3);
universe@777 922 cx_strupper(tok);
universe@777 923
universe@777 924 ret = cx_strtok_next_m(&ctx, &tok);
universe@777 925 CX_TEST_ASSERT(ret);
universe@777 926 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("separated")));
universe@777 927 CX_TEST_ASSERT(ctx.pos == 17);
universe@777 928 CX_TEST_ASSERT(ctx.next_pos == 27);
universe@777 929 CX_TEST_ASSERT(ctx.delim_pos == 26);
universe@777 930 CX_TEST_ASSERT(ctx.found == 4);
universe@777 931 cx_strupper(tok);
universe@777 932
universe@777 933 ret = cx_strtok_next_m(&ctx, &tok);
universe@777 934 CX_TEST_ASSERT(ret);
universe@777 935 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(tok), CX_STR("string")));
universe@777 936 CX_TEST_ASSERT(ctx.pos == 27);
universe@777 937 CX_TEST_ASSERT(ctx.next_pos == 33);
universe@777 938 CX_TEST_ASSERT(ctx.delim_pos == 33);
universe@777 939 CX_TEST_ASSERT(ctx.found == 5);
universe@777 940 cx_strupper(tok);
universe@777 941
universe@777 942 ret = cx_strtok_next_m(&ctx, &tok);
universe@777 943 CX_TEST_ASSERT(!ret);
universe@777 944 CX_TEST_ASSERT(ctx.pos == 27);
universe@777 945 CX_TEST_ASSERT(ctx.next_pos == 33);
universe@777 946 CX_TEST_ASSERT(ctx.delim_pos == 33);
universe@777 947 CX_TEST_ASSERT(ctx.found == 5);
universe@777 948
universe@777 949 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(str), CX_STR("AN,ARBITRARILY;||SEPARATED;STRING")));
universe@777 950 }
universe@777 951 cx_strfree(&str);
universe@777 952 }
universe@777 953
universe@777 954
universe@777 955 CxTestSuite *cx_test_suite_string(void) {
universe@777 956 CxTestSuite *suite = cx_test_suite_new("string");
universe@777 957
universe@777 958 cx_test_register(suite, test_string_construct);
universe@777 959 cx_test_register(suite, test_strfree);
universe@777 960 cx_test_register(suite, test_strdup);
universe@777 961 cx_test_register(suite, test_strdup_shortened);
universe@777 962 cx_test_register(suite, test_strlen);
universe@777 963 cx_test_register(suite, test_strsubs);
universe@777 964 cx_test_register(suite, test_strchr);
universe@777 965 cx_test_register(suite, test_strrchr);
universe@777 966 cx_test_register(suite, test_strstr);
universe@777 967 cx_test_register(suite, test_strcmp);
universe@777 968 cx_test_register(suite, test_strcasecmp);
universe@777 969 cx_test_register(suite, test_strcat);
universe@777 970 cx_test_register(suite, test_strsplit);
universe@777 971 cx_test_register(suite, test_strsplit_a);
universe@777 972 cx_test_register(suite, test_strtrim);
universe@777 973 cx_test_register(suite, test_strprefix);
universe@777 974 cx_test_register(suite, test_strsuffix);
universe@777 975 cx_test_register(suite, test_strcaseprefix);
universe@777 976 cx_test_register(suite, test_strcasesuffix);
universe@777 977 cx_test_register(suite, test_strreplace);
universe@777 978 cx_test_register(suite, test_strupper);
universe@777 979 cx_test_register(suite, test_strlower);
universe@777 980 cx_test_register(suite, test_strtok);
universe@777 981 cx_test_register(suite, test_strtok_m);
universe@777 982 cx_test_register(suite, test_strtok_delim);
universe@777 983 cx_test_register(suite, test_strtok_next_easy);
universe@777 984 cx_test_register(suite, test_strtok_next_unlimited);
universe@777 985 cx_test_register(suite, test_strtok_next_advanced);
universe@777 986
universe@777 987 return suite;
universe@777 988 }

mercurial