Update.
[glibc.git] / string / tester.c
blob39ae0d837eb2f1fdb09577dc3caad38e85e3f7fb
1 /* Tester for string functions.
2 Copyright (C) 1995-2000, 2001 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 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.
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.
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. */
20 #ifndef _GNU_SOURCE
21 #define _GNU_SOURCE
22 #endif
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
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <strings.h>
35 #include <fcntl.h>
37 #ifndef HAVE_GNU_LD
38 #define _sys_nerr sys_nerr
39 #define _sys_errlist sys_errlist
40 #endif
42 #define STREQ(a, b) (strcmp((a), (b)) == 0)
44 const char *it = "<UNSET>"; /* Routine name for message routines. */
45 size_t errors = 0;
47 /* Complain if condition is not true. */
48 static void
49 check (int thing, int number)
51 if (!thing)
53 printf("%s flunked test %d\n", it, number);
54 ++errors;
58 /* Complain if first two args don't strcmp as equal. */
59 static void
60 equal (const char *a, const char *b, int number)
62 check(a != NULL && b != NULL && STREQ (a, b), number);
65 char one[50];
66 char two[50];
67 char *cp;
69 static void
70 test_strcmp (void)
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);
84 char buf1[0x40], buf2[0x40];
85 int i, j;
86 for (i=0; i < 0x10; i++)
87 for (j = 0; j < 0x10; j++)
89 int k;
90 for (k = 0; k < 0x3f; k++)
92 buf1[j] = '0' ^ (k & 4);
93 buf2[j] = '4' ^ (k & 4);
95 buf1[i] = buf1[0x3f] = 0;
96 buf2[j] = buf2[0x3f] = 0;
97 for (k = 0; k < 0xf; k++)
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;
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)
131 static void
132 test_strcpy (void)
134 int i;
135 it = "strcpy";
136 check (strcpy (one, "abcd") == one, 1); /* Returned value. */
137 equal (one, "abcd", 2); /* Basic test. */
139 (void) strcpy (one, "x");
140 equal (one, "x", 3); /* Writeover. */
141 equal (one+2, "cd", 4); /* Wrote too much? */
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? */
148 (void) strcpy (one, "");
149 equal (one, "", 7); /* Boundary condition. */
151 for (i = 0; i < 16; i++)
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));
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);
178 static void
179 test_stpcpy (void)
181 it = "stpcpy";
182 check ((stpcpy (one, "a") - one) == 1, 1);
183 equal (one, "a", 2);
185 check ((stpcpy (one, "ab") - one) == 2, 3);
186 equal (one, "ab", 4);
188 check ((stpcpy (one, "abc") - one) == 3, 5);
189 equal (one, "abc", 6);
191 check ((stpcpy (one, "abcd") - one) == 4, 7);
192 equal (one, "abcd", 8);
194 check ((stpcpy (one, "abcde") - one) == 5, 9);
195 equal (one, "abcde", 10);
197 check ((stpcpy (one, "abcdef") - one) == 6, 11);
198 equal (one, "abcdef", 12);
200 check ((stpcpy (one, "abcdefg") - one) == 7, 13);
201 equal (one, "abcdefg", 14);
203 check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
204 equal (one, "abcdefgh", 16);
206 check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
207 equal (one, "abcdefghi", 18);
209 check ((stpcpy (one, "x") - one) == 1, 19);
210 equal (one, "x", 20); /* Writeover. */
211 equal (one+2, "cdefghi", 21); /* Wrote too much? */
213 check ((stpcpy (one, "xx") - one) == 2, 22);
214 equal (one, "xx", 23); /* Writeover. */
215 equal (one+3, "defghi", 24); /* Wrote too much? */
217 check ((stpcpy (one, "xxx") - one) == 3, 25);
218 equal (one, "xxx", 26); /* Writeover. */
219 equal (one+4, "efghi", 27); /* Wrote too much? */
221 check ((stpcpy (one, "xxxx") - one) == 4, 28);
222 equal (one, "xxxx", 29); /* Writeover. */
223 equal (one+5, "fghi", 30); /* Wrote too much? */
225 check ((stpcpy (one, "xxxxx") - one) == 5, 31);
226 equal (one, "xxxxx", 32); /* Writeover. */
227 equal (one+6, "ghi", 33); /* Wrote too much? */
229 check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
230 equal (one, "xxxxxx", 35); /* Writeover. */
231 equal (one+7, "hi", 36); /* Wrote too much? */
233 check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
234 equal (one, "xxxxxxx", 38); /* Writeover. */
235 equal (one+8, "i", 39); /* Wrote too much? */
237 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
238 equal (one, "abc", 41);
239 equal (one + 4, "xxx", 42);
241 SIMPLE_COPY(stpcpy, 0, "", 43);
242 SIMPLE_COPY(stpcpy, 1, "1", 44);
243 SIMPLE_COPY(stpcpy, 2, "22", 45);
244 SIMPLE_COPY(stpcpy, 3, "333", 46);
245 SIMPLE_COPY(stpcpy, 4, "4444", 47);
246 SIMPLE_COPY(stpcpy, 5, "55555", 48);
247 SIMPLE_COPY(stpcpy, 6, "666666", 49);
248 SIMPLE_COPY(stpcpy, 7, "7777777", 50);
249 SIMPLE_COPY(stpcpy, 8, "88888888", 51);
250 SIMPLE_COPY(stpcpy, 9, "999999999", 52);
251 SIMPLE_COPY(stpcpy, 10, "0000000000", 53);
252 SIMPLE_COPY(stpcpy, 11, "11111111111", 54);
253 SIMPLE_COPY(stpcpy, 12, "222222222222", 55);
254 SIMPLE_COPY(stpcpy, 13, "3333333333333", 56);
255 SIMPLE_COPY(stpcpy, 14, "44444444444444", 57);
256 SIMPLE_COPY(stpcpy, 15, "555555555555555", 58);
257 SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59);
260 static void
261 test_stpncpy (void)
263 it = "stpncpy";
264 memset (one, 'x', sizeof (one));
265 check (stpncpy (one, "abc", 2) == one + 2, 1);
266 check (stpncpy (one, "abc", 3) == one + 3, 2);
267 check (stpncpy (one, "abc", 4) == one + 3, 3);
268 check (one[3] == '\0' && one[4] == 'x', 4);
269 check (stpncpy (one, "abcd", 5) == one + 4, 5);
270 check (one[4] == '\0' && one[5] == 'x', 6);
271 check (stpncpy (one, "abcd", 6) == one + 4, 7);
272 check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
275 static void
276 test_strcat (void)
278 it = "strcat";
279 (void) strcpy (one, "ijk");
280 check (strcat (one, "lmn") == one, 1); /* Returned value. */
281 equal (one, "ijklmn", 2); /* Basic test. */
283 (void) strcpy (one, "x");
284 (void) strcat (one, "yz");
285 equal (one, "xyz", 3); /* Writeover. */
286 equal (one+4, "mn", 4); /* Wrote too much? */
288 (void) strcpy (one, "gh");
289 (void) strcpy (two, "ef");
290 (void) strcat (one, two);
291 equal (one, "ghef", 5); /* Basic test encore. */
292 equal (two, "ef", 6); /* Stomped on source? */
294 (void) strcpy (one, "");
295 (void) strcat (one, "");
296 equal (one, "", 7); /* Boundary conditions. */
297 (void) strcpy (one, "ab");
298 (void) strcat (one, "");
299 equal (one, "ab", 8);
300 (void) strcpy (one, "");
301 (void) strcat (one, "cd");
302 equal (one, "cd", 9);
305 static void
306 test_strncat (void)
308 /* First test it as strcat, with big counts, then test the count
309 mechanism. */
310 it = "strncat";
311 (void) strcpy (one, "ijk");
312 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
313 equal (one, "ijklmn", 2); /* Basic test. */
315 (void) strcpy (one, "x");
316 (void) strncat (one, "yz", 99);
317 equal (one, "xyz", 3); /* Writeover. */
318 equal (one+4, "mn", 4); /* Wrote too much? */
320 (void) strcpy (one, "gh");
321 (void) strcpy (two, "ef");
322 (void) strncat (one, two, 99);
323 equal (one, "ghef", 5); /* Basic test encore. */
324 equal (two, "ef", 6); /* Stomped on source? */
326 (void) strcpy (one, "");
327 (void) strncat (one, "", 99);
328 equal (one, "", 7); /* Boundary conditions. */
329 (void) strcpy (one, "ab");
330 (void) strncat (one, "", 99);
331 equal (one, "ab", 8);
332 (void) strcpy (one, "");
333 (void) strncat (one, "cd", 99);
334 equal (one, "cd", 9);
336 (void) strcpy (one, "ab");
337 (void) strncat (one, "cdef", 2);
338 equal (one, "abcd", 10); /* Count-limited. */
340 (void) strncat (one, "gh", 0);
341 equal (one, "abcd", 11); /* Zero count. */
343 (void) strncat (one, "gh", 2);
344 equal (one, "abcdgh", 12); /* Count and length equal. */
347 static void
348 test_strncmp (void)
350 /* First test as strcmp with big counts, then test count code. */
351 it = "strncmp";
352 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
353 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
354 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
355 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
356 check (strncmp ("abcd", "abc", 99) > 0, 5);
357 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
358 check (strncmp ("abce", "abcd", 99) > 0, 7);
359 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
360 check (strncmp ("a\203", "a\003", 2) > 0, 9);
361 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
362 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
363 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
364 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
367 static void
368 test_strncpy (void)
370 /* Testing is a bit different because of odd semantics. */
371 it = "strncpy";
372 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
373 equal (one, "abc", 2); /* Did the copy go right? */
375 (void) strcpy (one, "abcdefgh");
376 (void) strncpy (one, "xyz", 2);
377 equal (one, "xycdefgh", 3); /* Copy cut by count. */
379 (void) strcpy (one, "abcdefgh");
380 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
381 equal (one, "xyzdefgh", 4);
383 (void) strcpy (one, "abcdefgh");
384 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
385 equal (one, "xyz", 5);
386 equal (one+4, "efgh", 6); /* Wrote too much? */
388 (void) strcpy (one, "abcdefgh");
389 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
390 equal (one, "xyz", 7);
391 equal (one+4, "", 8);
392 equal (one+5, "fgh", 9);
394 (void) strcpy (one, "abc");
395 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
396 equal (one, "abc", 10);
398 (void) strncpy (one, "", 2); /* Zero-length source. */
399 equal (one, "", 11);
400 equal (one+1, "", 12);
401 equal (one+2, "c", 13);
403 (void) strcpy (one, "hi there");
404 (void) strncpy (two, one, 9);
405 equal (two, "hi there", 14); /* Just paranoia. */
406 equal (one, "hi there", 15); /* Stomped on source? */
409 static void
410 test_strlen (void)
412 it = "strlen";
413 check (strlen ("") == 0, 1); /* Empty. */
414 check (strlen ("a") == 1, 2); /* Single char. */
415 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
417 char buf[4096];
418 int i;
419 char *p;
420 for (i=0; i < 0x100; i++)
422 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
423 strcpy (p, "OK");
424 strcpy (p+3, "BAD/WRONG");
425 check (strlen (p) == 2, 4+i);
430 static void
431 test_strchr (void)
433 it = "strchr";
434 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
435 (void) strcpy (one, "abcd");
436 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
437 check (strchr (one, 'd') == one+3, 3); /* End of string. */
438 check (strchr (one, 'a') == one, 4); /* Beginning. */
439 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
440 (void) strcpy (one, "ababa");
441 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
442 (void) strcpy (one, "");
443 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
444 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
446 char buf[4096];
447 int i;
448 char *p;
449 for (i=0; i < 0x100; i++)
451 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
452 strcpy (p, "OK");
453 strcpy (p+3, "BAD/WRONG");
454 check (strchr (p, '/') == NULL, 9+i);
459 static void
460 test_strchrnul (void)
462 const char *os;
463 it = "strchrnul";
464 cp = strchrnul ((os = "abcd"), 'z');
465 check (*cp == '\0', 1); /* Not found. */
466 check (cp == os + 4, 2);
467 (void) strcpy (one, "abcd");
468 check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */
469 check (strchrnul (one, 'd') == one+3, 4); /* End of string. */
470 check (strchrnul (one, 'a') == one, 5); /* Beginning. */
471 check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */
472 (void) strcpy (one, "ababa");
473 check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */
474 (void) strcpy (one, "");
475 check (strchrnul (one, 'b') == one, 8); /* Empty string. */
476 check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */
478 char buf[4096];
479 int i;
480 char *p;
481 for (i=0; i < 0x100; i++)
483 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
484 strcpy (p, "OK");
485 strcpy (p+3, "BAD/WRONG");
486 cp = strchrnul (p, '/');
487 check (*cp == '\0', 9+2*i);
488 check (cp == p+2, 10+2*i);
493 static void
494 test_rawmemchr (void)
496 it = "rawmemchr";
497 (void) strcpy (one, "abcd");
498 check (rawmemchr (one, 'c') == one+2, 1); /* Basic test. */
499 check (rawmemchr (one, 'd') == one+3, 2); /* End of string. */
500 check (rawmemchr (one, 'a') == one, 3); /* Beginning. */
501 check (rawmemchr (one, '\0') == one+4, 4); /* Finding NUL. */
502 (void) strcpy (one, "ababa");
503 check (rawmemchr (one, 'b') == one+1, 5); /* Finding first. */
504 (void) strcpy (one, "");
505 check (rawmemchr (one, '\0') == one, 6); /* NUL in empty string. */
507 char buf[4096];
508 int i;
509 char *p;
510 for (i=0; i < 0x100; i++)
512 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
513 strcpy (p, "OK");
514 strcpy (p+3, "BAD/WRONG");
515 check (rawmemchr (p, 'R') == p+8, 6+i);
520 static void
521 test_index (void)
523 it = "index";
524 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
525 (void) strcpy (one, "abcd");
526 check (index (one, 'c') == one+2, 2); /* Basic test. */
527 check (index (one, 'd') == one+3, 3); /* End of string. */
528 check (index (one, 'a') == one, 4); /* Beginning. */
529 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
530 (void) strcpy (one, "ababa");
531 check (index (one, 'b') == one+1, 6); /* Finding first. */
532 (void) strcpy (one, "");
533 check (index (one, 'b') == NULL, 7); /* Empty string. */
534 check (index (one, '\0') == one, 8); /* NUL in empty string. */
537 static void
538 test_strrchr (void)
540 it = "strrchr";
541 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
542 (void) strcpy (one, "abcd");
543 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
544 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
545 check (strrchr (one, 'a') == one, 4); /* Beginning. */
546 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
547 (void) strcpy (one, "ababa");
548 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
549 (void) strcpy (one, "");
550 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
551 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
553 char buf[4096];
554 int i;
555 char *p;
556 for (i=0; i < 0x100; i++)
558 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
559 strcpy (p, "OK");
560 strcpy (p+3, "BAD/WRONG");
561 check (strrchr (p, '/') == NULL, 9+i);
566 static void
567 test_memrchr (void)
569 size_t l;
570 it = "memrchr";
571 check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */
572 (void) strcpy (one, "abcd");
573 l = strlen (one) + 1;
574 check (memrchr (one, 'c', l) == one+2, 2); /* Basic test. */
575 check (memrchr (one, 'd', l) == one+3, 3); /* End of string. */
576 check (memrchr (one, 'a', l) == one, 4); /* Beginning. */
577 check (memrchr (one, '\0', l) == one+4, 5); /* Finding NUL. */
578 (void) strcpy (one, "ababa");
579 l = strlen (one) + 1;
580 check (memrchr (one, 'b', l) == one+3, 6); /* Finding last. */
581 (void) strcpy (one, "");
582 l = strlen (one) + 1;
583 check (memrchr (one, 'b', l) == NULL, 7); /* Empty string. */
584 check (memrchr (one, '\0', l) == one, 8); /* NUL in empty string. */
586 /* now test all possible alignment and length combinations to catch
587 bugs due to unrolled loops (assuming unrolling is limited to no
588 more than 128 byte chunks: */
590 char buf[128 + sizeof(long)];
591 long align, len, i, pos;
593 for (align = 0; align < (long) sizeof(long); ++align) {
594 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
595 for (i = 0; i < len; ++i)
596 buf[align + i] = 'x'; /* don't depend on memset... */
598 for (pos = len - 1; pos >= 0; --pos) {
599 #if 0
600 printf("align %d, len %d, pos %d\n", align, len, pos);
601 #endif
602 check(memrchr(buf + align, 'x', len) == buf + align + pos, 9);
603 check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
604 10);
605 buf[align + pos] = '-';
612 static void
613 test_rindex (void)
615 it = "rindex";
616 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
617 (void) strcpy (one, "abcd");
618 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
619 check (rindex (one, 'd') == one+3, 3); /* End of string. */
620 check (rindex (one, 'a') == one, 4); /* Beginning. */
621 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
622 (void) strcpy (one, "ababa");
623 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
624 (void) strcpy (one, "");
625 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
626 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
629 static void
630 test_strpbrk (void)
632 it = "strpbrk";
633 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
634 (void) strcpy(one, "abcd");
635 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
636 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
637 check(strpbrk(one, "a") == one, 4); /* Beginning. */
638 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
639 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
640 (void) strcpy(one, "abcabdea");
641 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
642 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
643 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
644 (void) strcpy(one, "");
645 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
646 (void) strcpy(one, "");
647 check(strpbrk(one, "bcd") == NULL, 11); /* Empty string. */
648 (void) strcpy(one, "");
649 check(strpbrk(one, "bcde") == NULL, 12); /* Empty string. */
650 check(strpbrk(one, "") == NULL, 13); /* Both strings empty. */
651 (void) strcpy(one, "abcabdea");
652 check(strpbrk(one, "befg") == one+1, 14); /* Finding first. */
653 check(strpbrk(one, "cbr") == one+1, 15); /* With multiple search. */
654 check(strpbrk(one, "db") == one+1, 16); /* Another variant. */
655 check(strpbrk(one, "efgh") == one+6, 17); /* And yet another. */
658 static void
659 test_strstr (void)
661 it = "strstr";
662 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
663 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
664 (void) strcpy(one, "abcd");
665 check(strstr(one, "c") == one+2, 3); /* Basic test. */
666 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
667 check(strstr(one, "d") == one+3, 5); /* End of string. */
668 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
669 check(strstr(one, "abc") == one, 7); /* Beginning. */
670 check(strstr(one, "abcd") == one, 8); /* Exact match. */
671 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
672 check(strstr(one, "de") == NULL, 10); /* Past end. */
673 check(strstr(one, "") == one, 11); /* Finding empty. */
674 (void) strcpy(one, "ababa");
675 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
676 (void) strcpy(one, "");
677 check(strstr(one, "b") == NULL, 13); /* Empty string. */
678 check(strstr(one, "") == one, 14); /* Empty in empty string. */
679 (void) strcpy(one, "bcbca");
680 check(strstr(one, "bca") == one+2, 15); /* False start. */
681 (void) strcpy(one, "bbbcabbca");
682 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
685 static void
686 test_strspn (void)
688 it = "strspn";
689 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
690 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
691 check(strspn("abc", "qx") == 0, 3); /* None. */
692 check(strspn("", "ab") == 0, 4); /* Null string. */
693 check(strspn("abc", "") == 0, 5); /* Null search list. */
696 static void
697 test_strcspn (void)
699 it = "strcspn";
700 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
701 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
702 check(strcspn("abc", "abc") == 0, 3); /* None. */
703 check(strcspn("", "ab") == 0, 4); /* Null string. */
704 check(strcspn("abc", "") == 3, 5); /* Null search list. */
707 static void
708 test_strtok (void)
710 it = "strtok";
711 (void) strcpy(one, "first, second, third");
712 equal(strtok(one, ", "), "first", 1); /* Basic test. */
713 equal(one, "first", 2);
714 equal(strtok((char *)NULL, ", "), "second", 3);
715 equal(strtok((char *)NULL, ", "), "third", 4);
716 check(strtok((char *)NULL, ", ") == NULL, 5);
717 (void) strcpy(one, ", first, ");
718 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
719 check(strtok((char *)NULL, ", ") == NULL, 7);
720 (void) strcpy(one, "1a, 1b; 2a, 2b");
721 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
722 equal(strtok((char *)NULL, "; "), "1b", 9);
723 equal(strtok((char *)NULL, ", "), "2a", 10);
724 (void) strcpy(two, "x-y");
725 equal(strtok(two, "-"), "x", 11); /* New string before done. */
726 equal(strtok((char *)NULL, "-"), "y", 12);
727 check(strtok((char *)NULL, "-") == NULL, 13);
728 (void) strcpy(one, "a,b, c,, ,d");
729 equal(strtok(one, ", "), "a", 14); /* Different separators. */
730 equal(strtok((char *)NULL, ", "), "b", 15);
731 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
732 equal(strtok((char *)NULL, " ,"), "d", 17);
733 check(strtok((char *)NULL, ", ") == NULL, 18);
734 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
735 (void) strcpy(one, ", ");
736 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
737 (void) strcpy(one, "");
738 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
739 (void) strcpy(one, "abc");
740 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
741 check(strtok((char *)NULL, ", ") == NULL, 23);
742 (void) strcpy(one, "abc");
743 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
744 check(strtok((char *)NULL, "") == NULL, 25);
745 (void) strcpy(one, "abcdefgh");
746 (void) strcpy(one, "a,b,c");
747 equal(strtok(one, ","), "a", 26); /* Basics again... */
748 equal(strtok((char *)NULL, ","), "b", 27);
749 equal(strtok((char *)NULL, ","), "c", 28);
750 check(strtok((char *)NULL, ",") == NULL, 29);
751 equal(one+6, "gh", 30); /* Stomped past end? */
752 equal(one, "a", 31); /* Stomped old tokens? */
753 equal(one+2, "b", 32);
754 equal(one+4, "c", 33);
757 static void
758 test_strtok_r (void)
760 it = "strtok_r";
761 (void) strcpy(one, "first, second, third");
762 cp = NULL; /* Always initialize cp to make sure it doesn't point to some old data. */
763 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
764 equal(one, "first", 2);
765 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
766 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
767 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
768 (void) strcpy(one, ", first, ");
769 cp = NULL;
770 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
771 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
772 (void) strcpy(one, "1a, 1b; 2a, 2b");
773 cp = NULL;
774 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
775 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
776 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
777 (void) strcpy(two, "x-y");
778 cp = NULL;
779 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
780 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
781 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
782 (void) strcpy(one, "a,b, c,, ,d");
783 cp = NULL;
784 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
785 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
786 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
787 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
788 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
789 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
790 (void) strcpy(one, ", ");
791 cp = NULL;
792 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
793 (void) strcpy(one, "");
794 cp = NULL;
795 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
796 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22); /* Persistence. */
797 (void) strcpy(one, "abc");
798 cp = NULL;
799 equal(strtok_r(one, ", ", &cp), "abc", 23); /* No delimiters. */
800 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
801 (void) strcpy(one, "abc");
802 cp = NULL;
803 equal(strtok_r(one, "", &cp), "abc", 25); /* Empty delimiter list. */
804 check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
805 (void) strcpy(one, "abcdefgh");
806 (void) strcpy(one, "a,b,c");
807 cp = NULL;
808 equal(strtok_r(one, ",", &cp), "a", 27); /* Basics again... */
809 equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
810 equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
811 check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
812 equal(one+6, "gh", 31); /* Stomped past end? */
813 equal(one, "a", 32); /* Stomped old tokens? */
814 equal(one+2, "b", 33);
815 equal(one+4, "c", 34);
818 static void
819 test_strsep (void)
821 char *ptr;
822 it = "strsep";
823 cp = strcpy(one, "first, second, third");
824 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
825 equal(one, "first", 2);
826 equal(strsep(&cp, ", "), "", 3);
827 equal(strsep(&cp, ", "), "second", 4);
828 equal(strsep(&cp, ", "), "", 5);
829 equal(strsep(&cp, ", "), "third", 6);
830 check(strsep(&cp, ", ") == NULL, 7);
831 cp = strcpy(one, ", first, ");
832 equal(strsep(&cp, ", "), "", 8);
833 equal(strsep(&cp, ", "), "", 9);
834 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
835 equal(strsep(&cp, ", "), "", 11);
836 equal(strsep(&cp, ", "), "", 12);
837 check(strsep(&cp, ", ") == NULL, 13);
838 cp = strcpy(one, "1a, 1b; 2a, 2b");
839 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */
840 equal(strsep(&cp, ", "), "", 15);
841 equal(strsep(&cp, "; "), "1b", 16);
842 equal(strsep(&cp, ", "), "", 17);
843 equal(strsep(&cp, ", "), "2a", 18);
844 cp = strcpy(two, "x-y");
845 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */
846 equal(strsep(&cp, "-"), "y", 20);
847 check(strsep(&cp, "-") == NULL, 21);
848 cp = strcpy(one, "a,b, c,, ,d ");
849 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */
850 equal(strsep(&cp, ", "), "b", 23);
851 equal(strsep(&cp, " ,"), "", 24);
852 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */
853 equal(strsep(&cp, " ,"), "", 26);
854 equal(strsep(&cp, " ,"), "", 27);
855 equal(strsep(&cp, " ,"), "", 28);
856 equal(strsep(&cp, " ,"), "d", 29);
857 equal(strsep(&cp, " ,"), "", 30);
858 check(strsep(&cp, ", ") == NULL, 31);
859 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
860 cp = strcpy(one, ", ");
861 equal(strsep(&cp, ", "), "", 33);
862 equal(strsep(&cp, ", "), "", 34);
863 equal(strsep(&cp, ", "), "", 35);
864 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
865 cp = strcpy(one, "");
866 equal(strsep(&cp, ", "), "", 37);
867 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
868 cp = strcpy(one, "abc");
869 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */
870 check(strsep(&cp, ", ") == NULL, 40);
871 cp = strcpy(one, "abc");
872 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */
873 check(strsep(&cp, "") == NULL, 42);
874 (void) strcpy(one, "abcdefgh");
875 cp = strcpy(one, "a,b,c");
876 equal(strsep(&cp, ","), "a", 43); /* Basics again... */
877 equal(strsep(&cp, ","), "b", 44);
878 equal(strsep(&cp, ","), "c", 45);
879 check(strsep(&cp, ",") == NULL, 46);
880 equal(one+6, "gh", 47); /* Stomped past end? */
881 equal(one, "a", 48); /* Stomped old tokens? */
882 equal(one+2, "b", 49);
883 equal(one+4, "c", 50);
886 char text[] = "This,is,a,test";
887 char *list = strdupa (text);
888 equal (strsep (&list, ","), "This", 51);
889 equal (strsep (&list, ","), "is", 52);
890 equal (strsep (&list, ","), "a", 53);
891 equal (strsep (&list, ","), "test", 54);
892 check (strsep (&list, ",") == NULL, 55);
895 cp = strcpy(one, "a,b, c,, ,d,");
896 equal(strsep(&cp, ","), "a", 56); /* Different separators. */
897 equal(strsep(&cp, ","), "b", 57);
898 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */
899 equal(strsep(&cp, ","), "", 59);
900 equal(strsep(&cp, ","), " ", 60);
901 equal(strsep(&cp, ","), "d", 61);
902 equal(strsep(&cp, ","), "", 62);
903 check(strsep(&cp, ",") == NULL, 63);
904 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */
906 cp = strcpy(one, "a,b, c,, ,d,");
907 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */
908 equal(strsep(&cp, "x,y"), "b", 66);
909 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */
910 equal(strsep(&cp, "xy,"), "", 68);
911 equal(strsep(&cp, "x,y"), " ", 69);
912 equal(strsep(&cp, ",xy"), "d", 70);
913 equal(strsep(&cp, "xy,"), "", 71);
914 check(strsep(&cp, "x,y") == NULL, 72);
915 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
917 cp = strcpy(one, "ABC");
918 one[4] = ':';
919 equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */
920 ptr = strsep(&cp, ":");
921 equal(ptr, "", 75);
922 check(ptr == one + 3, 76);
923 check(cp == NULL, 77);
925 cp = strcpy(one, "ABC");
926 one[4] = ':';
927 equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */
928 ptr = strsep(&cp, ":.");
929 equal(ptr, "", 79);
930 check(ptr == one + 3, 80);
932 cp = strcpy(one, "ABC"); /* No token in string. */
933 equal(strsep(&cp, ","), "ABC", 81);
934 check(cp == NULL, 82);
936 *one = '\0'; /* Empty string. */
937 cp = one;
938 ptr = strsep(&cp, ",");
939 equal(ptr, "", 83);
940 check(ptr == one, 84);
941 check(cp == NULL, 85);
943 *one = '\0'; /* Empty string and no token. */
944 cp = one;
945 ptr = strsep(&cp, "");
946 equal(ptr, "", 86);
947 check(ptr == one , 87);
948 check(cp == NULL, 88);
951 static void
952 test_memcmp (void)
954 it = "memcmp";
955 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
956 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
957 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
958 check(memcmp("abce", "abcd", 4) > 0, 4);
959 check(memcmp("alph", "beta", 4) < 0, 5);
960 check(memcmp("a\203", "a\003", 2) > 0, 6);
961 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
962 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
965 static void
966 test_memchr (void)
968 it = "memchr";
969 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
970 (void) strcpy(one, "abcd");
971 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
972 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
973 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
974 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
975 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
976 (void) strcpy(one, "ababa");
977 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
978 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
979 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
980 (void) strcpy(one, "a\203b");
981 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
983 /* now test all possible alignment and length combinations to catch
984 bugs due to unrolled loops (assuming unrolling is limited to no
985 more than 128 byte chunks: */
987 char buf[128 + sizeof(long)];
988 long align, len, i, pos;
990 for (align = 0; align < (long) sizeof(long); ++align) {
991 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
992 for (i = 0; i < len; ++i) {
993 buf[align + i] = 'x'; /* don't depend on memset... */
995 for (pos = 0; pos < len; ++pos) {
996 #if 0
997 printf("align %d, len %d, pos %d\n", align, len, pos);
998 #endif
999 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
1000 check(memchr(buf + align, 'x', pos) == NULL, 11);
1001 buf[align + pos] = '-';
1008 static void
1009 test_memcpy (void)
1011 int i;
1012 it = "memcpy";
1013 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
1014 equal(one, "abc", 2); /* Did the copy go right? */
1016 (void) strcpy(one, "abcdefgh");
1017 (void) memcpy(one+1, "xyz", 2);
1018 equal(one, "axydefgh", 3); /* Basic test. */
1020 (void) strcpy(one, "abc");
1021 (void) memcpy(one, "xyz", 0);
1022 equal(one, "abc", 4); /* Zero-length copy. */
1024 (void) strcpy(one, "hi there");
1025 (void) strcpy(two, "foo");
1026 (void) memcpy(two, one, 9);
1027 equal(two, "hi there", 5); /* Just paranoia. */
1028 equal(one, "hi there", 6); /* Stomped on source? */
1030 for (i = 0; i < 16; i++)
1032 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1033 strcpy (one, x);
1034 check (memcpy (one + i, "hi there", 9) == one + i,
1035 7 + (i * 6)); /* Unaligned destination. */
1036 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1037 equal (one + i, "hi there", 9 + (i * 6));
1038 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1039 check (memcpy (two, one + i, 9) == two,
1040 11 + (i * 6)); /* Unaligned source. */
1041 equal (two, "hi there", 12 + (i * 6));
1045 static void
1046 test_mempcpy (void)
1048 int i;
1049 it = "mempcpy";
1050 check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */
1051 equal(one, "abc", 2); /* Did the copy go right? */
1053 (void) strcpy(one, "abcdefgh");
1054 (void) mempcpy(one+1, "xyz", 2);
1055 equal(one, "axydefgh", 3); /* Basic test. */
1057 (void) strcpy(one, "abc");
1058 (void) mempcpy(one, "xyz", 0);
1059 equal(one, "abc", 4); /* Zero-length copy. */
1061 (void) strcpy(one, "hi there");
1062 (void) strcpy(two, "foo");
1063 (void) mempcpy(two, one, 9);
1064 equal(two, "hi there", 5); /* Just paranoia. */
1065 equal(one, "hi there", 6); /* Stomped on source? */
1067 for (i = 0; i < 16; i++)
1069 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1070 strcpy (one, x);
1071 check (mempcpy (one + i, "hi there", 9) == one + i + 9,
1072 7 + (i * 6)); /* Unaligned destination. */
1073 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1074 equal (one + i, "hi there", 9 + (i * 6));
1075 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1076 check (mempcpy (two, one + i, 9) == two + 9,
1077 11 + (i * 6)); /* Unaligned source. */
1078 equal (two, "hi there", 12 + (i * 6));
1082 static void
1083 test_memmove (void)
1085 it = "memmove";
1086 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
1087 equal(one, "abc", 2); /* Did the copy go right? */
1089 (void) strcpy(one, "abcdefgh");
1090 (void) memmove(one+1, "xyz", 2);
1091 equal(one, "axydefgh", 3); /* Basic test. */
1093 (void) strcpy(one, "abc");
1094 (void) memmove(one, "xyz", 0);
1095 equal(one, "abc", 4); /* Zero-length copy. */
1097 (void) strcpy(one, "hi there");
1098 (void) strcpy(two, "foo");
1099 (void) memmove(two, one, 9);
1100 equal(two, "hi there", 5); /* Just paranoia. */
1101 equal(one, "hi there", 6); /* Stomped on source? */
1103 (void) strcpy(one, "abcdefgh");
1104 (void) memmove(one+1, one, 9);
1105 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
1107 (void) strcpy(one, "abcdefgh");
1108 (void) memmove(one+1, one+2, 7);
1109 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
1111 (void) strcpy(one, "abcdefgh");
1112 (void) memmove(one, one, 9);
1113 equal(one, "abcdefgh", 9); /* 100% overlap. */
1116 static void
1117 test_memccpy (void)
1119 /* First test like memcpy, then the search part The SVID, the only
1120 place where memccpy is mentioned, says overlap might fail, so we
1121 don't try it. Besides, it's hard to see the rationale for a
1122 non-left-to-right memccpy. */
1123 it = "memccpy";
1124 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
1125 equal(one, "abc", 2); /* Did the copy go right? */
1127 (void) strcpy(one, "abcdefgh");
1128 (void) memccpy(one+1, "xyz", 'q', 2);
1129 equal(one, "axydefgh", 3); /* Basic test. */
1131 (void) strcpy(one, "abc");
1132 (void) memccpy(one, "xyz", 'q', 0);
1133 equal(one, "abc", 4); /* Zero-length copy. */
1135 (void) strcpy(one, "hi there");
1136 (void) strcpy(two, "foo");
1137 (void) memccpy(two, one, 'q', 9);
1138 equal(two, "hi there", 5); /* Just paranoia. */
1139 equal(one, "hi there", 6); /* Stomped on source? */
1141 (void) strcpy(one, "abcdefgh");
1142 (void) strcpy(two, "horsefeathers");
1143 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
1144 equal(one, "abcdefgh", 8); /* Source intact? */
1145 equal(two, "abcdefeathers", 9); /* Copy correct? */
1147 (void) strcpy(one, "abcd");
1148 (void) strcpy(two, "bumblebee");
1149 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
1150 equal(two, "aumblebee", 11);
1151 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
1152 equal(two, "abcdlebee", 13);
1153 (void) strcpy(one, "xyz");
1154 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
1155 equal(two, "xbcdlebee", 15);
1158 static void
1159 test_memset (void)
1161 int i;
1163 it = "memset";
1164 (void) strcpy(one, "abcdefgh");
1165 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
1166 equal(one, "axxxefgh", 2); /* Basic test. */
1168 (void) memset(one+2, 'y', 0);
1169 equal(one, "axxxefgh", 3); /* Zero-length set. */
1171 (void) memset(one+5, 0, 1);
1172 equal(one, "axxxe", 4); /* Zero fill. */
1173 equal(one+6, "gh", 5); /* And the leftover. */
1175 (void) memset(one+2, 010045, 1);
1176 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
1178 /* Non-8bit fill character. */
1179 memset (one, 0x101, sizeof (one));
1180 for (i = 0; i < (int) sizeof (one); ++i)
1181 check (one[i] == '\01', 7);
1183 /* Test for more complex versions of memset, for all alignments and
1184 lengths up to 256. This test takes a little while, perhaps it should
1185 be made weaker? */
1187 char data[512];
1188 int j;
1189 int k;
1190 int c;
1192 for (i = 0; i < 512; i++)
1193 data[i] = 'x';
1194 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
1195 memset(,'y',) */
1196 for (j = 0; j < 256; j++)
1197 for (i = 0; i < 256; i++)
1199 memset (data + i, c, j);
1200 for (k = 0; k < i; k++)
1201 if (data[k] != 'x')
1202 goto fail;
1203 for (k = i; k < i+j; k++)
1205 if (data[k] != c)
1206 goto fail;
1207 data[k] = 'x';
1209 for (k = i+j; k < 512; k++)
1210 if (data[k] != 'x')
1211 goto fail;
1212 continue;
1214 fail:
1215 check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
1220 static void
1221 test_bcopy (void)
1223 /* Much like memcpy. Berklix manual is silent about overlap, so
1224 don't test it. */
1225 it = "bcopy";
1226 (void) bcopy("abc", one, 4);
1227 equal(one, "abc", 1); /* Simple copy. */
1229 (void) strcpy(one, "abcdefgh");
1230 (void) bcopy("xyz", one+1, 2);
1231 equal(one, "axydefgh", 2); /* Basic test. */
1233 (void) strcpy(one, "abc");
1234 (void) bcopy("xyz", one, 0);
1235 equal(one, "abc", 3); /* Zero-length copy. */
1237 (void) strcpy(one, "hi there");
1238 (void) strcpy(two, "foo");
1239 (void) bcopy(one, two, 9);
1240 equal(two, "hi there", 4); /* Just paranoia. */
1241 equal(one, "hi there", 5); /* Stomped on source? */
1244 static void
1245 test_bzero (void)
1247 it = "bzero";
1248 (void) strcpy(one, "abcdef");
1249 bzero(one+2, 2);
1250 equal(one, "ab", 1); /* Basic test. */
1251 equal(one+3, "", 2);
1252 equal(one+4, "ef", 3);
1254 (void) strcpy(one, "abcdef");
1255 bzero(one+2, 0);
1256 equal(one, "abcdef", 4); /* Zero-length copy. */
1259 static void
1260 test_strndup (void)
1262 char *p, *q;
1263 it = "strndup";
1264 p = strndup("abcdef", 12);
1265 check(p != NULL, 1);
1266 if (p != NULL)
1268 equal(p, "abcdef", 2);
1269 q = strndup(p + 1, 2);
1270 check(q != NULL, 3);
1271 if (q != NULL)
1272 equal(q, "bc", 4);
1273 free (q);
1275 free (p);
1276 p = strndup("abc def", 3);
1277 check(p != NULL, 5);
1278 if (p != NULL)
1279 equal(p, "abc", 6);
1280 free (p);
1283 static void
1284 test_bcmp (void)
1286 it = "bcmp";
1287 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1288 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1289 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1290 check(bcmp("abce", "abcd", 4) != 0, 4);
1291 check(bcmp("alph", "beta", 4) != 0, 5);
1292 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1293 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1296 static void
1297 test_strerror (void)
1299 it = "strerror";
1300 check(strerror(EDOM) != 0, 1);
1301 check(strerror(ERANGE) != 0, 2);
1302 check(strerror(ENOENT) != 0, 3);
1306 main (void)
1308 int status;
1310 /* Test strcmp first because we use it to test other things. */
1311 test_strcmp ();
1313 /* Test strcpy next because we need it to set up other tests. */
1314 test_strcpy ();
1316 /* A closely related function is stpcpy. */
1317 test_stpcpy ();
1319 /* stpncpy. */
1320 test_stpncpy ();
1322 /* strcat. */
1323 test_strcat ();
1325 /* strncat. */
1326 test_strncat ();
1328 /* strncmp. */
1329 test_strncmp ();
1331 /* strncpy. */
1332 test_strncpy ();
1334 /* strlen. */
1335 test_strlen ();
1337 /* strchr. */
1338 test_strchr ();
1340 /* strchrnul. */
1341 test_strchrnul ();
1343 /* rawmemchr. */
1344 test_rawmemchr ();
1346 /* index - just like strchr. */
1347 test_index ();
1349 /* strrchr. */
1350 test_strrchr ();
1352 /* memrchr. */
1353 test_memrchr ();
1355 /* rindex - just like strrchr. */
1356 test_rindex ();
1358 /* strpbrk - somewhat like strchr. */
1359 test_strpbrk ();
1361 /* strstr - somewhat like strchr. */
1362 test_strstr ();
1364 /* strspn. */
1365 test_strspn ();
1367 /* strcspn. */
1368 test_strcspn ();
1370 /* strtok - the hard one. */
1371 test_strtok ();
1373 /* strtok_r. */
1374 test_strtok_r ();
1376 /* strsep. */
1377 test_strsep ();
1379 /* memcmp. */
1380 test_memcmp ();
1382 /* memchr. */
1383 test_memchr ();
1385 /* memcpy - need not work for overlap. */
1386 test_memcpy ();
1388 /* memmove - must work on overlap. */
1389 test_memmove ();
1391 /* mempcpy */
1392 test_mempcpy ();
1394 /* memccpy. */
1395 test_memccpy ();
1397 /* memset. */
1398 test_memset ();
1400 /* bcopy. */
1401 test_bcopy ();
1403 /* bzero. */
1404 test_bzero ();
1406 /* bcmp - somewhat like memcmp. */
1407 test_bcmp ();
1409 /* strndup. */
1410 test_strndup ();
1412 /* strerror - VERY system-dependent. */
1413 test_strerror ();
1416 if (errors == 0)
1418 status = EXIT_SUCCESS;
1419 puts("No errors.");
1421 else
1423 status = EXIT_FAILURE;
1424 printf("%Zd errors.\n", errors);
1427 return status;