11 #define _sys_nerr sys_nerr
12 #define _sys_errlist sys_errlist
15 #define STREQ(a, b) (strcmp((a), (b)) == 0)
17 CONST char *it = "<UNSET>"; /* Routine name for message routines. */
20 /* Complain if condition is not true. */
22 DEFUN(check, (thing, number), int thing AND int number)
26 printf("%s flunked test %d\n", it, number);
31 /* Complain if first two args don't strcmp as equal. */
33 DEFUN(equal, (a, b, number), CONST char *a AND CONST char *b AND int number)
35 check(a != NULL && b != NULL && STREQ(a, b), number);
42 DEFUN(main, (argc, argv), int argc AND char **argv)
44 /* Test strcmp first because we use it to test other things. */
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);
56 /* Test strcpy next because we need it to set up other tests. */
58 check(strcpy(one, "abcd") == one, 1); /* Returned value. */
59 equal(one, "abcd", 2); /* Basic test. */
61 (void) strcpy(one, "x");
62 equal(one, "x", 3); /* Writeover. */
63 equal(one+2, "cd", 4); /* Wrote too much? */
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? */
70 (void) strcpy(one, "");
71 equal(one, "", 7); /* Boundary condition. */
75 (void) strcpy(one, "ijk");
76 check(strcat(one, "lmn") == one, 1); /* Returned value. */
77 equal(one, "ijklmn", 2); /* Basic test. */
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? */
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? */
90 (void) strcpy(one, "");
91 (void) strcat(one, "");
92 equal(one, "", 7); /* Boundary conditions. */
93 (void) strcpy(one, "ab");
94 (void) strcat(one, "");
96 (void) strcpy(one, "");
97 (void) strcat(one, "cd");
100 /* strncat - first test it as strcat, with big counts,
101 then test the count mechanism. */
103 (void) strcpy(one, "ijk");
104 check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */
105 equal(one, "ijklmn", 2); /* Basic test. */
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? */
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? */
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);
124 (void) strcpy(one, "");
125 (void) strncat(one, "cd", 99);
128 (void) strcpy(one, "ab");
129 (void) strncat(one, "cdef", 2);
130 equal(one, "abcd", 10); /* Count-limited. */
132 (void) strncat(one, "gh", 0);
133 equal(one, "abcd", 11); /* Zero count. */
135 (void) strncat(one, "gh", 2);
136 equal(one, "abcdgh", 12); /* Count and length equal. */
138 /* strncmp - first test as strcmp with big counts,
139 then test count code. */
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. */
155 /* strncpy - testing is a bit different because of odd semantics. */
157 check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */
158 equal(one, "abc", 2); /* Did the copy go right? */
160 (void) strcpy(one, "abcdefgh");
161 (void) strncpy(one, "xyz", 2);
162 equal(one, "xycdefgh", 3); /* Copy cut by count. */
164 (void) strcpy(one, "abcdefgh");
165 (void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
166 equal(one, "xyzdefgh", 4);
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? */
173 (void) strcpy(one, "abcdefgh");
174 (void) strncpy(one, "xyz", 5); /* Copy includes padding. */
175 equal(one, "xyz", 7);
177 equal(one+5, "fgh", 9);
179 (void) strcpy(one, "abc");
180 (void) strncpy(one, "xyz", 0); /* Zero-length copy. */
181 equal(one, "abc", 10);
183 (void) strncpy(one, "", 2); /* Zero-length source. */
185 equal(one+1, "", 12);
186 equal(one+2, "c", 13);
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? */
195 check(strlen("") == 0, 1); /* Empty. */
196 check(strlen("a") == 1, 2); /* Single char. */
197 check(strlen("abcd") == 4, 3); /* Multiple chars. */
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. */
213 /* index - just like strchr. */
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. */
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. */
241 /* rindex - just like strrchr. */
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. */
255 /* strpbrk - somewhat like strchr. */
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. */
272 /* strstr - somewhat like strchr. */
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. */
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. */
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. */
312 /* strtok - the hard one. */
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);
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. */
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. */
385 /* memcpy - need not work for overlap. */
387 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
388 equal(one, "abc", 2); /* Did the copy go right? */
390 (void) strcpy(one, "abcdefgh");
391 (void) memcpy(one+1, "xyz", 2);
392 equal(one, "axydefgh", 3); /* Basic test. */
394 (void) strcpy(one, "abc");
395 (void) memcpy(one, "xyz", 0);
396 equal(one, "abc", 4); /* Zero-length copy. */
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? */
404 /* memmove - must work on overlap. */
406 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
407 equal(one, "abc", 2); /* Did the copy go right? */
409 (void) strcpy(one, "abcdefgh");
410 (void) memmove(one+1, "xyz", 2);
411 equal(one, "axydefgh", 3); /* Basic test. */
413 (void) strcpy(one, "abc");
414 (void) memmove(one, "xyz", 0);
415 equal(one, "abc", 4); /* Zero-length copy. */
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? */
423 (void) strcpy(one, "abcdefgh");
424 (void) memmove(one+1, one, 9);
425 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
427 (void) strcpy(one, "abcdefgh");
428 (void) memmove(one+1, one+2, 7);
429 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
431 (void) strcpy(one, "abcdefgh");
432 (void) memmove(one, one, 9);
433 equal(one, "abcdefgh", 9); /* 100% overlap. */
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. */
440 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
441 equal(one, "abc", 2); /* Did the copy go right? */
443 (void) strcpy(one, "abcdefgh");
444 (void) memccpy(one+1, "xyz", 'q', 2);
445 equal(one, "axydefgh", 3); /* Basic test. */
447 (void) strcpy(one, "abc");
448 (void) memccpy(one, "xyz", 'q', 0);
449 equal(one, "abc", 4); /* Zero-length copy. */
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? */
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? */
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);
475 (void) strcpy(one, "abcdefgh");
476 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
477 equal(one, "axxxefgh", 2); /* Basic test. */
479 (void) memset(one+2, 'y', 0);
480 equal(one, "axxxefgh", 3); /* Zero-length set. */
482 (void) memset(one+5, 0, 1);
483 equal(one, "axxxe", 4); /* Zero fill. */
484 equal(one+6, "gh", 5); /* And the leftover. */
486 (void) memset(one+2, 010045, 1);
487 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
489 /* bcopy - much like memcpy.
490 Berklix manual is silent about overlap, so don't test it. */
492 (void) bcopy("abc", one, 4);
493 equal(one, "abc", 1); /* Simple copy. */
495 (void) strcpy(one, "abcdefgh");
496 (void) bcopy("xyz", one+1, 2);
497 equal(one, "axydefgh", 2); /* Basic test. */
499 (void) strcpy(one, "abc");
500 (void) bcopy("xyz", one, 0);
501 equal(one, "abc", 3); /* Zero-length copy. */
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? */
511 (void) strcpy(one, "abcdef");
513 equal(one, "ab", 1); /* Basic test. */
515 equal(one+4, "ef", 3);
517 (void) strcpy(one, "abcdef");
519 equal(one, "abcdef", 4); /* Zero-length copy. */
521 /* bcmp - somewhat like memcmp. */
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. */
531 /* strerror - VERY system-dependent. */
533 extern CONST unsigned int _sys_nerr;
534 extern CONST char *CONST _sys_errlist[];
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);
546 status = EXIT_SUCCESS;
551 status = EXIT_FAILURE;
552 printf("%Z errors.\n", errors);