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, "abcde") - one) == 5, 1);
139 equal (one, "abcde", 2);
141 check ((stpcpy (one, "x") - one) == 1, 3);
142 equal (one, "x", 4); /* Writeover. */
143 equal (one+2, "cde", 5); /* Wrote too much? */
145 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 6);
146 equal (one, "abc", 7);
147 equal (one + 4, "e", 8);
152 memset (one, 'x', sizeof (one));
153 check (stpncpy (one, "abc", 2) == one + 2, 1);
154 check (stpncpy (one, "abc", 3) == one + 3, 2);
155 check (stpncpy (one, "abc", 4) == one + 3, 3);
156 check (one[3] == '\0' && one[4] == 'x', 4);
157 check (stpncpy (one, "abcd", 5) == one + 4, 5);
158 check (one[4] == '\0' && one[5] == 'x', 6);
159 check (stpncpy (one, "abcd", 6) == one + 4, 7);
160 check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
164 (void) strcpy (one, "ijk");
165 check (strcat (one, "lmn") == one, 1); /* Returned value. */
166 equal (one, "ijklmn", 2); /* Basic test. */
168 (void) strcpy (one, "x");
169 (void) strcat (one, "yz");
170 equal (one, "xyz", 3); /* Writeover. */
171 equal (one+4, "mn", 4); /* Wrote too much? */
173 (void) strcpy (one, "gh");
174 (void) strcpy (two, "ef");
175 (void) strcat (one, two);
176 equal (one, "ghef", 5); /* Basic test encore. */
177 equal (two, "ef", 6); /* Stomped on source? */
179 (void) strcpy (one, "");
180 (void) strcat (one, "");
181 equal (one, "", 7); /* Boundary conditions. */
182 (void) strcpy (one, "ab");
183 (void) strcat (one, "");
184 equal (one, "ab", 8);
185 (void) strcpy (one, "");
186 (void) strcat (one, "cd");
187 equal (one, "cd", 9);
189 /* strncat - first test it as strcat, with big counts,
190 then test the count mechanism. */
192 (void) strcpy (one, "ijk");
193 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
194 equal (one, "ijklmn", 2); /* Basic test. */
196 (void) strcpy (one, "x");
197 (void) strncat (one, "yz", 99);
198 equal (one, "xyz", 3); /* Writeover. */
199 equal (one+4, "mn", 4); /* Wrote too much? */
201 (void) strcpy (one, "gh");
202 (void) strcpy (two, "ef");
203 (void) strncat (one, two, 99);
204 equal (one, "ghef", 5); /* Basic test encore. */
205 equal (two, "ef", 6); /* Stomped on source? */
207 (void) strcpy (one, "");
208 (void) strncat (one, "", 99);
209 equal (one, "", 7); /* Boundary conditions. */
210 (void) strcpy (one, "ab");
211 (void) strncat (one, "", 99);
212 equal (one, "ab", 8);
213 (void) strcpy (one, "");
214 (void) strncat (one, "cd", 99);
215 equal (one, "cd", 9);
217 (void) strcpy (one, "ab");
218 (void) strncat (one, "cdef", 2);
219 equal (one, "abcd", 10); /* Count-limited. */
221 (void) strncat (one, "gh", 0);
222 equal (one, "abcd", 11); /* Zero count. */
224 (void) strncat (one, "gh", 2);
225 equal (one, "abcdgh", 12); /* Count and length equal. */
227 /* strncmp - first test as strcmp with big counts,
228 then test count code. */
230 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
231 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
232 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
233 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
234 check (strncmp ("abcd", "abc", 99) > 0, 5);
235 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
236 check (strncmp ("abce", "abcd", 99) > 0, 7);
237 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
238 check (strncmp ("a\203", "a\003", 2) > 0, 9);
239 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
240 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
241 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
242 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
244 /* strncpy - testing is a bit different because of odd semantics. */
246 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
247 equal (one, "abc", 2); /* Did the copy go right? */
249 (void) strcpy (one, "abcdefgh");
250 (void) strncpy (one, "xyz", 2);
251 equal (one, "xycdefgh", 3); /* Copy cut by count. */
253 (void) strcpy (one, "abcdefgh");
254 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
255 equal (one, "xyzdefgh", 4);
257 (void) strcpy (one, "abcdefgh");
258 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
259 equal (one, "xyz", 5);
260 equal (one+4, "efgh", 6); /* Wrote too much? */
262 (void) strcpy (one, "abcdefgh");
263 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
264 equal (one, "xyz", 7);
265 equal (one+4, "", 8);
266 equal (one+5, "fgh", 9);
268 (void) strcpy (one, "abc");
269 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
270 equal (one, "abc", 10);
272 (void) strncpy (one, "", 2); /* Zero-length source. */
274 equal (one+1, "", 12);
275 equal (one+2, "c", 13);
277 (void) strcpy (one, "hi there");
278 (void) strncpy (two, one, 9);
279 equal (two, "hi there", 14); /* Just paranoia. */
280 equal (one, "hi there", 15); /* Stomped on source? */
284 check (strlen ("") == 0, 1); /* Empty. */
285 check (strlen ("a") == 1, 2); /* Single char. */
286 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
291 for (i=0; i < 0x100; i++)
293 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
295 strcpy (p+3, "BAD/WRONG");
296 check (strlen (p) == 2, 4+i);
302 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
303 (void) strcpy (one, "abcd");
304 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
305 check (strchr (one, 'd') == one+3, 3); /* End of string. */
306 check (strchr (one, 'a') == one, 4); /* Beginning. */
307 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
308 (void) strcpy (one, "ababa");
309 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
310 (void) strcpy (one, "");
311 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
312 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
317 for (i=0; i < 0x100; i++)
319 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
321 strcpy (p+3, "BAD/WRONG");
322 check (strchr (p, '/') == NULL, 9+i);
327 /* index - just like strchr. */
329 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
330 (void) strcpy (one, "abcd");
331 check (index (one, 'c') == one+2, 2); /* Basic test. */
332 check (index (one, 'd') == one+3, 3); /* End of string. */
333 check (index (one, 'a') == one, 4); /* Beginning. */
334 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
335 (void) strcpy (one, "ababa");
336 check (index (one, 'b') == one+1, 6); /* Finding first. */
337 (void) strcpy (one, "");
338 check (index (one, 'b') == NULL, 7); /* Empty string. */
339 check (index (one, '\0') == one, 8); /* NUL in empty string. */
344 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
345 (void) strcpy (one, "abcd");
346 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
347 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
348 check (strrchr (one, 'a') == one, 4); /* Beginning. */
349 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
350 (void) strcpy (one, "ababa");
351 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
352 (void) strcpy (one, "");
353 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
354 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
359 for (i=0; i < 0x100; i++)
361 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
363 strcpy (p+3, "BAD/WRONG");
364 check (strrchr (p, '/') == NULL, 9+i);
369 /* rindex - just like strrchr. */
371 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
372 (void) strcpy (one, "abcd");
373 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
374 check (rindex (one, 'd') == one+3, 3); /* End of string. */
375 check (rindex (one, 'a') == one, 4); /* Beginning. */
376 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
377 (void) strcpy (one, "ababa");
378 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
379 (void) strcpy (one, "");
380 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
381 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
384 /* strpbrk - somewhat like strchr. */
386 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
387 (void) strcpy(one, "abcd");
388 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
389 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
390 check(strpbrk(one, "a") == one, 4); /* Beginning. */
391 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
392 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
393 (void) strcpy(one, "abcabdea");
394 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
395 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
396 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
397 (void) strcpy(one, "");
398 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
399 check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
401 /* strstr - somewhat like strchr. */
403 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
404 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
405 (void) strcpy(one, "abcd");
406 check(strstr(one, "c") == one+2, 3); /* Basic test. */
407 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
408 check(strstr(one, "d") == one+3, 5); /* End of string. */
409 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
410 check(strstr(one, "abc") == one, 7); /* Beginning. */
411 check(strstr(one, "abcd") == one, 8); /* Exact match. */
412 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
413 check(strstr(one, "de") == NULL, 10); /* Past end. */
414 check(strstr(one, "") == one, 11); /* Finding empty. */
415 (void) strcpy(one, "ababa");
416 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
417 (void) strcpy(one, "");
418 check(strstr(one, "b") == NULL, 13); /* Empty string. */
419 check(strstr(one, "") == one, 14); /* Empty in empty string. */
420 (void) strcpy(one, "bcbca");
421 check(strstr(one, "bca") == one+2, 15); /* False start. */
422 (void) strcpy(one, "bbbcabbca");
423 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
427 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
428 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
429 check(strspn("abc", "qx") == 0, 3); /* None. */
430 check(strspn("", "ab") == 0, 4); /* Null string. */
431 check(strspn("abc", "") == 0, 5); /* Null search list. */
435 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
436 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
437 check(strcspn("abc", "abc") == 0, 3); /* None. */
438 check(strcspn("", "ab") == 0, 4); /* Null string. */
439 check(strcspn("abc", "") == 3, 5); /* Null search list. */
441 /* strtok - the hard one. */
443 (void) strcpy(one, "first, second, third");
444 equal(strtok(one, ", "), "first", 1); /* Basic test. */
445 equal(one, "first", 2);
446 equal(strtok((char *)NULL, ", "), "second", 3);
447 equal(strtok((char *)NULL, ", "), "third", 4);
448 check(strtok((char *)NULL, ", ") == NULL, 5);
449 (void) strcpy(one, ", first, ");
450 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
451 check(strtok((char *)NULL, ", ") == NULL, 7);
452 (void) strcpy(one, "1a, 1b; 2a, 2b");
453 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
454 equal(strtok((char *)NULL, "; "), "1b", 9);
455 equal(strtok((char *)NULL, ", "), "2a", 10);
456 (void) strcpy(two, "x-y");
457 equal(strtok(two, "-"), "x", 11); /* New string before done. */
458 equal(strtok((char *)NULL, "-"), "y", 12);
459 check(strtok((char *)NULL, "-") == NULL, 13);
460 (void) strcpy(one, "a,b, c,, ,d");
461 equal(strtok(one, ", "), "a", 14); /* Different separators. */
462 equal(strtok((char *)NULL, ", "), "b", 15);
463 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
464 equal(strtok((char *)NULL, " ,"), "d", 17);
465 check(strtok((char *)NULL, ", ") == NULL, 18);
466 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
467 (void) strcpy(one, ", ");
468 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
469 (void) strcpy(one, "");
470 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
471 (void) strcpy(one, "abc");
472 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
473 check(strtok((char *)NULL, ", ") == NULL, 23);
474 (void) strcpy(one, "abc");
475 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
476 check(strtok((char *)NULL, "") == NULL, 25);
477 (void) strcpy(one, "abcdefgh");
478 (void) strcpy(one, "a,b,c");
479 equal(strtok(one, ","), "a", 26); /* Basics again... */
480 equal(strtok((char *)NULL, ","), "b", 27);
481 equal(strtok((char *)NULL, ","), "c", 28);
482 check(strtok((char *)NULL, ",") == NULL, 29);
483 equal(one+6, "gh", 30); /* Stomped past end? */
484 equal(one, "a", 31); /* Stomped old tokens? */
485 equal(one+2, "b", 32);
486 equal(one+4, "c", 33);
490 (void) strcpy(one, "first, second, third");
491 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
492 equal(one, "first", 2);
493 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
494 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
495 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
496 (void) strcpy(one, ", first, ");
497 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
498 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
499 (void) strcpy(one, "1a, 1b; 2a, 2b");
500 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
501 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
502 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
503 (void) strcpy(two, "x-y");
504 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
505 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
506 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
507 (void) strcpy(one, "a,b, c,, ,d");
508 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
509 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
510 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
511 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
512 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
513 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
514 (void) strcpy(one, ", ");
515 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
516 (void) strcpy(one, "");
517 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
518 (void) strcpy(one, "abc");
519 equal(strtok_r(one, ", ", &cp), "abc", 22); /* No delimiters. */
520 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 23);
521 (void) strcpy(one, "abc");
522 equal(strtok_r(one, "", &cp), "abc", 24); /* Empty delimiter list. */
523 check(strtok_r((char *)NULL, "", &cp) == NULL, 25);
524 (void) strcpy(one, "abcdefgh");
525 (void) strcpy(one, "a,b,c");
526 equal(strtok_r(one, ",", &cp), "a", 26); /* Basics again... */
527 equal(strtok_r((char *)NULL, ",", &cp), "b", 27);
528 equal(strtok_r((char *)NULL, ",", &cp), "c", 28);
529 check(strtok_r((char *)NULL, ",", &cp) == NULL, 29);
530 equal(one+6, "gh", 30); /* Stomped past end? */
531 equal(one, "a", 31); /* Stomped old tokens? */
532 equal(one+2, "b", 32);
533 equal(one+4, "c", 33);
537 cp = strcpy(one, "first, second, third");
538 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
539 equal(one, "first", 2);
540 equal(strsep(&cp, ", "), "", 3);
541 equal(strsep(&cp, ", "), "second", 4);
542 equal(strsep(&cp, ", "), "", 5);
543 equal(strsep(&cp, ", "), "third", 6);
544 check(strsep(&cp, ", ") == NULL, 7);
545 cp = strcpy(one, ", first, ");
546 equal(strsep(&cp, ", "), "", 8);
547 equal(strsep(&cp, ", "), "", 9);
548 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
549 equal(strsep(&cp, ", "), "", 11);
550 check(strsep(&cp, ", ") == NULL, 12);
551 cp = strcpy(one, "1a, 1b; 2a, 2b");
552 equal(strsep(&cp, ", "), "1a", 13); /* Changing delim lists. */
553 equal(strsep(&cp, ", "), "", 14);
554 equal(strsep(&cp, "; "), "1b", 15);
555 equal(strsep(&cp, ", "), "", 16);
556 equal(strsep(&cp, ", "), "2a", 17);
557 cp = strcpy(two, "x-y");
558 equal(strsep(&cp, "-"), "x", 18); /* New string before done. */
559 equal(strsep(&cp, "-"), "y", 19);
560 check(strsep(&cp, "-") == NULL, 20);
561 cp = strcpy(one, "a,b, c,, ,d");
562 equal(strsep(&cp, ", "), "a", 21); /* Different separators. */
563 equal(strsep(&cp, ", "), "b", 22);
564 equal(strsep(&cp, " ,"), "", 23);
565 equal(strsep(&cp, " ,"), "c", 24); /* Permute list too. */
566 equal(strsep(&cp, " ,"), "", 25);
567 equal(strsep(&cp, " ,"), "", 26);
568 equal(strsep(&cp, " ,"), "", 27);
569 equal(strsep(&cp, " ,"), "d", 28);
570 check(strsep(&cp, ", ") == NULL, 29);
571 check(strsep(&cp, ", ") == NULL, 30); /* Persistence. */
572 cp = strcpy(one, ", ");
573 equal(strsep(&cp, ", "), "", 31);
574 equal(strsep(&cp, ", "), "", 32);
575 check(strsep(&cp, ", ") == NULL, 33); /* No tokens. */
576 cp = strcpy(one, "");
577 check(strsep(&cp, ", ") == NULL, 34); /* Empty string. */
578 cp = strcpy(one, "abc");
579 equal(strsep(&cp, ", "), "abc", 35); /* No delimiters. */
580 check(strsep(&cp, ", ") == NULL, 36);
581 cp = strcpy(one, "abc");
582 equal(strsep(&cp, ""), "abc", 37); /* Empty delimiter list. */
583 check(strsep(&cp, "") == NULL, 38);
584 (void) strcpy(one, "abcdefgh");
585 cp = strcpy(one, "a,b,c");
586 equal(strsep(&cp, ","), "a", 39); /* Basics again... */
587 equal(strsep(&cp, ","), "b", 40);
588 equal(strsep(&cp, ","), "c", 41);
589 check(strsep(&cp, ",") == NULL, 42);
590 equal(one+6, "gh", 43); /* Stomped past end? */
591 equal(one, "a", 44); /* Stomped old tokens? */
592 equal(one+2, "b", 45);
593 equal(one+4, "c", 46);
597 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
598 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
599 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
600 check(memcmp("abce", "abcd", 4) > 0, 4);
601 check(memcmp("alph", "beta", 4) < 0, 5);
602 check(memcmp("a\203", "a\003", 2) > 0, 6);
603 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
604 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
608 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
609 (void) strcpy(one, "abcd");
610 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
611 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
612 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
613 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
614 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
615 (void) strcpy(one, "ababa");
616 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
617 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
618 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
619 (void) strcpy(one, "a\203b");
620 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
622 /* now test all possible alignment and length combinations to catch
623 bugs due to unrolled loops (assuming unrolling is limited to no
624 more than 128 byte chunks: */
626 char buf[128 + sizeof(long)];
627 long align, len, i, pos;
629 for (align = 0; align < (long) sizeof(long); ++align) {
630 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
631 for (i = 0; i < len; ++i) {
632 buf[align + i] = 'x'; /* don't depend on memset... */
634 for (pos = 0; pos < len; ++pos) {
636 printf("align %d, len %d, pos %d\n", align, len, pos);
638 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
639 check(memchr(buf + align, 'x', pos) == NULL, 11);
640 buf[align + pos] = '-';
646 /* memcpy - need not work for overlap. */
648 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
649 equal(one, "abc", 2); /* Did the copy go right? */
651 (void) strcpy(one, "abcdefgh");
652 (void) memcpy(one+1, "xyz", 2);
653 equal(one, "axydefgh", 3); /* Basic test. */
655 (void) strcpy(one, "abc");
656 (void) memcpy(one, "xyz", 0);
657 equal(one, "abc", 4); /* Zero-length copy. */
659 (void) strcpy(one, "hi there");
660 (void) strcpy(two, "foo");
661 (void) memcpy(two, one, 9);
662 equal(two, "hi there", 5); /* Just paranoia. */
663 equal(one, "hi there", 6); /* Stomped on source? */
665 /* memmove - must work on overlap. */
667 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
668 equal(one, "abc", 2); /* Did the copy go right? */
670 (void) strcpy(one, "abcdefgh");
671 (void) memmove(one+1, "xyz", 2);
672 equal(one, "axydefgh", 3); /* Basic test. */
674 (void) strcpy(one, "abc");
675 (void) memmove(one, "xyz", 0);
676 equal(one, "abc", 4); /* Zero-length copy. */
678 (void) strcpy(one, "hi there");
679 (void) strcpy(two, "foo");
680 (void) memmove(two, one, 9);
681 equal(two, "hi there", 5); /* Just paranoia. */
682 equal(one, "hi there", 6); /* Stomped on source? */
684 (void) strcpy(one, "abcdefgh");
685 (void) memmove(one+1, one, 9);
686 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
688 (void) strcpy(one, "abcdefgh");
689 (void) memmove(one+1, one+2, 7);
690 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
692 (void) strcpy(one, "abcdefgh");
693 (void) memmove(one, one, 9);
694 equal(one, "abcdefgh", 9); /* 100% overlap. */
696 /* memccpy - first test like memcpy, then the search part
697 The SVID, the only place where memccpy is mentioned, says
698 overlap might fail, so we don't try it. Besides, it's hard
699 to see the rationale for a non-left-to-right memccpy. */
701 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
702 equal(one, "abc", 2); /* Did the copy go right? */
704 (void) strcpy(one, "abcdefgh");
705 (void) memccpy(one+1, "xyz", 'q', 2);
706 equal(one, "axydefgh", 3); /* Basic test. */
708 (void) strcpy(one, "abc");
709 (void) memccpy(one, "xyz", 'q', 0);
710 equal(one, "abc", 4); /* Zero-length copy. */
712 (void) strcpy(one, "hi there");
713 (void) strcpy(two, "foo");
714 (void) memccpy(two, one, 'q', 9);
715 equal(two, "hi there", 5); /* Just paranoia. */
716 equal(one, "hi there", 6); /* Stomped on source? */
718 (void) strcpy(one, "abcdefgh");
719 (void) strcpy(two, "horsefeathers");
720 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
721 equal(one, "abcdefgh", 8); /* Source intact? */
722 equal(two, "abcdefeathers", 9); /* Copy correct? */
724 (void) strcpy(one, "abcd");
725 (void) strcpy(two, "bumblebee");
726 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
727 equal(two, "aumblebee", 11);
728 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
729 equal(two, "abcdlebee", 13);
730 (void) strcpy(one, "xyz");
731 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
732 equal(two, "xbcdlebee", 15);
736 (void) strcpy(one, "abcdefgh");
737 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
738 equal(one, "axxxefgh", 2); /* Basic test. */
740 (void) memset(one+2, 'y', 0);
741 equal(one, "axxxefgh", 3); /* Zero-length set. */
743 (void) memset(one+5, 0, 1);
744 equal(one, "axxxe", 4); /* Zero fill. */
745 equal(one+6, "gh", 5); /* And the leftover. */
747 (void) memset(one+2, 010045, 1);
748 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
750 /* Test for more complex versions of memset, for all alignments and
751 lengths up to 256. This test takes a little while, perhaps it should
760 for (i = 0; i < 512; i++)
762 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
764 for (j = 0; j < 256; j++)
765 for (i = 0; i < 256; i++)
768 for (k = 0; k < i; k++)
771 for (k = i; k < i+j; k++)
777 for (k = i+j; k < 512; k++)
783 check(0,7+i+j*256+(c != 0)*256*256);
787 /* bcopy - much like memcpy.
788 Berklix manual is silent about overlap, so don't test it. */
790 (void) bcopy("abc", one, 4);
791 equal(one, "abc", 1); /* Simple copy. */
793 (void) strcpy(one, "abcdefgh");
794 (void) bcopy("xyz", one+1, 2);
795 equal(one, "axydefgh", 2); /* Basic test. */
797 (void) strcpy(one, "abc");
798 (void) bcopy("xyz", one, 0);
799 equal(one, "abc", 3); /* Zero-length copy. */
801 (void) strcpy(one, "hi there");
802 (void) strcpy(two, "foo");
803 (void) bcopy(one, two, 9);
804 equal(two, "hi there", 4); /* Just paranoia. */
805 equal(one, "hi there", 5); /* Stomped on source? */
809 (void) strcpy(one, "abcdef");
811 equal(one, "ab", 1); /* Basic test. */
813 equal(one+4, "ef", 3);
815 (void) strcpy(one, "abcdef");
817 equal(one, "abcdef", 4); /* Zero-length copy. */
820 /* bcmp - somewhat like memcmp. */
822 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
823 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
824 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
825 check(bcmp("abce", "abcd", 4) != 0, 4);
826 check(bcmp("alph", "beta", 4) != 0, 5);
827 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
828 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
832 char text[] = "This,is,a,test";
835 check (!strcmp ("This", strsep (&list, ",")), 1);
836 check (!strcmp ("is", strsep (&list, ",")), 2);
837 check (!strcmp ("a", strsep (&list, ",")), 3);
838 check (!strcmp ("test", strsep (&list, ",")), 4);
839 check (strsep (&list, ",") == NULL, 5);
842 /* strerror - VERY system-dependent. */
846 f = __open("/", O_WRONLY); /* Should always fail. */
847 check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
848 equal(strerror(errno), _sys_errlist[errno], 2);
855 status = EXIT_SUCCESS;
860 status = EXIT_FAILURE;
861 printf("%Zd errors.\n", errors);