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