tests/test_string.c

changeset 1500
d20037235c9c
parent 1426
3a89b31f0724
equal deleted inserted replaced
1499:d0a0a41405bb 1500:d20037235c9c
41 CX_TEST(test_string_construct) { 41 CX_TEST(test_string_construct) {
42 cxstring s1 = CX_STR("1234"); 42 cxstring s1 = CX_STR("1234");
43 cxstring s2 = cx_strn("abcd", 2); 43 cxstring s2 = cx_strn("abcd", 2);
44 cxmutstr s3 = cx_mutstr((char *) "1234"); 44 cxmutstr s3 = cx_mutstr((char *) "1234");
45 cxmutstr s4 = cx_mutstrn((char *) "abcd", 2); 45 cxmutstr s4 = cx_mutstrn((char *) "abcd", 2);
46 cxstring snull = cx_str(NULL);
47 cxmutstr mnull = cx_mutstr(NULL);
46 CX_TEST_DO { 48 CX_TEST_DO {
47 CX_TEST_ASSERT(s1.length == 4); 49 CX_TEST_ASSERT(s1.length == 4);
48 CX_TEST_ASSERT(strncmp(s1.ptr, "1234", 4) == 0); 50 CX_TEST_ASSERT(strncmp(s1.ptr, "1234", 4) == 0);
49 CX_TEST_ASSERT(s2.length == 2); 51 CX_TEST_ASSERT(s2.length == 2);
50 CX_TEST_ASSERT(strncmp(s2.ptr, "ab", 2) == 0); 52 CX_TEST_ASSERT(strncmp(s2.ptr, "ab", 2) == 0);
51 CX_TEST_ASSERT(s3.length == 4); 53 CX_TEST_ASSERT(s3.length == 4);
52 CX_TEST_ASSERT(strncmp(s3.ptr, "1234", 4) == 0); 54 CX_TEST_ASSERT(strncmp(s3.ptr, "1234", 4) == 0);
53 CX_TEST_ASSERT(s4.length == 2); 55 CX_TEST_ASSERT(s4.length == 2);
54 CX_TEST_ASSERT(strncmp(s4.ptr, "ab", 2) == 0); 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, ""));
55 } 63 }
56 } 64 }
57 65
58 CX_TEST(test_string_cast) { 66 CX_TEST(test_string_cast) {
59 char *c1 = (char*) "123"; 67 char *c1 = (char*) "123";
87 CX_TEST_ASSERT(str.length == 16); 95 CX_TEST_ASSERT(str.length == 16);
88 cx_strfree_a(alloc, &str); 96 cx_strfree_a(alloc, &str);
89 CX_TEST_ASSERT(str.ptr == NULL); 97 CX_TEST_ASSERT(str.ptr == NULL);
90 CX_TEST_ASSERT(str.length == 0); 98 CX_TEST_ASSERT(str.length == 0);
91 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 99 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
100 // check that this does not explode
101 cx_strfree(NULL);
102 cx_strfree_a(alloc, NULL);
92 } 103 }
93 cx_testing_allocator_destroy(&talloc); 104 cx_testing_allocator_destroy(&talloc);
94 } 105 }
95 106
96 CX_TEST(test_strdup) { 107 CX_TEST(test_strdup) {
391 cxmutstr t6 = cx_strdup(cx_str("Hello")); 402 cxmutstr t6 = cx_strdup(cx_str("Hello"));
392 t6 = cx_strcat_m(t6, 2, cx_str(", "), cx_str("World!")); 403 t6 = cx_strcat_m(t6, 2, cx_str(", "), cx_str("World!"));
393 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t6), cx_str("Hello, World!"))); 404 CX_TEST_ASSERT(0 == cx_strcmp(cx_strcast(t6), cx_str("Hello, World!")));
394 ASSERT_ZERO_TERMINATED(t6); 405 ASSERT_ZERO_TERMINATED(t6);
395 cx_strfree(&t6); 406 cx_strfree(&t6);
407
408 // test overflow with fake strings
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);
396 } 418 }
397 cx_testing_allocator_destroy(&talloc); 419 cx_testing_allocator_destroy(&talloc);
398 } 420 }
399 421
400 CX_TEST(test_strcat_more_than_eight) { 422 CX_TEST(test_strcat_more_than_eight) {
750 cxmutstr replan9 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 9); 772 cxmutstr replan9 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 9);
751 const char *an9expected = "xxxxxxxxxa"; 773 const char *an9expected = "xxxxxxxxxa";
752 774
753 cxmutstr replan10 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 10); 775 cxmutstr replan10 = cx_strreplacen(astr, cx_str("a"), cx_str("x"), 10);
754 const char *an10expected = "xxxxxxxxxx"; 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";
755 780
756 CX_TEST_DO { 781 CX_TEST_DO {
757 cxmutstr repl1_a = cx_strreplace_a(alloc, csstr, cx_str("AB"), cx_str("*")); 782 cxmutstr repl1_a = cx_strreplace_a(alloc, csstr, cx_str("AB"), cx_str("*"));
758 const char *expeced1_a = "test * ab TEST xyz"; 783 const char *expeced1_a = "test * ab TEST xyz";
759 784
787 CX_TEST_ASSERT(0 == strcmp(replan10.ptr, an10expected)); 812 CX_TEST_ASSERT(0 == strcmp(replan10.ptr, an10expected));
788 ASSERT_ZERO_TERMINATED(repl1_a); 813 ASSERT_ZERO_TERMINATED(repl1_a);
789 CX_TEST_ASSERT(0 == strcmp(repl1_a.ptr, expeced1_a)); 814 CX_TEST_ASSERT(0 == strcmp(repl1_a.ptr, expeced1_a));
790 ASSERT_ZERO_TERMINATED(repl2_a); 815 ASSERT_ZERO_TERMINATED(repl2_a);
791 CX_TEST_ASSERT(0 == strcmp(repl2_a.ptr, expected2_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));
792 819
793 cx_strfree_a(alloc, &repl1_a); 820 cx_strfree_a(alloc, &repl1_a);
794 cx_strfree_a(alloc, &repl2_a); 821 cx_strfree_a(alloc, &repl2_a);
795 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 822 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
796 } 823 }
805 cx_strfree(&replpre); 832 cx_strfree(&replpre);
806 cx_strfree(&replan1); 833 cx_strfree(&replan1);
807 cx_strfree(&replan4); 834 cx_strfree(&replan4);
808 cx_strfree(&replan9); 835 cx_strfree(&replan9);
809 cx_strfree(&replan10); 836 cx_strfree(&replan10);
837 cx_strfree(&norepl);
810 cx_testing_allocator_destroy(&talloc); 838 cx_testing_allocator_destroy(&talloc);
811 } 839 }
812 840
813 CX_TEST(test_strtok) { 841 CX_TEST(test_strtok) {
814 cxstring str = CX_STR("a,comma,separated,string"); 842 cxstring str = CX_STR("a,comma,separated,string");
1105 // can fit only in unsigned long long 1133 // can fit only in unsigned long long
1106 errno = 0; 1134 errno = 0;
1107 CX_TEST_ASSERT(0 != cx_strtoll(cx_str("0x8df9CE03AbC90815"), &ll, 16)); 1135 CX_TEST_ASSERT(0 != cx_strtoll(cx_str("0x8df9CE03AbC90815"), &ll, 16));
1108 CX_TEST_ASSERT(errno == ERANGE); 1136 CX_TEST_ASSERT(errno == ERANGE);
1109 1137
1138 // negative overflow (we only test for 64 bit long long)
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 // edge case: empty and NULL string
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 // edge case: unsupported base
1157 errno = 0;
1158 CX_TEST_ASSERT(0 != cx_strtoll(cx_str("7"), &ll, 12));
1159 CX_TEST_ASSERT(errno == EINVAL);
1160
1161 // edge case: incorrect sign characters
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
1110 // edge case: only the sign bit is set 1181 // edge case: only the sign bit is set
1111 errno = 0; 1182 errno = 0;
1112 CX_TEST_ASSERT(0 != cx_strtoi16(cx_str("0x8000"), &i16, 16)); 1183 CX_TEST_ASSERT(0 != cx_strtoi16(cx_str("0x8000"), &i16, 16));
1113 CX_TEST_ASSERT(errno == ERANGE); 1184 CX_TEST_ASSERT(errno == ERANGE);
1114 errno = 0; 1185 errno = 0;
1161 uint32_t u32; 1232 uint32_t u32;
1162 uint64_t u64; 1233 uint64_t u64;
1163 size_t z; 1234 size_t z;
1164 CX_TEST_DO { 1235 CX_TEST_DO {
1165 // do some brute force tests with all ranges 1236 // do some brute force tests with all ranges
1237 test_strtoint_rollout(0, 10);
1166 test_strtoint_rollout(47, 10); 1238 test_strtoint_rollout(47, 10);
1167 test_strtoint_rollout(210, 10); 1239 test_strtoint_rollout(210, 10);
1168 test_strtoint_rollout(5678, 10); 1240 test_strtoint_rollout(5678, 10);
1169 test_strtoint_rollout(40678, 10); 1241 test_strtoint_rollout(40678, 10);
1170 test_strtoint_rollout(1350266537, 10); 1242 test_strtoint_rollout(1350266537, 10);
1171 test_strtoint_rollout(3350266537, 10); 1243 test_strtoint_rollout(3350266537, 10);
1172 test_strtoint_rollout(473350266537, 10); 1244 test_strtoint_rollout(473350266537, 10);
1245 test_strtoint_rollout(0, 8);
1173 test_strtoint_rollout(057, 8); 1246 test_strtoint_rollout(057, 8);
1174 test_strtoint_rollout(0322, 8); 1247 test_strtoint_rollout(0322, 8);
1175 test_strtoint_rollout(013056, 8); 1248 test_strtoint_rollout(013056, 8);
1176 test_strtoint_rollout(0117346, 8); 1249 test_strtoint_rollout(0117346, 8);
1177 test_strtoint_rollout(012036667251, 8); 1250 test_strtoint_rollout(012036667251, 8);
1178 test_strtoint_rollout(030754201251, 8); 1251 test_strtoint_rollout(030754201251, 8);
1179 test_strtoint_rollout(06706567757251, 8); 1252 test_strtoint_rollout(06706567757251, 8);
1180 test_strtoint_rollout(01767716340165362204025, 8); 1253 test_strtoint_rollout(01767716340165362204025, 8);
1254 test_strtoint_rollout(0x0, 16);
1255 test_strtoint_rollout(0, 16);
1181 test_strtoint_rollout(0x65, 16); 1256 test_strtoint_rollout(0x65, 16);
1182 test_strtoint_rollout(0xf5, 16); 1257 test_strtoint_rollout(0xf5, 16);
1183 test_strtoint_rollout(0xABC5, 16); 1258 test_strtoint_rollout(0xABC5, 16);
1184 test_strtoint_rollout(0xFBC5, 16); 1259 test_strtoint_rollout(0xFBC5, 16);
1185 test_strtoint_rollout(0x6df9CE03, 16); 1260 test_strtoint_rollout(0x6df9CE03, 16);
1186 test_strtoint_rollout(0xFdf9CE03, 16); 1261 test_strtoint_rollout(0xFdf9CE03, 16);
1187 test_strtoint_rollout(0x6df9CE03AbC90815, 16); 1262 test_strtoint_rollout(0x6df9CE03AbC90815, 16);
1188 test_strtoint_rollout(0xfdf9CE03AbC90815, 16); 1263 test_strtoint_rollout(0xfdf9CE03AbC90815, 16);
1189 #if __STDC_VERSION__ >= 202300L 1264 #if __STDC_VERSION__ >= 202300L
1265 test_strtoint_rollout(0b0, 2);
1266 test_strtoint_rollout(0, 2);
1190 test_strtoint_rollout(0b01000010100100101110101001110101, 2); 1267 test_strtoint_rollout(0b01000010100100101110101001110101, 2);
1191 test_strtoint_rollout(0b00011010101100001111111001010100, 2); 1268 test_strtoint_rollout(0b00011010101100001111111001010100, 2);
1192 test_strtoint_rollout(0b10110001001001010001010111010011, 2); 1269 test_strtoint_rollout(0b10110001001001010001010111010011, 2);
1193 #endif 1270 #endif
1194 1271
1216 CX_TEST_ASSERT(errno == ERANGE); 1293 CX_TEST_ASSERT(errno == ERANGE);
1217 errno = 0; 1294 errno = 0;
1218 CX_TEST_ASSERT(0 == cx_strtou8_lc(cx_str("1010 1011"), &u8, 2, " ")); 1295 CX_TEST_ASSERT(0 == cx_strtou8_lc(cx_str("1010 1011"), &u8, 2, " "));
1219 CX_TEST_ASSERT(errno == 0); 1296 CX_TEST_ASSERT(errno == 0);
1220 CX_TEST_ASSERT(u8 == 0xAB); 1297 CX_TEST_ASSERT(u8 == 0xAB);
1298
1299 // edge case: empty and NULL string
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 // edge case: unsupported base
1308 errno = 0;
1309 CX_TEST_ASSERT(0 != cx_strtoull(cx_str("7"), &ull, 12));
1310 CX_TEST_ASSERT(errno == EINVAL);
1311
1312 // edge case: prefix only
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);
1221 } 1328 }
1222 } 1329 }
1223 1330
1224 CX_TEST(test_string_to_float) { 1331 CX_TEST(test_string_to_float) {
1225 float f; 1332 float f;
1273 double d; 1380 double d;
1274 CX_TEST_DO { 1381 CX_TEST_DO {
1275 CX_TEST_ASSERT(0 == cx_strtod(cx_str("11.3"), &d)); 1382 CX_TEST_ASSERT(0 == cx_strtod(cx_str("11.3"), &d));
1276 CX_TEST_ASSERT(0 == cx_vcmp_double(11.3, d)); 1383 CX_TEST_ASSERT(0 == cx_vcmp_double(11.3, d));
1277 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
1278 CX_TEST_ASSERT(0 == cx_strtod(cx_str("-13.37"), &d)); 1391 CX_TEST_ASSERT(0 == cx_strtod(cx_str("-13.37"), &d));
1279 CX_TEST_ASSERT(0 == cx_vcmp_double(-13.37, d)); 1392 CX_TEST_ASSERT(0 == cx_vcmp_double(-13.37, d));
1280 1393
1281 CX_TEST_ASSERT(0 == cx_strtod(cx_str("-4.711e+1"), &d)); 1394 CX_TEST_ASSERT(0 == cx_strtod(cx_str("-4.711e+1"), &d));
1282 CX_TEST_ASSERT(0 == cx_vcmp_double(-47.11, d)); 1395 CX_TEST_ASSERT(0 == cx_vcmp_double(-47.11, d));
1287 CX_TEST_ASSERT(0 == cx_strtod_lc(cx_str("138,339.4"), &d, '.', ",")); 1400 CX_TEST_ASSERT(0 == cx_strtod_lc(cx_str("138,339.4"), &d, '.', ","));
1288 CX_TEST_ASSERT(0 == cx_vcmp_double(138339.4, d)); 1401 CX_TEST_ASSERT(0 == cx_vcmp_double(138339.4, d));
1289 1402
1290 CX_TEST_ASSERT(0 == cx_strtod_lc(cx_str("138,339.4"), &d, ',', ".")); 1403 CX_TEST_ASSERT(0 == cx_strtod_lc(cx_str("138,339.4"), &d, ',', "."));
1291 CX_TEST_ASSERT(0 == cx_vcmp_double(138.3394, 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);
1292 1452
1293 // TODO: test and improve support for big numbers, precision, and out-of-range detection 1453 // TODO: test and improve support for big numbers, precision, and out-of-range detection
1294 } 1454 }
1295 } 1455 }
1296 1456

mercurial