github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/stdlib.c (about) 1 #include "tests.h" 2 #include <assert.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 #define test_strto0(actual, func, end) \ 7 /* strtod */ \ 8 func(strtod(actual, &endptr)); \ 9 func(strtod(actual, NULL)); \ 10 is_streq(endptr, end); \ 11 /* strtof */ \ 12 func(strtof(actual, &endptr)); \ 13 func(strtof(actual, NULL)); \ 14 is_streq(endptr, end); \ 15 /* strtold */ \ 16 func(strtold(actual, &endptr)); \ 17 func(strtold(actual, NULL)); \ 18 is_streq(endptr, end); 19 20 #define test_strto1(actual, func, expected, end) \ 21 /* strtod */ \ 22 func(strtod(actual, &endptr), expected); \ 23 func(strtod(actual, NULL), expected); \ 24 is_streq(endptr, end); \ 25 /* strtof */ \ 26 func(strtof(actual, &endptr), expected); \ 27 func(strtof(actual, NULL), expected); \ 28 is_streq(endptr, end); \ 29 /* strtold */ \ 30 func(strtold(actual, &endptr), expected); \ 31 func(strtold(actual, NULL), expected); \ 32 is_streq(endptr, end); 33 34 #define test_ato(actual, expected, end) \ 35 /* atoi */ \ 36 is_eq(atoi(actual), expected); \ 37 /* atol */ \ 38 is_eq(atol(actual), expected); \ 39 /* atoll */ \ 40 is_eq(atoll(actual), expected); \ 41 /* strtol */ \ 42 is_eq(strtol(actual, &endptr, 10), expected); \ 43 is_streq(endptr, end); \ 44 is_eq(strtol(actual, NULL, 10), expected); \ 45 /* strtoll */ \ 46 is_eq(strtoll(actual, &endptr, 10), expected); \ 47 is_streq(endptr, end); \ 48 is_eq(strtoll(actual, NULL, 10), expected); \ 49 /* strtoul */ \ 50 if (expected >= 0) { \ 51 is_eq(strtoul(actual, &endptr, 10), expected); \ 52 is_streq(endptr, end); \ 53 is_eq(strtoul(actual, NULL, 10), expected); \ 54 } \ 55 /* strtoull */ \ 56 if (expected >= 0) { \ 57 is_eq(strtoull(actual, &endptr, 10), expected); \ 58 is_streq(endptr, end); \ 59 is_eq(strtoull(actual, NULL, 10), expected); \ 60 } 61 62 #define test_strtol(actual, radix, expected, end) \ 63 /* strtol */ \ 64 is_eq(strtol(actual, &endptr, radix), expected); \ 65 is_streq(endptr, end); \ 66 /* strtoll */ \ 67 is_eq(strtoll(actual, &endptr, radix), expected); \ 68 is_streq(endptr, end); \ 69 /* strtoul */ \ 70 is_eq(strtoul(actual, &endptr, radix), expected); \ 71 is_streq(endptr, end); \ 72 /* strtoull */ \ 73 is_eq(strtoull(actual, &endptr, radix), expected); \ 74 is_streq(endptr, end); 75 76 void test_malloc1() 77 { 78 diag("malloc1"); 79 80 int i = 16, n; 81 char* buffer; 82 83 buffer = (char*)malloc(i + 1); 84 is_not_null(buffer) or_return(); 85 86 for (n = 0; n < i; n++) 87 buffer[n] = i % 26 + 'a'; 88 buffer[i] = '\0'; 89 90 is_streq(buffer, "qqqqqqqqqqqqqqqq"); 91 free(buffer); 92 } 93 94 void test_malloc2() 95 { 96 diag("malloc2"); 97 98 int* p; 99 p = (int*)malloc(sizeof(int)); 100 is_not_null(p) or_return(); 101 102 *p = 5; 103 104 is_eq(*p, 5); 105 } 106 107 // Mix around all the types to make sure it is still actually allocating the 108 // correct size. 109 void test_malloc3() 110 { 111 diag("malloc3"); 112 113 is_eq(sizeof(int), 4); 114 is_eq(sizeof(double), 8); 115 116 // 10 ints, should be 5 doubles. Also use a bad cast to make sure that it 117 // doesn't interfere with the types. 118 double* d; 119 d = (char*)malloc(sizeof(int) * 10); 120 is_not_null(d) or_return(); 121 122 // We can't test how much memory has been allocated by Go, but we can test 123 // that there are 5 items. 124 *d = 123; 125 d[4] = 456; 126 127 is_eq(*d, 123); 128 is_eq(d[4], 456); 129 } 130 131 void test_malloc4() 132 { 133 diag("malloc4"); 134 135 int length = 5; 136 137 char* m = malloc(length * sizeof(char)); 138 is_not_null(m) or_return(); 139 (void)(m); 140 141 char* m2 = malloc(sizeof(char) * length); 142 is_not_null(m2) or_return(); 143 (void)(m2); 144 145 char* m3; 146 m3 = malloc(sizeof(char) * length); 147 is_not_null(m3) or_return(); 148 (void)(m3); 149 150 char* m4; 151 m4 = malloc(length * sizeof(char)); 152 is_not_null(m4) or_return(); 153 (void)(m4); 154 } 155 156 void test_malloc5() 157 { 158 int size = 5; 159 void* v = malloc(size * size); 160 char* c = (char*)v; 161 for (int n = 0; n < size * size - 1; n++) 162 c[n] = n % 26 + 'a'; 163 c[size * size - 1] = '\0'; 164 printf("malloc5: %s\n", c); 165 } 166 167 void test_realloc() 168 { 169 { 170 int size = 5; 171 void* v = realloc((char*)(NULL), size * size); 172 char* c = (char*)v; 173 for (int n = 0; n < size * size - 1; n++) 174 c[n] = n % 26 + 'a'; 175 c[size * size - 1] = '\0'; 176 printf("realloc: %s\n", c); 177 } 178 { 179 // from : https://www.geeksforgeeks.org/g-fact-66/ 180 int* ptr = (int*)malloc(sizeof(int) * 2); 181 int* ptr_new; 182 183 *ptr = 10; 184 *(ptr + 1) = 20; 185 186 ptr_new = (int*)realloc(ptr, sizeof(int) * 3); 187 *(ptr_new + 2) = 30; 188 189 is_eq(*(ptr_new + 0), 10); 190 is_eq(*(ptr_new + 1), 20); 191 is_eq(*(ptr_new + 2), 30); 192 } 193 { 194 // from : https://www.tutorialspoint.com/c_standard_library/c_function_realloc.htm 195 char* str; 196 197 /* Initial memory allocation */ 198 str = (char*)malloc(15); 199 strcpy(str, "tutorialspoint"); 200 printf("String = %s\n", str); 201 202 /* Reallocating memory */ 203 str = (char*)realloc(str, 25); 204 strcat(str, ".com"); 205 printf("String = %s\n", str); 206 } 207 } 208 209 // calloc() works exactly the same as malloc() however the memory is zeroed out. 210 // In Go all allocated memory is zeroed out so they actually are the same thing. 211 void test_calloc() 212 { 213 diag("calloc"); 214 215 is_eq(sizeof(int), 4); 216 is_eq(sizeof(double), 8); 217 218 // 10 ints, should be 5 doubles. Also use a bad cast to make sure that it 219 // doesn't interfere with the types. 220 double* d; 221 d = (char*)calloc(10, sizeof(int)); 222 is_not_null(d) or_return(); 223 224 // We can't test how much memory has been allocated by Go, but we can test 225 // that there are 5 items. 226 *d = 123; 227 d[4] = 456; 228 229 is_eq(*d, 123); 230 is_eq(d[4], 456); 231 } 232 233 void* cs_calloc(int n) 234 { 235 int sizeT = sizeof(int); 236 return (n < 2 ? NULL : calloc(n, sizeT)); 237 (void)sizeT; 238 } 239 240 void test_calloc2() 241 { 242 diag("calloc2"); 243 is_null(cs_calloc(0)); 244 is_true(cs_calloc(5) != NULL); 245 } 246 247 void test_free() 248 { 249 int *buffer1, *buffer2, *buffer3; 250 buffer1 = (int*)malloc(100 * sizeof(int)); 251 buffer2 = (int*)calloc(100, sizeof(int)); 252 buffer3 = (int*)realloc(buffer2, 500 * sizeof(int)); 253 int i = 0; 254 free((i += 1, buffer1)); 255 if (buffer2 != NULL) { 256 i += 1; 257 } 258 if (i == 2) { 259 free(buffer3); 260 i++; 261 } 262 is_eq(i, 3); 263 } 264 265 int values[] = { 40, 10, 100, 90, 20, 25 }; 266 int compare(const void* a, const void* b) 267 { 268 return (*(int*)a - *(int*)b); 269 } 270 271 void test_system() 272 { 273 diag("system"); 274 is_eq(system("true"), 0); 275 is_not_eq(system("false"), 0); 276 } 277 278 void q_sort() 279 { 280 diag("qsort"); 281 qsort(values, 6, sizeof(int), compare); 282 is_eq(values[0], 10); 283 is_eq(values[1], 20); 284 is_eq(values[2], 25); 285 is_eq(values[3], 40); 286 is_eq(values[4], 90); 287 is_eq(values[5], 100); 288 } 289 290 void b_search() 291 { 292 diag("bsearch"); 293 294 int array[] = { 0, 5, 10, 15, 20 }; 295 // With array of int 296 int key_exist = 10; 297 int* res; 298 299 res = bsearch(&key_exist, array, 5, sizeof(int), compare); 300 is_true(res == &(array[2])); 301 302 /* This teshttps://github.com/Konstantin8105/c4go/pull/476t must be activated when the discussion https://github.com/Konstantin8105/c4go/pull/476 is resolved */ 303 /* int key_no_exist = 12; */ 304 /* res = bsearch(&key_no_exist, array, 5, sizeof(int), compare); */ 305 /* is_null(res); */ 306 } 307 308 #define COMPLEX struct MyComplex 309 struct MyComplex { 310 double re; 311 double im; 312 }; 313 void struct_with_define() 314 { 315 COMPLEX a = { 45, 12 }; 316 is_eq(a.im, 12); 317 } 318 319 void test_atoi_post() 320 { 321 char* num[3] = { { "123" }, { "987" }, { "456" } }; 322 char** w = # 323 int n; 324 n = atoi(*w); 325 is_streq(*w, "123"); 326 is_eq(n, 123); 327 328 n = atoi((*w)++); 329 is_streq(*w, "23"); 330 is_eq(n, 123); 331 332 n = atoi((*w)); 333 is_streq(*w, "23"); 334 is_eq(n, 23); 335 } 336 337 // TODO: 338 // static void * my_memrchr(void *m, int c, long n) 339 // { 340 // int i; 341 // for (i = 0; i < n; i++) 342 // if (*(unsigned char *) (m + n - 1 - i) == c) 343 // return m + n - 1 - i; 344 // // pointer checking: m + n - 1 - i 345 // return NULL; 346 // } 347 // 348 // void test_my_memrchr() 349 // { 350 // unsigned char * word = "Hello my dear world"; 351 // void * p = my_memrchr(word, (int)('d'), 18); 352 // is_not_null(p); 353 // p = my_memrchr(word, (int)('z'), 18); 354 // is_null(p); 355 // } 356 357 // TODO: 358 // void printbuffer (const char* pt, size_t max) 359 // { 360 // int length; 361 // wchar_t dest; 362 // 363 // mblen (NULL, 0); /* reset mblen */ 364 // mbtowc (NULL, NULL, 0); /* reset mbtowc */ 365 // 366 // while (max>0) { 367 // length = mblen (pt, max); 368 // if (length<1) break; 369 // mbtowc(&dest,pt,length); 370 // printf ("[%lc]",dest); 371 // pt+=length; max-=length; 372 // } 373 // } 374 // 375 // void test_mblen() 376 // { 377 // const char str [] = "test string"; 378 // printbuffer (str,sizeof(str)); 379 // } 380 381 // TODO: 382 // void test_wctomb() 383 // { 384 // const wchar_t str[] = L"wctomb example"; 385 // const wchar_t* pt; 386 // char buffer [MB_CUR_MAX]; 387 // int i,length; 388 // 389 // pt = str; 390 // while (*pt) { 391 // length = wctomb(buffer,*pt); 392 // if (length<1) break; 393 // for (i=0;i<length;++i) printf ("[%c]",buffer[i]); 394 // ++pt; 395 // } 396 // } 397 398 int main() 399 { 400 plan(771); 401 402 struct_with_define(); 403 404 char* endptr; 405 406 diag("abs"); 407 is_eq(abs(-5), 5); 408 is_eq(abs(7), 7); 409 is_eq(abs(0), 0); 410 411 diag("atof"); 412 is_eq(atof("123"), 123); 413 is_eq(atof("1.23"), 1.23); 414 is_eq(atof(""), 0); 415 is_eq(atof("1.2e6"), 1.2e6); 416 is_eq(atof(" \n123"), 123); 417 is_eq(atof("\t123foo"), 123); 418 is_eq(atof("+1.23"), 1.23); 419 is_eq(atof("-1.23"), -1.23); 420 is_eq(atof("1.2E-6"), 1.2e-6); 421 is_eq(atof("1a2b"), 1); 422 is_eq(atof("1a.2b"), 1); 423 is_eq(atof("a1.2b"), 0); 424 is_eq(atof("1.2Ee-6"), 1.2); 425 is_eq(atof("-1..23"), -1); 426 is_eq(atof("-1.2.3"), -1.2); 427 is_eq(atof("foo"), 0); 428 is_eq(atof("+1.2+3"), 1.2); 429 is_eq(atof("-1.-23"), -1); 430 is_eq(atof("-.23"), -0.23); 431 is_eq(atof(".4"), 0.4); 432 is_eq(atof("0xabc"), 2748); 433 is_eq(atof("0x1b9"), 441); 434 is_eq(atof("0x"), 0); 435 is_eq(atof("0X1f9"), 505); 436 is_eq(atof("-0X1f9"), -505); 437 is_eq(atof("+0x1f9"), 505); 438 is_eq(atof("0X"), 0); 439 is_eq(atof("0xfaz"), 250); 440 is_eq(atof("0Xzaf"), 0); 441 is_eq(atof("0xabcp2"), 10992); 442 is_eq(atof("0xabcP3"), 21984); 443 is_eq(atof("0xabcP2z"), 10992); 444 is_eq(atof("0xabcp-2"), 687); 445 is_eq(atof("0xabcp+2"), 10992); 446 is_inf(atof("inf"), 1); 447 is_inf(atof("INF"), 1); 448 is_inf(atof("Inf"), 1); 449 is_inf(atof("-Inf"), -1); 450 is_inf(atof("+INF"), 1); 451 is_inf(atof("infinity"), 1); 452 is_inf(atof("INFINITY"), 1); 453 is_inf(atof("Infinity"), 1); 454 is_inf(atof("+INFINITY"), 1); 455 is_inf(atof("-InfINITY"), -1); 456 is_nan(atof("nan")); 457 is_nan(atof("NaN")); 458 is_nan(atof("+NaN")); 459 is_nan(atof("NAN")); 460 is_nan(atof("-NAN")); 461 is_nan(atof("nanabc123")); 462 is_nan(atof("NANz123")); 463 is_nan(atof("NaN123z")); 464 is_nan(atof("-NANz123")); 465 // This causes a segfault in C: 466 // is_eq(atof(NULL), 0); 467 468 diag("atoi / atol / atoll / strtol / strtoll / strtoul"); 469 test_ato("123", 123, ""); 470 test_ato("+456", 456, ""); 471 test_ato("-52", -52, ""); 472 test_ato("foo", 0, "foo"); 473 test_ato(" \t123", 123, ""); 474 test_ato("", 0, ""); 475 test_ato(" \t", 0, " \t"); 476 test_ato("123abc", 123, "abc"); 477 478 diag("div"); 479 { 480 div_t result = div(17, 5); 481 is_eq(result.quot, 3) 482 is_eq(result.rem, 2) 483 484 result 485 = div(-17, 5); 486 is_eq(result.quot, -3) 487 is_eq(result.rem, -2) 488 489 result 490 = div(17, -5); 491 is_eq(result.quot, -3) 492 is_eq(result.rem, 2) 493 494 result 495 = div(-17, -5); 496 is_eq(result.quot, 3) 497 is_eq(result.rem, -2) 498 } 499 500 diag("calloc"); 501 test_calloc(); 502 503 // exit() is handled in tests/exit.c 504 505 // free() is handled with the malloc and calloc tests. 506 diag("free"); 507 test_free(); 508 509 diag("getenv"); 510 is_not_null(getenv("PATH")); 511 is_not_null(getenv("HOME")); 512 is_null(getenv("FOOBAR")); 513 514 diag("labs"); 515 is_eq(labs(-5), 5); 516 is_eq(labs(7), 7); 517 is_eq(labs(0), 0); 518 519 diag("ldiv"); 520 { 521 ldiv_t result = ldiv(17, 5); 522 is_eq(result.quot, 3) 523 is_eq(result.rem, 2) 524 525 result 526 = ldiv(-17, 5); 527 is_eq(result.quot, -3) 528 is_eq(result.rem, -2) 529 530 result 531 = ldiv(17, -5); 532 is_eq(result.quot, -3) 533 is_eq(result.rem, 2) 534 535 result 536 = ldiv(-17, -5); 537 is_eq(result.quot, 3) 538 is_eq(result.rem, -2) 539 } 540 541 diag("llabs"); 542 is_eq(llabs(-5), 5); 543 is_eq(llabs(7), 7); 544 is_eq(llabs(0), 0); 545 546 diag("lldiv"); 547 { 548 lldiv_t result = lldiv(17, 5); 549 is_eq(result.quot, 3) 550 is_eq(result.rem, 2) 551 552 result 553 = lldiv(-17, 5); 554 is_eq(result.quot, -3) 555 is_eq(result.rem, -2) 556 557 result 558 = lldiv(17, -5); 559 is_eq(result.quot, -3) 560 is_eq(result.rem, 2) 561 562 result 563 = lldiv(-17, -5); 564 is_eq(result.quot, 3) 565 is_eq(result.rem, -2) 566 } 567 568 diag("malloc"); 569 test_malloc1(); 570 test_malloc2(); 571 test_malloc3(); 572 test_malloc4(); 573 test_malloc5(); 574 575 diag("realloc"); 576 test_realloc(); 577 578 test_calloc2(); 579 580 diag("rand"); 581 int i, nextRand, lastRand = rand(); 582 for (i = 0; i < 10; ++i) { 583 nextRand = rand(); 584 is_not_eq(lastRand, nextRand) 585 } 586 587 diag("srand"); 588 srand(0); 589 lastRand = rand(); 590 for (i = 0; i < 10; ++i) { 591 nextRand = rand(); 592 is_not_eq(lastRand, nextRand) 593 } 594 595 srand(0); 596 int a1 = rand(); 597 int a2 = rand(); 598 int a3 = rand(); 599 600 srand(0); 601 int b1 = rand(); 602 int b2 = rand(); 603 int b3 = rand(); 604 605 is_eq(a1, b1); 606 is_eq(a2, b2); 607 is_eq(a3, b3); 608 609 diag("strtod / strtof / strtold"); 610 test_strto1("123", is_eq, 123, ""); 611 test_strto1("1.23", is_eq, 1.23, ""); 612 test_strto1("", is_eq, 0, ""); 613 test_strto1("1.2e6", is_eq, 1.2e6, ""); 614 test_strto1(" \n123", is_eq, 123, ""); 615 test_strto1("\t123foo", is_eq, 123, "foo"); 616 test_strto1("+1.23", is_eq, 1.23, ""); 617 test_strto1("-1.23", is_eq, -1.23, ""); 618 test_strto1("1.2E-6", is_eq, 1.2e-6, ""); 619 test_strto1("1a2b", is_eq, 1, "a2b"); 620 test_strto1("1a.2b", is_eq, 1, "a.2b"); 621 test_strto1("a1.2b", is_eq, 0, "a1.2b"); 622 test_strto1("1.2Ee-6", is_eq, 1.2, "Ee-6"); 623 test_strto1("-1..23", is_eq, -1, ".23"); 624 test_strto1("-1.2.3", is_eq, -1.2, ".3"); 625 test_strto1("foo", is_eq, 0, "foo"); 626 test_strto1("+1.2+3", is_eq, 1.2, "+3"); 627 test_strto1("-1.-23", is_eq, -1, "-23"); 628 test_strto1("-.23", is_eq, -0.23, ""); 629 test_strto1(".4", is_eq, 0.4, ""); 630 test_strto1("0xabc", is_eq, 2748, ""); 631 test_strto1("0x1b9", is_eq, 441, ""); 632 test_strto1("0x", is_eq, 0, "x"); 633 test_strto1("0X1f9", is_eq, 505, ""); 634 test_strto1("-0X1f9", is_eq, -505, ""); 635 test_strto1("+0x1f9", is_eq, 505, ""); 636 test_strto1("0X", is_eq, 0, "X"); 637 test_strto1("0xfaz", is_eq, 250, "z"); 638 test_strto1("0Xzaf", is_eq, 0, "Xzaf"); 639 test_strto1("0xabcp2", is_eq, 10992, ""); 640 test_strto1("0xabcP3", is_eq, 21984, ""); 641 test_strto1("0xabcP2z", is_eq, 10992, "z"); 642 test_strto1("0xabcp-2", is_eq, 687, ""); 643 test_strto1("0xabcp+2", is_eq, 10992, ""); 644 645 test_strto1("inf", is_inf, 1, ""); 646 test_strto1("INF", is_inf, 1, ""); 647 test_strto1("Inf", is_inf, 1, ""); 648 test_strto1("-Inf", is_inf, -1, ""); 649 test_strto1("+INF", is_inf, 1, ""); 650 test_strto1("infinity", is_inf, 1, ""); 651 test_strto1("INFINITY", is_inf, 1, ""); 652 test_strto1("Infinity", is_inf, 1, ""); 653 test_strto1("+INFINITY", is_inf, 1, ""); 654 test_strto1("-InfINITY", is_inf, -1, ""); 655 656 test_strto0("nan", is_nan, ""); 657 test_strto0("NaN", is_nan, ""); 658 test_strto0("+NaN", is_nan, ""); 659 test_strto0("NAN", is_nan, ""); 660 test_strto0("-NAN", is_nan, ""); 661 662 test_strto0("nanabc123", is_nan, "abc123"); 663 test_strto0("NANz123", is_nan, "z123"); 664 test_strto0("NaN123z", is_nan, "123z"); 665 test_strto0("-NANz123", is_nan, "z123"); 666 667 // This causes a segfault in C: 668 // test_strtod1(NULL, is_eq, 0, ""); 669 670 diag("strtol / strtoll / strtoul / strtoull"); 671 test_strtol("123", 8, 83, ""); 672 test_strtol("123abc", 16, 1194684, ""); 673 test_strtol("123abc", 8, 83, "abc"); 674 675 diag("abs int"); 676 { 677 int h = -1000; 678 printf("%d %d\n", abs(h) / 100, abs(h) % 100); 679 } 680 681 diag("atoi_post"); 682 test_atoi_post(); 683 684 diag("system"); 685 test_system(); 686 687 diag("q_sort"); 688 q_sort(); 689 690 diag("b_search"); 691 b_search(); 692 693 // test_mblen(); 694 // test_wctomb(); 695 696 // TODO: 697 // diag("my_memrchr"); 698 // test_my_memrchr(); 699 700 diag("EXIT_FAILURE"); 701 is_eq(EXIT_FAILURE, 1); 702 703 diag("EXIT_SUCCESS"); 704 is_eq(EXIT_SUCCESS, 0); 705 706 diag("MB_CUR_MAX"); 707 is_eq(MB_CUR_MAX, 1); 708 709 diag("RAND_MAX"); 710 is_eq(RAND_MAX, 2147483647); 711 712 done_testing(); 713 }