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