5105e4eea431f0658b0252e7b5e8501d5560a8ef
[platform/upstream/glibc.git] / string / tester.c
1 /* Tester for string functions.
2    Copyright (C) 1995, 1996, 1997, 1998, 1999 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 Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
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    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #ifndef _GNU_SOURCE
21 #define _GNU_SOURCE
22 #endif
23
24 /* Make sure we don't test the optimized inline functions if we want to
25    test the real implementation.  */
26 #if !defined DO_STRING_INLINES
27 #undef __USE_STRING_INLINES
28 #endif
29
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <strings.h>
35 #include <fcntl.h>
36
37 #ifndef HAVE_GNU_LD
38 #define _sys_nerr       sys_nerr
39 #define _sys_errlist    sys_errlist
40 #endif
41
42 #define STREQ(a, b)     (strcmp((a), (b)) == 0)
43
44 const char *it = "<UNSET>";     /* Routine name for message routines. */
45 size_t errors = 0;
46
47 /* Complain if condition is not true.  */
48 void
49 check (int thing, int number)
50 {
51   if (!thing)
52     {
53       printf("%s flunked test %d\n", it, number);
54       ++errors;
55     }
56 }
57
58 /* Complain if first two args don't strcmp as equal.  */
59 void
60 equal (const char *a, const char *b, int number)
61 {
62   check(a != NULL && b != NULL && STREQ (a, b), number);
63 }
64
65 char one[50];
66 char two[50];
67 char *cp;
68
69 void
70 test_strcmp (void)
71 {
72   it = "strcmp";
73   check (strcmp ("", "") == 0, 1);              /* Trivial case. */
74   check (strcmp ("a", "a") == 0, 2);            /* Identity. */
75   check (strcmp ("abc", "abc") == 0, 3);        /* Multicharacter. */
76   check (strcmp ("abc", "abcd") < 0, 4);        /* Length mismatches. */
77   check (strcmp ("abcd", "abc") > 0, 5);
78   check (strcmp ("abcd", "abce") < 0, 6);       /* Honest miscompares. */
79   check (strcmp ("abce", "abcd") > 0, 7);
80   check (strcmp ("a\203", "a") > 0, 8);         /* Tricky if char signed. */
81   check (strcmp ("a\203", "a\003") > 0, 9);
82
83   {
84     char buf1[0x40], buf2[0x40];
85     int i, j;
86     for (i=0; i < 0x10; i++)
87       for (j = 0; j < 0x10; j++)
88         {
89           int k;
90           for (k = 0; k < 0x3f; k++)
91             {
92               buf1[j] = '0' ^ (k & 4);
93               buf2[j] = '4' ^ (k & 4);
94             }
95           buf1[i] = buf1[0x3f] = 0;
96           buf2[j] = buf2[0x3f] = 0;
97           for (k = 0; k < 0xf; k++)
98             {
99               int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
100               check (strcmp (buf1+i,buf2+j) == 0, cnum);
101               buf1[i+k] = 'A' + i + k;
102               buf1[i+k+1] = 0;
103               check (strcmp (buf1+i,buf2+j) > 0, cnum+1);
104               check (strcmp (buf2+j,buf1+i) < 0, cnum+2);
105               buf2[j+k] = 'B' + i + k;
106               buf2[j+k+1] = 0;
107               check (strcmp (buf1+i,buf2+j) < 0, cnum+3);
108               check (strcmp (buf2+j,buf1+i) > 0, cnum+4);
109               buf2[j+k] = 'A' + i + k;
110               buf1[i] = 'A' + i + 0x80;
111               check (strcmp (buf1+i,buf2+j) > 0, cnum+5);
112               check (strcmp (buf2+j,buf1+i) < 0, cnum+6);
113               buf1[i] = 'A' + i;
114             }
115         }
116   }
117 }
118
119 #define SIMPLE_COPY(fn, n, str, ntest) \
120   do {                                                                        \
121     int __n;                                                                  \
122     char *cp;                                                                 \
123     for (__n = 0; __n < sizeof (one); ++__n)                                  \
124       one[__n] = 'Z';                                                         \
125     fn (one, str);                                                            \
126     for (cp = one, __n = 0; __n < n; ++__n, ++cp)                             \
127       check (*cp == '0' + (n % 10), ntest);                                   \
128     check (*cp == '\0', ntest);                                               \
129   } while (0)
130
131 void
132 test_strcpy (void)
133 {
134   int i;
135   it = "strcpy";
136   check (strcpy (one, "abcd") == one, 1); /* Returned value. */
137   equal (one, "abcd", 2);               /* Basic test. */
138
139   (void) strcpy (one, "x");
140   equal (one, "x", 3);                  /* Writeover. */
141   equal (one+2, "cd", 4);               /* Wrote too much? */
142
143   (void) strcpy (two, "hi there");
144   (void) strcpy (one, two);
145   equal (one, "hi there", 5);           /* Basic test encore. */
146   equal (two, "hi there", 6);           /* Stomped on source? */
147
148   (void) strcpy (one, "");
149   equal (one, "", 7);                   /* Boundary condition. */
150
151   for (i = 0; i < 16; i++)
152     {
153       (void) strcpy (one + i, "hi there");      /* Unaligned destination. */
154       equal (one + i, "hi there", 8 + (i * 2));
155       (void) strcpy (two, one + i);             /* Unaligned source. */
156       equal (two, "hi there", 9 + (i * 2));
157     }
158
159   SIMPLE_COPY(strcpy, 0, "", 41);
160   SIMPLE_COPY(strcpy, 1, "1", 42);
161   SIMPLE_COPY(strcpy, 2, "22", 43);
162   SIMPLE_COPY(strcpy, 3, "333", 44);
163   SIMPLE_COPY(strcpy, 4, "4444", 45);
164   SIMPLE_COPY(strcpy, 5, "55555", 46);
165   SIMPLE_COPY(strcpy, 6, "666666", 47);
166   SIMPLE_COPY(strcpy, 7, "7777777", 48);
167   SIMPLE_COPY(strcpy, 8, "88888888", 49);
168   SIMPLE_COPY(strcpy, 9, "999999999", 50);
169   SIMPLE_COPY(strcpy, 10, "0000000000", 51);
170   SIMPLE_COPY(strcpy, 11, "11111111111", 52);
171   SIMPLE_COPY(strcpy, 12, "222222222222", 53);
172   SIMPLE_COPY(strcpy, 13, "3333333333333", 54);
173   SIMPLE_COPY(strcpy, 14, "44444444444444", 55);
174   SIMPLE_COPY(strcpy, 15, "555555555555555", 56);
175   SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);
176 }
177
178 void
179 test_stpcpy (void)
180 {
181   it = "stpcpy";
182   check ((stpcpy (one, "a") - one) == 1, 1);
183   equal (one, "a", 2);
184
185   check ((stpcpy (one, "ab") - one) == 2, 3);
186   equal (one, "ab", 4);
187
188   check ((stpcpy (one, "abc") - one) == 3, 5);
189   equal (one, "abc", 6);
190
191   check ((stpcpy (one, "abcd") - one) == 4, 7);
192   equal (one, "abcd", 8);
193
194   check ((stpcpy (one, "abcde") - one) == 5, 9);
195   equal (one, "abcde", 10);
196
197   check ((stpcpy (one, "abcdef") - one) == 6, 11);
198   equal (one, "abcdef", 12);
199
200   check ((stpcpy (one, "abcdefg") - one) == 7, 13);
201   equal (one, "abcdefg", 14);
202
203   check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
204   equal (one, "abcdefgh", 16);
205
206   check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
207   equal (one, "abcdefghi", 18);
208
209   check ((stpcpy (one, "x") - one) == 1, 19);
210   equal (one, "x", 20);                 /* Writeover. */
211   equal (one+2, "cdefghi", 21);         /* Wrote too much? */
212
213   check ((stpcpy (one, "xx") - one) == 2, 22);
214   equal (one, "xx", 23);                /* Writeover. */
215   equal (one+3, "defghi", 24);          /* Wrote too much? */
216
217   check ((stpcpy (one, "xxx") - one) == 3, 25);
218   equal (one, "xxx", 26);               /* Writeover. */
219   equal (one+4, "efghi", 27);           /* Wrote too much? */
220
221   check ((stpcpy (one, "xxxx") - one) == 4, 28);
222   equal (one, "xxxx", 29);              /* Writeover. */
223   equal (one+5, "fghi", 30);            /* Wrote too much? */
224
225   check ((stpcpy (one, "xxxxx") - one) == 5, 31);
226   equal (one, "xxxxx", 32);             /* Writeover. */
227   equal (one+6, "ghi", 33);             /* Wrote too much? */
228
229   check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
230   equal (one, "xxxxxx", 35);            /* Writeover. */
231   equal (one+7, "hi", 36);              /* Wrote too much? */
232
233   check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
234   equal (one, "xxxxxxx", 38);           /* Writeover. */
235   equal (one+8, "i", 39);               /* Wrote too much? */
236
237   check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
238   equal (one, "abc", 41);
239   equal (one + 4, "xxx", 42);
240
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);
258 }
259
260 void
261 test_stpncpy (void)
262 {
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);
273 }
274
275 void
276 test_strcat (void)
277 {
278   it = "strcat";
279   (void) strcpy (one, "ijk");
280   check (strcat (one, "lmn") == one, 1); /* Returned value. */
281   equal (one, "ijklmn", 2);             /* Basic test. */
282
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? */
287
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? */
293
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);
303 }
304
305 void
306 test_strncat (void)
307 {
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. */
314
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? */
319
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? */
325
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);
335
336   (void) strcpy (one, "ab");
337   (void) strncat (one, "cdef", 2);
338   equal (one, "abcd", 10);                      /* Count-limited. */
339
340   (void) strncat (one, "gh", 0);
341   equal (one, "abcd", 11);                      /* Zero count. */
342
343   (void) strncat (one, "gh", 2);
344   equal (one, "abcdgh", 12);            /* Count and length equal. */
345 }
346
347 void
348 test_strncmp (void)
349 {
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. */
365 }
366
367 void
368 test_strncpy (void)
369 {
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? */
374
375   (void) strcpy (one, "abcdefgh");
376   (void) strncpy (one, "xyz", 2);
377   equal (one, "xycdefgh", 3);                   /* Copy cut by count. */
378
379   (void) strcpy (one, "abcdefgh");
380   (void) strncpy (one, "xyz", 3);               /* Copy cut just before NUL. */
381   equal (one, "xyzdefgh", 4);
382
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? */
387
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);
393
394   (void) strcpy (one, "abc");
395   (void) strncpy (one, "xyz", 0);               /* Zero-length copy. */
396   equal (one, "abc", 10);
397
398   (void) strncpy (one, "", 2);          /* Zero-length source. */
399   equal (one, "", 11);
400   equal (one+1, "", 12);
401   equal (one+2, "c", 13);
402
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? */
407 }
408
409 void
410 test_strlen (void)
411 {
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. */
416   {
417     char buf[4096];
418     int i;
419     char *p;
420     for (i=0; i < 0x100; i++)
421       {
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);
426       }
427    }
428 }
429
430 void
431 test_strchr (void)
432 {
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. */
445   {
446     char buf[4096];
447     int i;
448     char *p;
449     for (i=0; i < 0x100; i++)
450       {
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);
455       }
456    }
457 }
458
459 void
460 test_strchrnul (void)
461 {
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. */
477   {
478     char buf[4096];
479     int i;
480     char *p;
481     for (i=0; i < 0x100; i++)
482       {
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);
489       }
490    }
491 }
492
493 void
494 test_rawmemchr (void)
495 {
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. */
506   {
507     char buf[4096];
508     int i;
509     char *p;
510     for (i=0; i < 0x100; i++)
511       {
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);
516       }
517    }
518 }
519
520 void
521 test_index (void)
522 {
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. */
535 }
536
537 void
538 test_strrchr (void)
539 {
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. */
552   {
553     char buf[4096];
554     int i;
555     char *p;
556     for (i=0; i < 0x100; i++)
557       {
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);
562       }
563    }
564 }
565
566 void
567 test_rindex (void)
568 {
569   it = "rindex";
570   check (rindex ("abcd", 'z') == NULL, 1);      /* Not found. */
571   (void) strcpy (one, "abcd");
572   check (rindex (one, 'c') == one+2, 2);        /* Basic test. */
573   check (rindex (one, 'd') == one+3, 3);        /* End of string. */
574   check (rindex (one, 'a') == one, 4);  /* Beginning. */
575   check (rindex (one, '\0') == one+4, 5);       /* Finding NUL. */
576   (void) strcpy (one, "ababa");
577   check (rindex (one, 'b') == one+3, 6);        /* Finding last. */
578   (void) strcpy (one, "");
579   check (rindex (one, 'b') == NULL, 7); /* Empty string. */
580   check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
581 }
582
583 void
584 test_strpbrk (void)
585 {
586   it = "strpbrk";
587   check(strpbrk("abcd", "z") == NULL, 1);       /* Not found. */
588   (void) strcpy(one, "abcd");
589   check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
590   check(strpbrk(one, "d") == one+3, 3); /* End of string. */
591   check(strpbrk(one, "a") == one, 4);   /* Beginning. */
592   check(strpbrk(one, "") == NULL, 5);   /* Empty search list. */
593   check(strpbrk(one, "cb") == one+1, 6);        /* Multiple search. */
594   (void) strcpy(one, "abcabdea");
595   check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
596   check(strpbrk(one, "cb") == one+1, 8);        /* With multiple search. */
597   check(strpbrk(one, "db") == one+1, 9);        /* Another variant. */
598   (void) strcpy(one, "");
599   check(strpbrk(one, "bc") == NULL, 10);        /* Empty string. */
600   (void) strcpy(one, "");
601   check(strpbrk(one, "bcd") == NULL, 11);       /* Empty string. */
602   (void) strcpy(one, "");
603   check(strpbrk(one, "bcde") == NULL, 12);      /* Empty string. */
604   check(strpbrk(one, "") == NULL, 13);  /* Both strings empty. */
605   (void) strcpy(one, "abcabdea");
606   check(strpbrk(one, "befg") == one+1, 14);     /* Finding first. */
607   check(strpbrk(one, "cbr") == one+1, 15);      /* With multiple search. */
608   check(strpbrk(one, "db") == one+1, 16);       /* Another variant. */
609   check(strpbrk(one, "efgh") == one+6, 17);     /* And yet another. */
610 }
611
612 void
613 test_strstr (void)
614 {
615   it = "strstr";
616   check(strstr("abcd", "z") == NULL, 1);        /* Not found. */
617   check(strstr("abcd", "abx") == NULL, 2);      /* Dead end. */
618   (void) strcpy(one, "abcd");
619   check(strstr(one, "c") == one+2, 3);  /* Basic test. */
620   check(strstr(one, "bc") == one+1, 4); /* Multichar. */
621   check(strstr(one, "d") == one+3, 5);  /* End of string. */
622   check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
623   check(strstr(one, "abc") == one, 7);  /* Beginning. */
624   check(strstr(one, "abcd") == one, 8); /* Exact match. */
625   check(strstr(one, "abcde") == NULL, 9);       /* Too long. */
626   check(strstr(one, "de") == NULL, 10); /* Past end. */
627   check(strstr(one, "") == one, 11);    /* Finding empty. */
628   (void) strcpy(one, "ababa");
629   check(strstr(one, "ba") == one+1, 12);        /* Finding first. */
630   (void) strcpy(one, "");
631   check(strstr(one, "b") == NULL, 13);  /* Empty string. */
632   check(strstr(one, "") == one, 14);    /* Empty in empty string. */
633   (void) strcpy(one, "bcbca");
634   check(strstr(one, "bca") == one+2, 15);       /* False start. */
635   (void) strcpy(one, "bbbcabbca");
636   check(strstr(one, "bbca") == one+1, 16);      /* With overlap. */
637 }
638
639 void
640 test_strspn (void)
641 {
642   it = "strspn";
643   check(strspn("abcba", "abc") == 5, 1);        /* Whole string. */
644   check(strspn("abcba", "ab") == 2, 2); /* Partial. */
645   check(strspn("abc", "qx") == 0, 3);   /* None. */
646   check(strspn("", "ab") == 0, 4);      /* Null string. */
647   check(strspn("abc", "") == 0, 5);     /* Null search list. */
648 }
649
650 void
651 test_strcspn (void)
652 {
653   it = "strcspn";
654   check(strcspn("abcba", "qx") == 5, 1);        /* Whole string. */
655   check(strcspn("abcba", "cx") == 2, 2);        /* Partial. */
656   check(strcspn("abc", "abc") == 0, 3); /* None. */
657   check(strcspn("", "ab") == 0, 4);     /* Null string. */
658   check(strcspn("abc", "") == 3, 5);    /* Null search list. */
659 }
660
661 void
662 test_strtok (void)
663 {
664   it = "strtok";
665   (void) strcpy(one, "first, second, third");
666   equal(strtok(one, ", "), "first", 1); /* Basic test. */
667   equal(one, "first", 2);
668   equal(strtok((char *)NULL, ", "), "second", 3);
669   equal(strtok((char *)NULL, ", "), "third", 4);
670   check(strtok((char *)NULL, ", ") == NULL, 5);
671   (void) strcpy(one, ", first, ");
672   equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
673   check(strtok((char *)NULL, ", ") == NULL, 7);
674   (void) strcpy(one, "1a, 1b; 2a, 2b");
675   equal(strtok(one, ", "), "1a", 8);    /* Changing delim lists. */
676   equal(strtok((char *)NULL, "; "), "1b", 9);
677   equal(strtok((char *)NULL, ", "), "2a", 10);
678   (void) strcpy(two, "x-y");
679   equal(strtok(two, "-"), "x", 11);     /* New string before done. */
680   equal(strtok((char *)NULL, "-"), "y", 12);
681   check(strtok((char *)NULL, "-") == NULL, 13);
682   (void) strcpy(one, "a,b, c,, ,d");
683   equal(strtok(one, ", "), "a", 14);    /* Different separators. */
684   equal(strtok((char *)NULL, ", "), "b", 15);
685   equal(strtok((char *)NULL, " ,"), "c", 16);   /* Permute list too. */
686   equal(strtok((char *)NULL, " ,"), "d", 17);
687   check(strtok((char *)NULL, ", ") == NULL, 18);
688   check(strtok((char *)NULL, ", ") == NULL, 19);        /* Persistence. */
689   (void) strcpy(one, ", ");
690   check(strtok(one, ", ") == NULL, 20); /* No tokens. */
691   (void) strcpy(one, "");
692   check(strtok(one, ", ") == NULL, 21); /* Empty string. */
693   (void) strcpy(one, "abc");
694   equal(strtok(one, ", "), "abc", 22);  /* No delimiters. */
695   check(strtok((char *)NULL, ", ") == NULL, 23);
696   (void) strcpy(one, "abc");
697   equal(strtok(one, ""), "abc", 24);    /* Empty delimiter list. */
698   check(strtok((char *)NULL, "") == NULL, 25);
699   (void) strcpy(one, "abcdefgh");
700   (void) strcpy(one, "a,b,c");
701   equal(strtok(one, ","), "a", 26);     /* Basics again... */
702   equal(strtok((char *)NULL, ","), "b", 27);
703   equal(strtok((char *)NULL, ","), "c", 28);
704   check(strtok((char *)NULL, ",") == NULL, 29);
705   equal(one+6, "gh", 30);                       /* Stomped past end? */
706   equal(one, "a", 31);                  /* Stomped old tokens? */
707   equal(one+2, "b", 32);
708   equal(one+4, "c", 33);
709 }
710
711 void
712 test_strtok_r (void)
713 {
714   it = "strtok_r";
715   (void) strcpy(one, "first, second, third");
716   equal(strtok_r(one, ", ", &cp), "first", 1);  /* Basic test. */
717   equal(one, "first", 2);
718   equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
719   equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
720   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
721   (void) strcpy(one, ", first, ");
722   equal(strtok_r(one, ", ", &cp), "first", 6);  /* Extra delims, 1 tok. */
723   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
724   (void) strcpy(one, "1a, 1b; 2a, 2b");
725   equal(strtok_r(one, ", ", &cp), "1a", 8);     /* Changing delim lists. */
726   equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
727   equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
728   (void) strcpy(two, "x-y");
729   equal(strtok_r(two, "-", &cp), "x", 11);      /* New string before done. */
730   equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
731   check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
732   (void) strcpy(one, "a,b, c,, ,d");
733   equal(strtok_r(one, ", ", &cp), "a", 14);     /* Different separators. */
734   equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
735   equal(strtok_r((char *)NULL, " ,", &cp), "c", 16);    /* Permute list too. */
736   equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
737   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
738   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
739   (void) strcpy(one, ", ");
740   check(strtok_r(one, ", ", &cp) == NULL, 20);  /* No tokens. */
741   (void) strcpy(one, "");
742   check(strtok_r(one, ", ", &cp) == NULL, 21);  /* Empty string. */
743   (void) strcpy(one, "abc");
744   equal(strtok_r(one, ", ", &cp), "abc", 22);   /* No delimiters. */
745   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 23);
746   (void) strcpy(one, "abc");
747   equal(strtok_r(one, "", &cp), "abc", 24);     /* Empty delimiter list. */
748   check(strtok_r((char *)NULL, "", &cp) == NULL, 25);
749   (void) strcpy(one, "abcdefgh");
750   (void) strcpy(one, "a,b,c");
751   equal(strtok_r(one, ",", &cp), "a", 26);      /* Basics again... */
752   equal(strtok_r((char *)NULL, ",", &cp), "b", 27);
753   equal(strtok_r((char *)NULL, ",", &cp), "c", 28);
754   check(strtok_r((char *)NULL, ",", &cp) == NULL, 29);
755   equal(one+6, "gh", 30);                       /* Stomped past end? */
756   equal(one, "a", 31);                  /* Stomped old tokens? */
757   equal(one+2, "b", 32);
758   equal(one+4, "c", 33);
759 }
760
761 void
762 test_strsep (void)
763 {
764   it = "strsep";
765   cp = strcpy(one, "first, second, third");
766   equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
767   equal(one, "first", 2);
768   equal(strsep(&cp, ", "), "", 3);
769   equal(strsep(&cp, ", "), "second", 4);
770   equal(strsep(&cp, ", "), "", 5);
771   equal(strsep(&cp, ", "), "third", 6);
772   check(strsep(&cp, ", ") == NULL, 7);
773   cp = strcpy(one, ", first, ");
774   equal(strsep(&cp, ", "), "", 8);
775   equal(strsep(&cp, ", "), "", 9);
776   equal(strsep(&cp, ", "), "first", 10);        /* Extra delims, 1 tok. */
777   equal(strsep(&cp, ", "), "", 11);
778   equal(strsep(&cp, ", "), "", 12);
779   check(strsep(&cp, ", ") == NULL, 13);
780   cp = strcpy(one, "1a, 1b; 2a, 2b");
781   equal(strsep(&cp, ", "), "1a", 14);   /* Changing delim lists. */
782   equal(strsep(&cp, ", "), "", 15);
783   equal(strsep(&cp, "; "), "1b", 16);
784   equal(strsep(&cp, ", "), "", 17);
785   equal(strsep(&cp, ", "), "2a", 18);
786   cp = strcpy(two, "x-y");
787   equal(strsep(&cp, "-"), "x", 19);     /* New string before done. */
788   equal(strsep(&cp, "-"), "y", 20);
789   check(strsep(&cp, "-") == NULL, 21);
790   cp = strcpy(one, "a,b, c,, ,d ");
791   equal(strsep(&cp, ", "), "a", 22);    /* Different separators. */
792   equal(strsep(&cp, ", "), "b", 23);
793   equal(strsep(&cp, " ,"), "", 24);
794   equal(strsep(&cp, " ,"), "c", 25);    /* Permute list too. */
795   equal(strsep(&cp, " ,"), "", 26);
796   equal(strsep(&cp, " ,"), "", 27);
797   equal(strsep(&cp, " ,"), "", 28);
798   equal(strsep(&cp, " ,"), "d", 29);
799   equal(strsep(&cp, " ,"), "", 30);
800   check(strsep(&cp, ", ") == NULL, 31);
801   check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
802   cp = strcpy(one, ", ");
803   equal(strsep(&cp, ", "), "", 33);
804   equal(strsep(&cp, ", "), "", 34);
805   equal(strsep(&cp, ", "), "", 35);
806   check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
807   cp = strcpy(one, "");
808   equal(strsep(&cp, ", "), "", 37);
809   check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
810   cp = strcpy(one, "abc");
811   equal(strsep(&cp, ", "), "abc", 39);  /* No delimiters. */
812   check(strsep(&cp, ", ") == NULL, 40);
813   cp = strcpy(one, "abc");
814   equal(strsep(&cp, ""), "abc", 41);    /* Empty delimiter list. */
815   check(strsep(&cp, "") == NULL, 42);
816   (void) strcpy(one, "abcdefgh");
817   cp = strcpy(one, "a,b,c");
818   equal(strsep(&cp, ","), "a", 43);     /* Basics again... */
819   equal(strsep(&cp, ","), "b", 44);
820   equal(strsep(&cp, ","), "c", 45);
821   check(strsep(&cp, ",") == NULL, 46);
822   equal(one+6, "gh", 47);               /* Stomped past end? */
823   equal(one, "a", 48);                  /* Stomped old tokens? */
824   equal(one+2, "b", 49);
825   equal(one+4, "c", 50);
826
827   {
828     char text[] = "This,is,a,test";
829     char *list = strdupa (text);
830     equal (strsep (&list, ","), "This", 51);
831     equal (strsep (&list, ","), "is", 52);
832     equal (strsep (&list, ","), "a", 53);
833     equal (strsep (&list, ","), "test", 54);
834     check (strsep (&list, ",") == NULL, 55);
835   }
836
837   cp = strcpy(one, "a,b, c,, ,d,");
838   equal(strsep(&cp, ","), "a", 56);     /* Different separators. */
839   equal(strsep(&cp, ","), "b", 57);
840   equal(strsep(&cp, ","), " c", 58);    /* Permute list too. */
841   equal(strsep(&cp, ","), "", 59);
842   equal(strsep(&cp, ","), " ", 60);
843   equal(strsep(&cp, ","), "d", 61);
844   equal(strsep(&cp, ","), "", 62);
845   check(strsep(&cp, ",") == NULL, 63);
846   check(strsep(&cp, ",") == NULL, 64);  /* Persistence. */
847
848   cp = strcpy(one, "a,b, c,, ,d,");
849   equal(strsep(&cp, "xy,"), "a", 65);   /* Different separators. */
850   equal(strsep(&cp, "x,y"), "b", 66);
851   equal(strsep(&cp, ",xy"), " c", 67);  /* Permute list too. */
852   equal(strsep(&cp, "xy,"), "", 68);
853   equal(strsep(&cp, "x,y"), " ", 69);
854   equal(strsep(&cp, ",xy"), "d", 70);
855   equal(strsep(&cp, "xy,"), "", 71);
856   check(strsep(&cp, "x,y") == NULL, 72);
857   check(strsep(&cp, ",xy") == NULL, 73);        /* Persistence. */
858 }
859
860 void
861 test_memcmp (void)
862 {
863   it = "memcmp";
864   check(memcmp("a", "a", 1) == 0, 1);           /* Identity. */
865   check(memcmp("abc", "abc", 3) == 0, 2);       /* Multicharacter. */
866   check(memcmp("abcd", "abce", 4) < 0, 3);      /* Honestly unequal. */
867   check(memcmp("abce", "abcd", 4) > 0, 4);
868   check(memcmp("alph", "beta", 4) < 0, 5);
869   check(memcmp("a\203", "a\003", 2) > 0, 6);
870   check(memcmp("abce", "abcd", 3) == 0, 7);     /* Count limited. */
871   check(memcmp("abc", "def", 0) == 0, 8);       /* Zero count. */
872 }
873
874 void
875 test_memchr (void)
876 {
877   it = "memchr";
878   check(memchr("abcd", 'z', 4) == NULL, 1);     /* Not found. */
879   (void) strcpy(one, "abcd");
880   check(memchr(one, 'c', 4) == one+2, 2);       /* Basic test. */
881   check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
882   check(memchr(one, 'd', 4) == one+3, 3);       /* End of string. */
883   check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
884   check(memchr(one, '\0', 5) == one+4, 5);      /* Finding NUL. */
885   (void) strcpy(one, "ababa");
886   check(memchr(one, 'b', 5) == one+1, 6);       /* Finding first. */
887   check(memchr(one, 'b', 0) == NULL, 7);        /* Zero count. */
888   check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
889   (void) strcpy(one, "a\203b");
890   check(memchr(one, 0203, 3) == one+1, 9);      /* Unsignedness. */
891
892   /* now test all possible alignment and length combinations to catch
893      bugs due to unrolled loops (assuming unrolling is limited to no
894      more than 128 byte chunks: */
895   {
896     char buf[128 + sizeof(long)];
897     long align, len, i, pos;
898
899     for (align = 0; align < (long) sizeof(long); ++align) {
900       for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
901         for (i = 0; i < len; ++i) {
902           buf[align + i] = 'x';         /* don't depend on memset... */
903         }
904         for (pos = 0; pos < len; ++pos) {
905 #if 0
906           printf("align %d, len %d, pos %d\n", align, len, pos);
907 #endif
908           check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
909           check(memchr(buf + align, 'x', pos) == NULL, 11);
910           buf[align + pos] = '-';
911         }
912       }
913     }
914   }
915 }
916
917 void
918 test_memcpy (void)
919 {
920   it = "memcpy";
921   check(memcpy(one, "abc", 4) == one, 1);       /* Returned value. */
922   equal(one, "abc", 2);                 /* Did the copy go right? */
923
924   (void) strcpy(one, "abcdefgh");
925   (void) memcpy(one+1, "xyz", 2);
926   equal(one, "axydefgh", 3);            /* Basic test. */
927
928   (void) strcpy(one, "abc");
929   (void) memcpy(one, "xyz", 0);
930   equal(one, "abc", 4);                 /* Zero-length copy. */
931
932   (void) strcpy(one, "hi there");
933   (void) strcpy(two, "foo");
934   (void) memcpy(two, one, 9);
935   equal(two, "hi there", 5);            /* Just paranoia. */
936   equal(one, "hi there", 6);            /* Stomped on source? */
937 }
938
939 void
940 test_memmove (void)
941 {
942   it = "memmove";
943   check(memmove(one, "abc", 4) == one, 1);      /* Returned value. */
944   equal(one, "abc", 2);                 /* Did the copy go right? */
945
946   (void) strcpy(one, "abcdefgh");
947   (void) memmove(one+1, "xyz", 2);
948   equal(one, "axydefgh", 3);            /* Basic test. */
949
950   (void) strcpy(one, "abc");
951   (void) memmove(one, "xyz", 0);
952   equal(one, "abc", 4);                 /* Zero-length copy. */
953
954   (void) strcpy(one, "hi there");
955   (void) strcpy(two, "foo");
956   (void) memmove(two, one, 9);
957   equal(two, "hi there", 5);            /* Just paranoia. */
958   equal(one, "hi there", 6);            /* Stomped on source? */
959
960   (void) strcpy(one, "abcdefgh");
961   (void) memmove(one+1, one, 9);
962   equal(one, "aabcdefgh", 7);           /* Overlap, right-to-left. */
963
964   (void) strcpy(one, "abcdefgh");
965   (void) memmove(one+1, one+2, 7);
966   equal(one, "acdefgh", 8);             /* Overlap, left-to-right. */
967
968   (void) strcpy(one, "abcdefgh");
969   (void) memmove(one, one, 9);
970   equal(one, "abcdefgh", 9);            /* 100% overlap. */
971 }
972
973 void
974 test_memccpy (void)
975 {
976   /* First test like memcpy, then the search part The SVID, the only
977      place where memccpy is mentioned, says overlap might fail, so we
978      don't try it.  Besides, it's hard to see the rationale for a
979      non-left-to-right memccpy.  */
980   it = "memccpy";
981   check(memccpy(one, "abc", 'q', 4) == NULL, 1);        /* Returned value. */
982   equal(one, "abc", 2);                 /* Did the copy go right? */
983
984   (void) strcpy(one, "abcdefgh");
985   (void) memccpy(one+1, "xyz", 'q', 2);
986   equal(one, "axydefgh", 3);            /* Basic test. */
987
988   (void) strcpy(one, "abc");
989   (void) memccpy(one, "xyz", 'q', 0);
990   equal(one, "abc", 4);                 /* Zero-length copy. */
991
992   (void) strcpy(one, "hi there");
993   (void) strcpy(two, "foo");
994   (void) memccpy(two, one, 'q', 9);
995   equal(two, "hi there", 5);            /* Just paranoia. */
996   equal(one, "hi there", 6);            /* Stomped on source? */
997
998   (void) strcpy(one, "abcdefgh");
999   (void) strcpy(two, "horsefeathers");
1000   check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
1001   equal(one, "abcdefgh", 8);            /* Source intact? */
1002   equal(two, "abcdefeathers", 9);               /* Copy correct? */
1003
1004   (void) strcpy(one, "abcd");
1005   (void) strcpy(two, "bumblebee");
1006   check(memccpy(two, one, 'a', 4) == two+1, 10);        /* First char. */
1007   equal(two, "aumblebee", 11);
1008   check(memccpy(two, one, 'd', 4) == two+4, 12);        /* Last char. */
1009   equal(two, "abcdlebee", 13);
1010   (void) strcpy(one, "xyz");
1011   check(memccpy(two, one, 'x', 1) == two+1, 14);        /* Singleton. */
1012   equal(two, "xbcdlebee", 15);
1013 }
1014
1015 void
1016 test_memset (void)
1017 {
1018   int i;
1019
1020   it = "memset";
1021   (void) strcpy(one, "abcdefgh");
1022   check(memset(one+1, 'x', 3) == one+1, 1);     /* Return value. */
1023   equal(one, "axxxefgh", 2);            /* Basic test. */
1024
1025   (void) memset(one+2, 'y', 0);
1026   equal(one, "axxxefgh", 3);            /* Zero-length set. */
1027
1028   (void) memset(one+5, 0, 1);
1029   equal(one, "axxxe", 4);                       /* Zero fill. */
1030   equal(one+6, "gh", 5);                        /* And the leftover. */
1031
1032   (void) memset(one+2, 010045, 1);
1033   equal(one, "ax\045xe", 6);            /* Unsigned char convert. */
1034
1035   /* Non-8bit fill character.  */
1036   memset (one, 0x101, sizeof (one));
1037   for (i = 0; i < sizeof (one); ++i)
1038     check (one[i] == '\01', 7);
1039
1040   /* Test for more complex versions of memset, for all alignments and
1041      lengths up to 256. This test takes a little while, perhaps it should
1042      be made weaker?  */
1043   {
1044     char data[512];
1045     int j;
1046     int k;
1047     int c;
1048
1049     for (i = 0; i < 512; i++)
1050       data[i] = 'x';
1051     for (c = 0; c <= 'y'; c += 'y')  /* check for memset(,0,) and
1052                                         memset(,'y',) */
1053       for (j = 0; j < 256; j++)
1054         for (i = 0; i < 256; i++)
1055           {
1056             memset (data + i, c, j);
1057             for (k = 0; k < i; k++)
1058               if (data[k] != 'x')
1059                 goto fail;
1060             for (k = i; k < i+j; k++)
1061               {
1062                 if (data[k] != c)
1063                   goto fail;
1064                 data[k] = 'x';
1065               }
1066             for (k = i+j; k < 512; k++)
1067               if (data[k] != 'x')
1068                 goto fail;
1069             continue;
1070
1071           fail:
1072             check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
1073           }
1074   }
1075 }
1076
1077 void
1078 test_bcopy (void)
1079 {
1080   /* Much like memcpy.  Berklix manual is silent about overlap, so
1081      don't test it.  */
1082   it = "bcopy";
1083   (void) bcopy("abc", one, 4);
1084   equal(one, "abc", 1);                 /* Simple copy. */
1085
1086   (void) strcpy(one, "abcdefgh");
1087   (void) bcopy("xyz", one+1, 2);
1088   equal(one, "axydefgh", 2);            /* Basic test. */
1089
1090   (void) strcpy(one, "abc");
1091   (void) bcopy("xyz", one, 0);
1092   equal(one, "abc", 3);                 /* Zero-length copy. */
1093
1094   (void) strcpy(one, "hi there");
1095   (void) strcpy(two, "foo");
1096   (void) bcopy(one, two, 9);
1097   equal(two, "hi there", 4);            /* Just paranoia. */
1098   equal(one, "hi there", 5);            /* Stomped on source? */
1099 }
1100
1101 void
1102 test_bzero (void)
1103 {
1104   it = "bzero";
1105   (void) strcpy(one, "abcdef");
1106   bzero(one+2, 2);
1107   equal(one, "ab", 1);                  /* Basic test. */
1108   equal(one+3, "", 2);
1109   equal(one+4, "ef", 3);
1110
1111   (void) strcpy(one, "abcdef");
1112   bzero(one+2, 0);
1113   equal(one, "abcdef", 4);              /* Zero-length copy. */
1114 }
1115
1116 void
1117 test_bcmp (void)
1118 {
1119   it = "bcmp";
1120   check(bcmp("a", "a", 1) == 0, 1);     /* Identity. */
1121   check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1122   check(bcmp("abcd", "abce", 4) != 0, 3);       /* Honestly unequal. */
1123   check(bcmp("abce", "abcd", 4) != 0, 4);
1124   check(bcmp("alph", "beta", 4) != 0, 5);
1125   check(bcmp("abce", "abcd", 3) == 0, 6);       /* Count limited. */
1126   check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1127 }
1128
1129 void
1130 test_strerror (void)
1131 {
1132   int f;
1133   it = "strerror";
1134   f = __open("/", O_WRONLY);    /* Should always fail. */
1135   check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
1136   equal(strerror(errno), _sys_errlist[errno], 2);
1137 }
1138
1139 int
1140 main (void)
1141 {
1142   int status;
1143
1144   /* Test strcmp first because we use it to test other things.  */
1145   test_strcmp ();
1146
1147   /* Test strcpy next because we need it to set up other tests.  */
1148   test_strcpy ();
1149
1150   /* A closely related function is stpcpy.  */
1151   test_stpcpy ();
1152
1153   /* stpncpy.  */
1154   test_stpncpy ();
1155
1156   /* strcat.  */
1157   test_strcat ();
1158
1159   /* strncat.  */
1160   test_strncat ();
1161
1162   /* strncmp.  */
1163   test_strncmp ();
1164
1165   /* strncpy.  */
1166   test_strncpy ();
1167
1168   /* strlen.  */
1169   test_strlen ();
1170
1171   /* strchr.  */
1172   test_strchr ();
1173
1174   /* strchrnul.  */
1175   test_strchrnul ();
1176
1177   /* rawmemchr.  */
1178   test_rawmemchr ();
1179
1180   /* index - just like strchr.  */
1181   test_index ();
1182
1183   /* strrchr.  */
1184   test_strrchr ();
1185
1186   /* rindex - just like strrchr.  */
1187   test_rindex ();
1188
1189   /* strpbrk - somewhat like strchr.  */
1190   test_strpbrk ();
1191
1192   /* strstr - somewhat like strchr.  */
1193   test_strstr ();
1194
1195   /* strspn.  */
1196   test_strspn ();
1197
1198   /* strcspn.  */
1199   test_strcspn ();
1200
1201   /* strtok - the hard one.  */
1202   test_strtok ();
1203
1204   /* strtok_r.  */
1205   test_strtok_r ();
1206
1207   /* strsep.  */
1208   test_strsep ();
1209
1210   /* memcmp.  */
1211   test_memcmp ();
1212
1213   /* memchr.  */
1214   test_memchr ();
1215
1216   /* memcpy - need not work for overlap.  */
1217   test_memcpy ();
1218
1219   /* memmove - must work on overlap.  */
1220   test_memmove ();
1221
1222   /* memccpy.  */
1223   test_memccpy ();
1224
1225   /* memset.  */
1226   test_memset ();
1227
1228   /* bcopy.  */
1229   test_bcopy ();
1230
1231   /* bzero.  */
1232   test_bzero ();
1233
1234   /* bcmp - somewhat like memcmp.  */
1235   test_bcmp ();
1236
1237   /* strerror - VERY system-dependent.  */
1238   test_strerror ();
1239
1240
1241   if (errors == 0)
1242     {
1243       status = EXIT_SUCCESS;
1244       puts("No errors.");
1245     }
1246   else
1247     {
1248       status = EXIT_FAILURE;
1249       printf("%Zd errors.\n", errors);
1250     }
1251   exit(status);
1252 }