1 /* Tester for string functions.
2 Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
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 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
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
38 #define _sys_nerr sys_nerr
39 #define _sys_errlist sys_errlist
42 #define STREQ(a, b) (strcmp((a), (b)) == 0)
44 const char *it = "<UNSET>"; /* Routine name for message routines. */
47 /* Complain if condition is not true. */
49 check (int thing, int number)
53 printf("%s flunked test %d\n", it, number);
58 /* Complain if first two args don't strcmp as equal. */
59 void equal (const char *a, const char *b, int number)
61 check(a != NULL && b != NULL && STREQ (a, b), number);
72 /* Test strcmp first because we use it to test other things. */
74 check (strcmp ("", "") == 0, 1); /* Trivial case. */
75 check (strcmp ("a", "a") == 0, 2); /* Identity. */
76 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
77 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
78 check (strcmp ("abcd", "abc") > 0, 5);
79 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
80 check (strcmp ("abce", "abcd") > 0, 7);
81 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
82 check (strcmp ("a\203", "a\003") > 0, 9);
85 char buf1[0x40], buf2[0x40];
87 for (i=0; i < 0x10; i++)
88 for (j = 0; j < 0x10; j++)
91 for (k = 0; k < 0x3f; k++)
93 buf1[j] = '0' ^ (k & 4);
94 buf2[j] = '4' ^ (k & 4);
96 buf1[i] = buf1[0x3f] = 0;
97 buf2[j] = buf2[0x3f] = 0;
98 for (k = 0; k < 0xf; k++)
100 int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
101 check (strcmp (buf1+i,buf2+j) == 0, cnum);
102 buf1[i+k] = 'A' + i + k;
104 check (strcmp (buf1+i,buf2+j) > 0, cnum+1);
105 check (strcmp (buf2+j,buf1+i) < 0, cnum+2);
106 buf2[j+k] = 'B' + i + k;
108 check (strcmp (buf1+i,buf2+j) < 0, cnum+3);
109 check (strcmp (buf2+j,buf1+i) > 0, cnum+4);
110 buf2[j+k] = 'A' + i + k;
111 buf1[i] = 'A' + i + 0x80;
112 check (strcmp (buf1+i,buf2+j) > 0, cnum+5);
113 check (strcmp (buf2+j,buf1+i) < 0, cnum+6);
119 /* Test strcpy next because we need it to set up other tests. */
121 check (strcpy (one, "abcd") == one, 1); /* Returned value. */
122 equal (one, "abcd", 2); /* Basic test. */
124 (void) strcpy (one, "x");
125 equal (one, "x", 3); /* Writeover. */
126 equal (one+2, "cd", 4); /* Wrote too much? */
128 (void) strcpy (two, "hi there");
129 (void) strcpy (one, two);
130 equal (one, "hi there", 5); /* Basic test encore. */
131 equal (two, "hi there", 6); /* Stomped on source? */
133 (void) strcpy (one, "");
134 equal (one, "", 7); /* Boundary condition. */
136 /* A closely related function is stpcpy. */
138 check ((stpcpy (one, "a") - one) == 1, 1);
141 check ((stpcpy (one, "ab") - one) == 2, 3);
142 equal (one, "ab", 4);
144 check ((stpcpy (one, "abc") - one) == 3, 5);
145 equal (one, "abc", 6);
147 check ((stpcpy (one, "abcd") - one) == 4, 7);
148 equal (one, "abcd", 8);
150 check ((stpcpy (one, "abcde") - one) == 5, 9);
151 equal (one, "abcde", 10);
153 check ((stpcpy (one, "abcdef") - one) == 6, 11);
154 equal (one, "abcdef", 12);
156 check ((stpcpy (one, "abcdefg") - one) == 7, 13);
157 equal (one, "abcdefg", 14);
159 check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
160 equal (one, "abcdefgh", 16);
162 check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
163 equal (one, "abcdefghi", 18);
165 check ((stpcpy (one, "x") - one) == 1, 19);
166 equal (one, "x", 20); /* Writeover. */
167 equal (one+2, "cdefghi", 21); /* Wrote too much? */
169 check ((stpcpy (one, "xx") - one) == 2, 22);
170 equal (one, "xx", 23); /* Writeover. */
171 equal (one+3, "defghi", 24); /* Wrote too much? */
173 check ((stpcpy (one, "xxx") - one) == 3, 25);
174 equal (one, "xxx", 26); /* Writeover. */
175 equal (one+4, "efghi", 27); /* Wrote too much? */
177 check ((stpcpy (one, "xxxx") - one) == 4, 28);
178 equal (one, "xxxx", 29); /* Writeover. */
179 equal (one+5, "fghi", 30); /* Wrote too much? */
181 check ((stpcpy (one, "xxxxx") - one) == 5, 31);
182 equal (one, "xxxxx", 32); /* Writeover. */
183 equal (one+6, "ghi", 33); /* Wrote too much? */
185 check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
186 equal (one, "xxxxxx", 35); /* Writeover. */
187 equal (one+7, "hi", 36); /* Wrote too much? */
189 check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
190 equal (one, "xxxxxxx", 38); /* Writeover. */
191 equal (one+8, "i", 39); /* Wrote too much? */
193 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
194 equal (one, "abc", 41);
195 equal (one + 4, "xxx", 42);
200 memset (one, 'x', sizeof (one));
201 check (stpncpy (one, "abc", 2) == one + 2, 1);
202 check (stpncpy (one, "abc", 3) == one + 3, 2);
203 check (stpncpy (one, "abc", 4) == one + 3, 3);
204 check (one[3] == '\0' && one[4] == 'x', 4);
205 check (stpncpy (one, "abcd", 5) == one + 4, 5);
206 check (one[4] == '\0' && one[5] == 'x', 6);
207 check (stpncpy (one, "abcd", 6) == one + 4, 7);
208 check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
212 (void) strcpy (one, "ijk");
213 check (strcat (one, "lmn") == one, 1); /* Returned value. */
214 equal (one, "ijklmn", 2); /* Basic test. */
216 (void) strcpy (one, "x");
217 (void) strcat (one, "yz");
218 equal (one, "xyz", 3); /* Writeover. */
219 equal (one+4, "mn", 4); /* Wrote too much? */
221 (void) strcpy (one, "gh");
222 (void) strcpy (two, "ef");
223 (void) strcat (one, two);
224 equal (one, "ghef", 5); /* Basic test encore. */
225 equal (two, "ef", 6); /* Stomped on source? */
227 (void) strcpy (one, "");
228 (void) strcat (one, "");
229 equal (one, "", 7); /* Boundary conditions. */
230 (void) strcpy (one, "ab");
231 (void) strcat (one, "");
232 equal (one, "ab", 8);
233 (void) strcpy (one, "");
234 (void) strcat (one, "cd");
235 equal (one, "cd", 9);
237 /* strncat - first test it as strcat, with big counts,
238 then test the count mechanism. */
240 (void) strcpy (one, "ijk");
241 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
242 equal (one, "ijklmn", 2); /* Basic test. */
244 (void) strcpy (one, "x");
245 (void) strncat (one, "yz", 99);
246 equal (one, "xyz", 3); /* Writeover. */
247 equal (one+4, "mn", 4); /* Wrote too much? */
249 (void) strcpy (one, "gh");
250 (void) strcpy (two, "ef");
251 (void) strncat (one, two, 99);
252 equal (one, "ghef", 5); /* Basic test encore. */
253 equal (two, "ef", 6); /* Stomped on source? */
255 (void) strcpy (one, "");
256 (void) strncat (one, "", 99);
257 equal (one, "", 7); /* Boundary conditions. */
258 (void) strcpy (one, "ab");
259 (void) strncat (one, "", 99);
260 equal (one, "ab", 8);
261 (void) strcpy (one, "");
262 (void) strncat (one, "cd", 99);
263 equal (one, "cd", 9);
265 (void) strcpy (one, "ab");
266 (void) strncat (one, "cdef", 2);
267 equal (one, "abcd", 10); /* Count-limited. */
269 (void) strncat (one, "gh", 0);
270 equal (one, "abcd", 11); /* Zero count. */
272 (void) strncat (one, "gh", 2);
273 equal (one, "abcdgh", 12); /* Count and length equal. */
275 /* strncmp - first test as strcmp with big counts,
276 then test count code. */
278 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
279 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
280 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
281 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
282 check (strncmp ("abcd", "abc", 99) > 0, 5);
283 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
284 check (strncmp ("abce", "abcd", 99) > 0, 7);
285 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
286 check (strncmp ("a\203", "a\003", 2) > 0, 9);
287 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
288 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
289 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
290 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
292 /* strncpy - testing is a bit different because of odd semantics. */
294 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
295 equal (one, "abc", 2); /* Did the copy go right? */
297 (void) strcpy (one, "abcdefgh");
298 (void) strncpy (one, "xyz", 2);
299 equal (one, "xycdefgh", 3); /* Copy cut by count. */
301 (void) strcpy (one, "abcdefgh");
302 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
303 equal (one, "xyzdefgh", 4);
305 (void) strcpy (one, "abcdefgh");
306 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
307 equal (one, "xyz", 5);
308 equal (one+4, "efgh", 6); /* Wrote too much? */
310 (void) strcpy (one, "abcdefgh");
311 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
312 equal (one, "xyz", 7);
313 equal (one+4, "", 8);
314 equal (one+5, "fgh", 9);
316 (void) strcpy (one, "abc");
317 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
318 equal (one, "abc", 10);
320 (void) strncpy (one, "", 2); /* Zero-length source. */
322 equal (one+1, "", 12);
323 equal (one+2, "c", 13);
325 (void) strcpy (one, "hi there");
326 (void) strncpy (two, one, 9);
327 equal (two, "hi there", 14); /* Just paranoia. */
328 equal (one, "hi there", 15); /* Stomped on source? */
332 check (strlen ("") == 0, 1); /* Empty. */
333 check (strlen ("a") == 1, 2); /* Single char. */
334 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
339 for (i=0; i < 0x100; i++)
341 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
343 strcpy (p+3, "BAD/WRONG");
344 check (strlen (p) == 2, 4+i);
350 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
351 (void) strcpy (one, "abcd");
352 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
353 check (strchr (one, 'd') == one+3, 3); /* End of string. */
354 check (strchr (one, 'a') == one, 4); /* Beginning. */
355 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
356 (void) strcpy (one, "ababa");
357 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
358 (void) strcpy (one, "");
359 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
360 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
365 for (i=0; i < 0x100; i++)
367 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
369 strcpy (p+3, "BAD/WRONG");
370 check (strchr (p, '/') == NULL, 9+i);
375 /* index - just like strchr. */
377 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
378 (void) strcpy (one, "abcd");
379 check (index (one, 'c') == one+2, 2); /* Basic test. */
380 check (index (one, 'd') == one+3, 3); /* End of string. */
381 check (index (one, 'a') == one, 4); /* Beginning. */
382 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
383 (void) strcpy (one, "ababa");
384 check (index (one, 'b') == one+1, 6); /* Finding first. */
385 (void) strcpy (one, "");
386 check (index (one, 'b') == NULL, 7); /* Empty string. */
387 check (index (one, '\0') == one, 8); /* NUL in empty string. */
392 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
393 (void) strcpy (one, "abcd");
394 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
395 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
396 check (strrchr (one, 'a') == one, 4); /* Beginning. */
397 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
398 (void) strcpy (one, "ababa");
399 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
400 (void) strcpy (one, "");
401 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
402 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
407 for (i=0; i < 0x100; i++)
409 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
411 strcpy (p+3, "BAD/WRONG");
412 check (strrchr (p, '/') == NULL, 9+i);
417 /* rindex - just like strrchr. */
419 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
420 (void) strcpy (one, "abcd");
421 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
422 check (rindex (one, 'd') == one+3, 3); /* End of string. */
423 check (rindex (one, 'a') == one, 4); /* Beginning. */
424 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
425 (void) strcpy (one, "ababa");
426 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
427 (void) strcpy (one, "");
428 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
429 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
432 /* strpbrk - somewhat like strchr. */
434 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
435 (void) strcpy(one, "abcd");
436 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
437 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
438 check(strpbrk(one, "a") == one, 4); /* Beginning. */
439 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
440 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
441 (void) strcpy(one, "abcabdea");
442 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
443 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
444 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
445 (void) strcpy(one, "");
446 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
447 check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
449 /* strstr - somewhat like strchr. */
451 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
452 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
453 (void) strcpy(one, "abcd");
454 check(strstr(one, "c") == one+2, 3); /* Basic test. */
455 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
456 check(strstr(one, "d") == one+3, 5); /* End of string. */
457 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
458 check(strstr(one, "abc") == one, 7); /* Beginning. */
459 check(strstr(one, "abcd") == one, 8); /* Exact match. */
460 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
461 check(strstr(one, "de") == NULL, 10); /* Past end. */
462 check(strstr(one, "") == one, 11); /* Finding empty. */
463 (void) strcpy(one, "ababa");
464 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
465 (void) strcpy(one, "");
466 check(strstr(one, "b") == NULL, 13); /* Empty string. */
467 check(strstr(one, "") == one, 14); /* Empty in empty string. */
468 (void) strcpy(one, "bcbca");
469 check(strstr(one, "bca") == one+2, 15); /* False start. */
470 (void) strcpy(one, "bbbcabbca");
471 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
475 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
476 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
477 check(strspn("abc", "qx") == 0, 3); /* None. */
478 check(strspn("", "ab") == 0, 4); /* Null string. */
479 check(strspn("abc", "") == 0, 5); /* Null search list. */
483 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
484 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
485 check(strcspn("abc", "abc") == 0, 3); /* None. */
486 check(strcspn("", "ab") == 0, 4); /* Null string. */
487 check(strcspn("abc", "") == 3, 5); /* Null search list. */
489 /* strtok - the hard one. */
491 (void) strcpy(one, "first, second, third");
492 equal(strtok(one, ", "), "first", 1); /* Basic test. */
493 equal(one, "first", 2);
494 equal(strtok((char *)NULL, ", "), "second", 3);
495 equal(strtok((char *)NULL, ", "), "third", 4);
496 check(strtok((char *)NULL, ", ") == NULL, 5);
497 (void) strcpy(one, ", first, ");
498 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
499 check(strtok((char *)NULL, ", ") == NULL, 7);
500 (void) strcpy(one, "1a, 1b; 2a, 2b");
501 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
502 equal(strtok((char *)NULL, "; "), "1b", 9);
503 equal(strtok((char *)NULL, ", "), "2a", 10);
504 (void) strcpy(two, "x-y");
505 equal(strtok(two, "-"), "x", 11); /* New string before done. */
506 equal(strtok((char *)NULL, "-"), "y", 12);
507 check(strtok((char *)NULL, "-") == NULL, 13);
508 (void) strcpy(one, "a,b, c,, ,d");
509 equal(strtok(one, ", "), "a", 14); /* Different separators. */
510 equal(strtok((char *)NULL, ", "), "b", 15);
511 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
512 equal(strtok((char *)NULL, " ,"), "d", 17);
513 check(strtok((char *)NULL, ", ") == NULL, 18);
514 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
515 (void) strcpy(one, ", ");
516 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
517 (void) strcpy(one, "");
518 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
519 (void) strcpy(one, "abc");
520 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
521 check(strtok((char *)NULL, ", ") == NULL, 23);
522 (void) strcpy(one, "abc");
523 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
524 check(strtok((char *)NULL, "") == NULL, 25);
525 (void) strcpy(one, "abcdefgh");
526 (void) strcpy(one, "a,b,c");
527 equal(strtok(one, ","), "a", 26); /* Basics again... */
528 equal(strtok((char *)NULL, ","), "b", 27);
529 equal(strtok((char *)NULL, ","), "c", 28);
530 check(strtok((char *)NULL, ",") == NULL, 29);
531 equal(one+6, "gh", 30); /* Stomped past end? */
532 equal(one, "a", 31); /* Stomped old tokens? */
533 equal(one+2, "b", 32);
534 equal(one+4, "c", 33);
538 (void) strcpy(one, "first, second, third");
539 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
540 equal(one, "first", 2);
541 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
542 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
543 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
544 (void) strcpy(one, ", first, ");
545 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
546 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
547 (void) strcpy(one, "1a, 1b; 2a, 2b");
548 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
549 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
550 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
551 (void) strcpy(two, "x-y");
552 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
553 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
554 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
555 (void) strcpy(one, "a,b, c,, ,d");
556 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
557 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
558 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
559 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
560 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
561 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
562 (void) strcpy(one, ", ");
563 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
564 (void) strcpy(one, "");
565 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
566 (void) strcpy(one, "abc");
567 equal(strtok_r(one, ", ", &cp), "abc", 22); /* No delimiters. */
568 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 23);
569 (void) strcpy(one, "abc");
570 equal(strtok_r(one, "", &cp), "abc", 24); /* Empty delimiter list. */
571 check(strtok_r((char *)NULL, "", &cp) == NULL, 25);
572 (void) strcpy(one, "abcdefgh");
573 (void) strcpy(one, "a,b,c");
574 equal(strtok_r(one, ",", &cp), "a", 26); /* Basics again... */
575 equal(strtok_r((char *)NULL, ",", &cp), "b", 27);
576 equal(strtok_r((char *)NULL, ",", &cp), "c", 28);
577 check(strtok_r((char *)NULL, ",", &cp) == NULL, 29);
578 equal(one+6, "gh", 30); /* Stomped past end? */
579 equal(one, "a", 31); /* Stomped old tokens? */
580 equal(one+2, "b", 32);
581 equal(one+4, "c", 33);
585 cp = strcpy(one, "first, second, third");
586 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
587 equal(one, "first", 2);
588 equal(strsep(&cp, ", "), "", 3);
589 equal(strsep(&cp, ", "), "second", 4);
590 equal(strsep(&cp, ", "), "", 5);
591 equal(strsep(&cp, ", "), "third", 6);
592 check(strsep(&cp, ", ") == NULL, 7);
593 cp = strcpy(one, ", first, ");
594 equal(strsep(&cp, ", "), "", 8);
595 equal(strsep(&cp, ", "), "", 9);
596 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
597 equal(strsep(&cp, ", "), "", 11);
598 check(strsep(&cp, ", ") == NULL, 12);
599 cp = strcpy(one, "1a, 1b; 2a, 2b");
600 equal(strsep(&cp, ", "), "1a", 13); /* Changing delim lists. */
601 equal(strsep(&cp, ", "), "", 14);
602 equal(strsep(&cp, "; "), "1b", 15);
603 equal(strsep(&cp, ", "), "", 16);
604 equal(strsep(&cp, ", "), "2a", 17);
605 cp = strcpy(two, "x-y");
606 equal(strsep(&cp, "-"), "x", 18); /* New string before done. */
607 equal(strsep(&cp, "-"), "y", 19);
608 check(strsep(&cp, "-") == NULL, 20);
609 cp = strcpy(one, "a,b, c,, ,d");
610 equal(strsep(&cp, ", "), "a", 21); /* Different separators. */
611 equal(strsep(&cp, ", "), "b", 22);
612 equal(strsep(&cp, " ,"), "", 23);
613 equal(strsep(&cp, " ,"), "c", 24); /* Permute list too. */
614 equal(strsep(&cp, " ,"), "", 25);
615 equal(strsep(&cp, " ,"), "", 26);
616 equal(strsep(&cp, " ,"), "", 27);
617 equal(strsep(&cp, " ,"), "d", 28);
618 check(strsep(&cp, ", ") == NULL, 29);
619 check(strsep(&cp, ", ") == NULL, 30); /* Persistence. */
620 cp = strcpy(one, ", ");
621 equal(strsep(&cp, ", "), "", 31);
622 equal(strsep(&cp, ", "), "", 32);
623 check(strsep(&cp, ", ") == NULL, 33); /* No tokens. */
624 cp = strcpy(one, "");
625 check(strsep(&cp, ", ") == NULL, 34); /* Empty string. */
626 cp = strcpy(one, "abc");
627 equal(strsep(&cp, ", "), "abc", 35); /* No delimiters. */
628 check(strsep(&cp, ", ") == NULL, 36);
629 cp = strcpy(one, "abc");
630 equal(strsep(&cp, ""), "abc", 37); /* Empty delimiter list. */
631 check(strsep(&cp, "") == NULL, 38);
632 (void) strcpy(one, "abcdefgh");
633 cp = strcpy(one, "a,b,c");
634 equal(strsep(&cp, ","), "a", 39); /* Basics again... */
635 equal(strsep(&cp, ","), "b", 40);
636 equal(strsep(&cp, ","), "c", 41);
637 check(strsep(&cp, ",") == NULL, 42);
638 equal(one+6, "gh", 43); /* Stomped past end? */
639 equal(one, "a", 44); /* Stomped old tokens? */
640 equal(one+2, "b", 45);
641 equal(one+4, "c", 46);
645 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
646 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
647 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
648 check(memcmp("abce", "abcd", 4) > 0, 4);
649 check(memcmp("alph", "beta", 4) < 0, 5);
650 check(memcmp("a\203", "a\003", 2) > 0, 6);
651 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
652 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
656 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
657 (void) strcpy(one, "abcd");
658 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
659 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
660 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
661 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
662 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
663 (void) strcpy(one, "ababa");
664 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
665 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
666 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
667 (void) strcpy(one, "a\203b");
668 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
670 /* now test all possible alignment and length combinations to catch
671 bugs due to unrolled loops (assuming unrolling is limited to no
672 more than 128 byte chunks: */
674 char buf[128 + sizeof(long)];
675 long align, len, i, pos;
677 for (align = 0; align < (long) sizeof(long); ++align) {
678 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
679 for (i = 0; i < len; ++i) {
680 buf[align + i] = 'x'; /* don't depend on memset... */
682 for (pos = 0; pos < len; ++pos) {
684 printf("align %d, len %d, pos %d\n", align, len, pos);
686 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
687 check(memchr(buf + align, 'x', pos) == NULL, 11);
688 buf[align + pos] = '-';
694 /* memcpy - need not work for overlap. */
696 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
697 equal(one, "abc", 2); /* Did the copy go right? */
699 (void) strcpy(one, "abcdefgh");
700 (void) memcpy(one+1, "xyz", 2);
701 equal(one, "axydefgh", 3); /* Basic test. */
703 (void) strcpy(one, "abc");
704 (void) memcpy(one, "xyz", 0);
705 equal(one, "abc", 4); /* Zero-length copy. */
707 (void) strcpy(one, "hi there");
708 (void) strcpy(two, "foo");
709 (void) memcpy(two, one, 9);
710 equal(two, "hi there", 5); /* Just paranoia. */
711 equal(one, "hi there", 6); /* Stomped on source? */
713 /* memmove - must work on overlap. */
715 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
716 equal(one, "abc", 2); /* Did the copy go right? */
718 (void) strcpy(one, "abcdefgh");
719 (void) memmove(one+1, "xyz", 2);
720 equal(one, "axydefgh", 3); /* Basic test. */
722 (void) strcpy(one, "abc");
723 (void) memmove(one, "xyz", 0);
724 equal(one, "abc", 4); /* Zero-length copy. */
726 (void) strcpy(one, "hi there");
727 (void) strcpy(two, "foo");
728 (void) memmove(two, one, 9);
729 equal(two, "hi there", 5); /* Just paranoia. */
730 equal(one, "hi there", 6); /* Stomped on source? */
732 (void) strcpy(one, "abcdefgh");
733 (void) memmove(one+1, one, 9);
734 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
736 (void) strcpy(one, "abcdefgh");
737 (void) memmove(one+1, one+2, 7);
738 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
740 (void) strcpy(one, "abcdefgh");
741 (void) memmove(one, one, 9);
742 equal(one, "abcdefgh", 9); /* 100% overlap. */
744 /* memccpy - first test like memcpy, then the search part
745 The SVID, the only place where memccpy is mentioned, says
746 overlap might fail, so we don't try it. Besides, it's hard
747 to see the rationale for a non-left-to-right memccpy. */
749 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
750 equal(one, "abc", 2); /* Did the copy go right? */
752 (void) strcpy(one, "abcdefgh");
753 (void) memccpy(one+1, "xyz", 'q', 2);
754 equal(one, "axydefgh", 3); /* Basic test. */
756 (void) strcpy(one, "abc");
757 (void) memccpy(one, "xyz", 'q', 0);
758 equal(one, "abc", 4); /* Zero-length copy. */
760 (void) strcpy(one, "hi there");
761 (void) strcpy(two, "foo");
762 (void) memccpy(two, one, 'q', 9);
763 equal(two, "hi there", 5); /* Just paranoia. */
764 equal(one, "hi there", 6); /* Stomped on source? */
766 (void) strcpy(one, "abcdefgh");
767 (void) strcpy(two, "horsefeathers");
768 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
769 equal(one, "abcdefgh", 8); /* Source intact? */
770 equal(two, "abcdefeathers", 9); /* Copy correct? */
772 (void) strcpy(one, "abcd");
773 (void) strcpy(two, "bumblebee");
774 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
775 equal(two, "aumblebee", 11);
776 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
777 equal(two, "abcdlebee", 13);
778 (void) strcpy(one, "xyz");
779 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
780 equal(two, "xbcdlebee", 15);
784 (void) strcpy(one, "abcdefgh");
785 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
786 equal(one, "axxxefgh", 2); /* Basic test. */
788 (void) memset(one+2, 'y', 0);
789 equal(one, "axxxefgh", 3); /* Zero-length set. */
791 (void) memset(one+5, 0, 1);
792 equal(one, "axxxe", 4); /* Zero fill. */
793 equal(one+6, "gh", 5); /* And the leftover. */
795 (void) memset(one+2, 010045, 1);
796 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
798 /* Test for more complex versions of memset, for all alignments and
799 lengths up to 256. This test takes a little while, perhaps it should
808 for (i = 0; i < 512; i++)
810 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
812 for (j = 0; j < 256; j++)
813 for (i = 0; i < 256; i++)
816 for (k = 0; k < i; k++)
819 for (k = i; k < i+j; k++)
825 for (k = i+j; k < 512; k++)
831 check(0,7+i+j*256+(c != 0)*256*256);
835 /* bcopy - much like memcpy.
836 Berklix manual is silent about overlap, so don't test it. */
838 (void) bcopy("abc", one, 4);
839 equal(one, "abc", 1); /* Simple copy. */
841 (void) strcpy(one, "abcdefgh");
842 (void) bcopy("xyz", one+1, 2);
843 equal(one, "axydefgh", 2); /* Basic test. */
845 (void) strcpy(one, "abc");
846 (void) bcopy("xyz", one, 0);
847 equal(one, "abc", 3); /* Zero-length copy. */
849 (void) strcpy(one, "hi there");
850 (void) strcpy(two, "foo");
851 (void) bcopy(one, two, 9);
852 equal(two, "hi there", 4); /* Just paranoia. */
853 equal(one, "hi there", 5); /* Stomped on source? */
857 (void) strcpy(one, "abcdef");
859 equal(one, "ab", 1); /* Basic test. */
861 equal(one+4, "ef", 3);
863 (void) strcpy(one, "abcdef");
865 equal(one, "abcdef", 4); /* Zero-length copy. */
868 /* bcmp - somewhat like memcmp. */
870 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
871 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
872 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
873 check(bcmp("abce", "abcd", 4) != 0, 4);
874 check(bcmp("alph", "beta", 4) != 0, 5);
875 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
876 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
880 char text[] = "This,is,a,test";
883 check (!strcmp ("This", strsep (&list, ",")), 1);
884 check (!strcmp ("is", strsep (&list, ",")), 2);
885 check (!strcmp ("a", strsep (&list, ",")), 3);
886 check (!strcmp ("test", strsep (&list, ",")), 4);
887 check (strsep (&list, ",") == NULL, 5);
890 /* strerror - VERY system-dependent. */
894 f = __open("/", O_WRONLY); /* Should always fail. */
895 check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
896 equal(strerror(errno), _sys_errlist[errno], 2);
903 status = EXIT_SUCCESS;
908 status = EXIT_FAILURE;
909 printf("%Zd errors.\n", errors);