1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "cx/test.h"
30 #include "util_allocator.h"
31
32 #include "cx/string.h"
33 #include "cx/compare.h"
34
35 #include <limits.h>
36 #include <errno.h>
37
38 #define ASSERT_ZERO_TERMINATED(str)
CX_TEST_ASSERTM((str).ptr[(str).length] ==
'\0', \
39 #str " is not zero terminated")
40
41 CX_TEST(test_string_construct) {
42 cxstring s1 =
CX_STR(
"1234");
43 cxstring s2 = cx_strn(
"abcd",
2);
44 cxmutstr s3 = cx_mutstr((
char *)
"1234");
45 cxmutstr s4 = cx_mutstrn((
char *)
"abcd",
2);
46 cxstring snull = cx_str(
NULL);
47 cxmutstr mnull = cx_mutstr(
NULL);
48 CX_TEST_DO {
49 CX_TEST_ASSERT(s1.length ==
4);
50 CX_TEST_ASSERT(strncmp(s1.ptr,
"1234",
4) ==
0);
51 CX_TEST_ASSERT(s2.length ==
2);
52 CX_TEST_ASSERT(strncmp(s2.ptr,
"ab",
2) ==
0);
53 CX_TEST_ASSERT(s3.length ==
4);
54 CX_TEST_ASSERT(strncmp(s3.ptr,
"1234",
4) ==
0);
55 CX_TEST_ASSERT(s4.length ==
2);
56 CX_TEST_ASSERT(strncmp(s4.ptr,
"ab",
2) ==
0);
57 CX_TEST_ASSERT(
0 == snull.length);
58 CX_TEST_ASSERT(
NULL == snull.ptr);
59 CX_TEST_ASSERT(
0 == mnull.length);
60 CX_TEST_ASSERT(
NULL == mnull.ptr);
61 CX_TEST_ASSERT(
0 == cx_strcmp(snull,
""));
62 CX_TEST_ASSERT(
0 == cx_strcmp(mnull,
""));
63 }
64 }
65
66 CX_TEST(test_string_cast) {
67 char *c1 = (
char*)
"123";
68 const char *c2 =
"abcde";
69 unsigned char *c3 = (
unsigned char*)
"4711";
70 unsigned const char *c4 = (
unsigned const char*)
"xyz0815";
71 cxstring s1 = cx_strcast(c1);
72 cxstring s2 = cx_strcast(c2);
73 cxstring s3 = cx_strcast(c3);
74 cxstring s4 = cx_strcast(c4);
75 CX_TEST_DO {
76 CX_TEST_ASSERT(s1.length ==
3);
77 CX_TEST_ASSERT(strncmp(s1.ptr,
"123",
3) ==
0);
78 CX_TEST_ASSERT(s2.length ==
5);
79 CX_TEST_ASSERT(strncmp(s2.ptr,
"abcde",
5) ==
0);
80 CX_TEST_ASSERT(s3.length ==
4);
81 CX_TEST_ASSERT(strncmp(s3.ptr,
"4711",
4) ==
0);
82 CX_TEST_ASSERT(s4.length ==
7);
83 CX_TEST_ASSERT(strncmp(s4.ptr,
"xyz0815",
7) ==
0);
84 }
85 }
86
87 CX_TEST(test_strfree) {
88 CxTestingAllocator talloc;
89 cx_testing_allocator_init(&talloc);
90 CxAllocator *alloc = &talloc.base;
91 CX_TEST_DO {
92 char *test = cxMalloc(alloc,
16);
93 cxmutstr str = cx_mutstrn(test,
16);
94 CX_TEST_ASSERT(str.ptr == test);
95 CX_TEST_ASSERT(str.length ==
16);
96 cx_strfree_a(alloc, &str);
97 CX_TEST_ASSERT(str.ptr ==
NULL);
98 CX_TEST_ASSERT(str.length ==
0);
99 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
100
101 cx_strfree(
NULL);
102 cx_strfree_a(alloc,
NULL);
103 }
104 cx_testing_allocator_destroy(&talloc);
105 }
106
107 CX_TEST(test_strdup) {
108 cxstring str =
CX_STR(
"test");
109 cxmutstr dup = cx_strdup(str);
110 CX_TEST_DO {
111 CX_TEST_ASSERT(dup.length == str.length);
112 CX_TEST_ASSERT(
0 == strcmp(dup.ptr, str.ptr));
113 ASSERT_ZERO_TERMINATED(dup);
114 }
115 cx_strfree(&dup);
116 }
117
118 CX_TEST(test_strdup_shortened) {
119 cxstring str =
CX_STR(
"test");
120 str.length =
2;
121 cxmutstr dup = cx_strdup(str);
122 CX_TEST_DO {
123 CX_TEST_ASSERT(dup.length == str.length);
124 CX_TEST_ASSERT(
0 == strcmp(dup.ptr,
"te"));
125 ASSERT_ZERO_TERMINATED(dup);
126 }
127 cx_strfree(&dup);
128 }
129
130 CX_TEST(test_strcpy) {
131 CxTestingAllocator talloc;
132 cx_testing_allocator_init(&talloc);
133 const CxAllocator *alloc = &talloc.base;
134 cxstring str =
CX_STR(
"test string");
135 str.length =
8;
136 cxmutstr dup;
137 CX_TEST_DO {
138
139 dup = cx_strdup_a(alloc,
CX_STR(
"hello"));
140 CX_TEST_ASSERT(
0 == cx_strcpy_a(alloc, &dup, str));
141 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(dup),
CX_STR(
"test str")));
142 ASSERT_ZERO_TERMINATED(dup);
143 cx_strfree_a(alloc, &dup);
144
145
146 dup = cx_strdup_a(alloc,
CX_STR(
"hello, world!"));
147 CX_TEST_ASSERT(
0 == cx_strcpy_a(alloc, &dup, str));
148 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(dup),
CX_STR(
"test str")));
149 ASSERT_ZERO_TERMINATED(dup);
150 cx_strfree_a(alloc, &dup);
151
152
153 dup = cx_strdup_a(alloc,
CX_STR(
"testing!"));
154 CX_TEST_ASSERT(
0 == cx_strcpy_a(alloc, &dup, str));
155 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(dup),
CX_STR(
"test str")));
156 ASSERT_ZERO_TERMINATED(dup);
157 cx_strfree_a(alloc, &dup);
158
159
160 dup.ptr =
NULL;
161 CX_TEST_ASSERT(
0 == cx_strcpy_a(alloc, &dup, str));
162 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(dup),
CX_STR(
"test str")));
163 ASSERT_ZERO_TERMINATED(dup);
164 cx_strfree_a(alloc, &dup);
165 }
166 cx_testing_allocator_destroy(&talloc);
167 }
168
169 CX_TEST(test_strlen) {
170 cxstring s1 =
CX_STR(
"1234");
171 cxstring s2 =
CX_STR(
".:.:.");
172 cxstring s3 =
CX_STR(
"X");
173 CX_TEST_DO {
174 size_t len0 = cx_strlen(
0);
175 size_t len1 = cx_strlen(
1, s1);
176 size_t len2 = cx_strlen(
2, s1, s2);
177 size_t len3 = cx_strlen(
3, s1, s2, s3);
178
179 CX_TEST_ASSERT(len0 ==
0);
180 CX_TEST_ASSERT(len1 ==
4);
181 CX_TEST_ASSERT(len2 ==
9);
182 CX_TEST_ASSERT(len3 ==
10);
183 }
184 }
185
186 CX_TEST(test_strsubs) {
187 cxstring str =
CX_STR(
"A test string");
188
189 CX_TEST_DO {
190 cxstring sub = cx_strsubs(str,
0);
191 CX_TEST_ASSERT(
0 == cx_strcmp(sub, str));
192
193 sub = cx_strsubs(str,
2);
194 CX_TEST_ASSERT(
0 == cx_strcmp(sub, cx_str(
"test string")));
195
196 sub = cx_strsubs(str,
7);
197 CX_TEST_ASSERT(
0 == cx_strcmp(sub, cx_str(
"string")));
198
199 sub = cx_strsubs(str,
15);
200 CX_TEST_ASSERT(
0 == cx_strcmp(sub, cx_str(
"")));
201
202 sub = cx_strsubsl(str,
2,
4);
203 CX_TEST_ASSERT(
0 == cx_strcmp(sub, cx_str(
"test")));
204
205 sub = cx_strsubsl(str,
7,
3);
206 CX_TEST_ASSERT(
0 == cx_strcmp(sub, cx_str(
"str")));
207
208 sub = cx_strsubsl(str,
7,
20);
209 CX_TEST_ASSERT(
0 == cx_strcmp(sub, cx_str(
"string")));
210
211
212 cxmutstr m = cx_strsubs_m(cx_mutstrn(
NULL,
0),
0);
213 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(m), cx_str(
"")));
214 }
215 }
216
217 CX_TEST(test_strchr) {
218 cxstring str =
CX_STR(
"I will find you - and I will kill you");
219
220 CX_TEST_DO {
221 cxstring notfound = cx_strchr(str,
'x');
222 CX_TEST_ASSERT(notfound.length ==
0);
223
224 cxstring result = cx_strchr(str,
'w');
225 CX_TEST_ASSERT(result.length ==
35);
226 CX_TEST_ASSERT(
0 == strcmp(result.ptr,
"will find you - and I will kill you"));
227
228
229 cxmutstr m = cx_strchr_m(cx_mutstrn(
NULL,
0),
'a');
230 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(m), cx_str(
"")));
231 }
232 }
233
234 CX_TEST(test_strrchr) {
235 cxstring str =
CX_STR(
"X will find you - and I will kill you");
236
237 CX_TEST_DO {
238 cxstring notfound = cx_strrchr(str,
'x');
239 CX_TEST_ASSERT(notfound.length ==
0);
240
241 cxstring result = cx_strrchr(str,
'w');
242 CX_TEST_ASSERT(result.length ==
13);
243 CX_TEST_ASSERT(
0 == strcmp(result.ptr,
"will kill you"));
244
245 result = cx_strrchr(str,
'u');
246 CX_TEST_ASSERT(result.length ==
1);
247 CX_TEST_ASSERT(
0 == strcmp(result.ptr,
"u"));
248
249 result = cx_strrchr(str,
'X');
250 CX_TEST_ASSERT(
0 == cx_strcmp(result, str));
251
252
253 cxmutstr m = cx_strrchr_m(cx_mutstrn(
NULL,
0),
'a');
254 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(m), cx_str(
"")));
255 }
256 }
257
258 CX_TEST(test_strstr) {
259 cxstring str =
CX_STR(
"find the match in this string");
260
261 const size_t longstrpatternlen =
64 + cx_strstr_sbo_size;
262 const size_t longstrlen =
320 + longstrpatternlen +
14;
263
264
265
266
267 char *longstrc = calloc(longstrlen
+1,
1);
268 char *longstrpatternc = calloc(longstrpatternlen
+1,
1);
269
270 memcpy(longstrc,
271 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl"
272 "mnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx"
273 "yzabcdeababababnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij"
274 "klmnopqrstuvwxyzaababababababababrstuvwxyzabcdefghijklmnopqrstuv"
275 "abababababababababababababababababababababababababababababababab",
276 320
277 );
278 memcpy(longstrpatternc,
279 "abababababababababababababababababababababababababababababababab",
280 64
281 );
282 char x =
'a', y=
'b', z;
283 for (
size_t i =
0; i < cx_strstr_sbo_size ; i++) {
284 longstrpatternc[
64+i] = x;
285 longstrc[
320+i] = x;
286 z=x; x=y; y=z;
287 }
288 longstrpatternc[longstrpatternlen] =
'\0';
289 memcpy(longstrc+longstrlen
-14,
"wxyz1234567890",
15);
290
291 cxmutstr longstr = cx_mutstrn(longstrc, longstrlen);
292 cxstring longstrpattern = cx_strn(longstrpatternc, longstrpatternlen);
293 cxmutstr longstrresult = cx_mutstrn(longstrc
+256, longstrlen
-256);
294
295 CX_TEST_DO {
296 cxstring notfound = cx_strstr(str, cx_str(
"no match"));
297 CX_TEST_ASSERT(notfound.length ==
0);
298
299 cxstring result = cx_strstr(str, cx_str(
"match"));
300 CX_TEST_ASSERT(result.length ==
20);
301 CX_TEST_ASSERT(
0 == strcmp(result.ptr,
"match in this string"));
302
303 result = cx_strstr(str, cx_str(
""));
304 CX_TEST_ASSERT(result.length == str.length);
305 CX_TEST_ASSERT(
0 == strcmp(result.ptr, str.ptr));
306
307 cxmutstr resultm = cx_strstr_m(longstr, longstrpattern);
308 CX_TEST_ASSERT(resultm.length == longstrresult.length);
309 CX_TEST_ASSERT(
0 == strcmp(resultm.ptr, longstrresult.ptr));
310 }
311
312 free(longstrc);
313 free(longstrpatternc);
314 }
315
316 CX_TEST(test_strcmp) {
317 cxstring str =
CX_STR(
"compare this");
318 CX_TEST_DO {
319 CX_TEST_ASSERT(
0 == cx_strcmp(cx_str(
""), cx_str(
"")));
320 CX_TEST_ASSERT(
0 < cx_strcmp(str, cx_str(
"")));
321 CX_TEST_ASSERT(
0 == cx_strcmp(str, cx_str(
"compare this")));
322 CX_TEST_ASSERT(
0 != cx_strcmp(str, cx_str(
"Compare This")));
323 CX_TEST_ASSERT(
0 > cx_strcmp(str, cx_str(
"compare tool")));
324 CX_TEST_ASSERT(
0 < cx_strcmp(str, cx_str(
"compare shit")));
325 CX_TEST_ASSERT(
0 > cx_strcmp(str, cx_str(
"compare this not")));
326 CX_TEST_ASSERT(
0 < cx_strcmp(str, cx_str(
"compare")));
327 CX_TEST_ASSERT(
0 > cx_strcmp(str, cx_str(
"lex")));
328 CX_TEST_ASSERT(
0 < cx_strcmp(str, cx_str(
"another lex test")));
329 CX_TEST_ASSERT(
0 < cx_strcmp(str, cx_str(
"Lex")));
330 CX_TEST_ASSERT(
0 < cx_strcmp(str, cx_str(
"Another lex test")));
331
332 cxstring str2 =
CX_STR(
"Compare This");
333 CX_TEST_ASSERT(
0 != cx_strcmp_p(&str, &str2));
334 str2 =
CX_STR(
"compare this");
335 CX_TEST_ASSERT(
0 == cx_strcmp_p(&str, &str2));
336 }
337 }
338
339 CX_TEST(test_strcasecmp) {
340 cxstring str =
CX_STR(
"compare this");
341 CX_TEST_DO {
342 CX_TEST_ASSERT(
0 == cx_strcasecmp(cx_str(
""), cx_str(
"")));
343 CX_TEST_ASSERT(
0 < cx_strcasecmp(str, cx_str(
"")));
344 CX_TEST_ASSERT(
0 == cx_strcasecmp(str, cx_str(
"compare this")));
345 CX_TEST_ASSERT(
0 == cx_strcasecmp(str, cx_str(
"Compare This")));
346 CX_TEST_ASSERT(
0 > cx_strcasecmp(str, cx_str(
"compare tool")));
347 CX_TEST_ASSERT(
0 < cx_strcasecmp(str, cx_str(
"compare shit")));
348 CX_TEST_ASSERT(
0 > cx_strcasecmp(str, cx_str(
"compare this not")));
349 CX_TEST_ASSERT(
0 < cx_strcasecmp(str, cx_str(
"compare")));
350 CX_TEST_ASSERT(
0 > cx_strcasecmp(str, cx_str(
"lex")));
351 CX_TEST_ASSERT(
0 < cx_strcasecmp(str, cx_str(
"another lex test")));
352 CX_TEST_ASSERT(
0 > cx_strcasecmp(str, cx_str(
"Lex")));
353 CX_TEST_ASSERT(
0 < cx_strcasecmp(str, cx_str(
"Another lex test")));
354
355 cxstring str2 =
CX_STR(
"Compare This");
356 CX_TEST_ASSERT(
0 == cx_strcasecmp_p(&str, &str2));
357 str2 =
CX_STR(
"Compare Tool");
358 CX_TEST_ASSERT(
0 > cx_strcasecmp_p(&str, &str2));
359 }
360 }
361
362 CX_TEST(test_strcat) {
363 cxstring s1 =
CX_STR(
"12");
364 cxstring s2 =
CX_STR(
"34");
365 cxstring s3 =
CX_STR(
"56");
366 cxstring sn = {
NULL,
0};
367
368 CxTestingAllocator talloc;
369 cx_testing_allocator_init(&talloc);
370 CxAllocator *alloc = &talloc.base;
371
372 CX_TEST_DO {
373 cxmutstr t1 = cx_strcat_a(alloc,
2, s1, s2);
374 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(t1), cx_str(
"1234")));
375 ASSERT_ZERO_TERMINATED(t1);
376 cx_strfree_a(alloc, &t1);
377
378 cxmutstr t2 = cx_strcat_a(alloc,
3, s1, s2, s3);
379 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(t2), cx_str(
"123456")));
380 ASSERT_ZERO_TERMINATED(t2);
381 cx_strfree_a(alloc, &t2);
382
383 cxmutstr t3 = cx_strcat_a(alloc,
6, s1, sn, s2, sn, s3, sn);
384 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(t3), cx_str(
"123456")));
385 ASSERT_ZERO_TERMINATED(t3);
386 cx_strfree_a(alloc, &t3);
387
388 cxmutstr t4 = cx_strcat_a(alloc,
2, sn, sn);
389 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(t4), cx_str(
"")));
390 ASSERT_ZERO_TERMINATED(t4);
391 cx_strfree_a(alloc, &t4);
392
393 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
394
395
396 cxmutstr t5 = cx_strcat(
3, s3, s1, s2);
397 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(t5), cx_str(
"561234")));
398 ASSERT_ZERO_TERMINATED(t5);
399 cx_strfree(&t5);
400
401
402 cxmutstr t6 = cx_strdup(cx_str(
"Hello"));
403 t6 = cx_strcat_m(t6,
2, cx_str(
", "), cx_str(
"World!"));
404 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(t6), cx_str(
"Hello, World!")));
405 ASSERT_ZERO_TERMINATED(t6);
406 cx_strfree(&t6);
407
408
409 char *fakestr =
NULL;
410 cxstring a = cx_strn(fakestr,
SIZE_MAX /
3 -
10);
411 cxstring b = cx_strn(fakestr,
SIZE_MAX /
3 -
5);
412 cxstring c = cx_strn(fakestr,
SIZE_MAX /
3 +
20);
413 errno =
0;
414 cxmutstr z = cx_strcat(
3, a, b, c);
415 CX_TEST_ASSERT(errno ==
EOVERFLOW);
416 CX_TEST_ASSERT(z.ptr ==
NULL);
417 CX_TEST_ASSERT(z.length ==
0);
418 }
419 cx_testing_allocator_destroy(&talloc);
420 }
421
422 CX_TEST(test_strcat_more_than_eight) {
423 cxstring s1 =
CX_STR(
"12");
424 cxstring s2 =
CX_STR(
"34");
425 cxstring s3 =
CX_STR(
"56");
426 cxstring s4 =
CX_STR(
"78");
427 cxstring s5 =
CX_STR(
"9a");
428 cxstring s6 =
CX_STR(
"bc");
429 cxstring s7 =
CX_STR(
"de");
430 cxstring s8 =
CX_STR(
"f0");
431 cxstring s9 =
CX_STR(
"xy");
432
433 CX_TEST_DO {
434 cxmutstr r = cx_strcat(
9, s1, s2, s3, s4, s5, s6, s7, s8, s9);
435 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(r), cx_str(
"123456789abcdef0xy")));
436 ASSERT_ZERO_TERMINATED(r);
437 cx_strfree(&r);
438 }
439 }
440
441 CX_TEST(test_strsplit) {
442 cxstring test =
CX_STR(
"this,is,a,csv,string");
443 size_t capa =
8;
444 cxstring list[
8];
445 size_t n;
446 CX_TEST_DO {
447
448 n = cx_strsplit(test, cx_str(
""), capa, list);
449 CX_TEST_ASSERT(n ==
1);
450 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], test));
451
452
453 n = cx_strsplit(test, cx_str(
"z"), capa, list);
454 CX_TEST_ASSERT(n ==
1);
455 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], test));
456
457
458 n = cx_strsplit(test, cx_str(
"is,not"), capa, list);
459 CX_TEST_ASSERT(n ==
1);
460 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], test));
461
462
463 n = cx_strsplit(test, cx_str(
","), capa, list);
464 CX_TEST_ASSERT(n ==
5);
465 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"this")));
466 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"is")));
467 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
"a")));
468 CX_TEST_ASSERT(
0 == cx_strcmp(list[
3], cx_str(
"csv")));
469 CX_TEST_ASSERT(
0 == cx_strcmp(list[
4], cx_str(
"string")));
470
471
472 n = cx_strsplit(test, cx_str(
"is"), capa, list);
473 CX_TEST_ASSERT(n ==
3);
474 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"th")));
475 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
",")));
476 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
",a,csv,string")));
477
478
479 n = cx_strsplit(test, cx_str(
","),
3, list);
480 CX_TEST_ASSERT(n ==
3);
481 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"this")));
482 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"is")));
483 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
"a,csv,string")));
484
485
486 n = cx_strsplit(test, cx_str(
"is"),
2, list);
487 CX_TEST_ASSERT(n ==
2);
488 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"th")));
489 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
",is,a,csv,string")));
490
491
492 n = cx_strsplit(test, cx_str(
"this"), capa, list);
493 CX_TEST_ASSERT(n ==
2);
494 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"")));
495 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
",is,a,csv,string")));
496
497
498 n = cx_strsplit(test, cx_str(
"string"), capa, list);
499 CX_TEST_ASSERT(n ==
2);
500 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"this,is,a,csv,")));
501 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"")));
502
503
504
505 n = cx_strsplit(cx_str(
"a,b,c,"), cx_str(
","),
3, list);
506 CX_TEST_ASSERT(n ==
3);
507 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"a")));
508 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"b")));
509 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
"c,")));
510
511
512 n = cx_strsplit(test, cx_str(
"this,is,a,csv,string"), capa, list);
513 CX_TEST_ASSERT(n ==
2);
514 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"")));
515 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"")));
516
517
518 n = cx_strsplit(test, cx_str(
"this,is,a,csv,string,with,extension"), capa, list);
519 CX_TEST_ASSERT(n ==
1);
520 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], test));
521
522
523 n = cx_strsplit(test, cx_str(
"is,"), capa, list);
524 CX_TEST_ASSERT(n ==
3);
525 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"th")));
526 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"")));
527 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
"a,csv,string")));
528
529
530 cxmutstr mtest = cx_strdup(test);
531 cxmutstr mlist[
4];
532 n = cx_strsplit_m(mtest, cx_str(
"is,"),
4, mlist);
533 CX_TEST_ASSERT(n ==
3);
534 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(mlist[
0]), cx_str(
"th")));
535 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(mlist[
1]), cx_str(
"")));
536 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(mlist[
2]), cx_str(
"a,csv,string")));
537 cx_strfree(&mtest);
538 }
539 }
540
541 CX_TEST(test_strsplit_a) {
542 CxTestingAllocator talloc;
543 cx_testing_allocator_init(&talloc);
544 CxAllocator *alloc = &talloc.base;
545
546 cxstring test =
CX_STR(
"this,is,a,csv,string");
547 size_t capa =
8;
548 cxstring *list;
549 size_t n;
550 CX_TEST_DO {
551
552 n = cx_strsplit_a(alloc, test, cx_str(
""), capa, &list);
553 CX_TEST_ASSERT(n ==
1);
554 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], test));
555 cxFree(alloc, list);
556
557
558 n = cx_strsplit_a(alloc, test, cx_str(
"z"), capa, &list);
559 CX_TEST_ASSERT(n ==
1);
560 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], test));
561 cxFree(alloc, list);
562
563
564 n = cx_strsplit_a(alloc, test, cx_str(
"is,not"), capa, &list);
565 CX_TEST_ASSERT(n ==
1);
566 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], test));
567 cxFree(alloc, list);
568
569
570 n = cx_strsplit_a(alloc, test, cx_str(
","), capa, &list);
571 CX_TEST_ASSERT(n ==
5);
572 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"this")));
573 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"is")));
574 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
"a")));
575 CX_TEST_ASSERT(
0 == cx_strcmp(list[
3], cx_str(
"csv")));
576 CX_TEST_ASSERT(
0 == cx_strcmp(list[
4], cx_str(
"string")));
577 cxFree(alloc, list);
578
579
580 n = cx_strsplit_a(alloc, test, cx_str(
"is"), capa, &list);
581 CX_TEST_ASSERT(n ==
3);
582 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"th")));
583 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
",")));
584 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
",a,csv,string")));
585 cxFree(alloc, list);
586
587
588 n = cx_strsplit_a(alloc, test, cx_str(
","),
3, &list);
589 CX_TEST_ASSERT(n ==
3);
590 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"this")));
591 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"is")));
592 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
"a,csv,string")));
593 cxFree(alloc, list);
594
595
596 n = cx_strsplit_a(alloc, test, cx_str(
"is"),
2, &list);
597 CX_TEST_ASSERT(n ==
2);
598 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"th")));
599 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
",is,a,csv,string")));
600 cxFree(alloc, list);
601
602
603 n = cx_strsplit_a(alloc, test, cx_str(
"this"), capa, &list);
604 CX_TEST_ASSERT(n ==
2);
605 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"")));
606 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
",is,a,csv,string")));
607 cxFree(alloc, list);
608
609
610 n = cx_strsplit_a(alloc, test, cx_str(
"string"), capa, &list);
611 CX_TEST_ASSERT(n ==
2);
612 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"this,is,a,csv,")));
613 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"")));
614 cxFree(alloc, list);
615
616
617 n = cx_strsplit_a(alloc, cx_str(
"a,b,c,"), cx_str(
","),
3, &list);
618 CX_TEST_ASSERT(n ==
3);
619 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"a")));
620 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"b")));
621 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
"c,")));
622 cxFree(alloc, list);
623
624
625 n = cx_strsplit_a(alloc, test, cx_str(
"this,is,a,csv,string"), capa, &list);
626 CX_TEST_ASSERT(n ==
2);
627 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"")));
628 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"")));
629 cxFree(alloc, list);
630
631
632 n = cx_strsplit_a(alloc, test, cx_str(
"this,is,a,csv,string,with,extension"), capa, &list);
633 CX_TEST_ASSERT(n ==
1);
634 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], test));
635 cxFree(alloc, list);
636
637
638 n = cx_strsplit_a(alloc, test, cx_str(
"is,"), capa, &list);
639 CX_TEST_ASSERT(n ==
3);
640 CX_TEST_ASSERT(
0 == cx_strcmp(list[
0], cx_str(
"th")));
641 CX_TEST_ASSERT(
0 == cx_strcmp(list[
1], cx_str(
"")));
642 CX_TEST_ASSERT(
0 == cx_strcmp(list[
2], cx_str(
"a,csv,string")));
643 cxFree(alloc, list);
644
645
646 cxmutstr mtest = cx_strdup(test);
647 cxmutstr *mlist;
648 n = cx_strsplit_ma(alloc, mtest, cx_str(
"is,"),
4, &mlist);
649 CX_TEST_ASSERT(n ==
3);
650 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(mlist[
0]), cx_str(
"th")));
651 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(mlist[
1]), cx_str(
"")));
652 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(mlist[
2]), cx_str(
"a,csv,string")));
653 cxFree(alloc, mlist);
654 cx_strfree(&mtest);
655
656 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
657 }
658 cx_testing_allocator_destroy(&talloc);
659 }
660
661 CX_TEST(test_strtrim) {
662 cxstring t1 = cx_strtrim(cx_str(
" ein test \t "));
663 cxstring t2 = cx_strtrim(cx_str(
"abc"));
664 cxstring t3 = cx_strtrim(cx_str(
" 123"));
665 cxstring t4 = cx_strtrim(cx_str(
"xyz "));
666 cxstring t5 = cx_strtrim(cx_str(
" "));
667 cxstring empty = cx_strtrim(cx_str(
""));
668
669 CX_TEST_DO {
670 CX_TEST_ASSERT(
0 == cx_strcmp(t1, cx_str(
"ein test")));
671 CX_TEST_ASSERT(
0 == cx_strcmp(t2, cx_str(
"abc")));
672 CX_TEST_ASSERT(
0 == cx_strcmp(t3, cx_str(
"123")));
673 CX_TEST_ASSERT(
0 == cx_strcmp(t4, cx_str(
"xyz")));
674 CX_TEST_ASSERT(
0 == cx_strcmp(t5, cx_str(
"")));
675 CX_TEST_ASSERT(
0 == cx_strcmp(empty, cx_str(
"")));
676
677
678 cxmutstr m1 = cx_strtrim_m(cx_mutstr((
char *)
" ein test \t "));
679 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(m1), cx_str(
"ein test")));
680 }
681 }
682
683 CX_TEST(test_strprefix) {
684 cxstring str =
CX_STR(
"test my prefix and my suffix");
685 cxstring empty =
CX_STR(
"");
686 CX_TEST_DO {
687 CX_TEST_ASSERT(!cx_strprefix(empty, cx_str(
"pref")));
688 CX_TEST_ASSERT(cx_strprefix(str, empty));
689 CX_TEST_ASSERT(cx_strprefix(empty, empty));
690 CX_TEST_ASSERT(cx_strprefix(str, cx_str(
"test ")));
691 CX_TEST_ASSERT(!cx_strprefix(str, cx_str(
"8-) fsck ")));
692 }
693 }
694
695 CX_TEST(test_strsuffix) {
696 cxstring str =
CX_STR(
"test my prefix and my suffix");
697 cxstring empty =
CX_STR(
"");
698 CX_TEST_DO {
699 CX_TEST_ASSERT(!cx_strsuffix(empty, cx_str(
"suf")));
700 CX_TEST_ASSERT(cx_strsuffix(str, empty));
701 CX_TEST_ASSERT(cx_strsuffix(empty, empty));
702 CX_TEST_ASSERT(cx_strsuffix(str, cx_str(
"fix")));
703 CX_TEST_ASSERT(!cx_strsuffix(str, cx_str(
"fox")));
704 }
705 }
706
707 CX_TEST(test_strcaseprefix) {
708 cxstring str =
CX_STR(
"test my prefix and my suffix");
709 cxstring empty =
CX_STR(
"");
710 CX_TEST_DO {
711 CX_TEST_ASSERT(!cx_strcaseprefix(empty, cx_str(
"pREf")));
712 CX_TEST_ASSERT(cx_strcaseprefix(str, empty));
713 CX_TEST_ASSERT(cx_strcaseprefix(empty, empty));
714 CX_TEST_ASSERT(cx_strcaseprefix(str, cx_str(
"TEST ")));
715 CX_TEST_ASSERT(!cx_strcaseprefix(str, cx_str(
"8-) fsck ")));
716 }
717 }
718
719 CX_TEST(test_strcasesuffix) {
720 cxstring str =
CX_STR(
"test my prefix and my suffix");
721 cxstring empty =
CX_STR(
"");
722 CX_TEST_DO {
723 CX_TEST_ASSERT(!cx_strcasesuffix(empty, cx_str(
"sUf")));
724 CX_TEST_ASSERT(cx_strcasesuffix(str, empty));
725 CX_TEST_ASSERT(cx_strcasesuffix(empty, empty));
726 CX_TEST_ASSERT(cx_strcasesuffix(str, cx_str(
"FIX")));
727 CX_TEST_ASSERT(!cx_strcasesuffix(str, cx_str(
"fox")));
728 }
729 }
730
731 CX_TEST(test_strreplace) {
732 CxTestingAllocator talloc;
733 cx_testing_allocator_init(&talloc);
734 CxAllocator *alloc = &talloc.base;
735
736 cxstring str =
CX_STR(
"test ababab string aba");
737 cxstring longstr =
CX_STR(
738 "xyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacd");
739 cxstring notrail =
CX_STR(
"test abab");
740 cxstring empty =
CX_STR(
"");
741 cxstring astr =
CX_STR(
"aaaaaaaaaa");
742 cxstring csstr =
CX_STR(
"test AB ab TEST xyz");
743
744 cxmutstr repl = cx_strreplace(str, cx_str(
"abab"), cx_str(
"muchlonger"));
745 const char *expected =
"test muchlongerab string aba";
746
747 cxmutstr repln = cx_strreplacen(str, cx_str(
"ab"), cx_str(
"c"),
2);
748 const char *expectedn =
"test ccab string aba";
749
750 cxmutstr longrepl = cx_strreplace(longstr, cx_str(
"a"), cx_str(
"z"));
751 const char *longexpect =
"xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzcd";
752
753 cxmutstr replnotrail = cx_strreplace(notrail, cx_str(
"ab"), cx_str(
"z"));
754 const char *notrailexpect =
"test zz";
755
756 cxmutstr repleq = cx_strreplace(str, str, cx_str(
"hello"));
757 const char *eqexpect =
"hello";
758
759 cxmutstr replempty1 = cx_strreplace(empty, cx_str(
"ab"), cx_str(
"c"));
760 cxmutstr replempty2 = cx_strreplace(str, cx_str(
"abab"), empty);
761 const char *emptyexpect2 =
"test ab string aba";
762
763 cxmutstr replpre = cx_strreplace(str, cx_str(
"test "), cx_str(
"TEST "));
764 const char *preexpected =
"TEST ababab string aba";
765
766 cxmutstr replan1 = cx_strreplacen(astr, cx_str(
"a"), cx_str(
"x"),
1);
767 const char *an1expected =
"xaaaaaaaaa";
768
769 cxmutstr replan4 = cx_strreplacen(astr, cx_str(
"a"), cx_str(
"x"),
4);
770 const char *an4expected =
"xxxxaaaaaa";
771
772 cxmutstr replan9 = cx_strreplacen(astr, cx_str(
"a"), cx_str(
"x"),
9);
773 const char *an9expected =
"xxxxxxxxxa";
774
775 cxmutstr replan10 = cx_strreplacen(astr, cx_str(
"a"), cx_str(
"x"),
10);
776 const char *an10expected =
"xxxxxxxxxx";
777
778 cxmutstr norepl = cx_strreplace(cx_strn(
"hello world",
11), cx_str(
"worlds"), cx_str(
"test"));
779 const char *noreplexpect =
"hello world";
780
781 CX_TEST_DO {
782 cxmutstr repl1_a = cx_strreplace_a(alloc, csstr, cx_str(
"AB"), cx_str(
"*"));
783 const char *expeced1_a =
"test * ab TEST xyz";
784
785 cxmutstr repl2_a = cx_strreplace_a(alloc, csstr, cx_str(
"test"), cx_str(
"TEST"));
786 const char *expected2_a =
"TEST AB ab TEST xyz";
787
788 CX_TEST_ASSERT(repl.ptr != str.ptr);
789 ASSERT_ZERO_TERMINATED(repl);
790 CX_TEST_ASSERT(
0 == strcmp(repl.ptr, expected));
791 ASSERT_ZERO_TERMINATED(repln);
792 CX_TEST_ASSERT(
0 == strcmp(repln.ptr, expectedn));
793 ASSERT_ZERO_TERMINATED(longrepl);
794 CX_TEST_ASSERT(
0 == strcmp(longrepl.ptr, longexpect));
795 ASSERT_ZERO_TERMINATED(replnotrail);
796 CX_TEST_ASSERT(
0 == strcmp(replnotrail.ptr, notrailexpect));
797 ASSERT_ZERO_TERMINATED(repleq);
798 CX_TEST_ASSERT(
0 == strcmp(repleq.ptr, eqexpect));
799 ASSERT_ZERO_TERMINATED(replempty1);
800 CX_TEST_ASSERT(
0 == strcmp(replempty1.ptr,
""));
801 ASSERT_ZERO_TERMINATED(replempty2);
802 CX_TEST_ASSERT(
0 == strcmp(replempty2.ptr, emptyexpect2));
803 ASSERT_ZERO_TERMINATED(replpre);
804 CX_TEST_ASSERT(
0 == strcmp(replpre.ptr, preexpected));
805 ASSERT_ZERO_TERMINATED(replan1);
806 CX_TEST_ASSERT(
0 == strcmp(replan1.ptr, an1expected));
807 ASSERT_ZERO_TERMINATED(replan4);
808 CX_TEST_ASSERT(
0 == strcmp(replan4.ptr, an4expected));
809 ASSERT_ZERO_TERMINATED(replan9);
810 CX_TEST_ASSERT(
0 == strcmp(replan9.ptr, an9expected));
811 ASSERT_ZERO_TERMINATED(replan10);
812 CX_TEST_ASSERT(
0 == strcmp(replan10.ptr, an10expected));
813 ASSERT_ZERO_TERMINATED(repl1_a);
814 CX_TEST_ASSERT(
0 == strcmp(repl1_a.ptr, expeced1_a));
815 ASSERT_ZERO_TERMINATED(repl2_a);
816 CX_TEST_ASSERT(
0 == strcmp(repl2_a.ptr, expected2_a));
817 ASSERT_ZERO_TERMINATED(norepl);
818 CX_TEST_ASSERT(
0 == strcmp(norepl.ptr, noreplexpect));
819
820 cx_strfree_a(alloc, &repl1_a);
821 cx_strfree_a(alloc, &repl2_a);
822 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
823 }
824
825 cx_strfree(&repl);
826 cx_strfree(&repln);
827 cx_strfree(&longrepl);
828 cx_strfree(&replnotrail);
829 cx_strfree(&repleq);
830 cx_strfree(&replempty1);
831 cx_strfree(&replempty2);
832 cx_strfree(&replpre);
833 cx_strfree(&replan1);
834 cx_strfree(&replan4);
835 cx_strfree(&replan9);
836 cx_strfree(&replan10);
837 cx_strfree(&norepl);
838 cx_testing_allocator_destroy(&talloc);
839 }
840
841 CX_TEST(test_strtok) {
842 cxstring str =
CX_STR(
"a,comma,separated,string");
843 cxstring delim =
CX_STR(
",");
844 CX_TEST_DO {
845 CxStrtokCtx ctx = cx_strtok(str, delim,
3);
846 CX_TEST_ASSERT(ctx.str.ptr == str.ptr);
847 CX_TEST_ASSERT(ctx.str.length == str.length);
848 CX_TEST_ASSERT(ctx.delim.ptr == delim.ptr);
849 CX_TEST_ASSERT(ctx.delim.length == delim.length);
850 CX_TEST_ASSERT(ctx.limit ==
3);
851 CX_TEST_ASSERT(ctx.found ==
0);
852 CX_TEST_ASSERT(ctx.pos ==
0);
853 CX_TEST_ASSERT(ctx.next_pos ==
0);
854 CX_TEST_ASSERT(ctx.delim_more ==
NULL);
855 CX_TEST_ASSERT(ctx.delim_more_count ==
0);
856 }
857 }
858
859 CX_TEST(test_strtok_delim) {
860 cxstring str =
CX_STR(
"an,arbitrarily|separated;string");
861 cxstring delim =
CX_STR(
",");
862 cxstring delim_more[
2] = {
CX_STR(
"|"),
CX_STR(
";")};
863 CX_TEST_DO {
864 CxStrtokCtx ctx = cx_strtok(str, delim,
3);
865 cx_strtok_delim(&ctx, delim_more,
2);
866 CX_TEST_ASSERT(ctx.str.ptr == str.ptr);
867 CX_TEST_ASSERT(ctx.str.length == str.length);
868 CX_TEST_ASSERT(ctx.delim.ptr == delim.ptr);
869 CX_TEST_ASSERT(ctx.delim.length == delim.length);
870 CX_TEST_ASSERT(ctx.limit ==
3);
871 CX_TEST_ASSERT(ctx.found ==
0);
872 CX_TEST_ASSERT(ctx.pos ==
0);
873 CX_TEST_ASSERT(ctx.next_pos ==
0);
874 CX_TEST_ASSERT(ctx.delim_more == delim_more);
875 CX_TEST_ASSERT(ctx.delim_more_count ==
2);
876 }
877 }
878
879 CX_TEST(test_strtok_next_easy) {
880 cxstring str =
CX_STR(
"a,comma,separated,string");
881 cxstring delim =
CX_STR(
",");
882 CX_TEST_DO {
883 CxStrtokCtx ctx = cx_strtok(str, delim,
3);
884 bool ret;
885 cxstring tok;
886
887 ret = cx_strtok_next(&ctx, &tok);
888 CX_TEST_ASSERT(ret);
889 CX_TEST_ASSERT(
0 == cx_strcmp(tok, cx_str(
"a")));
890 CX_TEST_ASSERT(ctx.pos ==
0);
891 CX_TEST_ASSERT(ctx.next_pos ==
2);
892 CX_TEST_ASSERT(ctx.delim_pos ==
1);
893 CX_TEST_ASSERT(ctx.found ==
1);
894
895 ret = cx_strtok_next(&ctx, &tok);
896 CX_TEST_ASSERT(ret);
897 CX_TEST_ASSERT(
0 == cx_strcmp(tok, cx_str(
"comma")));
898 CX_TEST_ASSERT(ctx.pos ==
2);
899 CX_TEST_ASSERT(ctx.next_pos ==
8);
900 CX_TEST_ASSERT(ctx.delim_pos ==
7);
901 CX_TEST_ASSERT(ctx.found ==
2);
902
903 ret = cx_strtok_next(&ctx, &tok);
904 CX_TEST_ASSERT(ret);
905 CX_TEST_ASSERT(
0 == cx_strcmp(tok, cx_str(
"separated")));
906 CX_TEST_ASSERT(ctx.pos ==
8);
907 CX_TEST_ASSERT(ctx.next_pos ==
18);
908 CX_TEST_ASSERT(ctx.delim_pos ==
17);
909 CX_TEST_ASSERT(ctx.found ==
3);
910
911 ret = cx_strtok_next(&ctx, &tok);
912 CX_TEST_ASSERT(!ret);
913 CX_TEST_ASSERT(ctx.pos ==
8);
914 CX_TEST_ASSERT(ctx.next_pos ==
18);
915 CX_TEST_ASSERT(ctx.delim_pos ==
17);
916 CX_TEST_ASSERT(ctx.found ==
3);
917 }
918 }
919
920 CX_TEST(test_strtok_next_unlimited) {
921 cxstring str =
CX_STR(
"some;-;otherwise;-;separated;-;string;-;");
922 cxstring delim =
CX_STR(
";-;");
923 CX_TEST_DO {
924 CxStrtokCtx ctx = cx_strtok(str, delim,
SIZE_MAX);
925 bool ret;
926 cxstring tok;
927
928 ret = cx_strtok_next(&ctx, &tok);
929 CX_TEST_ASSERT(ret);
930 CX_TEST_ASSERT(
0 == cx_strcmp(tok, cx_str(
"some")));
931 CX_TEST_ASSERT(ctx.pos ==
0);
932 CX_TEST_ASSERT(ctx.next_pos ==
7);
933 CX_TEST_ASSERT(ctx.delim_pos ==
4);
934 CX_TEST_ASSERT(ctx.found ==
1);
935
936 ret = cx_strtok_next(&ctx, &tok);
937 CX_TEST_ASSERT(ret);
938 CX_TEST_ASSERT(
0 == cx_strcmp(tok, cx_str(
"otherwise")));
939 CX_TEST_ASSERT(ctx.pos ==
7);
940 CX_TEST_ASSERT(ctx.next_pos ==
19);
941 CX_TEST_ASSERT(ctx.delim_pos ==
16);
942 CX_TEST_ASSERT(ctx.found ==
2);
943
944 ret = cx_strtok_next(&ctx, &tok);
945 CX_TEST_ASSERT(ret);
946 CX_TEST_ASSERT(
0 == cx_strcmp(tok, cx_str(
"separated")));
947 CX_TEST_ASSERT(ctx.pos ==
19);
948 CX_TEST_ASSERT(ctx.next_pos ==
31);
949 CX_TEST_ASSERT(ctx.delim_pos ==
28);
950 CX_TEST_ASSERT(ctx.found ==
3);
951
952 ret = cx_strtok_next(&ctx, &tok);
953 CX_TEST_ASSERT(ret);
954 CX_TEST_ASSERT(
0 == cx_strcmp(tok, cx_str(
"string")));
955 CX_TEST_ASSERT(ctx.pos ==
31);
956 CX_TEST_ASSERT(ctx.next_pos ==
40);
957 CX_TEST_ASSERT(ctx.delim_pos ==
37);
958 CX_TEST_ASSERT(ctx.found ==
4);
959
960 ret = cx_strtok_next(&ctx, &tok);
961 CX_TEST_ASSERT(ret);
962 CX_TEST_ASSERT(
0 == cx_strcmp(tok, cx_str(
"")));
963 CX_TEST_ASSERT(ctx.pos ==
40);
964 CX_TEST_ASSERT(ctx.next_pos ==
40);
965 CX_TEST_ASSERT(ctx.delim_pos ==
40);
966 CX_TEST_ASSERT(ctx.found ==
5);
967
968 ret = cx_strtok_next(&ctx, &tok);
969 CX_TEST_ASSERT(!ret);
970 CX_TEST_ASSERT(ctx.pos ==
40);
971 CX_TEST_ASSERT(ctx.delim_pos ==
40);
972 CX_TEST_ASSERT(ctx.found ==
5);
973 }
974 }
975
976 static void test_toupper(cxmutstr string) {
977 for (
size_t i =
0; i < string.length; i++) {
978 if ((
unsigned int)(string.ptr[i] -
'a') <
26u) {
979 string.ptr[i] +=
'A' -
'a';
980 }
981 }
982 }
983
984 CX_TEST(test_strtok_next_advanced) {
985 cxmutstr str = cx_strdup(cx_str(
"an,arbitrarily;||separated;string"));
986 cxstring delim =
CX_STR(
",");
987 cxstring delim_more[
2] = {
CX_STR(
"||"),
CX_STR(
";")};
988 CX_TEST_DO {
989 CxStrtokCtx ctx = cx_strtok(str, delim,
10);
990 cx_strtok_delim(&ctx, delim_more,
2);
991 bool ret;
992 cxmutstr tok;
993
994 ret = cx_strtok_next_m(&ctx, &tok);
995 CX_TEST_ASSERT(ret);
996 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(tok), cx_str(
"an")));
997 CX_TEST_ASSERT(ctx.pos ==
0);
998 CX_TEST_ASSERT(ctx.next_pos ==
3);
999 CX_TEST_ASSERT(ctx.delim_pos ==
2);
1000 CX_TEST_ASSERT(ctx.found ==
1);
1001 test_toupper(tok);
1002
1003 ret = cx_strtok_next_m(&ctx, &tok);
1004 CX_TEST_ASSERT(ret);
1005 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(tok), cx_str(
"arbitrarily")));
1006 CX_TEST_ASSERT(ctx.pos ==
3);
1007 CX_TEST_ASSERT(ctx.next_pos ==
15);
1008 CX_TEST_ASSERT(ctx.delim_pos ==
14);
1009 CX_TEST_ASSERT(ctx.found ==
2);
1010 test_toupper(tok);
1011
1012 ret = cx_strtok_next_m(&ctx, &tok);
1013 CX_TEST_ASSERT(ret);
1014 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(tok), cx_str(
"")));
1015 CX_TEST_ASSERT(ctx.pos ==
15);
1016 CX_TEST_ASSERT(ctx.next_pos ==
17);
1017 CX_TEST_ASSERT(ctx.delim_pos ==
15);
1018 CX_TEST_ASSERT(ctx.found ==
3);
1019 test_toupper(tok);
1020
1021 ret = cx_strtok_next_m(&ctx, &tok);
1022 CX_TEST_ASSERT(ret);
1023 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(tok), cx_str(
"separated")));
1024 CX_TEST_ASSERT(ctx.pos ==
17);
1025 CX_TEST_ASSERT(ctx.next_pos ==
27);
1026 CX_TEST_ASSERT(ctx.delim_pos ==
26);
1027 CX_TEST_ASSERT(ctx.found ==
4);
1028 test_toupper(tok);
1029
1030 ret = cx_strtok_next_m(&ctx, &tok);
1031 CX_TEST_ASSERT(ret);
1032 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(tok), cx_str(
"string")));
1033 CX_TEST_ASSERT(ctx.pos ==
27);
1034 CX_TEST_ASSERT(ctx.next_pos ==
33);
1035 CX_TEST_ASSERT(ctx.delim_pos ==
33);
1036 CX_TEST_ASSERT(ctx.found ==
5);
1037 test_toupper(tok);
1038
1039 ret = cx_strtok_next_m(&ctx, &tok);
1040 CX_TEST_ASSERT(!ret);
1041 CX_TEST_ASSERT(ctx.pos ==
27);
1042 CX_TEST_ASSERT(ctx.next_pos ==
33);
1043 CX_TEST_ASSERT(ctx.delim_pos ==
33);
1044 CX_TEST_ASSERT(ctx.found ==
5);
1045
1046 CX_TEST_ASSERT(
0 == cx_strcmp(cx_strcast(str), cx_str(
"AN,ARBITRARILY;||SEPARATED;STRING")));
1047 }
1048 cx_strfree(&str);
1049 }
1050
1051 #define test_strtoint_impl(suffix, num, base, var, min, max) \
1052 do { \
1053 errno =
0; \
1054 int r = cx_strto##var(cx_str(
#num), &var, base); \
1055 if ((min) <= (num##suffix) && (num##suffix) <= (max)) { \
1056 CX_TEST_ASSERTM(
0 == r,
"failed for "#num); \
1057 CX_TEST_ASSERT(
0 == errno); \
1058 CX_TEST_ASSERT((num##suffix) == (
0##suffix)+(var)); \
1059 }
else { \
1060 CX_TEST_ASSERTM(
0 != r,
"out-of-range not detected for "#num " in variant "#var); \
1061 CX_TEST_ASSERT(
ERANGE == errno); \
1062 } \
1063 }
while (
0)
1064
1065 #define test_strtoint_rollout_signed_impl(num, base) \
1066 test_strtoint_impl(
LL, num, base, s,
SHRT_MIN,
SHRT_MAX); \
1067 test_strtoint_impl(
LL, num, base, i,
INT_MIN,
INT_MAX); \
1068 test_strtoint_impl(
LL, num, base, l,
LONG_MIN,
LONG_MAX); \
1069 test_strtoint_impl(
LL, num, base, ll,
LLONG_MIN,
LLONG_MAX); \
1070 test_strtoint_impl(
LL, num, base, i8,
INT8_MIN,
INT8_MAX); \
1071 test_strtoint_impl(
LL, num, base, i16,
INT16_MIN,
INT16_MAX); \
1072 test_strtoint_impl(
LL, num, base, i32,
INT32_MIN,
INT32_MAX); \
1073 test_strtoint_impl(
LL, num, base, i64,
INT64_MIN,
INT64_MAX);
1074
1075 #define test_strtoint_rollout_signed(num, base) \
1076 test_strtoint_rollout_signed_impl(num, base); \
1077 test_strtoint_rollout_signed_impl(-num, base)
1078
1079 #define test_strtoint_rollout(num, base) \
1080 test_strtoint_impl(
ULL, num, base, us,
0,
USHRT_MAX); \
1081 test_strtoint_impl(
ULL, num, base, u,
0,
UINT_MAX); \
1082 test_strtoint_impl(
ULL, num, base, ul,
0,
ULONG_MAX); \
1083 test_strtoint_impl(
ULL, num, base, ull,
0,
ULLONG_MAX); \
1084 test_strtoint_impl(
ULL, num, base, u8,
0,
UINT8_MAX); \
1085 test_strtoint_impl(
ULL, num, base, u16,
0,
UINT16_MAX); \
1086 test_strtoint_impl(
ULL, num, base, u32,
0,
UINT32_MAX); \
1087 test_strtoint_impl(
ULL, num, base, u64,
0,
UINT64_MAX); \
1088 test_strtoint_impl(
ULL, num, base, z,
0,
SIZE_MAX)
1089
1090 CX_TEST(test_string_to_signed_integer) {
1091 short s;
1092 int i;
1093 long l;
1094 long long ll;
1095 int8_t i8;
1096 int16_t i16;
1097 int32_t i32;
1098 int64_t i64;
1099 CX_TEST_DO {
1100
1101 test_strtoint_rollout_signed(
5,
10);
1102 test_strtoint_rollout_signed(
47,
10);
1103 test_strtoint_rollout_signed(
210,
10);
1104 test_strtoint_rollout_signed(
5678,
10);
1105 test_strtoint_rollout_signed(
40678,
10);
1106 test_strtoint_rollout_signed(
1350266537,
10);
1107 test_strtoint_rollout_signed(
3350266537,
10);
1108 test_strtoint_rollout_signed(
473350266537,
10);
1109 test_strtoint_rollout_signed(
057,
8);
1110 test_strtoint_rollout_signed(
0322,
8);
1111 test_strtoint_rollout_signed(
013056,
8);
1112 test_strtoint_rollout_signed(
0117346,
8);
1113 test_strtoint_rollout_signed(
012036667251,
8);
1114 test_strtoint_rollout_signed(
030754201251,
8);
1115 test_strtoint_rollout_signed(
06706567757251,
8);
1116 test_strtoint_rollout_signed(
0767716340165362204025,
8);
1117 test_strtoint_rollout_signed(
0x65,
16);
1118 test_strtoint_rollout_signed(
0xf5,
16);
1119 test_strtoint_rollout_signed(
0xABC5,
16);
1120 test_strtoint_rollout_signed(
0xFBC5,
16);
1121 test_strtoint_rollout_signed(
0x6df9CE03,
16);
1122 test_strtoint_rollout_signed(
0xFdf9CE03,
16);
1123 test_strtoint_rollout_signed(
0x6df9CE03AbC90815,
16);
1124 #if __STDC_VERSION__ >=
202300L
1125 test_strtoint_rollout_signed(
0b01000010100100101110101001110101,
2);
1126 test_strtoint_rollout_signed(
0b00011010101100001111111001010100,
2);
1127 test_strtoint_rollout_signed(
0b10110001001001010001010111010011,
2);
1128 #endif
1129
1130
1131
1132
1133
1134 errno =
0;
1135 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"0x8df9CE03AbC90815"), &ll,
16));
1136 CX_TEST_ASSERT(errno ==
ERANGE);
1137
1138
1139 #if LLONG_MAX ==
9223372036854775807ll
1140 errno =
0;
1141 CX_TEST_ASSERT(
0 == cx_strtoll(cx_str(
"-9223372036854775808"), &ll,
10));
1142 CX_TEST_ASSERT(ll ==
LLONG_MIN);
1143 CX_TEST_ASSERT(errno ==
0);
1144 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"-9223372036854775809"), &ll,
10));
1145 CX_TEST_ASSERT(errno ==
ERANGE);
1146 #endif
1147
1148
1149 errno =
0;
1150 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
""), &ll,
16));
1151 CX_TEST_ASSERT(errno ==
EINVAL);
1152 errno =
0;
1153 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
NULL), &ll,
16));
1154 CX_TEST_ASSERT(errno ==
EINVAL);
1155
1156
1157 errno =
0;
1158 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"7"), &ll,
12));
1159 CX_TEST_ASSERT(errno ==
EINVAL);
1160
1161
1162 errno =
0;
1163 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"-"), &ll,
10));
1164 CX_TEST_ASSERT(errno ==
EINVAL);
1165 errno =
0;
1166 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"+"), &ll,
10));
1167 CX_TEST_ASSERT(errno ==
EINVAL);
1168 errno =
0;
1169 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"-+15"), &ll,
10));
1170 CX_TEST_ASSERT(errno ==
EINVAL);
1171 errno =
0;
1172 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"--15"), &ll,
10));
1173 CX_TEST_ASSERT(errno ==
EINVAL);
1174 errno =
0;
1175 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"+-15"), &ll,
10));
1176 CX_TEST_ASSERT(errno ==
EINVAL);
1177 errno =
0;
1178 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"++15"), &ll,
10));
1179 CX_TEST_ASSERT(errno ==
EINVAL);
1180
1181
1182 errno =
0;
1183 CX_TEST_ASSERT(
0 != cx_strtoi16(cx_str(
"0x8000"), &i16,
16));
1184 CX_TEST_ASSERT(errno ==
ERANGE);
1185 errno =
0;
1186 CX_TEST_ASSERT(
0 == cx_strtoi16(cx_str(
"-0x8000"), &i16,
16));
1187 CX_TEST_ASSERT(errno ==
0);
1188 CX_TEST_ASSERT(i16 ==
INT16_MIN);
1189 errno =
0;
1190 CX_TEST_ASSERT(
0 != cx_strtoi64(cx_str(
"X8000000000000000"), &i64,
16));
1191 CX_TEST_ASSERT(errno ==
ERANGE);
1192 errno =
0;
1193 CX_TEST_ASSERT(
0 == cx_strtoi64(cx_str(
"-X8000000000000000"), &i64,
16));
1194 CX_TEST_ASSERT(errno ==
0);
1195 CX_TEST_ASSERT(i64 ==
INT64_MIN);
1196
1197
1198 CX_TEST_ASSERT(
0 == cx_strtoi32(cx_str(
"-123,456"), &i32,
10));
1199 CX_TEST_ASSERT(i32 ==
-123456);
1200 errno =
0;
1201 CX_TEST_ASSERT(
0 != cx_strtoi16_lc(cx_str(
"-Xab,cd"), &i16,
16,
"''"));
1202 CX_TEST_ASSERT(errno ==
EINVAL);
1203 errno =
0;
1204 CX_TEST_ASSERT(
0 != cx_strtoi16_lc(cx_str(
"-X''ab''cd"), &i16,
16,
"''"));
1205 CX_TEST_ASSERT(errno ==
ERANGE);
1206 errno =
0;
1207 CX_TEST_ASSERT(
0 == cx_strtoi16_lc(cx_str(
"-X''67''89"), &i16,
16,
"''"));
1208 CX_TEST_ASSERT(errno ==
0);
1209 CX_TEST_ASSERT(i16 ==
-0x6789);
1210
1211
1212 errno =
0;
1213 CX_TEST_ASSERT(
0 != cx_strtoi8_lc(cx_str(
"-1010 1011"), &i8,
2,
" "));
1214 CX_TEST_ASSERT(errno ==
ERANGE);
1215 errno =
0;
1216 CX_TEST_ASSERT(
0 != cx_strtoi8_lc(cx_str(
"1010 1011"), &i8,
2,
" "));
1217 CX_TEST_ASSERT(errno ==
ERANGE);
1218 errno =
0;
1219 CX_TEST_ASSERT(
0 == cx_strtoi8_lc(cx_str(
"-0101 0101"), &i8,
2,
" "));
1220 CX_TEST_ASSERT(errno ==
0);
1221 CX_TEST_ASSERT(i8 ==
-0x55);
1222 }
1223 }
1224
1225 CX_TEST(test_string_to_unsigned_integer) {
1226 unsigned short us;
1227 unsigned int u;
1228 unsigned long ul;
1229 unsigned long long ull;
1230 uint8_t u8;
1231 uint16_t u16;
1232 uint32_t u32;
1233 uint64_t u64;
1234 size_t z;
1235 CX_TEST_DO {
1236
1237 test_strtoint_rollout(
0,
10);
1238 test_strtoint_rollout(
47,
10);
1239 test_strtoint_rollout(
210,
10);
1240 test_strtoint_rollout(
5678,
10);
1241 test_strtoint_rollout(
40678,
10);
1242 test_strtoint_rollout(
1350266537,
10);
1243 test_strtoint_rollout(
3350266537,
10);
1244 test_strtoint_rollout(
473350266537,
10);
1245 test_strtoint_rollout(
0,
8);
1246 test_strtoint_rollout(
057,
8);
1247 test_strtoint_rollout(
0322,
8);
1248 test_strtoint_rollout(
013056,
8);
1249 test_strtoint_rollout(
0117346,
8);
1250 test_strtoint_rollout(
012036667251,
8);
1251 test_strtoint_rollout(
030754201251,
8);
1252 test_strtoint_rollout(
06706567757251,
8);
1253 test_strtoint_rollout(
01767716340165362204025,
8);
1254 test_strtoint_rollout(
0x0,
16);
1255 test_strtoint_rollout(
0,
16);
1256 test_strtoint_rollout(
0x65,
16);
1257 test_strtoint_rollout(
0xf5,
16);
1258 test_strtoint_rollout(
0xABC5,
16);
1259 test_strtoint_rollout(
0xFBC5,
16);
1260 test_strtoint_rollout(
0x6df9CE03,
16);
1261 test_strtoint_rollout(
0xFdf9CE03,
16);
1262 test_strtoint_rollout(
0x6df9CE03AbC90815,
16);
1263 test_strtoint_rollout(
0xfdf9CE03AbC90815,
16);
1264 #if __STDC_VERSION__ >=
202300L
1265 test_strtoint_rollout(
0b0,
2);
1266 test_strtoint_rollout(
0,
2);
1267 test_strtoint_rollout(
0b01000010100100101110101001110101,
2);
1268 test_strtoint_rollout(
0b00011010101100001111111001010100,
2);
1269 test_strtoint_rollout(
0b10110001001001010001010111010011,
2);
1270 #endif
1271
1272
1273
1274
1275
1276 CX_TEST_ASSERT(
0 == cx_strtou32(cx_str(
"+5"), &u32,
10));
1277 CX_TEST_ASSERT(u32 ==
5);
1278
1279
1280 CX_TEST_ASSERT(
0 == cx_strtou32(cx_str(
"123,456"), &u32,
10));
1281 CX_TEST_ASSERT(u32 ==
123456);
1282 errno =
0;
1283 CX_TEST_ASSERT(
0 != cx_strtou16_lc(cx_str(
"ab,cd"), &u16,
16,
"''"));
1284 CX_TEST_ASSERT(errno ==
EINVAL);
1285 errno =
0;
1286 CX_TEST_ASSERT(
0 == cx_strtou16_lc(cx_str(
"ab''cd"), &u16,
16,
"''"));
1287 CX_TEST_ASSERT(errno ==
0);
1288 CX_TEST_ASSERT(u16 ==
0xabcd);
1289
1290
1291 errno =
0;
1292 CX_TEST_ASSERT(
0 != cx_strtou8_lc(cx_str(
"1 1010 1011"), &u8,
2,
" "));
1293 CX_TEST_ASSERT(errno ==
ERANGE);
1294 errno =
0;
1295 CX_TEST_ASSERT(
0 == cx_strtou8_lc(cx_str(
"1010 1011"), &u8,
2,
" "));
1296 CX_TEST_ASSERT(errno ==
0);
1297 CX_TEST_ASSERT(u8 ==
0xAB);
1298
1299
1300 errno =
0;
1301 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
""), &ull,
16));
1302 CX_TEST_ASSERT(errno ==
EINVAL);
1303 errno =
0;
1304 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
NULL), &ull,
16));
1305 CX_TEST_ASSERT(errno ==
EINVAL);
1306
1307
1308 errno =
0;
1309 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
"7"), &ull,
12));
1310 CX_TEST_ASSERT(errno ==
EINVAL);
1311
1312
1313 errno =
0;
1314 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
"0b"), &ull,
2));
1315 CX_TEST_ASSERT(errno ==
EINVAL);
1316 errno =
0;
1317 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
"b"), &ull,
2));
1318 CX_TEST_ASSERT(errno ==
EINVAL);
1319 errno =
0;
1320 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
"0x"), &ull,
16));
1321 CX_TEST_ASSERT(errno ==
EINVAL);
1322 errno =
0;
1323 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
"x"), &ull,
16));
1324 CX_TEST_ASSERT(errno ==
EINVAL);
1325 errno =
0;
1326 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
"#"), &ull,
16));
1327 CX_TEST_ASSERT(errno ==
EINVAL);
1328 }
1329 }
1330
1331 CX_TEST(test_string_to_float) {
1332 float f;
1333 CX_TEST_DO {
1334 CX_TEST_ASSERT(
0 == cx_strtof(cx_str(
"11.3"), &f));
1335 CX_TEST_ASSERT(
0 == cx_vcmp_float(
11.3f, f));
1336
1337 CX_TEST_ASSERT(
0 == cx_strtof(cx_str(
"-4.711e+1"), &f));
1338 CX_TEST_ASSERT(
0 == cx_vcmp_float(
-47.11f, f));
1339
1340 CX_TEST_ASSERT(
0 == cx_strtof(cx_str(
"1.67262192595e-27"), &f));
1341 CX_TEST_ASSERT(
0 == cx_vcmp_float(
1.67262192595e-27f, f));
1342
1343 CX_TEST_ASSERT(
0 == cx_strtof_lc(cx_str(
"138,339.4"), &f,
'.',
","));
1344 CX_TEST_ASSERT(
0 == cx_vcmp_float(
138339.4f, f));
1345
1346 CX_TEST_ASSERT(
0 == cx_strtof_lc(cx_str(
"138,339.4"), &f,
',',
"."));
1347 CX_TEST_ASSERT(
0 == cx_vcmp_float(
138.3394f, f));
1348
1349 errno =
0;
1350 CX_TEST_ASSERT(
0 != cx_strtof(cx_str(
"15e"), &f));
1351 CX_TEST_ASSERT(errno ==
EINVAL);
1352 errno =
0;
1353 CX_TEST_ASSERT(
0 != cx_strtof(cx_str(
"15e+"), &f));
1354 CX_TEST_ASSERT(errno ==
EINVAL);
1355 errno =
0;
1356 CX_TEST_ASSERT(
0 != cx_strtof(cx_str(
"15e-"), &f));
1357 CX_TEST_ASSERT(errno ==
EINVAL);
1358 CX_TEST_ASSERT(
0 == cx_strtof(cx_str(
"15e-0"), &f));
1359 CX_TEST_ASSERT(
0 == cx_vcmp_float(
15.f, f));
1360
1361 CX_TEST_ASSERT(
0 == cx_strtof(cx_str(
"3e38"), &f));
1362 CX_TEST_ASSERT(
0 == cx_vcmp_float(
3e38f, f));
1363 errno =
0;
1364 CX_TEST_ASSERT(
0 != cx_strtof(cx_str(
"3e39"), &f));
1365 CX_TEST_ASSERT(errno ==
ERANGE);
1366 CX_TEST_ASSERT(
0 == cx_strtof(cx_str(
"-3e38"), &f));
1367 CX_TEST_ASSERT(
0 == cx_vcmp_float(
-3e38f, f));
1368 errno =
0;
1369 CX_TEST_ASSERT(
0 != cx_strtof(cx_str(
"-3e39"), &f));
1370 CX_TEST_ASSERT(errno ==
ERANGE);
1371 CX_TEST_ASSERT(
0 == cx_strtof(cx_str(
"1.18e-38"), &f));
1372 CX_TEST_ASSERT(
0 == cx_vcmp_float(
1.18e-38f, f));
1373 errno =
0;
1374 CX_TEST_ASSERT(
0 != cx_strtof(cx_str(
"1.17e-38"), &f));
1375 CX_TEST_ASSERT(errno ==
ERANGE);
1376 }
1377 }
1378
1379 CX_TEST(test_string_to_double) {
1380 double d;
1381 CX_TEST_DO {
1382 CX_TEST_ASSERT(
0 == cx_strtod(cx_str(
"11.3"), &d));
1383 CX_TEST_ASSERT(
0 == cx_vcmp_double(
11.3, d));
1384
1385 CX_TEST_ASSERT(
0 == cx_strtod(cx_str(
"13."), &d));
1386 CX_TEST_ASSERT(
0 == cx_vcmp_double(
13.0, d));
1387
1388 CX_TEST_ASSERT(
0 == cx_strtod(cx_str(
"47"), &d));
1389 CX_TEST_ASSERT(
0 == cx_vcmp_double(
47.0, d));
1390
1391 CX_TEST_ASSERT(
0 == cx_strtod(cx_str(
"-13.37"), &d));
1392 CX_TEST_ASSERT(
0 == cx_vcmp_double(
-13.37, d));
1393
1394 CX_TEST_ASSERT(
0 == cx_strtod(cx_str(
"-4.711e+1"), &d));
1395 CX_TEST_ASSERT(
0 == cx_vcmp_double(
-47.11, d));
1396
1397 CX_TEST_ASSERT(
0 == cx_strtod(cx_str(
"1.67262192595e-27"), &d));
1398 CX_TEST_ASSERT(
0 == cx_vcmp_double(
1.67262192595e-27, d));
1399
1400 CX_TEST_ASSERT(
0 == cx_strtod_lc(cx_str(
"138,339.4"), &d,
'.',
","));
1401 CX_TEST_ASSERT(
0 == cx_vcmp_double(
138339.4, d));
1402
1403 CX_TEST_ASSERT(
0 == cx_strtod_lc(cx_str(
"138,339.4"), &d,
',',
"."));
1404 CX_TEST_ASSERT(
0 == cx_vcmp_double(
138.3394, d));
1405
1406 CX_TEST_ASSERT(
0 == cx_strtod_lc(cx_str(
"13.37e04.7"), &d,
',',
"."));
1407 CX_TEST_ASSERT(
0 == cx_vcmp_double(
1337e47, d));
1408
1409 d =
47.11;
1410 errno =
0;
1411 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
""), &d));
1412 CX_TEST_ASSERT(errno ==
EINVAL);
1413 CX_TEST_ASSERT(d ==
47.11);
1414 errno =
0;
1415 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
NULL), &d));
1416 CX_TEST_ASSERT(errno ==
EINVAL);
1417 CX_TEST_ASSERT(d ==
47.11);
1418 errno =
0;
1419 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
"+"), &d));
1420 CX_TEST_ASSERT(errno ==
EINVAL);
1421 CX_TEST_ASSERT(d ==
47.11);
1422 errno =
0;
1423 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
"-"), &d));
1424 CX_TEST_ASSERT(errno ==
EINVAL);
1425 CX_TEST_ASSERT(d ==
47.11);
1426 errno =
0;
1427 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
"+-5"), &d));
1428 CX_TEST_ASSERT(errno ==
EINVAL);
1429 CX_TEST_ASSERT(d ==
47.11);
1430 errno =
0;
1431 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
"-+5"), &d));
1432 CX_TEST_ASSERT(errno ==
EINVAL);
1433 CX_TEST_ASSERT(d ==
47.11);
1434 errno =
0;
1435 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
"++5"), &d));
1436 CX_TEST_ASSERT(errno ==
EINVAL);
1437 CX_TEST_ASSERT(d ==
47.11);
1438 errno =
0;
1439 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
"--5"), &d));
1440 CX_TEST_ASSERT(errno ==
EINVAL);
1441 CX_TEST_ASSERT(d ==
47.11);
1442
1443 errno =
0;
1444 CX_TEST_ASSERT(
0 != cx_strtod_lc(cx_str(
"."), &d,
'.',
"''"));
1445 CX_TEST_ASSERT(errno ==
EINVAL);
1446 CX_TEST_ASSERT(d ==
47.11);
1447
1448 errno =
0;
1449 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
"19e0x5"), &d));
1450 CX_TEST_ASSERT(errno ==
EINVAL);
1451 CX_TEST_ASSERT(d ==
47.11);
1452
1453
1454 }
1455 }
1456
1457 CX_TEST(test_string_to_number_notrim) {
1458 long long i;
1459 unsigned long long u;
1460 float f;
1461 double d;
1462 CX_TEST_DO {
1463 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
"-42 "), &i,
10));
1464 CX_TEST_ASSERT(
0 != cx_strtoll(cx_str(
" -42"), &i,
10));
1465 CX_TEST_ASSERT(
0 == cx_strtoll(cx_str(
"-42"), &i,
10));
1466 CX_TEST_ASSERT(i ==
-42);
1467
1468 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
"42 "), &u,
10));
1469 CX_TEST_ASSERT(
0 != cx_strtoull(cx_str(
" 42"), &u,
10));
1470 CX_TEST_ASSERT(
0 == cx_strtoull(cx_str(
"42"), &u,
10));
1471 CX_TEST_ASSERT(u ==
42);
1472
1473 CX_TEST_ASSERT(
0 != cx_strtof(cx_str(
"13.37 "), &f));
1474 CX_TEST_ASSERT(
0 != cx_strtof(cx_str(
" 13.37"), &f));
1475 CX_TEST_ASSERT(
0 == cx_strtof(cx_str(
"13.37"), &f));
1476 CX_TEST_ASSERT(
0 == cx_vcmp_float(f,
13.37f));
1477
1478 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
"13.37 "), &d));
1479 CX_TEST_ASSERT(
0 != cx_strtod(cx_str(
" 13.37"), &d));
1480 CX_TEST_ASSERT(
0 == cx_strtod(cx_str(
"13.37"), &d));
1481 CX_TEST_ASSERT(
0 == cx_vcmp_double(d,
13.37));
1482 }
1483 }
1484
1485 CX_TEST(test_strformat) {
1486 cxstring str =
CX_STR(
"Hello, World!");
1487 CX_TEST_DO {
1488 char actual[
64];
1489 snprintf(actual,
64,
"Test %"CX_PRIstr
" Success.",
CX_SFMT(str));
1490 CX_TEST_ASSERT(
0 == strncmp(
"Test Hello, World! Success.", actual,
64));
1491 }
1492 }
1493
1494 CxTestSuite *cx_test_suite_string(
void) {
1495 CxTestSuite *suite = cx_test_suite_new(
"string");
1496
1497 cx_test_register(suite, test_string_construct);
1498 cx_test_register(suite, test_string_cast);
1499 cx_test_register(suite, test_strfree);
1500 cx_test_register(suite, test_strdup);
1501 cx_test_register(suite, test_strdup_shortened);
1502 cx_test_register(suite, test_strcpy);
1503 cx_test_register(suite, test_strlen);
1504 cx_test_register(suite, test_strsubs);
1505 cx_test_register(suite, test_strchr);
1506 cx_test_register(suite, test_strrchr);
1507 cx_test_register(suite, test_strstr);
1508 cx_test_register(suite, test_strcmp);
1509 cx_test_register(suite, test_strcasecmp);
1510 cx_test_register(suite, test_strcat);
1511 cx_test_register(suite, test_strcat_more_than_eight);
1512 cx_test_register(suite, test_strsplit);
1513 cx_test_register(suite, test_strsplit_a);
1514 cx_test_register(suite, test_strtrim);
1515 cx_test_register(suite, test_strprefix);
1516 cx_test_register(suite, test_strsuffix);
1517 cx_test_register(suite, test_strcaseprefix);
1518 cx_test_register(suite, test_strcasesuffix);
1519 cx_test_register(suite, test_strreplace);
1520 cx_test_register(suite, test_strtok);
1521 cx_test_register(suite, test_strtok_delim);
1522 cx_test_register(suite, test_strtok_next_easy);
1523 cx_test_register(suite, test_strtok_next_unlimited);
1524 cx_test_register(suite, test_strtok_next_advanced);
1525 cx_test_register(suite, test_strformat);
1526
1527 return suite;
1528 }
1529
1530 CxTestSuite *cx_test_suite_string_to_number(
void) {
1531 CxTestSuite *suite = cx_test_suite_new(
"string to number");
1532
1533 cx_test_register(suite, test_string_to_signed_integer);
1534 cx_test_register(suite, test_string_to_unsigned_integer);
1535 cx_test_register(suite, test_string_to_float);
1536 cx_test_register(suite, test_string_to_double);
1537 cx_test_register(suite, test_string_to_number_notrim);
1538
1539 return suite;
1540 }
1541