Formerly ../string/tester.c.~5~
[kopensolaris-gnu/glibc.git] / string / tester.c
1 #include <ansidecl.h>
2 #include <errno.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <strings.h>
7 #include <fcntl.h>
8
9 #ifndef HAVE_GNU_LD
10 #define _sys_nerr       sys_nerr
11 #define _sys_errlist    sys_errlist
12 #endif
13
14 #define STREQ(a, b)     (strcmp((a), (b)) == 0)
15
16 CONST char *it = "<UNSET>";     /* Routine name for message routines. */
17 size_t errors = 0;
18
19 /* Complain if condition is not true.  */
20 void
21 DEFUN(check, (thing, number), int thing AND int number)
22 {
23   if (!thing)
24     {
25       printf("%s flunked test %d\n", it, number);
26       ++errors;
27     }
28 }
29
30 /* Complain if first two args don't strcmp as equal.  */
31 void
32 DEFUN(equal, (a, b, number), CONST char *a AND CONST char *b AND int number)
33 {
34   check(a != NULL && b != NULL && STREQ(a, b), number);
35 }
36
37 char one[50];
38 char two[50];
39
40 int
41 DEFUN(main, (argc, argv), int argc AND char **argv)
42 {
43   /* Test strcmp first because we use it to test other things.  */
44   it = "strcmp";
45   check(strcmp("", "") == 0, 1);                /* Trivial case. */
46   check(strcmp("a", "a") == 0, 2);              /* Identity. */
47   check(strcmp("abc", "abc") == 0, 3);          /* Multicharacter. */
48   check(strcmp("abc", "abcd") < 0, 4);          /* Length mismatches. */
49   check(strcmp("abcd", "abc") > 0, 5);
50   check(strcmp("abcd", "abce") < 0, 6);         /* Honest miscompares. */
51   check(strcmp("abce", "abcd") > 0, 7);
52   check(strcmp("a\203", "a") > 0, 8);           /* Tricky if char signed. */
53   check(strcmp("a\203", "a\003") > 0, 9);
54
55   /* Test strcpy next because we need it to set up other tests.  */
56   it = "strcpy";
57   check(strcpy(one, "abcd") == one, 1); /* Returned value. */
58   equal(one, "abcd", 2);                /* Basic test. */
59
60   (void) strcpy(one, "x");
61   equal(one, "x", 3);                   /* Writeover. */
62   equal(one+2, "cd", 4);                /* Wrote too much? */
63
64   (void) strcpy(two, "hi there");
65   (void) strcpy(one, two);
66   equal(one, "hi there", 5);            /* Basic test encore. */
67   equal(two, "hi there", 6);            /* Stomped on source? */
68
69   (void) strcpy(one, "");
70   equal(one, "", 7);                    /* Boundary condition. */
71
72   /* strcat.  */
73   it = "strcat";
74   (void) strcpy(one, "ijk");
75   check(strcat(one, "lmn") == one, 1);  /* Returned value. */
76   equal(one, "ijklmn", 2);              /* Basic test. */
77
78   (void) strcpy(one, "x");
79   (void) strcat(one, "yz");
80   equal(one, "xyz", 3);                 /* Writeover. */
81   equal(one+4, "mn", 4);                        /* Wrote too much? */
82
83   (void) strcpy(one, "gh");
84   (void) strcpy(two, "ef");
85   (void) strcat(one, two);
86   equal(one, "ghef", 5);                        /* Basic test encore. */
87   equal(two, "ef", 6);                  /* Stomped on source? */
88
89   (void) strcpy(one, "");
90   (void) strcat(one, "");
91   equal(one, "", 7);                    /* Boundary conditions. */
92   (void) strcpy(one, "ab");
93   (void) strcat(one, "");
94   equal(one, "ab", 8);
95   (void) strcpy(one, "");
96   (void) strcat(one, "cd");
97   equal(one, "cd", 9);
98
99   /* strncat - first test it as strcat, with big counts,
100      then test the count mechanism.  */
101   it = "strncat";
102   (void) strcpy(one, "ijk");
103   check(strncat(one, "lmn", 99) == one, 1);     /* Returned value. */
104   equal(one, "ijklmn", 2);              /* Basic test. */
105
106   (void) strcpy(one, "x");
107   (void) strncat(one, "yz", 99);
108   equal(one, "xyz", 3);                 /* Writeover. */
109   equal(one+4, "mn", 4);                        /* Wrote too much? */
110
111   (void) strcpy(one, "gh");
112   (void) strcpy(two, "ef");
113   (void) strncat(one, two, 99);
114   equal(one, "ghef", 5);                        /* Basic test encore. */
115   equal(two, "ef", 6);                  /* Stomped on source? */
116
117   (void) strcpy(one, "");
118   (void) strncat(one, "", 99);
119   equal(one, "", 7);                    /* Boundary conditions. */
120   (void) strcpy(one, "ab");
121   (void) strncat(one, "", 99);
122   equal(one, "ab", 8);
123   (void) strcpy(one, "");
124   (void) strncat(one, "cd", 99);
125   equal(one, "cd", 9);
126
127   (void) strcpy(one, "ab");
128   (void) strncat(one, "cdef", 2);
129   equal(one, "abcd", 10);                       /* Count-limited. */
130
131   (void) strncat(one, "gh", 0);
132   equal(one, "abcd", 11);                       /* Zero count. */
133
134   (void) strncat(one, "gh", 2);
135   equal(one, "abcdgh", 12);             /* Count and length equal. */
136
137   /* strncmp - first test as strcmp with big counts,
138      then test count code.  */
139   it = "strncmp";
140   check(strncmp("", "", 99) == 0, 1);   /* Trivial case. */
141   check(strncmp("a", "a", 99) == 0, 2); /* Identity. */
142   check(strncmp("abc", "abc", 99) == 0, 3);     /* Multicharacter. */
143   check(strncmp("abc", "abcd", 99) < 0, 4);     /* Length unequal. */
144   check(strncmp("abcd", "abc", 99) > 0, 5);
145   check(strncmp("abcd", "abce", 99) < 0, 6);    /* Honestly unequal. */
146   check(strncmp("abce", "abcd", 99) > 0, 7);
147   check(strncmp("a\203", "a", 2) > 0, 8);       /* Tricky if '\203' < 0 */
148   check(strncmp("a\203", "a\003", 2) > 0, 9);
149   check(strncmp("abce", "abcd", 3) == 0, 10);   /* Count limited. */
150   check(strncmp("abce", "abc", 3) == 0, 11);    /* Count == length. */
151   check(strncmp("abcd", "abce", 4) < 0, 12);    /* Nudging limit. */
152   check(strncmp("abc", "def", 0) == 0, 13);     /* Zero count. */
153
154   /* strncpy - testing is a bit different because of odd semantics.  */
155   it = "strncpy";
156   check(strncpy(one, "abc", 4) == one, 1);      /* Returned value. */
157   equal(one, "abc", 2);                 /* Did the copy go right? */
158
159   (void) strcpy(one, "abcdefgh");
160   (void) strncpy(one, "xyz", 2);
161   equal(one, "xycdefgh", 3);            /* Copy cut by count. */
162
163   (void) strcpy(one, "abcdefgh");
164   (void) strncpy(one, "xyz", 3);                /* Copy cut just before NUL. */
165   equal(one, "xyzdefgh", 4);
166
167   (void) strcpy(one, "abcdefgh");
168   (void) strncpy(one, "xyz", 4);                /* Copy just includes NUL. */
169   equal(one, "xyz", 5);
170   equal(one+4, "efgh", 6);              /* Wrote too much? */
171
172   (void) strcpy(one, "abcdefgh");
173   (void) strncpy(one, "xyz", 5);                /* Copy includes padding. */
174   equal(one, "xyz", 7);
175   equal(one+4, "", 8);
176   equal(one+5, "fgh", 9);
177
178   (void) strcpy(one, "abc");
179   (void) strncpy(one, "xyz", 0);                /* Zero-length copy. */
180   equal(one, "abc", 10);        
181
182   (void) strncpy(one, "", 2);           /* Zero-length source. */
183   equal(one, "", 11);
184   equal(one+1, "", 12); 
185   equal(one+2, "c", 13);
186
187   (void) strcpy(one, "hi there");
188   (void) strncpy(two, one, 9);
189   equal(two, "hi there", 14);           /* Just paranoia. */
190   equal(one, "hi there", 15);           /* Stomped on source? */
191
192   /* strlen.  */
193   it = "strlen";
194   check(strlen("") == 0, 1);            /* Empty. */
195   check(strlen("a") == 1, 2);           /* Single char. */
196   check(strlen("abcd") == 4, 3);                /* Multiple chars. */
197
198   /* strchr.  */
199   it = "strchr";
200   check(strchr("abcd", 'z') == NULL, 1);        /* Not found. */
201   (void) strcpy(one, "abcd");
202   check(strchr(one, 'c') == one+2, 2);  /* Basic test. */
203   check(strchr(one, 'd') == one+3, 3);  /* End of string. */
204   check(strchr(one, 'a') == one, 4);    /* Beginning. */
205   check(strchr(one, '\0') == one+4, 5); /* Finding NUL. */
206   (void) strcpy(one, "ababa");
207   check(strchr(one, 'b') == one+1, 6);  /* Finding first. */
208   (void) strcpy(one, "");
209   check(strchr(one, 'b') == NULL, 7);   /* Empty string. */
210   check(strchr(one, '\0') == one, 8);   /* NUL in empty string. */
211
212   /* index - just like strchr.  */
213   it = "index";
214   check(index("abcd", 'z') == NULL, 1); /* Not found. */
215   (void) strcpy(one, "abcd");
216   check(index(one, 'c') == one+2, 2);   /* Basic test. */
217   check(index(one, 'd') == one+3, 3);   /* End of string. */
218   check(index(one, 'a') == one, 4);     /* Beginning. */
219   check(index(one, '\0') == one+4, 5);  /* Finding NUL. */
220   (void) strcpy(one, "ababa");
221   check(index(one, 'b') == one+1, 6);   /* Finding first. */
222   (void) strcpy(one, "");
223   check(index(one, 'b') == NULL, 7);    /* Empty string. */
224   check(index(one, '\0') == one, 8);    /* NUL in empty string. */
225
226   /* strrchr.  */
227   it = "strrchr";
228   check(strrchr("abcd", 'z') == NULL, 1);       /* Not found. */
229   (void) strcpy(one, "abcd");
230   check(strrchr(one, 'c') == one+2, 2); /* Basic test. */
231   check(strrchr(one, 'd') == one+3, 3); /* End of string. */
232   check(strrchr(one, 'a') == one, 4);   /* Beginning. */
233   check(strrchr(one, '\0') == one+4, 5);        /* Finding NUL. */
234   (void) strcpy(one, "ababa");
235   check(strrchr(one, 'b') == one+3, 6); /* Finding last. */
236   (void) strcpy(one, "");
237   check(strrchr(one, 'b') == NULL, 7);  /* Empty string. */
238   check(strrchr(one, '\0') == one, 8);  /* NUL in empty string. */
239
240   /* rindex - just like strrchr.  */
241   it = "rindex";
242   check(rindex("abcd", 'z') == NULL, 1);        /* Not found. */
243   (void) strcpy(one, "abcd");
244   check(rindex(one, 'c') == one+2, 2);  /* Basic test. */
245   check(rindex(one, 'd') == one+3, 3);  /* End of string. */
246   check(rindex(one, 'a') == one, 4);    /* Beginning. */
247   check(rindex(one, '\0') == one+4, 5); /* Finding NUL. */
248   (void) strcpy(one, "ababa");
249   check(rindex(one, 'b') == one+3, 6);  /* Finding last. */
250   (void) strcpy(one, "");
251   check(rindex(one, 'b') == NULL, 7);   /* Empty string. */
252   check(rindex(one, '\0') == one, 8);   /* NUL in empty string. */
253
254   /* strpbrk - somewhat like strchr.  */
255   it = "strpbrk";
256   check(strpbrk("abcd", "z") == NULL, 1);       /* Not found. */
257   (void) strcpy(one, "abcd");
258   check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
259   check(strpbrk(one, "d") == one+3, 3); /* End of string. */
260   check(strpbrk(one, "a") == one, 4);   /* Beginning. */
261   check(strpbrk(one, "") == NULL, 5);   /* Empty search list. */
262   check(strpbrk(one, "cb") == one+1, 6);        /* Multiple search. */
263   (void) strcpy(one, "abcabdea");
264   check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
265   check(strpbrk(one, "cb") == one+1, 8);        /* With multiple search. */
266   check(strpbrk(one, "db") == one+1, 9);        /* Another variant. */
267   (void) strcpy(one, "");
268   check(strpbrk(one, "bc") == NULL, 10);        /* Empty string. */
269   check(strpbrk(one, "") == NULL, 11);  /* Both strings empty. */
270
271   /* strstr - somewhat like strchr.  */
272   it = "strstr";
273   check(strstr("abcd", "z") == NULL, 1);        /* Not found. */
274   check(strstr("abcd", "abx") == NULL, 2);      /* Dead end. */
275   (void) strcpy(one, "abcd");
276   check(strstr(one, "c") == one+2, 3);  /* Basic test. */
277   check(strstr(one, "bc") == one+1, 4); /* Multichar. */
278   check(strstr(one, "d") == one+3, 5);  /* End of string. */
279   check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
280   check(strstr(one, "abc") == one, 7);  /* Beginning. */
281   check(strstr(one, "abcd") == one, 8); /* Exact match. */
282   check(strstr(one, "abcde") == NULL, 9);       /* Too long. */
283   check(strstr(one, "de") == NULL, 10); /* Past end. */
284   check(strstr(one, "") == one+4, 11);  /* Finding empty. */
285   (void) strcpy(one, "ababa");
286   check(strstr(one, "ba") == one+1, 12);        /* Finding first. */
287   (void) strcpy(one, "");
288   check(strstr(one, "b") == NULL, 13);  /* Empty string. */
289   check(strstr(one, "") == one, 14);    /* Empty in empty string. */
290   (void) strcpy(one, "bcbca");
291   check(strstr(one, "bca") == one+2, 15);       /* False start. */
292   (void) strcpy(one, "bbbcabbca");
293   check(strstr(one, "bbca") == one+1, 16);      /* With overlap. */
294
295   /* strspn.  */
296   it = "strspn";
297   check(strspn("abcba", "abc") == 5, 1);        /* Whole string. */
298   check(strspn("abcba", "ab") == 2, 2); /* Partial. */
299   check(strspn("abc", "qx") == 0, 3);   /* None. */
300   check(strspn("", "ab") == 0, 4);      /* Null string. */
301   check(strspn("abc", "") == 0, 5);     /* Null search list. */
302
303   /* strcspn.  */
304   it = "strcspn";
305   check(strcspn("abcba", "qx") == 5, 1);        /* Whole string. */
306   check(strcspn("abcba", "cx") == 2, 2);        /* Partial. */
307   check(strcspn("abc", "abc") == 0, 3); /* None. */
308   check(strcspn("", "ab") == 0, 4);     /* Null string. */
309   check(strcspn("abc", "") == 3, 5);    /* Null search list. */
310
311   /* strtok - the hard one.  */
312   it = "strtok";
313   (void) strcpy(one, "first, second, third");
314   equal(strtok(one, ", "), "first", 1); /* Basic test. */
315   equal(one, "first", 2);
316   equal(strtok((char *)NULL, ", "), "second", 3);
317   equal(strtok((char *)NULL, ", "), "third", 4);
318   check(strtok((char *)NULL, ", ") == NULL, 5);
319   (void) strcpy(one, ", first, ");
320   equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
321   check(strtok((char *)NULL, ", ") == NULL, 7);
322   (void) strcpy(one, "1a, 1b; 2a, 2b");
323   equal(strtok(one, ", "), "1a", 8);    /* Changing delim lists. */
324   equal(strtok((char *)NULL, "; "), "1b", 9);
325   equal(strtok((char *)NULL, ", "), "2a", 10);
326   (void) strcpy(two, "x-y");
327   equal(strtok(two, "-"), "x", 11);     /* New string before done. */
328   equal(strtok((char *)NULL, "-"), "y", 12);
329   check(strtok((char *)NULL, "-") == NULL, 13);
330   (void) strcpy(one, "a,b, c,, ,d");
331   equal(strtok(one, ", "), "a", 14);    /* Different separators. */
332   equal(strtok((char *)NULL, ", "), "b", 15);
333   equal(strtok((char *)NULL, " ,"), "c", 16);   /* Permute list too. */
334   equal(strtok((char *)NULL, " ,"), "d", 17);
335   check(strtok((char *)NULL, ", ") == NULL, 18);
336   check(strtok((char *)NULL, ", ") == NULL, 19);        /* Persistence. */
337   (void) strcpy(one, ", ");
338   check(strtok(one, ", ") == NULL, 20); /* No tokens. */
339   (void) strcpy(one, "");
340   check(strtok(one, ", ") == NULL, 21); /* Empty string. */
341   (void) strcpy(one, "abc");
342   equal(strtok(one, ", "), "abc", 22);  /* No delimiters. */
343   check(strtok((char *)NULL, ", ") == NULL, 23);
344   (void) strcpy(one, "abc");
345   equal(strtok(one, ""), "abc", 24);    /* Empty delimiter list. */
346   check(strtok((char *)NULL, "") == NULL, 25);
347   (void) strcpy(one, "abcdefgh");
348   (void) strcpy(one, "a,b,c");
349   equal(strtok(one, ","), "a", 26);     /* Basics again... */
350   equal(strtok((char *)NULL, ","), "b", 27);
351   equal(strtok((char *)NULL, ","), "c", 28);
352   check(strtok((char *)NULL, ",") == NULL, 29);
353   equal(one+6, "gh", 30);                       /* Stomped past end? */
354   equal(one, "a", 31);                  /* Stomped old tokens? */
355   equal(one+2, "b", 32);
356   equal(one+4, "c", 33);
357
358   /* memcmp.  */
359   it = "memcmp";
360   check(memcmp("a", "a", 1) == 0, 1);   /* Identity. */
361   check(memcmp("abc", "abc", 3) == 0, 2);       /* Multicharacter. */
362   check(memcmp("abcd", "abce", 4) < 0, 3);      /* Honestly unequal. */
363   check(memcmp("abce", "abcd", 4) > 0, 4);
364   check(memcmp("alph", "beta", 4) < 0, 5);
365   check(memcmp("a\203", "a\003", 2) > 0, 6);
366   check(memcmp("abce", "abcd", 3) == 0, 7);     /* Count limited. */
367   check(memcmp("abc", "def", 0) == 0, 8);       /* Zero count. */
368
369   /* memchr.  */
370   it = "memchr";
371   check(memchr("abcd", 'z', 4) == NULL, 1);     /* Not found. */
372   (void) strcpy(one, "abcd");
373   check(memchr(one, 'c', 4) == one+2, 2);       /* Basic test. */
374   check(memchr(one, 'd', 4) == one+3, 3);       /* End of string. */
375   check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
376   check(memchr(one, '\0', 5) == one+4, 5);      /* Finding NUL. */
377   (void) strcpy(one, "ababa");
378   check(memchr(one, 'b', 5) == one+1, 6);       /* Finding first. */
379   check(memchr(one, 'b', 0) == NULL, 7);        /* Zero count. */
380   check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
381   (void) strcpy(one, "a\203b");
382   check(memchr(one, 0203, 3) == one+1, 9);      /* Unsignedness. */
383
384   /* memcpy - need not work for overlap.  */
385   it = "memcpy";
386   check(memcpy(one, "abc", 4) == one, 1);       /* Returned value. */
387   equal(one, "abc", 2);                 /* Did the copy go right? */
388
389   (void) strcpy(one, "abcdefgh");
390   (void) memcpy(one+1, "xyz", 2);
391   equal(one, "axydefgh", 3);            /* Basic test. */
392
393   (void) strcpy(one, "abc");
394   (void) memcpy(one, "xyz", 0);
395   equal(one, "abc", 4);                 /* Zero-length copy. */
396
397   (void) strcpy(one, "hi there");
398   (void) strcpy(two, "foo");
399   (void) memcpy(two, one, 9);
400   equal(two, "hi there", 5);            /* Just paranoia. */
401   equal(one, "hi there", 6);            /* Stomped on source? */
402
403   /* memmove - must work on overlap.  */
404   it = "memmove";
405   check(memmove(one, "abc", 4) == one, 1);      /* Returned value. */
406   equal(one, "abc", 2);                 /* Did the copy go right? */
407
408   (void) strcpy(one, "abcdefgh");
409   (void) memmove(one+1, "xyz", 2);
410   equal(one, "axydefgh", 3);            /* Basic test. */
411
412   (void) strcpy(one, "abc");
413   (void) memmove(one, "xyz", 0);
414   equal(one, "abc", 4);                 /* Zero-length copy. */
415
416   (void) strcpy(one, "hi there");
417   (void) strcpy(two, "foo");
418   (void) memmove(two, one, 9);
419   equal(two, "hi there", 5);            /* Just paranoia. */
420   equal(one, "hi there", 6);            /* Stomped on source? */
421
422   (void) strcpy(one, "abcdefgh");
423   (void) memmove(one+1, one, 9);
424   equal(one, "aabcdefgh", 7);           /* Overlap, right-to-left. */
425
426   (void) strcpy(one, "abcdefgh");
427   (void) memmove(one+1, one+2, 7);
428   equal(one, "acdefgh", 8);             /* Overlap, left-to-right. */
429
430   (void) strcpy(one, "abcdefgh");
431   (void) memmove(one, one, 9);
432   equal(one, "abcdefgh", 9);            /* 100% overlap. */
433
434   /* memccpy - first test like memcpy, then the search part
435      The SVID, the only place where memccpy is mentioned, says
436      overlap might fail, so we don't try it.  Besides, it's hard
437      to see the rationale for a non-left-to-right memccpy.  */
438   it = "memccpy";
439   check(memccpy(one, "abc", 'q', 4) == NULL, 1);        /* Returned value. */
440   equal(one, "abc", 2);                 /* Did the copy go right? */
441
442   (void) strcpy(one, "abcdefgh");
443   (void) memccpy(one+1, "xyz", 'q', 2);
444   equal(one, "axydefgh", 3);            /* Basic test. */
445
446   (void) strcpy(one, "abc");
447   (void) memccpy(one, "xyz", 'q', 0);
448   equal(one, "abc", 4);                 /* Zero-length copy. */
449
450   (void) strcpy(one, "hi there");
451   (void) strcpy(two, "foo");
452   (void) memccpy(two, one, 'q', 9);
453   equal(two, "hi there", 5);            /* Just paranoia. */
454   equal(one, "hi there", 6);            /* Stomped on source? */
455
456   (void) strcpy(one, "abcdefgh");
457   (void) strcpy(two, "horsefeathers");
458   check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
459   equal(one, "abcdefgh", 8);            /* Source intact? */
460   equal(two, "abcdefeathers", 9);               /* Copy correct? */
461
462   (void) strcpy(one, "abcd");
463   (void) strcpy(two, "bumblebee");
464   check(memccpy(two, one, 'a', 4) == two+1, 10);        /* First char. */
465   equal(two, "aumblebee", 11);
466   check(memccpy(two, one, 'd', 4) == two+4, 12);        /* Last char. */
467   equal(two, "abcdlebee", 13);
468   (void) strcpy(one, "xyz");
469   check(memccpy(two, one, 'x', 1) == two+1, 14);        /* Singleton. */
470   equal(two, "xbcdlebee", 15);
471
472   /* memset.  */
473   it = "memset";
474   (void) strcpy(one, "abcdefgh");
475   check(memset(one+1, 'x', 3) == one+1, 1);     /* Return value. */
476   equal(one, "axxxefgh", 2);            /* Basic test. */
477
478   (void) memset(one+2, 'y', 0);
479   equal(one, "axxxefgh", 3);            /* Zero-length set. */
480
481   (void) memset(one+5, 0, 1);
482   equal(one, "axxxe", 4);                       /* Zero fill. */
483   equal(one+6, "gh", 5);                        /* And the leftover. */
484
485   (void) memset(one+2, 010045, 1);
486   equal(one, "ax\045xe", 6);            /* Unsigned char convert. */
487
488   /* bcopy - much like memcpy.
489      Berklix manual is silent about overlap, so don't test it.  */
490   it = "bcopy";
491   (void) bcopy("abc", one, 4);
492   equal(one, "abc", 1);                 /* Simple copy. */
493
494   (void) strcpy(one, "abcdefgh");
495   (void) bcopy("xyz", one+1, 2);
496   equal(one, "axydefgh", 2);            /* Basic test. */
497
498   (void) strcpy(one, "abc");
499   (void) bcopy("xyz", one, 0);
500   equal(one, "abc", 3);                 /* Zero-length copy. */
501
502   (void) strcpy(one, "hi there");
503   (void) strcpy(two, "foo");
504   (void) bcopy(one, two, 9);
505   equal(two, "hi there", 4);            /* Just paranoia. */
506   equal(one, "hi there", 5);            /* Stomped on source? */
507
508   /* bzero.  */
509   it = "bzero";
510   (void) strcpy(one, "abcdef");
511   bzero(one+2, 2);
512   equal(one, "ab", 1);                  /* Basic test. */
513   equal(one+3, "", 2);
514   equal(one+4, "ef", 3);
515
516   (void) strcpy(one, "abcdef");
517   bzero(one+2, 0);
518   equal(one, "abcdef", 4);              /* Zero-length copy. */
519
520   /* bcmp - somewhat like memcmp.  */
521   it = "bcmp";
522   check(bcmp("a", "a", 1) == 0, 1);     /* Identity. */
523   check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
524   check(bcmp("abcd", "abce", 4) != 0, 3);       /* Honestly unequal. */
525   check(bcmp("abce", "abcd", 4) != 0, 4);
526   check(bcmp("alph", "beta", 4) != 0, 5);
527   check(bcmp("abce", "abcd", 3) == 0, 6);       /* Count limited. */
528   check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
529
530   /* strerror - VERY system-dependent.  */
531   {
532     int f;
533     it = "strerror";
534     f = open("/", O_WRONLY);    /* Should always fail. */
535     check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
536     equal(strerror(errno), _sys_errlist[errno], 2);
537   }
538
539   {
540     int status;
541     if (errors == 0)
542       {
543         status = EXIT_SUCCESS;
544         puts("No errors.");
545       }
546     else
547       {
548         status = EXIT_FAILURE;
549         printf("%Z errors.\n", errors);
550       }
551     exit(status);
552   }
553 }