1 /* Tester for string functions. 2 Copyright (C) 1995-2000, 2001, 2003 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 02111-1307 USA. */ 19 20 #ifndef _GNU_SOURCE 21 #define _GNU_SOURCE 22 #endif 23 24 /* Make sure we don't test the optimized inline functions if we want to 25 test the real implementation. */ 26 #if !defined DO_STRING_INLINES 27 #undef __USE_STRING_INLINES 28 #endif 29 30 #include <errno.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <strings.h> 35 #include <fcntl.h> 36 37 #ifndef HAVE_GNU_LD 38 #define _sys_nerr sys_nerr 39 #define _sys_errlist sys_errlist 40 #endif 41 42 #define STREQ(a, b) (strcmp((a), (b)) == 0) 43 44 const char *it = "<UNSET>"; /* Routine name for message routines. */ 45 size_t errors = 0; 46 47 /* Complain if condition is not true. */ 48 static void 49 check (int thing, int number) 50 { 51 if (!thing) 52 { 53 printf("%s flunked test %d\n", it, number); 54 ++errors; 55 } 56 } 57 58 /* Complain if first two args don't strcmp as equal. */ 59 static void 60 equal (const char *a, const char *b, int number) 61 { 62 check(a != NULL && b != NULL && STREQ (a, b), number); 63 } 64 65 char one[50]; 66 char two[50]; 67 char *cp; 68 69 static void 70 test_strcmp (void) 71 { 72 it = "strcmp"; 73 check (strcmp ("", "") == 0, 1); /* Trivial case. */ 74 check (strcmp ("a", "a") == 0, 2); /* Identity. */ 75 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */ 76 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */ 77 check (strcmp ("abcd", "abc") > 0, 5); 78 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */ 79 check (strcmp ("abce", "abcd") > 0, 7); 80 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */ 81 check (strcmp ("a\203", "a\003") > 0, 9); 82 83 { 84 char buf1[0x40], buf2[0x40]; 85 int i, j; 86 for (i=0; i < 0x10; i++) 87 for (j = 0; j < 0x10; j++) 88 { 89 int k; 90 for (k = 0; k < 0x3f; k++) 91 { 92 buf1[k] = '0' ^ (k & 4); 93 buf2[k] = '4' ^ (k & 4); 94 } 95 buf1[i] = buf1[0x3f] = 0; 96 buf2[j] = buf2[0x3f] = 0; 97 for (k = 0; k < 0xf; k++) 98 { 99 int cnum = 0x10+0x10*k+0x100*j+0x1000*i; 100 check (strcmp (buf1+i,buf2+j) == 0, cnum); 101 buf1[i+k] = 'A' + i + k; 102 buf1[i+k+1] = 0; 103 check (strcmp (buf1+i,buf2+j) > 0, cnum+1); 104 check (strcmp (buf2+j,buf1+i) < 0, cnum+2); 105 buf2[j+k] = 'B' + i + k; 106 buf2[j+k+1] = 0; 107 check (strcmp (buf1+i,buf2+j) < 0, cnum+3); 108 check (strcmp (buf2+j,buf1+i) > 0, cnum+4); 109 buf2[j+k] = 'A' + i + k; 110 buf1[i] = 'A' + i + 0x80; 111 check (strcmp (buf1+i,buf2+j) > 0, cnum+5); 112 check (strcmp (buf2+j,buf1+i) < 0, cnum+6); 113 buf1[i] = 'A' + i; 114 } 115 } 116 } 117 } 118 119 #define SIMPLE_COPY(fn, n, str, ntest) \ 120 do { \ 121 int __n; \ 122 char *cp; \ 123 for (__n = 0; __n < (int) sizeof (one); ++__n) \ 124 one[__n] = 'Z'; \ 125 fn (one, str); \ 126 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \ 127 check (*cp == '0' + (n % 10), ntest); \ 128 check (*cp == '\0', ntest); \ 129 } while (0) 130 131 static void 132 test_strcpy (void) 133 { 134 int i; 135 it = "strcpy"; 136 check (strcpy (one, "abcd") == one, 1); /* Returned value. */ 137 equal (one, "abcd", 2); /* Basic test. */ 138 139 (void) strcpy (one, "x"); 140 equal (one, "x", 3); /* Writeover. */ 141 equal (one+2, "cd", 4); /* Wrote too much? */ 142 143 (void) strcpy (two, "hi there"); 144 (void) strcpy (one, two); 145 equal (one, "hi there", 5); /* Basic test encore. */ 146 equal (two, "hi there", 6); /* Stomped on source? */ 147 148 (void) strcpy (one, ""); 149 equal (one, "", 7); /* Boundary condition. */ 150 151 for (i = 0; i < 16; i++) 152 { 153 (void) strcpy (one + i, "hi there"); /* Unaligned destination. */ 154 equal (one + i, "hi there", 8 + (i * 2)); 155 (void) strcpy (two, one + i); /* Unaligned source. */ 156 equal (two, "hi there", 9 + (i * 2)); 157 } 158 159 SIMPLE_COPY(strcpy, 0, "", 41); 160 SIMPLE_COPY(strcpy, 1, "1", 42); 161 SIMPLE_COPY(strcpy, 2, "22", 43); 162 SIMPLE_COPY(strcpy, 3, "333", 44); 163 SIMPLE_COPY(strcpy, 4, "4444", 45); 164 SIMPLE_COPY(strcpy, 5, "55555", 46); 165 SIMPLE_COPY(strcpy, 6, "666666", 47); 166 SIMPLE_COPY(strcpy, 7, "7777777", 48); 167 SIMPLE_COPY(strcpy, 8, "88888888", 49); 168 SIMPLE_COPY(strcpy, 9, "999999999", 50); 169 SIMPLE_COPY(strcpy, 10, "0000000000", 51); 170 SIMPLE_COPY(strcpy, 11, "11111111111", 52); 171 SIMPLE_COPY(strcpy, 12, "222222222222", 53); 172 SIMPLE_COPY(strcpy, 13, "3333333333333", 54); 173 SIMPLE_COPY(strcpy, 14, "44444444444444", 55); 174 SIMPLE_COPY(strcpy, 15, "555555555555555", 56); 175 SIMPLE_COPY(strcpy, 16, "6666666666666666", 57); 176 177 /* Simple test using implicitly coerced `void *' arguments. */ 178 { const void *src = "frobozz"; 179 void *dst = one; 180 check (strcpy (dst, src) == dst, 1); 181 equal (dst, "frobozz", 2); 182 } 183 } 184 185 static void 186 test_stpcpy (void) 187 { 188 it = "stpcpy"; 189 check ((stpcpy (one, "a") - one) == 1, 1); 190 equal (one, "a", 2); 191 192 check ((stpcpy (one, "ab") - one) == 2, 3); 193 equal (one, "ab", 4); 194 195 check ((stpcpy (one, "abc") - one) == 3, 5); 196 equal (one, "abc", 6); 197 198 check ((stpcpy (one, "abcd") - one) == 4, 7); 199 equal (one, "abcd", 8); 200 201 check ((stpcpy (one, "abcde") - one) == 5, 9); 202 equal (one, "abcde", 10); 203 204 check ((stpcpy (one, "abcdef") - one) == 6, 11); 205 equal (one, "abcdef", 12); 206 207 check ((stpcpy (one, "abcdefg") - one) == 7, 13); 208 equal (one, "abcdefg", 14); 209 210 check ((stpcpy (one, "abcdefgh") - one) == 8, 15); 211 equal (one, "abcdefgh", 16); 212 213 check ((stpcpy (one, "abcdefghi") - one) == 9, 17); 214 equal (one, "abcdefghi", 18); 215 216 check ((stpcpy (one, "x") - one) == 1, 19); 217 equal (one, "x", 20); /* Writeover. */ 218 equal (one+2, "cdefghi", 21); /* Wrote too much? */ 219 220 check ((stpcpy (one, "xx") - one) == 2, 22); 221 equal (one, "xx", 23); /* Writeover. */ 222 equal (one+3, "defghi", 24); /* Wrote too much? */ 223 224 check ((stpcpy (one, "xxx") - one) == 3, 25); 225 equal (one, "xxx", 26); /* Writeover. */ 226 equal (one+4, "efghi", 27); /* Wrote too much? */ 227 228 check ((stpcpy (one, "xxxx") - one) == 4, 28); 229 equal (one, "xxxx", 29); /* Writeover. */ 230 equal (one+5, "fghi", 30); /* Wrote too much? */ 231 232 check ((stpcpy (one, "xxxxx") - one) == 5, 31); 233 equal (one, "xxxxx", 32); /* Writeover. */ 234 equal (one+6, "ghi", 33); /* Wrote too much? */ 235 236 check ((stpcpy (one, "xxxxxx") - one) == 6, 34); 237 equal (one, "xxxxxx", 35); /* Writeover. */ 238 equal (one+7, "hi", 36); /* Wrote too much? */ 239 240 check ((stpcpy (one, "xxxxxxx") - one) == 7, 37); 241 equal (one, "xxxxxxx", 38); /* Writeover. */ 242 equal (one+8, "i", 39); /* Wrote too much? */ 243 244 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40); 245 equal (one, "abc", 41); 246 equal (one + 4, "xxx", 42); 247 248 SIMPLE_COPY(stpcpy, 0, "", 43); 249 SIMPLE_COPY(stpcpy, 1, "1", 44); 250 SIMPLE_COPY(stpcpy, 2, "22", 45); 251 SIMPLE_COPY(stpcpy, 3, "333", 46); 252 SIMPLE_COPY(stpcpy, 4, "4444", 47); 253 SIMPLE_COPY(stpcpy, 5, "55555", 48); 254 SIMPLE_COPY(stpcpy, 6, "666666", 49); 255 SIMPLE_COPY(stpcpy, 7, "7777777", 50); 256 SIMPLE_COPY(stpcpy, 8, "88888888", 51); 257 SIMPLE_COPY(stpcpy, 9, "999999999", 52); 258 SIMPLE_COPY(stpcpy, 10, "0000000000", 53); 259 SIMPLE_COPY(stpcpy, 11, "11111111111", 54); 260 SIMPLE_COPY(stpcpy, 12, "222222222222", 55); 261 SIMPLE_COPY(stpcpy, 13, "3333333333333", 56); 262 SIMPLE_COPY(stpcpy, 14, "44444444444444", 57); 263 SIMPLE_COPY(stpcpy, 15, "555555555555555", 58); 264 SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59); 265 } 266 267 // DDD: better done by testing for the function. 268 #if !defined(__APPLE__) 269 static void 270 test_stpncpy (void) 271 { 272 it = "stpncpy"; 273 memset (one, 'x', sizeof (one)); 274 check (stpncpy (one, "abc", 2) == one + 2, 1); 275 check (stpncpy (one, "abc", 3) == one + 3, 2); 276 check (stpncpy (one, "abc", 4) == one + 3, 3); 277 check (one[3] == '\0' && one[4] == 'x', 4); 278 check (stpncpy (one, "abcd", 5) == one + 4, 5); 279 check (one[4] == '\0' && one[5] == 'x', 6); 280 check (stpncpy (one, "abcd", 6) == one + 4, 7); 281 check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8); 282 } 283 #endif 284 285 static void 286 test_strcat (void) 287 { 288 it = "strcat"; 289 (void) strcpy (one, "ijk"); 290 check (strcat (one, "lmn") == one, 1); /* Returned value. */ 291 equal (one, "ijklmn", 2); /* Basic test. */ 292 293 (void) strcpy (one, "x"); 294 (void) strcat (one, "yz"); 295 equal (one, "xyz", 3); /* Writeover. */ 296 equal (one+4, "mn", 4); /* Wrote too much? */ 297 298 (void) strcpy (one, "gh"); 299 (void) strcpy (two, "ef"); 300 (void) strcat (one, two); 301 equal (one, "ghef", 5); /* Basic test encore. */ 302 equal (two, "ef", 6); /* Stomped on source? */ 303 304 (void) strcpy (one, ""); 305 (void) strcat (one, ""); 306 equal (one, "", 7); /* Boundary conditions. */ 307 (void) strcpy (one, "ab"); 308 (void) strcat (one, ""); 309 equal (one, "ab", 8); 310 (void) strcpy (one, ""); 311 (void) strcat (one, "cd"); 312 equal (one, "cd", 9); 313 } 314 315 static void 316 test_strncat (void) 317 { 318 /* First test it as strcat, with big counts, then test the count 319 mechanism. */ 320 it = "strncat"; 321 (void) strcpy (one, "ijk"); 322 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */ 323 equal (one, "ijklmn", 2); /* Basic test. */ 324 325 (void) strcpy (one, "x"); 326 (void) strncat (one, "yz", 99); 327 equal (one, "xyz", 3); /* Writeover. */ 328 equal (one+4, "mn", 4); /* Wrote too much? */ 329 330 (void) strcpy (one, "gh"); 331 (void) strcpy (two, "ef"); 332 (void) strncat (one, two, 99); 333 equal (one, "ghef", 5); /* Basic test encore. */ 334 equal (two, "ef", 6); /* Stomped on source? */ 335 336 (void) strcpy (one, ""); 337 (void) strncat (one, "", 99); 338 equal (one, "", 7); /* Boundary conditions. */ 339 (void) strcpy (one, "ab"); 340 (void) strncat (one, "", 99); 341 equal (one, "ab", 8); 342 (void) strcpy (one, ""); 343 (void) strncat (one, "cd", 99); 344 equal (one, "cd", 9); 345 346 (void) strcpy (one, "ab"); 347 (void) strncat (one, "cdef", 2); 348 equal (one, "abcd", 10); /* Count-limited. */ 349 350 (void) strncat (one, "gh", 0); 351 equal (one, "abcd", 11); /* Zero count. */ 352 353 (void) strncat (one, "gh", 2); 354 equal (one, "abcdgh", 12); /* Count and length equal. */ 355 } 356 357 static void 358 test_strncmp (void) 359 { 360 /* First test as strcmp with big counts, then test count code. */ 361 it = "strncmp"; 362 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */ 363 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */ 364 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */ 365 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */ 366 check (strncmp ("abcd", "abc", 99) > 0, 5); 367 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */ 368 check (strncmp ("abce", "abcd", 99) > 0, 7); 369 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */ 370 check (strncmp ("a\203", "a\003", 2) > 0, 9); 371 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */ 372 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */ 373 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */ 374 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */ 375 } 376 377 static void 378 test_strncpy (void) 379 { 380 /* Testing is a bit different because of odd semantics. */ 381 it = "strncpy"; 382 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */ 383 equal (one, "abc", 2); /* Did the copy go right? */ 384 385 (void) strcpy (one, "abcdefgh"); 386 (void) strncpy (one, "xyz", 2); 387 equal (one, "xycdefgh", 3); /* Copy cut by count. */ 388 389 (void) strcpy (one, "abcdefgh"); 390 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */ 391 equal (one, "xyzdefgh", 4); 392 393 (void) strcpy (one, "abcdefgh"); 394 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */ 395 equal (one, "xyz", 5); 396 equal (one+4, "efgh", 6); /* Wrote too much? */ 397 398 (void) strcpy (one, "abcdefgh"); 399 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */ 400 equal (one, "xyz", 7); 401 equal (one+4, "", 8); 402 equal (one+5, "fgh", 9); 403 404 (void) strcpy (one, "abc"); 405 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */ 406 equal (one, "abc", 10); 407 408 (void) strncpy (one, "", 2); /* Zero-length source. */ 409 equal (one, "", 11); 410 equal (one+1, "", 12); 411 equal (one+2, "c", 13); 412 413 (void) strcpy (one, "hi there"); 414 (void) strncpy (two, one, 9); 415 equal (two, "hi there", 14); /* Just paranoia. */ 416 equal (one, "hi there", 15); /* Stomped on source? */ 417 } 418 419 static void 420 test_strlen (void) 421 { 422 it = "strlen"; 423 check (strlen ("") == 0, 1); /* Empty. */ 424 check (strlen ("a") == 1, 2); /* Single char. */ 425 check (strlen ("abcd") == 4, 3); /* Multiple chars. */ 426 { 427 char buf[4096]; 428 int i; 429 char *p; 430 for (i=0; i < 0x100; i++) 431 { 432 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i; 433 strcpy (p, "OK"); 434 strcpy (p+3, "BAD/WRONG"); 435 check (strlen (p) == 2, 4+i); 436 } 437 } 438 } 439 440 static void 441 test_strchr (void) 442 { 443 it = "strchr"; 444 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */ 445 (void) strcpy (one, "abcd"); 446 check (strchr (one, 'c') == one+2, 2); /* Basic test. */ 447 check (strchr (one, 'd') == one+3, 3); /* End of string. */ 448 check (strchr (one, 'a') == one, 4); /* Beginning. */ 449 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */ 450 (void) strcpy (one, "ababa"); 451 check (strchr (one, 'b') == one+1, 6); /* Finding first. */ 452 (void) strcpy (one, ""); 453 check (strchr (one, 'b') == NULL, 7); /* Empty string. */ 454 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */ 455 { 456 char buf[4096]; 457 int i; 458 char *p; 459 for (i=0; i < 0x100; i++) 460 { 461 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i; 462 strcpy (p, "OK"); 463 strcpy (p+3, "BAD/WRONG"); 464 check (strchr (p, '/') == NULL, 9+i); 465 } 466 } 467 } 468 469 // DDD: better done by testing for the function. 470 #if !defined(__APPLE__) 471 static void 472 test_strchrnul (void) 473 { 474 const char *os; 475 it = "strchrnul"; 476 cp = strchrnul ((os = "abcd"), 'z'); 477 check (*cp == '\0', 1); /* Not found. */ 478 check (cp == os + 4, 2); 479 (void) strcpy (one, "abcd"); 480 check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */ 481 check (strchrnul (one, 'd') == one+3, 4); /* End of string. */ 482 check (strchrnul (one, 'a') == one, 5); /* Beginning. */ 483 check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */ 484 (void) strcpy (one, "ababa"); 485 check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */ 486 (void) strcpy (one, ""); 487 check (strchrnul (one, 'b') == one, 8); /* Empty string. */ 488 check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */ 489 { 490 char buf[4096]; 491 int i; 492 char *p; 493 for (i=0; i < 0x100; i++) 494 { 495 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i; 496 strcpy (p, "OK"); 497 strcpy (p+3, "BAD/WRONG"); 498 cp = strchrnul (p, '/'); 499 check (*cp == '\0', 9+2*i); 500 check (cp == p+2, 10+2*i); 501 } 502 } 503 } 504 #endif 505 506 // DDD: better done by testing for the function. 507 #if !defined(__APPLE__) && !defined(__sun) 508 static void 509 test_rawmemchr (void) 510 { 511 it = "rawmemchr"; 512 (void) strcpy (one, "abcd"); 513 check (rawmemchr (one, 'c') == one+2, 1); /* Basic test. */ 514 check (rawmemchr (one, 'd') == one+3, 2); /* End of string. */ 515 check (rawmemchr (one, 'a') == one, 3); /* Beginning. */ 516 check (rawmemchr (one, '\0') == one+4, 4); /* Finding NUL. */ 517 (void) strcpy (one, "ababa"); 518 check (rawmemchr (one, 'b') == one+1, 5); /* Finding first. */ 519 (void) strcpy (one, ""); 520 check (rawmemchr (one, '\0') == one, 6); /* NUL in empty string. */ 521 { 522 char buf[4096]; 523 int i; 524 char *p; 525 for (i=0; i < 0x100; i++) 526 { 527 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i; 528 strcpy (p, "OK"); 529 strcpy (p+3, "BAD/WRONG"); 530 check (rawmemchr (p, 'R') == p+8, 6+i); 531 } 532 } 533 } 534 #endif 535 536 static void 537 test_index (void) 538 { 539 it = "index"; 540 check (index ("abcd", 'z') == NULL, 1); /* Not found. */ 541 (void) strcpy (one, "abcd"); 542 check (index (one, 'c') == one+2, 2); /* Basic test. */ 543 check (index (one, 'd') == one+3, 3); /* End of string. */ 544 check (index (one, 'a') == one, 4); /* Beginning. */ 545 check (index (one, '\0') == one+4, 5); /* Finding NUL. */ 546 (void) strcpy (one, "ababa"); 547 check (index (one, 'b') == one+1, 6); /* Finding first. */ 548 (void) strcpy (one, ""); 549 check (index (one, 'b') == NULL, 7); /* Empty string. */ 550 check (index (one, '\0') == one, 8); /* NUL in empty string. */ 551 } 552 553 static void 554 test_strrchr (void) 555 { 556 it = "strrchr"; 557 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */ 558 (void) strcpy (one, "abcd"); 559 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */ 560 check (strrchr (one, 'd') == one+3, 3); /* End of string. */ 561 check (strrchr (one, 'a') == one, 4); /* Beginning. */ 562 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */ 563 (void) strcpy (one, "ababa"); 564 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */ 565 (void) strcpy (one, ""); 566 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */ 567 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */ 568 { 569 char buf[4096]; 570 int i; 571 char *p; 572 for (i=0; i < 0x100; i++) 573 { 574 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i; 575 strcpy (p, "OK"); 576 strcpy (p+3, "BAD/WRONG"); 577 check (strrchr (p, '/') == NULL, 9+i); 578 } 579 } 580 } 581 582 // DDD: better done by testing for the function. 583 #if !defined(__APPLE__) && !defined(__sun) 584 static void 585 test_memrchr (void) 586 { 587 size_t l; 588 it = "memrchr"; 589 check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */ 590 (void) strcpy (one, "abcd"); 591 l = strlen (one) + 1; 592 check (memrchr (one, 'c', l) == one+2, 2); /* Basic test. */ 593 check (memrchr (one, 'd', l) == one+3, 3); /* End of string. */ 594 check (memrchr (one, 'a', l) == one, 4); /* Beginning. */ 595 check (memrchr (one, '\0', l) == one+4, 5); /* Finding NUL. */ 596 (void) strcpy (one, "ababa"); 597 l = strlen (one) + 1; 598 check (memrchr (one, 'b', l) == one+3, 6); /* Finding last. */ 599 (void) strcpy (one, ""); 600 l = strlen (one) + 1; 601 check (memrchr (one, 'b', l) == NULL, 7); /* Empty string. */ 602 check (memrchr (one, '\0', l) == one, 8); /* NUL in empty string. */ 603 604 /* now test all possible alignment and length combinations to catch 605 bugs due to unrolled loops (assuming unrolling is limited to no 606 more than 128 byte chunks: */ 607 { 608 char buf[128 + sizeof(long)]; 609 long align, len, i, pos; 610 611 for (align = 0; align < (long) sizeof(long); ++align) { 612 for (len = 0; len < (long) (sizeof(buf) - align); ++len) { 613 for (i = 0; i < len; ++i) 614 buf[align + i] = 'x'; /* don't depend on memset... */ 615 616 for (pos = len - 1; pos >= 0; --pos) { 617 #if 0 618 printf("align %d, len %d, pos %d\n", align, len, pos); 619 #endif 620 check(memrchr(buf + align, 'x', len) == buf + align + pos, 9); 621 check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL, 622 10); 623 buf[align + pos] = '-'; 624 } 625 } 626 } 627 } 628 } 629 #endif 630 631 static void 632 test_rindex (void) 633 { 634 it = "rindex"; 635 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */ 636 (void) strcpy (one, "abcd"); 637 check (rindex (one, 'c') == one+2, 2); /* Basic test. */ 638 check (rindex (one, 'd') == one+3, 3); /* End of string. */ 639 check (rindex (one, 'a') == one, 4); /* Beginning. */ 640 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */ 641 (void) strcpy (one, "ababa"); 642 check (rindex (one, 'b') == one+3, 6); /* Finding last. */ 643 (void) strcpy (one, ""); 644 check (rindex (one, 'b') == NULL, 7); /* Empty string. */ 645 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */ 646 } 647 648 static void 649 test_strpbrk (void) 650 { 651 it = "strpbrk"; 652 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */ 653 (void) strcpy(one, "abcd"); 654 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */ 655 check(strpbrk(one, "d") == one+3, 3); /* End of string. */ 656 check(strpbrk(one, "a") == one, 4); /* Beginning. */ 657 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */ 658 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */ 659 (void) strcpy(one, "abcabdea"); 660 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */ 661 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */ 662 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */ 663 (void) strcpy(one, ""); 664 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */ 665 (void) strcpy(one, ""); 666 check(strpbrk(one, "bcd") == NULL, 11); /* Empty string. */ 667 (void) strcpy(one, ""); 668 check(strpbrk(one, "bcde") == NULL, 12); /* Empty string. */ 669 check(strpbrk(one, "") == NULL, 13); /* Both strings empty. */ 670 (void) strcpy(one, "abcabdea"); 671 check(strpbrk(one, "befg") == one+1, 14); /* Finding first. */ 672 check(strpbrk(one, "cbr") == one+1, 15); /* With multiple search. */ 673 check(strpbrk(one, "db") == one+1, 16); /* Another variant. */ 674 check(strpbrk(one, "efgh") == one+6, 17); /* And yet another. */ 675 } 676 677 static void 678 test_strstr (void) 679 { 680 it = "strstr"; 681 check(strstr("abcd", "z") == NULL, 1); /* Not found. */ 682 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */ 683 (void) strcpy(one, "abcd"); 684 check(strstr(one, "c") == one+2, 3); /* Basic test. */ 685 check(strstr(one, "bc") == one+1, 4); /* Multichar. */ 686 check(strstr(one, "d") == one+3, 5); /* End of string. */ 687 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */ 688 check(strstr(one, "abc") == one, 7); /* Beginning. */ 689 check(strstr(one, "abcd") == one, 8); /* Exact match. */ 690 check(strstr(one, "abcde") == NULL, 9); /* Too long. */ 691 check(strstr(one, "de") == NULL, 10); /* Past end. */ 692 check(strstr(one, "") == one, 11); /* Finding empty. */ 693 (void) strcpy(one, "ababa"); 694 check(strstr(one, "ba") == one+1, 12); /* Finding first. */ 695 (void) strcpy(one, ""); 696 check(strstr(one, "b") == NULL, 13); /* Empty string. */ 697 check(strstr(one, "") == one, 14); /* Empty in empty string. */ 698 (void) strcpy(one, "bcbca"); 699 check(strstr(one, "bca") == one+2, 15); /* False start. */ 700 (void) strcpy(one, "bbbcabbca"); 701 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */ 702 } 703 704 static void 705 test_strspn (void) 706 { 707 it = "strspn"; 708 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */ 709 check(strspn("abcba", "ab") == 2, 2); /* Partial. */ 710 check(strspn("abc", "qx") == 0, 3); /* None. */ 711 check(strspn("", "ab") == 0, 4); /* Null string. */ 712 check(strspn("abc", "") == 0, 5); /* Null search list. */ 713 } 714 715 static void 716 test_strcspn (void) 717 { 718 it = "strcspn"; 719 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */ 720 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */ 721 check(strcspn("abc", "abc") == 0, 3); /* None. */ 722 check(strcspn("", "ab") == 0, 4); /* Null string. */ 723 check(strcspn("abc", "") == 3, 5); /* Null search list. */ 724 } 725 726 static void 727 test_strtok (void) 728 { 729 it = "strtok"; 730 (void) strcpy(one, "first, second, third"); 731 equal(strtok(one, ", "), "first", 1); /* Basic test. */ 732 equal(one, "first", 2); 733 equal(strtok((char *)NULL, ", "), "second", 3); 734 equal(strtok((char *)NULL, ", "), "third", 4); 735 check(strtok((char *)NULL, ", ") == NULL, 5); 736 (void) strcpy(one, ", first, "); 737 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */ 738 check(strtok((char *)NULL, ", ") == NULL, 7); 739 (void) strcpy(one, "1a, 1b; 2a, 2b"); 740 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */ 741 equal(strtok((char *)NULL, "; "), "1b", 9); 742 equal(strtok((char *)NULL, ", "), "2a", 10); 743 (void) strcpy(two, "x-y"); 744 equal(strtok(two, "-"), "x", 11); /* New string before done. */ 745 equal(strtok((char *)NULL, "-"), "y", 12); 746 check(strtok((char *)NULL, "-") == NULL, 13); 747 (void) strcpy(one, "a,b, c,, ,d"); 748 equal(strtok(one, ", "), "a", 14); /* Different separators. */ 749 equal(strtok((char *)NULL, ", "), "b", 15); 750 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */ 751 equal(strtok((char *)NULL, " ,"), "d", 17); 752 check(strtok((char *)NULL, ", ") == NULL, 18); 753 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */ 754 (void) strcpy(one, ", "); 755 check(strtok(one, ", ") == NULL, 20); /* No tokens. */ 756 (void) strcpy(one, ""); 757 check(strtok(one, ", ") == NULL, 21); /* Empty string. */ 758 (void) strcpy(one, "abc"); 759 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */ 760 check(strtok((char *)NULL, ", ") == NULL, 23); 761 (void) strcpy(one, "abc"); 762 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */ 763 check(strtok((char *)NULL, "") == NULL, 25); 764 (void) strcpy(one, "abcdefgh"); 765 (void) strcpy(one, "a,b,c"); 766 equal(strtok(one, ","), "a", 26); /* Basics again... */ 767 equal(strtok((char *)NULL, ","), "b", 27); 768 equal(strtok((char *)NULL, ","), "c", 28); 769 check(strtok((char *)NULL, ",") == NULL, 29); 770 equal(one+6, "gh", 30); /* Stomped past end? */ 771 equal(one, "a", 31); /* Stomped old tokens? */ 772 equal(one+2, "b", 32); 773 equal(one+4, "c", 33); 774 } 775 776 static void 777 test_strtok_r (void) 778 { 779 it = "strtok_r"; 780 (void) strcpy(one, "first, second, third"); 781 cp = NULL; /* Always initialize cp to make sure it doesn't point to some old data. */ 782 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */ 783 equal(one, "first", 2); 784 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3); 785 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4); 786 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5); 787 (void) strcpy(one, ", first, "); 788 cp = NULL; 789 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */ 790 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7); 791 (void) strcpy(one, "1a, 1b; 2a, 2b"); 792 cp = NULL; 793 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */ 794 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9); 795 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10); 796 (void) strcpy(two, "x-y"); 797 cp = NULL; 798 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */ 799 equal(strtok_r((char *)NULL, "-", &cp), "y", 12); 800 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13); 801 (void) strcpy(one, "a,b, c,, ,d"); 802 cp = NULL; 803 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */ 804 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15); 805 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */ 806 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17); 807 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18); 808 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */ 809 (void) strcpy(one, ", "); 810 cp = NULL; 811 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */ 812 (void) strcpy(one, ""); 813 cp = NULL; 814 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */ 815 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22); /* Persistence. */ 816 (void) strcpy(one, "abc"); 817 cp = NULL; 818 equal(strtok_r(one, ", ", &cp), "abc", 23); /* No delimiters. */ 819 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24); 820 (void) strcpy(one, "abc"); 821 cp = NULL; 822 equal(strtok_r(one, "", &cp), "abc", 25); /* Empty delimiter list. */ 823 check(strtok_r((char *)NULL, "", &cp) == NULL, 26); 824 (void) strcpy(one, "abcdefgh"); 825 (void) strcpy(one, "a,b,c"); 826 cp = NULL; 827 equal(strtok_r(one, ",", &cp), "a", 27); /* Basics again... */ 828 equal(strtok_r((char *)NULL, ",", &cp), "b", 28); 829 equal(strtok_r((char *)NULL, ",", &cp), "c", 29); 830 check(strtok_r((char *)NULL, ",", &cp) == NULL, 30); 831 equal(one+6, "gh", 31); /* Stomped past end? */ 832 equal(one, "a", 32); /* Stomped old tokens? */ 833 equal(one+2, "b", 33); 834 equal(one+4, "c", 34); 835 } 836 837 static void 838 test_strsep (void) 839 { 840 char *ptr; 841 it = "strsep"; 842 cp = strcpy(one, "first, second, third"); 843 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */ 844 equal(one, "first", 2); 845 equal(strsep(&cp, ", "), "", 3); 846 equal(strsep(&cp, ", "), "second", 4); 847 equal(strsep(&cp, ", "), "", 5); 848 equal(strsep(&cp, ", "), "third", 6); 849 check(strsep(&cp, ", ") == NULL, 7); 850 cp = strcpy(one, ", first, "); 851 equal(strsep(&cp, ", "), "", 8); 852 equal(strsep(&cp, ", "), "", 9); 853 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */ 854 equal(strsep(&cp, ", "), "", 11); 855 equal(strsep(&cp, ", "), "", 12); 856 check(strsep(&cp, ", ") == NULL, 13); 857 cp = strcpy(one, "1a, 1b; 2a, 2b"); 858 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */ 859 equal(strsep(&cp, ", "), "", 15); 860 equal(strsep(&cp, "; "), "1b", 16); 861 equal(strsep(&cp, ", "), "", 17); 862 equal(strsep(&cp, ", "), "2a", 18); 863 cp = strcpy(two, "x-y"); 864 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */ 865 equal(strsep(&cp, "-"), "y", 20); 866 check(strsep(&cp, "-") == NULL, 21); 867 cp = strcpy(one, "a,b, c,, ,d "); 868 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */ 869 equal(strsep(&cp, ", "), "b", 23); 870 equal(strsep(&cp, " ,"), "", 24); 871 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */ 872 equal(strsep(&cp, " ,"), "", 26); 873 equal(strsep(&cp, " ,"), "", 27); 874 equal(strsep(&cp, " ,"), "", 28); 875 equal(strsep(&cp, " ,"), "d", 29); 876 equal(strsep(&cp, " ,"), "", 30); 877 check(strsep(&cp, ", ") == NULL, 31); 878 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */ 879 cp = strcpy(one, ", "); 880 equal(strsep(&cp, ", "), "", 33); 881 equal(strsep(&cp, ", "), "", 34); 882 equal(strsep(&cp, ", "), "", 35); 883 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */ 884 cp = strcpy(one, ""); 885 equal(strsep(&cp, ", "), "", 37); 886 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */ 887 cp = strcpy(one, "abc"); 888 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */ 889 check(strsep(&cp, ", ") == NULL, 40); 890 cp = strcpy(one, "abc"); 891 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */ 892 check(strsep(&cp, "") == NULL, 42); 893 (void) strcpy(one, "abcdefgh"); 894 cp = strcpy(one, "a,b,c"); 895 equal(strsep(&cp, ","), "a", 43); /* Basics again... */ 896 equal(strsep(&cp, ","), "b", 44); 897 equal(strsep(&cp, ","), "c", 45); 898 check(strsep(&cp, ",") == NULL, 46); 899 equal(one+6, "gh", 47); /* Stomped past end? */ 900 equal(one, "a", 48); /* Stomped old tokens? */ 901 equal(one+2, "b", 49); 902 equal(one+4, "c", 50); 903 904 { 905 # if !defined(__APPLE__) 906 char text[] = "This,is,a,test"; 907 char *list = strdupa (text); 908 equal (strsep (&list, ","), "This", 51); 909 equal (strsep (&list, ","), "is", 52); 910 equal (strsep (&list, ","), "a", 53); 911 equal (strsep (&list, ","), "test", 54); 912 check (strsep (&list, ",") == NULL, 55); 913 # endif 914 } 915 916 cp = strcpy(one, "a,b, c,, ,d,"); 917 equal(strsep(&cp, ","), "a", 56); /* Different separators. */ 918 equal(strsep(&cp, ","), "b", 57); 919 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */ 920 equal(strsep(&cp, ","), "", 59); 921 equal(strsep(&cp, ","), " ", 60); 922 equal(strsep(&cp, ","), "d", 61); 923 equal(strsep(&cp, ","), "", 62); 924 check(strsep(&cp, ",") == NULL, 63); 925 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */ 926 927 cp = strcpy(one, "a,b, c,, ,d,"); 928 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */ 929 equal(strsep(&cp, "x,y"), "b", 66); 930 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */ 931 equal(strsep(&cp, "xy,"), "", 68); 932 equal(strsep(&cp, "x,y"), " ", 69); 933 equal(strsep(&cp, ",xy"), "d", 70); 934 equal(strsep(&cp, "xy,"), "", 71); 935 check(strsep(&cp, "x,y") == NULL, 72); 936 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */ 937 938 cp = strcpy(one, "ABC"); 939 one[4] = ':'; 940 equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */ 941 ptr = strsep(&cp, ":"); 942 equal(ptr, "", 75); 943 check(ptr == one + 3, 76); 944 check(cp == NULL, 77); 945 946 cp = strcpy(one, "ABC"); 947 one[4] = ':'; 948 equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */ 949 ptr = strsep(&cp, ":."); 950 equal(ptr, "", 79); 951 check(ptr == one + 3, 80); 952 953 cp = strcpy(one, "ABC"); /* No token in string. */ 954 equal(strsep(&cp, ","), "ABC", 81); 955 check(cp == NULL, 82); 956 957 *one = '\0'; /* Empty string. */ 958 cp = one; 959 ptr = strsep(&cp, ","); 960 equal(ptr, "", 83); 961 check(ptr == one, 84); 962 check(cp == NULL, 85); 963 964 *one = '\0'; /* Empty string and no token. */ 965 cp = one; 966 ptr = strsep(&cp, ""); 967 equal(ptr, "", 86); 968 check(ptr == one , 87); 969 check(cp == NULL, 88); 970 } 971 972 static void 973 test_memcmp (void) 974 { 975 it = "memcmp"; 976 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */ 977 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ 978 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */ 979 check(memcmp("abce", "abcd", 4) > 0, 4); 980 check(memcmp("alph", "beta", 4) < 0, 5); 981 check(memcmp("a\203", "a\003", 2) > 0, 6); 982 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */ 983 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */ 984 } 985 986 static void 987 test_memchr (void) 988 { 989 it = "memchr"; 990 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */ 991 (void) strcpy(one, "abcd"); 992 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */ 993 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */ 994 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */ 995 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */ 996 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */ 997 (void) strcpy(one, "ababa"); 998 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */ 999 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */ 1000 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */ 1001 (void) strcpy(one, "a\203b"); 1002 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */ 1003 1004 /* now test all possible alignment and length combinations to catch 1005 bugs due to unrolled loops (assuming unrolling is limited to no 1006 more than 128 byte chunks: */ 1007 { 1008 char buf[128 + sizeof(long)]; 1009 long align, len, i, pos; 1010 1011 for (align = 0; align < (long) sizeof(long); ++align) { 1012 for (len = 0; len < (long) (sizeof(buf) - align); ++len) { 1013 for (i = 0; i < len; ++i) { 1014 buf[align + i] = 'x'; /* don't depend on memset... */ 1015 } 1016 for (pos = 0; pos < len; ++pos) { 1017 #if 0 1018 printf("align %d, len %d, pos %d\n", align, len, pos); 1019 #endif 1020 check(memchr(buf + align, 'x', len) == buf + align + pos, 10); 1021 check(memchr(buf + align, 'x', pos) == NULL, 11); 1022 buf[align + pos] = '-'; 1023 } 1024 } 1025 } 1026 } 1027 } 1028 1029 static void 1030 test_memcpy (void) 1031 { 1032 int i; 1033 it = "memcpy"; 1034 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */ 1035 equal(one, "abc", 2); /* Did the copy go right? */ 1036 1037 (void) strcpy(one, "abcdefgh"); 1038 (void) memcpy(one+1, "xyz", 2); 1039 equal(one, "axydefgh", 3); /* Basic test. */ 1040 1041 (void) strcpy(one, "abc"); 1042 (void) memcpy(one, "xyz", 0); 1043 equal(one, "abc", 4); /* Zero-length copy. */ 1044 1045 (void) strcpy(one, "hi there"); 1046 (void) strcpy(two, "foo"); 1047 (void) memcpy(two, one, 9); 1048 equal(two, "hi there", 5); /* Just paranoia. */ 1049 equal(one, "hi there", 6); /* Stomped on source? */ 1050 1051 for (i = 0; i < 16; i++) 1052 { 1053 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 1054 strcpy (one, x); 1055 check (memcpy (one + i, "hi there", 9) == one + i, 1056 7 + (i * 6)); /* Unaligned destination. */ 1057 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */ 1058 equal (one + i, "hi there", 9 + (i * 6)); 1059 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */ 1060 check (memcpy (two, one + i, 9) == two, 1061 11 + (i * 6)); /* Unaligned source. */ 1062 equal (two, "hi there", 12 + (i * 6)); 1063 } 1064 } 1065 1066 #if !defined(__APPLE__) && !defined(__sun) 1067 static void 1068 test_mempcpy (void) 1069 { 1070 int i; 1071 it = "mempcpy"; 1072 check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */ 1073 equal(one, "abc", 2); /* Did the copy go right? */ 1074 1075 (void) strcpy(one, "abcdefgh"); 1076 (void) mempcpy(one+1, "xyz", 2); 1077 equal(one, "axydefgh", 3); /* Basic test. */ 1078 1079 (void) strcpy(one, "abc"); 1080 (void) mempcpy(one, "xyz", 0); 1081 equal(one, "abc", 4); /* Zero-length copy. */ 1082 1083 (void) strcpy(one, "hi there"); 1084 (void) strcpy(two, "foo"); 1085 (void) mempcpy(two, one, 9); 1086 equal(two, "hi there", 5); /* Just paranoia. */ 1087 equal(one, "hi there", 6); /* Stomped on source? */ 1088 1089 for (i = 0; i < 16; i++) 1090 { 1091 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 1092 strcpy (one, x); 1093 check (mempcpy (one + i, "hi there", 9) == one + i + 9, 1094 7 + (i * 6)); /* Unaligned destination. */ 1095 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */ 1096 equal (one + i, "hi there", 9 + (i * 6)); 1097 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */ 1098 check (mempcpy (two, one + i, 9) == two + 9, 1099 11 + (i * 6)); /* Unaligned source. */ 1100 equal (two, "hi there", 12 + (i * 6)); 1101 } 1102 } 1103 #endif 1104 1105 static void 1106 test_memmove (void) 1107 { 1108 it = "memmove"; 1109 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */ 1110 equal(one, "abc", 2); /* Did the copy go right? */ 1111 1112 (void) strcpy(one, "abcdefgh"); 1113 (void) memmove(one+1, "xyz", 2); 1114 equal(one, "axydefgh", 3); /* Basic test. */ 1115 1116 (void) strcpy(one, "abc"); 1117 (void) memmove(one, "xyz", 0); 1118 equal(one, "abc", 4); /* Zero-length copy. */ 1119 1120 (void) strcpy(one, "hi there"); 1121 (void) strcpy(two, "foo"); 1122 (void) memmove(two, one, 9); 1123 equal(two, "hi there", 5); /* Just paranoia. */ 1124 equal(one, "hi there", 6); /* Stomped on source? */ 1125 1126 (void) strcpy(one, "abcdefgh"); 1127 (void) memmove(one+1, one, 9); 1128 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */ 1129 1130 (void) strcpy(one, "abcdefgh"); 1131 (void) memmove(one+1, one+2, 7); 1132 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */ 1133 1134 (void) strcpy(one, "abcdefgh"); 1135 (void) memmove(one, one, 9); 1136 equal(one, "abcdefgh", 9); /* 100% overlap. */ 1137 } 1138 1139 static void 1140 test_memccpy (void) 1141 { 1142 /* First test like memcpy, then the search part The SVID, the only 1143 place where memccpy is mentioned, says overlap might fail, so we 1144 don't try it. Besides, it's hard to see the rationale for a 1145 non-left-to-right memccpy. */ 1146 it = "memccpy"; 1147 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */ 1148 equal(one, "abc", 2); /* Did the copy go right? */ 1149 1150 (void) strcpy(one, "abcdefgh"); 1151 (void) memccpy(one+1, "xyz", 'q', 2); 1152 equal(one, "axydefgh", 3); /* Basic test. */ 1153 1154 (void) strcpy(one, "abc"); 1155 (void) memccpy(one, "xyz", 'q', 0); 1156 equal(one, "abc", 4); /* Zero-length copy. */ 1157 1158 (void) strcpy(one, "hi there"); 1159 (void) strcpy(two, "foo"); 1160 (void) memccpy(two, one, 'q', 9); 1161 equal(two, "hi there", 5); /* Just paranoia. */ 1162 equal(one, "hi there", 6); /* Stomped on source? */ 1163 1164 (void) strcpy(one, "abcdefgh"); 1165 (void) strcpy(two, "horsefeathers"); 1166 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */ 1167 equal(one, "abcdefgh", 8); /* Source intact? */ 1168 equal(two, "abcdefeathers", 9); /* Copy correct? */ 1169 1170 (void) strcpy(one, "abcd"); 1171 (void) strcpy(two, "bumblebee"); 1172 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */ 1173 equal(two, "aumblebee", 11); 1174 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */ 1175 equal(two, "abcdlebee", 13); 1176 (void) strcpy(one, "xyz"); 1177 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */ 1178 equal(two, "xbcdlebee", 15); 1179 } 1180 1181 static void 1182 test_memset (void) 1183 { 1184 int i; 1185 1186 it = "memset"; 1187 (void) strcpy(one, "abcdefgh"); 1188 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */ 1189 equal(one, "axxxefgh", 2); /* Basic test. */ 1190 1191 (void) memset(one+2, 'y', 0); 1192 equal(one, "axxxefgh", 3); /* Zero-length set. */ 1193 1194 (void) memset(one+5, 0, 1); 1195 equal(one, "axxxe", 4); /* Zero fill. */ 1196 equal(one+6, "gh", 5); /* And the leftover. */ 1197 1198 (void) memset(one+2, 010045, 1); 1199 equal(one, "ax\045xe", 6); /* Unsigned char convert. */ 1200 1201 /* Non-8bit fill character. */ 1202 memset (one, 0x101, sizeof (one)); 1203 for (i = 0; i < (int) sizeof (one); ++i) 1204 check (one[i] == '\01', 7); 1205 1206 /* Test for more complex versions of memset, for all alignments and 1207 lengths up to 256. This test takes a little while, perhaps it should 1208 be made weaker? */ 1209 { 1210 char data[512]; 1211 int j; 1212 int k; 1213 int c; 1214 1215 for (i = 0; i < 512; i++) 1216 data[i] = 'x'; 1217 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and 1218 memset(,'y',) */ 1219 for (j = 0; j < 256; j++) 1220 for (i = 0; i < 256; i++) 1221 { 1222 memset (data + i, c, j); 1223 for (k = 0; k < i; k++) 1224 if (data[k] != 'x') 1225 goto fail; 1226 for (k = i; k < i+j; k++) 1227 { 1228 if (data[k] != c) 1229 goto fail; 1230 data[k] = 'x'; 1231 } 1232 for (k = i+j; k < 512; k++) 1233 if (data[k] != 'x') 1234 goto fail; 1235 continue; 1236 1237 fail: 1238 check (0, 8 + i + j * 256 + (c != 0) * 256 * 256); 1239 } 1240 } 1241 } 1242 1243 static void 1244 test_bcopy (void) 1245 { 1246 /* Much like memcpy. Berklix manual is silent about overlap, so 1247 don't test it. */ 1248 it = "bcopy"; 1249 (void) bcopy("abc", one, 4); 1250 equal(one, "abc", 1); /* Simple copy. */ 1251 1252 (void) strcpy(one, "abcdefgh"); 1253 (void) bcopy("xyz", one+1, 2); 1254 equal(one, "axydefgh", 2); /* Basic test. */ 1255 1256 (void) strcpy(one, "abc"); 1257 (void) bcopy("xyz", one, 0); 1258 equal(one, "abc", 3); /* Zero-length copy. */ 1259 1260 (void) strcpy(one, "hi there"); 1261 (void) strcpy(two, "foo"); 1262 (void) bcopy(one, two, 9); 1263 equal(two, "hi there", 4); /* Just paranoia. */ 1264 equal(one, "hi there", 5); /* Stomped on source? */ 1265 } 1266 1267 static void 1268 test_bzero (void) 1269 { 1270 it = "bzero"; 1271 (void) strcpy(one, "abcdef"); 1272 bzero(one+2, 2); 1273 equal(one, "ab", 1); /* Basic test. */ 1274 equal(one+3, "", 2); 1275 equal(one+4, "ef", 3); 1276 1277 (void) strcpy(one, "abcdef"); 1278 bzero(one+2, 0); 1279 equal(one, "abcdef", 4); /* Zero-length copy. */ 1280 } 1281 1282 #if !defined(__APPLE__) 1283 static void 1284 test_strndup (void) 1285 { 1286 char *p, *q; 1287 it = "strndup"; 1288 p = strndup("abcdef", 12); 1289 check(p != NULL, 1); 1290 if (p != NULL) 1291 { 1292 equal(p, "abcdef", 2); 1293 q = strndup(p + 1, 2); 1294 check(q != NULL, 3); 1295 if (q != NULL) 1296 equal(q, "bc", 4); 1297 free (q); 1298 } 1299 free (p); 1300 p = strndup("abc def", 3); 1301 check(p != NULL, 5); 1302 if (p != NULL) 1303 equal(p, "abc", 6); 1304 free (p); 1305 } 1306 #endif 1307 1308 static void 1309 test_bcmp (void) 1310 { 1311 it = "bcmp"; 1312 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */ 1313 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ 1314 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */ 1315 check(bcmp("abce", "abcd", 4) != 0, 4); 1316 check(bcmp("alph", "beta", 4) != 0, 5); 1317 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */ 1318 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */ 1319 } 1320 1321 static void 1322 test_strerror (void) 1323 { 1324 it = "strerror"; 1325 check(strerror(EDOM) != 0, 1); 1326 check(strerror(ERANGE) != 0, 2); 1327 check(strerror(ENOENT) != 0, 3); 1328 } 1329 1330 static void 1331 test_strcasecmp (void) 1332 { 1333 it = "strcasecmp"; 1334 /* Note that the locale is "C". */ 1335 check(strcasecmp("a", "a") == 0, 1); 1336 check(strcasecmp("a", "A") == 0, 2); 1337 check(strcasecmp("A", "a") == 0, 3); 1338 check(strcasecmp("a", "b") < 0, 4); 1339 check(strcasecmp("c", "b") > 0, 5); 1340 check(strcasecmp("abc", "AbC") == 0, 6); 1341 check(strcasecmp("0123456789", "0123456789") == 0, 7); 1342 check(strcasecmp("", "0123456789") < 0, 8); 1343 check(strcasecmp("AbC", "") > 0, 9); 1344 check(strcasecmp("AbC", "A") > 0, 10); 1345 check(strcasecmp("AbC", "Ab") > 0, 11); 1346 check(strcasecmp("AbC", "ab") > 0, 12); 1347 } 1348 1349 static void 1350 test_strncasecmp (void) 1351 { 1352 it = "strncasecmp"; 1353 /* Note that the locale is "C". */ 1354 check(strncasecmp("a", "a", 5) == 0, 1); 1355 check(strncasecmp("a", "A", 5) == 0, 2); 1356 check(strncasecmp("A", "a", 5) == 0, 3); 1357 check(strncasecmp("a", "b", 5) < 0, 4); 1358 check(strncasecmp("c", "b", 5) > 0, 5); 1359 check(strncasecmp("abc", "AbC", 5) == 0, 6); 1360 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7); 1361 check(strncasecmp("", "0123456789", 10) < 0, 8); 1362 check(strncasecmp("AbC", "", 5) > 0, 9); 1363 check(strncasecmp("AbC", "A", 5) > 0, 10); 1364 check(strncasecmp("AbC", "Ab", 5) > 0, 11); 1365 check(strncasecmp("AbC", "ab", 5) > 0, 12); 1366 check(strncasecmp("0123456789", "AbC", 0) == 0, 13); 1367 check(strncasecmp("AbC", "abc", 1) == 0, 14); 1368 check(strncasecmp("AbC", "abc", 2) == 0, 15); 1369 check(strncasecmp("AbC", "abc", 3) == 0, 16); 1370 check(strncasecmp("AbC", "abcd", 3) == 0, 17); 1371 check(strncasecmp("AbC", "abcd", 4) < 0, 18); 1372 check(strncasecmp("ADC", "abcd", 1) == 0, 19); 1373 check(strncasecmp("ADC", "abcd", 2) > 0, 20); 1374 } 1375 1376 static void 1377 test_strcasestr (void) 1378 { 1379 it = "strcasestr"; 1380 check(strcasestr("abCd", "z") == NULL, 1); /* Not found. */ 1381 check(strcasestr("AbcD", "abX") == NULL, 2); /* Dead end. */ 1382 (void) strcpy(one, "abCd"); 1383 check(strcasestr(one, "c") == one+2, 3); /* Basic test. */ 1384 check(strcasestr(one, "Bc") == one+1, 4); /* Multichar. */ 1385 check(strcasestr(one, "d") == one+3, 5); /* End of string. */ 1386 check(strcasestr(one, "Cd") == one+2, 6); /* Tail of string. */ 1387 check(strcasestr(one, "aBc") == one, 7); /* Beginning. */ 1388 check(strcasestr(one, "aBcd") == one, 8); /* Exact match. */ 1389 check(strcasestr(one, "AbcDe") == NULL, 9); /* Too long. */ 1390 check(strcasestr(one, "dE") == NULL, 10); /* Past end. */ 1391 check(strcasestr(one, "") == one, 11); /* Finding empty. */ 1392 (void) strcpy(one, "abAba"); 1393 check(strcasestr(one, "Ba") == one+1, 12); /* Finding first. */ 1394 (void) strcpy(one, ""); 1395 check(strcasestr(one, "b") == NULL, 13); /* Empty string. */ 1396 check(strcasestr(one, "") == one, 14); /* Empty in empty string. */ 1397 (void) strcpy(one, "BcbCa"); 1398 check(strcasestr(one, "bCa") == one+2, 15); /* False start. */ 1399 (void) strcpy(one, "bbBcaBbcA"); 1400 check(strcasestr(one, "bbCa") == one+1, 16); /* With overlap. */ 1401 } 1402 1403 int 1404 main (void) 1405 { 1406 int status; 1407 1408 /* Test strcmp first because we use it to test other things. */ 1409 test_strcmp (); 1410 1411 /* Test strcpy next because we need it to set up other tests. */ 1412 test_strcpy (); 1413 1414 /* A closely related function is stpcpy. */ 1415 test_stpcpy (); 1416 1417 #if !defined(__APPLE__) 1418 /* stpncpy. */ 1419 test_stpncpy (); 1420 #endif 1421 1422 /* strcat. */ 1423 test_strcat (); 1424 1425 /* strncat. */ 1426 test_strncat (); 1427 1428 /* strncmp. */ 1429 test_strncmp (); 1430 1431 /* strncpy. */ 1432 test_strncpy (); 1433 1434 /* strlen. */ 1435 test_strlen (); 1436 1437 /* strchr. */ 1438 test_strchr (); 1439 1440 # if !defined(__APPLE__) 1441 /* strchrnul. */ 1442 test_strchrnul (); 1443 # endif 1444 1445 # if !defined(__APPLE__) && !defined(__sun) 1446 /* rawmemchr. */ 1447 test_rawmemchr (); 1448 # endif 1449 1450 /* index - just like strchr. */ 1451 test_index (); 1452 1453 /* strrchr. */ 1454 test_strrchr (); 1455 1456 # if !defined(__APPLE__) && !defined(__sun) 1457 /* memrchr. */ 1458 test_memrchr (); 1459 # endif 1460 1461 /* rindex - just like strrchr. */ 1462 test_rindex (); 1463 1464 /* strpbrk - somewhat like strchr. */ 1465 test_strpbrk (); 1466 1467 /* strstr - somewhat like strchr. */ 1468 test_strstr (); 1469 1470 /* strspn. */ 1471 test_strspn (); 1472 1473 /* strcspn. */ 1474 test_strcspn (); 1475 1476 /* strtok - the hard one. */ 1477 test_strtok (); 1478 1479 /* strtok_r. */ 1480 test_strtok_r (); 1481 1482 /* strsep. */ 1483 test_strsep (); 1484 1485 /* memcmp. */ 1486 test_memcmp (); 1487 1488 /* memchr. */ 1489 test_memchr (); 1490 1491 /* memcpy - need not work for overlap. */ 1492 test_memcpy (); 1493 1494 /* memmove - must work on overlap. */ 1495 test_memmove (); 1496 1497 # if !defined(__APPLE__) && !defined(__sun) 1498 /* mempcpy */ 1499 test_mempcpy (); 1500 # endif 1501 1502 /* memccpy. */ 1503 test_memccpy (); 1504 1505 /* memset. */ 1506 test_memset (); 1507 1508 /* bcopy. */ 1509 test_bcopy (); 1510 1511 /* bzero. */ 1512 test_bzero (); 1513 1514 /* bcmp - somewhat like memcmp. */ 1515 test_bcmp (); 1516 1517 #if !defined(__APPLE__) 1518 /* strndup. */ 1519 test_strndup (); 1520 #endif 1521 1522 /* strerror - VERY system-dependent. */ 1523 test_strerror (); 1524 1525 /* strcasecmp. Without locale dependencies. */ 1526 test_strcasecmp (); 1527 1528 /* strncasecmp. Without locale dependencies. */ 1529 test_strncasecmp (); 1530 1531 test_strcasestr (); 1532 1533 if (errors == 0) 1534 { 1535 status = EXIT_SUCCESS; 1536 //puts("No errors."); 1537 } 1538 else 1539 { 1540 status = EXIT_FAILURE; 1541 printf("%d errors.\n", (int)errors); 1542 } 1543 1544 return status; 1545 } 1546