1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tests/test_string.cpp Tue Feb 07 21:55:37 2023 +0100 1.3 @@ -0,0 +1,865 @@ 1.4 +/* 1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 1.6 + * 1.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions are met: 1.11 + * 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 1.15 + * 2. Redistributions in binary form must reproduce the above copyright 1.16 + * notice, this list of conditions and the following disclaimer in the 1.17 + * documentation and/or other materials provided with the distribution. 1.18 + * 1.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 1.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.29 + * POSSIBILITY OF SUCH DAMAGE. 1.30 + */ 1.31 + 1.32 +#include "cx/string.h" 1.33 +#include "util_allocator.h" 1.34 + 1.35 +#include <gtest/gtest.h> 1.36 + 1.37 +#define EXPECT_ZERO_TERMINATED(str) EXPECT_EQ((str).ptr[(str).length], '\0') 1.38 + 1.39 +TEST(String, construct) { 1.40 + cxstring s1 = cx_str("1234"); 1.41 + cxstring s2 = cx_strn("abcd", 2); 1.42 + cxmutstr s3 = cx_mutstr((char *) "1234"); 1.43 + cxmutstr s4 = cx_mutstrn((char *) "abcd", 2); 1.44 + 1.45 + EXPECT_EQ(s1.length, 4); 1.46 + EXPECT_EQ(s2.length, 2); 1.47 + EXPECT_EQ(s3.length, 4); 1.48 + EXPECT_EQ(s4.length, 2); 1.49 +} 1.50 + 1.51 +TEST(String, strfree) { 1.52 + CxTestingAllocator alloc; 1.53 + auto test = (char *) cxMalloc(&alloc, 16); 1.54 + cxmutstr str = cx_mutstrn(test, 16); 1.55 + ASSERT_EQ(str.ptr, test); 1.56 + EXPECT_EQ(str.length, 16); 1.57 + cx_strfree_a(&alloc, &str); 1.58 + EXPECT_EQ(str.ptr, nullptr); 1.59 + EXPECT_EQ(str.length, 0); 1.60 + EXPECT_TRUE(alloc.verify()); 1.61 +} 1.62 + 1.63 +TEST(String, strdup) { 1.64 + cxstring str = CX_STR("test"); 1.65 + cxmutstr dup = cx_strdup(str); 1.66 + ASSERT_EQ(dup.length, str.length); 1.67 + EXPECT_STREQ(dup.ptr, str.ptr); 1.68 + EXPECT_ZERO_TERMINATED(dup); 1.69 + cx_strfree(&dup); 1.70 + 1.71 + str.length = 2; 1.72 + dup = cx_strdup(str); 1.73 + ASSERT_EQ(dup.length, str.length); 1.74 + EXPECT_STREQ(dup.ptr, "te"); 1.75 + EXPECT_ZERO_TERMINATED(dup); 1.76 + cx_strfree(&dup); 1.77 +} 1.78 + 1.79 +TEST(String, strlen) { 1.80 + cxstring s1 = CX_STR("1234"); 1.81 + cxstring s2 = CX_STR(".:.:."); 1.82 + cxstring s3 = CX_STR("X"); 1.83 + 1.84 + size_t len0 = cx_strlen(0); 1.85 + size_t len1 = cx_strlen(1, s1); 1.86 + size_t len2 = cx_strlen(2, s1, s2); 1.87 + size_t len3 = cx_strlen(3, s1, s2, s3); 1.88 + 1.89 + EXPECT_EQ(len0, 0); 1.90 + EXPECT_EQ(len1, 4); 1.91 + EXPECT_EQ(len2, 9); 1.92 + EXPECT_EQ(len3, 10); 1.93 +} 1.94 + 1.95 +TEST(String, strsubs) { 1.96 + cxstring str = CX_STR("A test string"); 1.97 + 1.98 + cxstring sub = cx_strsubs(str, 0); 1.99 + EXPECT_EQ(cx_strcmp(sub, str), 0); 1.100 + 1.101 + sub = cx_strsubs(str, 2); 1.102 + EXPECT_EQ(cx_strcmp(sub, cx_str("test string")), 0); 1.103 + 1.104 + sub = cx_strsubs(str, 7); 1.105 + EXPECT_EQ(cx_strcmp(sub, cx_str("string")), 0); 1.106 + 1.107 + sub = cx_strsubs(str, 15); 1.108 + EXPECT_EQ(cx_strcmp(sub, cx_str("")), 0); 1.109 + 1.110 + sub = cx_strsubsl(str, 2, 4); 1.111 + EXPECT_EQ(cx_strcmp(sub, cx_str("test")), 0); 1.112 + 1.113 + sub = cx_strsubsl(str, 7, 3); 1.114 + EXPECT_EQ(cx_strcmp(sub, cx_str("str")), 0); 1.115 + 1.116 + sub = cx_strsubsl(str, 7, 20); 1.117 + EXPECT_EQ(cx_strcmp(sub, cx_str("string")), 0); 1.118 + 1.119 + // just for coverage, call the _m variant 1.120 + auto m = cx_strsubs_m(cx_mutstrn(nullptr, 0), 0); 1.121 + EXPECT_EQ(cx_strcmp(cx_strcast(m), cx_str("")), 0); 1.122 +} 1.123 + 1.124 +TEST(String, strchr) { 1.125 + cxstring str = CX_STR("I will find you - and I will kill you"); 1.126 + 1.127 + cxstring notfound = cx_strchr(str, 'x'); 1.128 + EXPECT_EQ(notfound.length, 0); 1.129 + 1.130 + cxstring result = cx_strchr(str, 'w'); 1.131 + EXPECT_EQ(result.length, 35); 1.132 + EXPECT_STREQ(result.ptr, "will find you - and I will kill you"); 1.133 + 1.134 + // just for coverage, call the _m variant 1.135 + auto m = cx_strchr_m(cx_mutstrn(nullptr, 0), 'a'); 1.136 + EXPECT_EQ(cx_strcmp(cx_strcast(m), cx_str("")), 0); 1.137 +} 1.138 + 1.139 +TEST(String, strrchr) { 1.140 + cxstring str = CX_STR("I will find you - and I will kill you"); 1.141 + 1.142 + cxstring notfound = cx_strrchr(str, 'x'); 1.143 + EXPECT_EQ(notfound.length, 0); 1.144 + 1.145 + cxstring result = cx_strrchr(str, 'w'); 1.146 + EXPECT_EQ(result.length, 13); 1.147 + EXPECT_STREQ(result.ptr, "will kill you"); 1.148 + 1.149 + // just for coverage, call the _m variant 1.150 + auto m = cx_strrchr_m(cx_mutstrn(nullptr, 0), 'a'); 1.151 + EXPECT_EQ(cx_strcmp(cx_strcast(m), cx_str("")), 0); 1.152 +} 1.153 + 1.154 +TEST(String, strstr) { 1.155 + cxstring str = CX_STR("find the match in this string"); 1.156 + cxstring longstr = CX_STR( 1.157 + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl" 1.158 + "mnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx" 1.159 + "yzabcdeababababnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij" 1.160 + "klmnopqrstuvwxyzaababababababababrstuvwxyzabcdefghijklmnopqrstuv" 1.161 + "abababababababababababababababababababababababababababababababab" 1.162 + "abababababababababababababababababababababababababababababababab" 1.163 + "abababababababababababababababababababababababababababababababab" 1.164 + "abababababababababababababababababababababababababababababababab" 1.165 + "abababababababababababababababababababababababababababababababab" 1.166 + "abababababababababababababababababababababababababababababababab" 1.167 + "wxyz1234567890"); 1.168 + cxstring longstrpattern = CX_STR( 1.169 + "abababababababababababababababababababababababababababababababab" 1.170 + "abababababababababababababababababababababababababababababababab" 1.171 + "abababababababababababababababababababababababababababababababab" 1.172 + "abababababababababababababababababababababababababababababababab" 1.173 + "abababababababababababababababababababababababababababababababab" 1.174 + ); 1.175 + cxstring longstrresult = CX_STR( 1.176 + "abababababababababababababababababababababababababababababababab" 1.177 + "abababababababababababababababababababababababababababababababab" 1.178 + "abababababababababababababababababababababababababababababababab" 1.179 + "abababababababababababababababababababababababababababababababab" 1.180 + "abababababababababababababababababababababababababababababababab" 1.181 + "abababababababababababababababababababababababababababababababab" 1.182 + "wxyz1234567890" 1.183 + ); 1.184 + 1.185 + cxstring notfound = cx_strstr(str, cx_str("no match")); 1.186 + EXPECT_EQ(notfound.length, 0); 1.187 + 1.188 + cxstring result = cx_strstr(str, cx_str("match")); 1.189 + EXPECT_EQ(result.length, 20); 1.190 + EXPECT_STREQ(result.ptr, "match in this string"); 1.191 + 1.192 + result = cx_strstr(str, cx_str("")); 1.193 + EXPECT_EQ(result.length, str.length); 1.194 + EXPECT_STREQ(result.ptr, str.ptr); 1.195 + 1.196 + result = cx_strstr(longstr, longstrpattern); 1.197 + EXPECT_EQ(result.length, longstrresult.length); 1.198 + EXPECT_STREQ(result.ptr, longstrresult.ptr); 1.199 + 1.200 + // just for coverage, call the _m variant 1.201 + auto mstr = cx_strdup(longstr); 1.202 + auto m = cx_strstr_m(mstr, longstrpattern); 1.203 + EXPECT_EQ(m.length, longstrresult.length); 1.204 + EXPECT_STREQ(m.ptr, longstrresult.ptr); 1.205 + cx_strfree(&mstr); 1.206 +} 1.207 + 1.208 +TEST(String, strcmp) { 1.209 + cxstring str = CX_STR("compare this"); 1.210 + 1.211 + EXPECT_EQ(cx_strcmp(cx_str(""), cx_str("")), 0); 1.212 + EXPECT_GT(cx_strcmp(str, cx_str("")), 0); 1.213 + EXPECT_EQ(cx_strcmp(str, cx_str("compare this")), 0); 1.214 + EXPECT_NE(cx_strcmp(str, cx_str("Compare This")), 0); 1.215 + EXPECT_LT(cx_strcmp(str, cx_str("compare tool")), 0); 1.216 + EXPECT_GT(cx_strcmp(str, cx_str("compare shit")), 0); 1.217 + EXPECT_LT(cx_strcmp(str, cx_str("compare this not")), 0); 1.218 + EXPECT_GT(cx_strcmp(str, cx_str("compare")), 0); 1.219 +} 1.220 + 1.221 +TEST(String, strcasecmp) { 1.222 + cxstring str = CX_STR("compare this"); 1.223 + 1.224 + EXPECT_EQ(cx_strcasecmp(cx_str(""), cx_str("")), 0); 1.225 + EXPECT_GT(cx_strcasecmp(str, cx_str("")), 0); 1.226 + EXPECT_EQ(cx_strcasecmp(str, cx_str("compare this")), 0); 1.227 + EXPECT_EQ(cx_strcasecmp(str, cx_str("Compare This")), 0); 1.228 + EXPECT_LT(cx_strcasecmp(str, cx_str("compare tool")), 0); 1.229 + EXPECT_GT(cx_strcasecmp(str, cx_str("compare shit")), 0); 1.230 + EXPECT_LT(cx_strcasecmp(str, cx_str("compare this not")), 0); 1.231 + EXPECT_GT(cx_strcasecmp(str, cx_str("compare")), 0); 1.232 +} 1.233 + 1.234 +TEST(String, strcat) { 1.235 + cxstring s1 = CX_STR("12"); 1.236 + cxstring s2 = CX_STR("34"); 1.237 + cxstring s3 = CX_STR("56"); 1.238 + cxstring sn = {nullptr, 0}; 1.239 + 1.240 + CxTestingAllocator alloc; 1.241 + 1.242 + cxmutstr t1 = cx_strcat_a(&alloc, 2, s1, s2); 1.243 + EXPECT_EQ(cx_strcmp(cx_strcast(t1), cx_str("1234")), 0); 1.244 + EXPECT_ZERO_TERMINATED(t1); 1.245 + cx_strfree_a(&alloc, &t1); 1.246 + 1.247 + cxmutstr t2 = cx_strcat_a(&alloc, 3, s1, s2, s3); 1.248 + EXPECT_EQ(cx_strcmp(cx_strcast(t2), cx_str("123456")), 0); 1.249 + EXPECT_ZERO_TERMINATED(t2); 1.250 + cx_strfree_a(&alloc, &t2); 1.251 + 1.252 + cxmutstr t3 = cx_strcat_a(&alloc, 6, s1, sn, s2, sn, s3, sn); 1.253 + EXPECT_EQ(cx_strcmp(cx_strcast(t3), cx_str("123456")), 0); 1.254 + EXPECT_ZERO_TERMINATED(t3); 1.255 + cx_strfree_a(&alloc, &t3); 1.256 + 1.257 + cxmutstr t4 = cx_strcat_a(&alloc, 2, sn, sn); 1.258 + EXPECT_EQ(cx_strcmp(cx_strcast(t4), cx_str("")), 0); 1.259 + EXPECT_ZERO_TERMINATED(t4); 1.260 + cx_strfree_a(&alloc, &t4); 1.261 + 1.262 + EXPECT_TRUE(alloc.verify()); 1.263 + 1.264 + // use the macro 1.265 + cxmutstr t5 = cx_strcat(3, s3, s1, s2); 1.266 + EXPECT_EQ(cx_strcmp(cx_strcast(t5), cx_str("561234")), 0); 1.267 + EXPECT_ZERO_TERMINATED(t5); 1.268 + cx_strfree(&t5); 1.269 +} 1.270 + 1.271 +TEST(String, strsplit) { 1.272 + 1.273 + cxstring test = cx_str("this,is,a,csv,string"); 1.274 + size_t capa = 8; 1.275 + cxstring list[8]; 1.276 + size_t n; 1.277 + 1.278 + // special case: empty string 1.279 + n = cx_strsplit(test, cx_str(""), capa, list); 1.280 + ASSERT_EQ(n, 1); 1.281 + EXPECT_EQ(cx_strcmp(list[0], test), 0); 1.282 + 1.283 + // no delimiter occurrence 1.284 + n = cx_strsplit(test, cx_str("z"), capa, list); 1.285 + ASSERT_EQ(n, 1); 1.286 + EXPECT_EQ(cx_strcmp(list[0], test), 0); 1.287 + 1.288 + // partially matching delimiter 1.289 + n = cx_strsplit(test, cx_str("is,not"), capa, list); 1.290 + ASSERT_EQ(n, 1); 1.291 + EXPECT_EQ(cx_strcmp(list[0], test), 0); 1.292 + 1.293 + // matching single-char delimiter 1.294 + n = cx_strsplit(test, cx_str(","), capa, list); 1.295 + ASSERT_EQ(n, 5); 1.296 + EXPECT_EQ(cx_strcmp(list[0], cx_str("this")), 0); 1.297 + EXPECT_EQ(cx_strcmp(list[1], cx_str("is")), 0); 1.298 + EXPECT_EQ(cx_strcmp(list[2], cx_str("a")), 0); 1.299 + EXPECT_EQ(cx_strcmp(list[3], cx_str("csv")), 0); 1.300 + EXPECT_EQ(cx_strcmp(list[4], cx_str("string")), 0); 1.301 + 1.302 + // matching multi-char delimiter 1.303 + n = cx_strsplit(test, cx_str("is"), capa, list); 1.304 + ASSERT_EQ(n, 3); 1.305 + EXPECT_EQ(cx_strcmp(list[0], cx_str("th")), 0); 1.306 + EXPECT_EQ(cx_strcmp(list[1], cx_str(",")), 0); 1.307 + EXPECT_EQ(cx_strcmp(list[2], cx_str(",a,csv,string")), 0); 1.308 + 1.309 + // bounded list using single-char delimiter 1.310 + n = cx_strsplit(test, cx_str(","), 3, list); 1.311 + ASSERT_EQ(n, 3); 1.312 + EXPECT_EQ(cx_strcmp(list[0], cx_str("this")), 0); 1.313 + EXPECT_EQ(cx_strcmp(list[1], cx_str("is")), 0); 1.314 + EXPECT_EQ(cx_strcmp(list[2], cx_str("a,csv,string")), 0); 1.315 + 1.316 + // bounded list using multi-char delimiter 1.317 + n = cx_strsplit(test, cx_str("is"), 2, list); 1.318 + ASSERT_EQ(n, 2); 1.319 + EXPECT_EQ(cx_strcmp(list[0], cx_str("th")), 0); 1.320 + EXPECT_EQ(cx_strcmp(list[1], cx_str(",is,a,csv,string")), 0); 1.321 + 1.322 + // start with delimiter 1.323 + n = cx_strsplit(test, cx_str("this"), capa, list); 1.324 + ASSERT_EQ(n, 2); 1.325 + EXPECT_EQ(cx_strcmp(list[0], cx_str("")), 0); 1.326 + EXPECT_EQ(cx_strcmp(list[1], cx_str(",is,a,csv,string")), 0); 1.327 + 1.328 + // end with delimiter 1.329 + n = cx_strsplit(test, cx_str("string"), capa, list); 1.330 + ASSERT_EQ(n, 2); 1.331 + EXPECT_EQ(cx_strcmp(list[0], cx_str("this,is,a,csv,")), 0); 1.332 + EXPECT_EQ(cx_strcmp(list[1], cx_str("")), 0); 1.333 + 1.334 + 1.335 + // end with delimiter exceed bound 1.336 + n = cx_strsplit(cx_str("a,b,c,"), cx_str(","), 3, list); 1.337 + ASSERT_EQ(n, 3); 1.338 + EXPECT_EQ(cx_strcmp(list[0], cx_str("a")), 0); 1.339 + EXPECT_EQ(cx_strcmp(list[1], cx_str("b")), 0); 1.340 + EXPECT_EQ(cx_strcmp(list[2], cx_str("c,")), 0); 1.341 + 1.342 + // exact match 1.343 + n = cx_strsplit(test, cx_str("this,is,a,csv,string"), capa, list); 1.344 + ASSERT_EQ(n, 2); 1.345 + EXPECT_EQ(cx_strcmp(list[0], cx_str("")), 0); 1.346 + EXPECT_EQ(cx_strcmp(list[1], cx_str("")), 0); 1.347 + 1.348 + // string to be split is only substring 1.349 + n = cx_strsplit(test, cx_str("this,is,a,csv,string,with,extension"), capa, list); 1.350 + ASSERT_EQ(n, 1); 1.351 + EXPECT_EQ(cx_strcmp(list[0], test), 0); 1.352 + 1.353 + // subsequent encounter of delimiter (the string between is empty) 1.354 + n = cx_strsplit(test, cx_str("is,"), capa, list); 1.355 + ASSERT_EQ(n, 3); 1.356 + EXPECT_EQ(cx_strcmp(list[0], cx_str("th")), 0); 1.357 + EXPECT_EQ(cx_strcmp(list[1], cx_str("")), 0); 1.358 + EXPECT_EQ(cx_strcmp(list[2], cx_str("a,csv,string")), 0); 1.359 + 1.360 + // call the _m variant just for coverage 1.361 + auto mtest = cx_strdup(test); 1.362 + cxmutstr mlist[4]; 1.363 + n = cx_strsplit_m(mtest, cx_str("is,"), 4, mlist); 1.364 + ASSERT_EQ(n, 3); 1.365 + EXPECT_EQ(cx_strcmp(cx_strcast(mlist[0]), cx_str("th")), 0); 1.366 + EXPECT_EQ(cx_strcmp(cx_strcast(mlist[1]), cx_str("")), 0); 1.367 + EXPECT_EQ(cx_strcmp(cx_strcast(mlist[2]), cx_str("a,csv,string")), 0); 1.368 + cx_strfree(&mtest); 1.369 +} 1.370 + 1.371 +TEST(String, strsplit_a) { 1.372 + CxTestingAllocator alloc; 1.373 + 1.374 + cxstring test = cx_str("this,is,a,csv,string"); 1.375 + size_t capa = 8; 1.376 + cxstring *list; 1.377 + size_t n; 1.378 + 1.379 + // special case: empty string 1.380 + n = cx_strsplit_a(&alloc, test, cx_str(""), capa, &list); 1.381 + ASSERT_EQ(n, 1); 1.382 + EXPECT_EQ(cx_strcmp(list[0], test), 0); 1.383 + cxFree(&alloc, list); 1.384 + 1.385 + // no delimiter occurrence 1.386 + n = cx_strsplit_a(&alloc, test, cx_str("z"), capa, &list); 1.387 + ASSERT_EQ(n, 1); 1.388 + EXPECT_EQ(cx_strcmp(list[0], test), 0); 1.389 + cxFree(&alloc, list); 1.390 + 1.391 + // partially matching delimiter 1.392 + n = cx_strsplit_a(&alloc, test, cx_str("is,not"), capa, &list); 1.393 + ASSERT_EQ(n, 1); 1.394 + EXPECT_EQ(cx_strcmp(list[0], test), 0); 1.395 + cxFree(&alloc, list); 1.396 + 1.397 + // matching single-char delimiter 1.398 + n = cx_strsplit_a(&alloc, test, cx_str(","), capa, &list); 1.399 + ASSERT_EQ(n, 5); 1.400 + EXPECT_EQ(cx_strcmp(list[0], cx_str("this")), 0); 1.401 + EXPECT_EQ(cx_strcmp(list[1], cx_str("is")), 0); 1.402 + EXPECT_EQ(cx_strcmp(list[2], cx_str("a")), 0); 1.403 + EXPECT_EQ(cx_strcmp(list[3], cx_str("csv")), 0); 1.404 + EXPECT_EQ(cx_strcmp(list[4], cx_str("string")), 0); 1.405 + cxFree(&alloc, list); 1.406 + 1.407 + // matching multi-char delimiter 1.408 + n = cx_strsplit_a(&alloc, test, cx_str("is"), capa, &list); 1.409 + ASSERT_EQ(n, 3); 1.410 + EXPECT_EQ(cx_strcmp(list[0], cx_str("th")), 0); 1.411 + EXPECT_EQ(cx_strcmp(list[1], cx_str(",")), 0); 1.412 + EXPECT_EQ(cx_strcmp(list[2], cx_str(",a,csv,string")), 0); 1.413 + cxFree(&alloc, list); 1.414 + 1.415 + // bounded list using single-char delimiter 1.416 + n = cx_strsplit_a(&alloc, test, cx_str(","), 3, &list); 1.417 + ASSERT_EQ(n, 3); 1.418 + EXPECT_EQ(cx_strcmp(list[0], cx_str("this")), 0); 1.419 + EXPECT_EQ(cx_strcmp(list[1], cx_str("is")), 0); 1.420 + EXPECT_EQ(cx_strcmp(list[2], cx_str("a,csv,string")), 0); 1.421 + cxFree(&alloc, list); 1.422 + 1.423 + // bounded list using multi-char delimiter 1.424 + n = cx_strsplit_a(&alloc, test, cx_str("is"), 2, &list); 1.425 + ASSERT_EQ(n, 2); 1.426 + EXPECT_EQ(cx_strcmp(list[0], cx_str("th")), 0); 1.427 + EXPECT_EQ(cx_strcmp(list[1], cx_str(",is,a,csv,string")), 0); 1.428 + cxFree(&alloc, list); 1.429 + 1.430 + // start with delimiter 1.431 + n = cx_strsplit_a(&alloc, test, cx_str("this"), capa, &list); 1.432 + ASSERT_EQ(n, 2); 1.433 + EXPECT_EQ(cx_strcmp(list[0], cx_str("")), 0); 1.434 + EXPECT_EQ(cx_strcmp(list[1], cx_str(",is,a,csv,string")), 0); 1.435 + cxFree(&alloc, list); 1.436 + 1.437 + // end with delimiter 1.438 + n = cx_strsplit_a(&alloc, test, cx_str("string"), capa, &list); 1.439 + ASSERT_EQ(n, 2); 1.440 + EXPECT_EQ(cx_strcmp(list[0], cx_str("this,is,a,csv,")), 0); 1.441 + EXPECT_EQ(cx_strcmp(list[1], cx_str("")), 0); 1.442 + cxFree(&alloc, list); 1.443 + 1.444 + // end with delimiter exceed bound 1.445 + n = cx_strsplit_a(&alloc, cx_str("a,b,c,"), cx_str(","), 3, &list); 1.446 + ASSERT_EQ(n, 3); 1.447 + EXPECT_EQ(cx_strcmp(list[0], cx_str("a")), 0); 1.448 + EXPECT_EQ(cx_strcmp(list[1], cx_str("b")), 0); 1.449 + EXPECT_EQ(cx_strcmp(list[2], cx_str("c,")), 0); 1.450 + cxFree(&alloc, list); 1.451 + 1.452 + // exact match 1.453 + n = cx_strsplit_a(&alloc, test, cx_str("this,is,a,csv,string"), capa, &list); 1.454 + ASSERT_EQ(n, 2); 1.455 + EXPECT_EQ(cx_strcmp(list[0], cx_str("")), 0); 1.456 + EXPECT_EQ(cx_strcmp(list[1], cx_str("")), 0); 1.457 + cxFree(&alloc, list); 1.458 + 1.459 + // string to be split is only substring 1.460 + n = cx_strsplit_a(&alloc, test, cx_str("this,is,a,csv,string,with,extension"), capa, &list); 1.461 + ASSERT_EQ(n, 1); 1.462 + EXPECT_EQ(cx_strcmp(list[0], test), 0); 1.463 + cxFree(&alloc, list); 1.464 + 1.465 + // subsequent encounter of delimiter (the string between is empty) 1.466 + n = cx_strsplit_a(&alloc, test, cx_str("is,"), capa, &list); 1.467 + ASSERT_EQ(n, 3); 1.468 + EXPECT_EQ(cx_strcmp(list[0], cx_str("th")), 0); 1.469 + EXPECT_EQ(cx_strcmp(list[1], cx_str("")), 0); 1.470 + EXPECT_EQ(cx_strcmp(list[2], cx_str("a,csv,string")), 0); 1.471 + cxFree(&alloc, list); 1.472 + 1.473 + // call the _m variant just for coverage 1.474 + auto mtest = cx_strdup(test); 1.475 + cxmutstr *mlist; 1.476 + n = cx_strsplit_ma(&alloc, mtest, cx_str("is,"), 4, &mlist); 1.477 + ASSERT_EQ(n, 3); 1.478 + EXPECT_EQ(cx_strcmp(cx_strcast(mlist[0]), cx_str("th")), 0); 1.479 + EXPECT_EQ(cx_strcmp(cx_strcast(mlist[1]), cx_str("")), 0); 1.480 + EXPECT_EQ(cx_strcmp(cx_strcast(mlist[2]), cx_str("a,csv,string")), 0); 1.481 + cxFree(&alloc, mlist); 1.482 + cx_strfree(&mtest); 1.483 + 1.484 + EXPECT_TRUE(alloc.verify()); 1.485 +} 1.486 + 1.487 +TEST(String, strtrim) { 1.488 + cxstring t1 = cx_strtrim(cx_str(" ein test \t ")); 1.489 + cxstring t2 = cx_strtrim(cx_str("abc")); 1.490 + cxstring t3 = cx_strtrim(cx_str(" 123")); 1.491 + cxstring t4 = cx_strtrim(cx_str("xyz ")); 1.492 + cxstring t5 = cx_strtrim(cx_str(" ")); 1.493 + cxstring empty = cx_strtrim(cx_str("")); 1.494 + 1.495 + EXPECT_EQ(cx_strcmp(t1, cx_str("ein test")), 0); 1.496 + EXPECT_EQ(cx_strcmp(t2, cx_str("abc")), 0); 1.497 + EXPECT_EQ(cx_strcmp(t3, cx_str("123")), 0); 1.498 + EXPECT_EQ(cx_strcmp(t4, cx_str("xyz")), 0); 1.499 + EXPECT_EQ(cx_strcmp(t5, cx_str("")), 0); 1.500 + EXPECT_EQ(cx_strcmp(empty, cx_str("")), 0); 1.501 + 1.502 + // call the _m variant just for coverage 1.503 + cxmutstr m1 = cx_strtrim_m(cx_mutstr((char *) " ein test \t ")); 1.504 + EXPECT_EQ(cx_strcmp(cx_strcast(m1), cx_str("ein test")), 0); 1.505 +} 1.506 + 1.507 +TEST(String, strprefix) { 1.508 + cxstring str = CX_STR("test my prefix and my suffix"); 1.509 + cxstring empty = CX_STR(""); 1.510 + EXPECT_FALSE(cx_strprefix(empty, cx_str("pref"))); 1.511 + EXPECT_TRUE(cx_strprefix(str, empty)); 1.512 + EXPECT_TRUE(cx_strprefix(empty, empty)); 1.513 + EXPECT_TRUE(cx_strprefix(str, cx_str("test "))); 1.514 + EXPECT_FALSE(cx_strprefix(str, cx_str("8-) fsck "))); 1.515 +} 1.516 + 1.517 +TEST(String, strsuffix) { 1.518 + cxstring str = CX_STR("test my prefix and my suffix"); 1.519 + cxstring empty = CX_STR(""); 1.520 + EXPECT_FALSE(cx_strsuffix(empty, cx_str("suf"))); 1.521 + EXPECT_TRUE(cx_strsuffix(str, empty)); 1.522 + EXPECT_TRUE(cx_strsuffix(empty, empty)); 1.523 + EXPECT_TRUE(cx_strsuffix(str, cx_str("fix"))); 1.524 + EXPECT_FALSE(cx_strsuffix(str, cx_str("fox"))); 1.525 +} 1.526 + 1.527 +TEST(String, strcaseprefix) { 1.528 + cxstring str = CX_STR("test my prefix and my suffix"); 1.529 + cxstring empty = CX_STR(""); 1.530 + EXPECT_FALSE(cx_strcaseprefix(empty, cx_str("pREf"))); 1.531 + EXPECT_TRUE(cx_strcaseprefix(str, empty)); 1.532 + EXPECT_TRUE(cx_strcaseprefix(empty, empty)); 1.533 + EXPECT_TRUE(cx_strcaseprefix(str, cx_str("TEST "))); 1.534 + EXPECT_FALSE(cx_strcaseprefix(str, cx_str("8-) fsck "))); 1.535 +} 1.536 + 1.537 +TEST(String, strcasesuffix) { 1.538 + cxstring str = CX_STR("test my prefix and my suffix"); 1.539 + cxstring empty = CX_STR(""); 1.540 + EXPECT_FALSE(cx_strcasesuffix(empty, cx_str("sUf"))); 1.541 + EXPECT_TRUE(cx_strcasesuffix(str, empty)); 1.542 + EXPECT_TRUE(cx_strcasesuffix(empty, empty)); 1.543 + EXPECT_TRUE(cx_strcasesuffix(str, cx_str("FIX"))); 1.544 + EXPECT_FALSE(cx_strcasesuffix(str, cx_str("fox"))); 1.545 +} 1.546 + 1.547 +TEST(String, strreplace) { 1.548 + CxTestingAllocator alloc; 1.549 + cxstring str = CX_STR("test ababab string aba"); 1.550 + cxstring longstr = CX_STR( 1.551 + "xyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacd"); 1.552 + cxstring notrail = CX_STR("test abab"); 1.553 + cxstring empty = CX_STR(""); 1.554 + cxstring astr = CX_STR("aaaaaaaaaa"); 1.555 + cxstring csstr = CX_STR("test AB ab TEST xyz"); 1.556 + 1.557 + cxmutstr repl = cx_strreplace(str, cx_str("abab"), cx_str("muchlonger")); 1.558 + auto expected = "test muchlongerab string aba"; 1.559 + 1.560 + cxmutstr repln = cx_strreplacen(str, cx_str("ab"), cx_str("c"), 2); 1.561 + auto expectedn = "test ccab string aba"; 1.562 + 1.563 + cxmutstr longrepl = cx_strreplace(longstr, cx_str("a"), cx_str("z")); 1.564 + auto longexpect = "xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzcd"; 1.565 + 1.566 + cxmutstr replnotrail = cx_strreplace(notrail, cx_str("ab"), cx_str("z")); 1.567 + auto notrailexpect = "test zz"; 1.568 + 1.569 + cxmutstr repleq = cx_strreplace(str, str, cx_str("hello")); 1.570 + auto eqexpect = "hello"; 1.571 + 1.572 + cxmutstr replempty1 = cx_strreplace(empty, cx_str("ab"), cx_str("c")); // expect: empty 1.573 + cxmutstr replempty2 = cx_strreplace(str, cx_str("abab"), empty); 1.574 + auto emptyexpect2 = "test ab string aba"; 1.575 + 1.576 + cxmutstr replpre = cx_strreplace(str, cx_str("test "), cx_str("TEST ")); 1.577 + auto preexpected = "TEST ababab string aba"; 1.578 + 1.579 + cxmutstr replan1 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 1); 1.580 + auto an1expected = "xaaaaaaaaa"; 1.581 + 1.582 + cxmutstr replan4 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 4); 1.583 + auto an4expected = "xxxxaaaaaa"; 1.584 + 1.585 + cxmutstr replan9 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 9); 1.586 + auto an9expected = "xxxxxxxxxa"; 1.587 + 1.588 + cxmutstr replan10 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 10); 1.589 + auto an10expected = "xxxxxxxxxx"; 1.590 + 1.591 + cxmutstr repl1_a = cx_strreplace_a(&alloc, csstr, cx_str("AB"), cx_str("*")); 1.592 + auto expeced1_a = "test * ab TEST xyz"; 1.593 + 1.594 + cxmutstr repl2_a = cx_strreplace_a(&alloc, csstr, cx_str("test"), cx_str("TEST")); 1.595 + auto expected2_a = "TEST AB ab TEST xyz"; 1.596 + 1.597 + 1.598 + EXPECT_NE(repl.ptr, str.ptr); 1.599 + EXPECT_ZERO_TERMINATED(repl); 1.600 + EXPECT_STREQ(repl.ptr, expected); 1.601 + EXPECT_ZERO_TERMINATED(repln); 1.602 + EXPECT_STREQ(repln.ptr, expectedn); 1.603 + EXPECT_ZERO_TERMINATED(longrepl); 1.604 + EXPECT_STREQ(longrepl.ptr, longexpect); 1.605 + EXPECT_ZERO_TERMINATED(replnotrail); 1.606 + EXPECT_STREQ(replnotrail.ptr, notrailexpect); 1.607 + EXPECT_ZERO_TERMINATED(repleq); 1.608 + EXPECT_STREQ(repleq.ptr, eqexpect); 1.609 + EXPECT_ZERO_TERMINATED(replempty1); 1.610 + EXPECT_STREQ(replempty1.ptr, ""); 1.611 + EXPECT_ZERO_TERMINATED(replempty2); 1.612 + EXPECT_STREQ(replempty2.ptr, emptyexpect2); 1.613 + EXPECT_ZERO_TERMINATED(replpre); 1.614 + EXPECT_STREQ(replpre.ptr, preexpected); 1.615 + EXPECT_ZERO_TERMINATED(replan1); 1.616 + EXPECT_STREQ(replan1.ptr, an1expected); 1.617 + EXPECT_ZERO_TERMINATED(replan4); 1.618 + EXPECT_STREQ(replan4.ptr, an4expected); 1.619 + EXPECT_ZERO_TERMINATED(replan9); 1.620 + EXPECT_STREQ(replan9.ptr, an9expected); 1.621 + EXPECT_ZERO_TERMINATED(replan10); 1.622 + EXPECT_STREQ(replan10.ptr, an10expected); 1.623 + EXPECT_ZERO_TERMINATED(repl1_a); 1.624 + EXPECT_STREQ(repl1_a.ptr, expeced1_a); 1.625 + EXPECT_ZERO_TERMINATED(repl2_a); 1.626 + EXPECT_STREQ(repl2_a.ptr, expected2_a); 1.627 + 1.628 + cx_strfree(&repl); 1.629 + cx_strfree(&repln); 1.630 + cx_strfree(&longrepl); 1.631 + cx_strfree(&replnotrail); 1.632 + cx_strfree(&repleq); 1.633 + cx_strfree(&replempty1); 1.634 + cx_strfree(&replempty2); 1.635 + cx_strfree(&replpre); 1.636 + cx_strfree(&replan1); 1.637 + cx_strfree(&replan4); 1.638 + cx_strfree(&replan9); 1.639 + cx_strfree(&replan10); 1.640 + 1.641 + cx_strfree_a(&alloc, &repl1_a); 1.642 + cx_strfree_a(&alloc, &repl2_a); 1.643 + EXPECT_TRUE(alloc.verify()); 1.644 +} 1.645 + 1.646 +TEST(String, strupper) { 1.647 + cxmutstr str = cx_strdup(cx_str("thIs 1s @ Te$t")); 1.648 + cx_strupper(str); 1.649 + EXPECT_STREQ(str.ptr, "THIS 1S @ TE$T"); 1.650 + cx_strfree(&str); 1.651 +} 1.652 + 1.653 +TEST(String, strlower) { 1.654 + cxmutstr str = cx_strdup(cx_str("thIs 1s @ Te$t")); 1.655 + cx_strlower(str); 1.656 + EXPECT_STREQ(str.ptr, "this 1s @ te$t"); 1.657 + cx_strfree(&str); 1.658 +} 1.659 + 1.660 +TEST(String, strtok) { 1.661 + cxstring str = cx_str("a,comma,separated,string"); 1.662 + cxstring delim = cx_str(","); 1.663 + CxStrtokCtx ctx = cx_strtok(str, delim, 3); 1.664 + EXPECT_EQ(ctx.str.ptr, str.ptr); 1.665 + EXPECT_EQ(ctx.str.length, str.length); 1.666 + EXPECT_EQ(ctx.delim.ptr, delim.ptr); 1.667 + EXPECT_EQ(ctx.delim.length, delim.length); 1.668 + EXPECT_EQ(ctx.limit, 3); 1.669 + EXPECT_EQ(ctx.found, 0); 1.670 + EXPECT_EQ(ctx.pos, 0); 1.671 + EXPECT_EQ(ctx.next_pos, 0); 1.672 + EXPECT_EQ(ctx.delim_more, nullptr); 1.673 + EXPECT_EQ(ctx.delim_more_count, 0); 1.674 +} 1.675 + 1.676 +TEST(String, strtok_m) { 1.677 + cxmutstr str = cx_strdup(cx_str("a,comma,separated,string")); 1.678 + cxstring delim = cx_str(","); 1.679 + CxStrtokCtx ctx = cx_strtok_m(str, delim, 3); 1.680 + EXPECT_EQ(ctx.str.ptr, str.ptr); 1.681 + EXPECT_EQ(ctx.str.length, str.length); 1.682 + EXPECT_EQ(ctx.delim.ptr, delim.ptr); 1.683 + EXPECT_EQ(ctx.delim.length, delim.length); 1.684 + EXPECT_EQ(ctx.limit, 3); 1.685 + EXPECT_EQ(ctx.found, 0); 1.686 + EXPECT_EQ(ctx.pos, 0); 1.687 + EXPECT_EQ(ctx.next_pos, 0); 1.688 + EXPECT_EQ(ctx.delim_more, nullptr); 1.689 + EXPECT_EQ(ctx.delim_more_count, 0); 1.690 + cx_strfree(&str); 1.691 +} 1.692 + 1.693 +TEST(String, strtok_delim) { 1.694 + cxstring str = cx_str("an,arbitrarily|separated;string"); 1.695 + cxstring delim = cx_str(","); 1.696 + cxstring delim_more[2] = {CX_STR("|"), CX_STR(";")}; 1.697 + CxStrtokCtx ctx = cx_strtok(str, delim, 3); 1.698 + cx_strtok_delim(&ctx, delim_more, 2); 1.699 + EXPECT_EQ(ctx.str.ptr, str.ptr); 1.700 + EXPECT_EQ(ctx.str.length, str.length); 1.701 + EXPECT_EQ(ctx.delim.ptr, delim.ptr); 1.702 + EXPECT_EQ(ctx.delim.length, delim.length); 1.703 + EXPECT_EQ(ctx.limit, 3); 1.704 + EXPECT_EQ(ctx.found, 0); 1.705 + EXPECT_EQ(ctx.pos, 0); 1.706 + EXPECT_EQ(ctx.next_pos, 0); 1.707 + EXPECT_EQ(ctx.delim_more, delim_more); 1.708 + EXPECT_EQ(ctx.delim_more_count, 2); 1.709 +} 1.710 + 1.711 +TEST(String, strtok_next_easy) { 1.712 + cxstring str = cx_str("a,comma,separated,string"); 1.713 + cxstring delim = cx_str(","); 1.714 + CxStrtokCtx ctx = cx_strtok(str, delim, 3); 1.715 + bool ret; 1.716 + cxstring tok; 1.717 + 1.718 + ret = cx_strtok_next(&ctx, &tok); 1.719 + ASSERT_TRUE(ret); 1.720 + EXPECT_EQ(cx_strcmp(tok, cx_str("a")), 0); 1.721 + EXPECT_EQ(ctx.pos, 0); 1.722 + EXPECT_EQ(ctx.next_pos, 2); 1.723 + EXPECT_EQ(ctx.delim_pos, 1); 1.724 + EXPECT_EQ(ctx.found, 1); 1.725 + 1.726 + ret = cx_strtok_next(&ctx, &tok); 1.727 + ASSERT_TRUE(ret); 1.728 + EXPECT_EQ(cx_strcmp(tok, cx_str("comma")), 0); 1.729 + EXPECT_EQ(ctx.pos, 2); 1.730 + EXPECT_EQ(ctx.next_pos, 8); 1.731 + EXPECT_EQ(ctx.delim_pos, 7); 1.732 + EXPECT_EQ(ctx.found, 2); 1.733 + 1.734 + ret = cx_strtok_next(&ctx, &tok); 1.735 + ASSERT_TRUE(ret); 1.736 + EXPECT_EQ(cx_strcmp(tok, cx_str("separated")), 0); 1.737 + EXPECT_EQ(ctx.pos, 8); 1.738 + EXPECT_EQ(ctx.next_pos, 18); 1.739 + EXPECT_EQ(ctx.delim_pos, 17); 1.740 + EXPECT_EQ(ctx.found, 3); 1.741 + 1.742 + ret = cx_strtok_next(&ctx, &tok); 1.743 + ASSERT_FALSE(ret); 1.744 + EXPECT_EQ(ctx.pos, 8); 1.745 + EXPECT_EQ(ctx.next_pos, 18); 1.746 + EXPECT_EQ(ctx.delim_pos, 17); 1.747 + EXPECT_EQ(ctx.found, 3); 1.748 +} 1.749 + 1.750 +TEST(String, strtok_next_unlimited) { 1.751 + cxstring str = cx_str("some;-;otherwise;-;separated;-;string;-;"); 1.752 + cxstring delim = cx_str(";-;"); 1.753 + CxStrtokCtx ctx = cx_strtok(str, delim, SIZE_MAX); 1.754 + bool ret; 1.755 + cxstring tok; 1.756 + 1.757 + ret = cx_strtok_next(&ctx, &tok); 1.758 + ASSERT_TRUE(ret); 1.759 + EXPECT_EQ(cx_strcmp(tok, cx_str("some")), 0); 1.760 + EXPECT_EQ(ctx.pos, 0); 1.761 + EXPECT_EQ(ctx.next_pos, 7); 1.762 + EXPECT_EQ(ctx.delim_pos, 4); 1.763 + EXPECT_EQ(ctx.found, 1); 1.764 + 1.765 + ret = cx_strtok_next(&ctx, &tok); 1.766 + ASSERT_TRUE(ret); 1.767 + EXPECT_EQ(cx_strcmp(tok, cx_str("otherwise")), 0); 1.768 + EXPECT_EQ(ctx.pos, 7); 1.769 + EXPECT_EQ(ctx.next_pos, 19); 1.770 + EXPECT_EQ(ctx.delim_pos, 16); 1.771 + EXPECT_EQ(ctx.found, 2); 1.772 + 1.773 + ret = cx_strtok_next(&ctx, &tok); 1.774 + ASSERT_TRUE(ret); 1.775 + EXPECT_EQ(cx_strcmp(tok, cx_str("separated")), 0); 1.776 + EXPECT_EQ(ctx.pos, 19); 1.777 + EXPECT_EQ(ctx.next_pos, 31); 1.778 + EXPECT_EQ(ctx.delim_pos, 28); 1.779 + EXPECT_EQ(ctx.found, 3); 1.780 + 1.781 + ret = cx_strtok_next(&ctx, &tok); 1.782 + ASSERT_TRUE(ret); 1.783 + EXPECT_EQ(cx_strcmp(tok, cx_str("string")), 0); 1.784 + EXPECT_EQ(ctx.pos, 31); 1.785 + EXPECT_EQ(ctx.next_pos, 40); 1.786 + EXPECT_EQ(ctx.delim_pos, 37); 1.787 + EXPECT_EQ(ctx.found, 4); 1.788 + 1.789 + ret = cx_strtok_next(&ctx, &tok); 1.790 + ASSERT_TRUE(ret); 1.791 + EXPECT_EQ(cx_strcmp(tok, cx_str("")), 0); 1.792 + EXPECT_EQ(ctx.pos, 40); 1.793 + EXPECT_EQ(ctx.next_pos, 40); 1.794 + EXPECT_EQ(ctx.delim_pos, 40); 1.795 + EXPECT_EQ(ctx.found, 5); 1.796 + 1.797 + ret = cx_strtok_next(&ctx, &tok); 1.798 + ASSERT_FALSE(ret); 1.799 + EXPECT_EQ(ctx.pos, 40); 1.800 + EXPECT_EQ(ctx.delim_pos, 40); 1.801 + EXPECT_EQ(ctx.found, 5); 1.802 +} 1.803 + 1.804 +TEST(String, strtok_next_advanced) { 1.805 + cxmutstr str = cx_strdup(cx_str("an,arbitrarily;||separated;string")); 1.806 + cxstring delim = cx_str(","); 1.807 + cxstring delim_more[2] = {CX_STR("||"), CX_STR(";")}; 1.808 + CxStrtokCtx ctx = cx_strtok_m(str, delim, 10); 1.809 + cx_strtok_delim(&ctx, delim_more, 2); 1.810 + bool ret; 1.811 + cxmutstr tok; 1.812 + 1.813 + ret = cx_strtok_next_m(&ctx, &tok); 1.814 + ASSERT_TRUE(ret); 1.815 + EXPECT_EQ(cx_strcmp(cx_strcast(tok), cx_str("an")), 0); 1.816 + EXPECT_EQ(ctx.pos, 0); 1.817 + EXPECT_EQ(ctx.next_pos, 3); 1.818 + EXPECT_EQ(ctx.delim_pos, 2); 1.819 + EXPECT_EQ(ctx.found, 1); 1.820 + cx_strupper(tok); 1.821 + 1.822 + ret = cx_strtok_next_m(&ctx, &tok); 1.823 + ASSERT_TRUE(ret); 1.824 + EXPECT_EQ(cx_strcmp(cx_strcast(tok), cx_str("arbitrarily")), 0); 1.825 + EXPECT_EQ(ctx.pos, 3); 1.826 + EXPECT_EQ(ctx.next_pos, 15); 1.827 + EXPECT_EQ(ctx.delim_pos, 14); 1.828 + EXPECT_EQ(ctx.found, 2); 1.829 + cx_strupper(tok); 1.830 + 1.831 + ret = cx_strtok_next_m(&ctx, &tok); 1.832 + ASSERT_TRUE(ret); 1.833 + EXPECT_EQ(cx_strcmp(cx_strcast(tok), cx_str("")), 0); 1.834 + EXPECT_EQ(ctx.pos, 15); 1.835 + EXPECT_EQ(ctx.next_pos, 17); 1.836 + EXPECT_EQ(ctx.delim_pos, 15); 1.837 + EXPECT_EQ(ctx.found, 3); 1.838 + cx_strupper(tok); 1.839 + 1.840 + ret = cx_strtok_next_m(&ctx, &tok); 1.841 + ASSERT_TRUE(ret); 1.842 + EXPECT_EQ(cx_strcmp(cx_strcast(tok), cx_str("separated")), 0); 1.843 + EXPECT_EQ(ctx.pos, 17); 1.844 + EXPECT_EQ(ctx.next_pos, 27); 1.845 + EXPECT_EQ(ctx.delim_pos, 26); 1.846 + EXPECT_EQ(ctx.found, 4); 1.847 + cx_strupper(tok); 1.848 + 1.849 + ret = cx_strtok_next_m(&ctx, &tok); 1.850 + ASSERT_TRUE(ret); 1.851 + EXPECT_EQ(cx_strcmp(cx_strcast(tok), cx_str("string")), 0); 1.852 + EXPECT_EQ(ctx.pos, 27); 1.853 + EXPECT_EQ(ctx.next_pos, 33); 1.854 + EXPECT_EQ(ctx.delim_pos, 33); 1.855 + EXPECT_EQ(ctx.found, 5); 1.856 + cx_strupper(tok); 1.857 + 1.858 + ret = cx_strtok_next_m(&ctx, &tok); 1.859 + ASSERT_FALSE(ret); 1.860 + EXPECT_EQ(ctx.pos, 27); 1.861 + EXPECT_EQ(ctx.next_pos, 33); 1.862 + EXPECT_EQ(ctx.delim_pos, 33); 1.863 + EXPECT_EQ(ctx.found, 5); 1.864 + 1.865 + EXPECT_EQ(cx_strcmp(cx_strcast(str), cx_str("AN,ARBITRARILY;||SEPARATED;STRING")), 0); 1.866 + 1.867 + cx_strfree(&str); 1.868 +}