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