10 #define _sys_nerr sys_nerr
11 #define _sys_errlist sys_errlist
14 #define STREQ(a, b) (strcmp((a), (b)) == 0)
16 CONST char *it = "<UNSET>"; /* Routine name for message routines. */
19 /* Complain if condition is not true. */
21 DEFUN(check, (thing, number), int thing AND int number)
25 printf("%s flunked test %d\n", it, number);
30 /* Complain if first two args don't strcmp as equal. */
32 DEFUN(equal, (a, b, number), CONST char *a AND CONST char *b AND int number)
34 check(a != NULL && b != NULL && STREQ(a, b), number);
41 DEFUN(main, (argc, argv), int argc AND char **argv)
43 /* Test strcmp first because we use it to test other things. */
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);
55 /* Test strcpy next because we need it to set up other tests. */
57 check(strcpy(one, "abcd") == one, 1); /* Returned value. */
58 equal(one, "abcd", 2); /* Basic test. */
60 (void) strcpy(one, "x");
61 equal(one, "x", 3); /* Writeover. */
62 equal(one+2, "cd", 4); /* Wrote too much? */
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? */
69 (void) strcpy(one, "");
70 equal(one, "", 7); /* Boundary condition. */
74 (void) strcpy(one, "ijk");
75 check(strcat(one, "lmn") == one, 1); /* Returned value. */
76 equal(one, "ijklmn", 2); /* Basic test. */
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? */
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? */
89 (void) strcpy(one, "");
90 (void) strcat(one, "");
91 equal(one, "", 7); /* Boundary conditions. */
92 (void) strcpy(one, "ab");
93 (void) strcat(one, "");
95 (void) strcpy(one, "");
96 (void) strcat(one, "cd");
99 /* strncat - first test it as strcat, with big counts,
100 then test the count mechanism. */
102 (void) strcpy(one, "ijk");
103 check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */
104 equal(one, "ijklmn", 2); /* Basic test. */
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? */
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? */
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);
123 (void) strcpy(one, "");
124 (void) strncat(one, "cd", 99);
127 (void) strcpy(one, "ab");
128 (void) strncat(one, "cdef", 2);
129 equal(one, "abcd", 10); /* Count-limited. */
131 (void) strncat(one, "gh", 0);
132 equal(one, "abcd", 11); /* Zero count. */
134 (void) strncat(one, "gh", 2);
135 equal(one, "abcdgh", 12); /* Count and length equal. */
137 /* strncmp - first test as strcmp with big counts,
138 then test count code. */
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. */
154 /* strncpy - testing is a bit different because of odd semantics. */
156 check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */
157 equal(one, "abc", 2); /* Did the copy go right? */
159 (void) strcpy(one, "abcdefgh");
160 (void) strncpy(one, "xyz", 2);
161 equal(one, "xycdefgh", 3); /* Copy cut by count. */
163 (void) strcpy(one, "abcdefgh");
164 (void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
165 equal(one, "xyzdefgh", 4);
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? */
172 (void) strcpy(one, "abcdefgh");
173 (void) strncpy(one, "xyz", 5); /* Copy includes padding. */
174 equal(one, "xyz", 7);
176 equal(one+5, "fgh", 9);
178 (void) strcpy(one, "abc");
179 (void) strncpy(one, "xyz", 0); /* Zero-length copy. */
180 equal(one, "abc", 10);
182 (void) strncpy(one, "", 2); /* Zero-length source. */
184 equal(one+1, "", 12);
185 equal(one+2, "c", 13);
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? */
194 check(strlen("") == 0, 1); /* Empty. */
195 check(strlen("a") == 1, 2); /* Single char. */
196 check(strlen("abcd") == 4, 3); /* Multiple chars. */
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. */
212 /* index - just like strchr. */
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. */
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. */
240 /* rindex - just like strrchr. */
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. */
254 /* strpbrk - somewhat like strchr. */
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. */
271 /* strstr - somewhat like strchr. */
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, 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. */
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. */
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. */
311 /* strtok - the hard one. */
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);
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. */
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. */
384 /* memcpy - need not work for overlap. */
386 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
387 equal(one, "abc", 2); /* Did the copy go right? */
389 (void) strcpy(one, "abcdefgh");
390 (void) memcpy(one+1, "xyz", 2);
391 equal(one, "axydefgh", 3); /* Basic test. */
393 (void) strcpy(one, "abc");
394 (void) memcpy(one, "xyz", 0);
395 equal(one, "abc", 4); /* Zero-length copy. */
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? */
403 /* memmove - must work on overlap. */
405 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
406 equal(one, "abc", 2); /* Did the copy go right? */
408 (void) strcpy(one, "abcdefgh");
409 (void) memmove(one+1, "xyz", 2);
410 equal(one, "axydefgh", 3); /* Basic test. */
412 (void) strcpy(one, "abc");
413 (void) memmove(one, "xyz", 0);
414 equal(one, "abc", 4); /* Zero-length copy. */
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? */
422 (void) strcpy(one, "abcdefgh");
423 (void) memmove(one+1, one, 9);
424 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
426 (void) strcpy(one, "abcdefgh");
427 (void) memmove(one+1, one+2, 7);
428 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
430 (void) strcpy(one, "abcdefgh");
431 (void) memmove(one, one, 9);
432 equal(one, "abcdefgh", 9); /* 100% overlap. */
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. */
439 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
440 equal(one, "abc", 2); /* Did the copy go right? */
442 (void) strcpy(one, "abcdefgh");
443 (void) memccpy(one+1, "xyz", 'q', 2);
444 equal(one, "axydefgh", 3); /* Basic test. */
446 (void) strcpy(one, "abc");
447 (void) memccpy(one, "xyz", 'q', 0);
448 equal(one, "abc", 4); /* Zero-length copy. */
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? */
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? */
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);
474 (void) strcpy(one, "abcdefgh");
475 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
476 equal(one, "axxxefgh", 2); /* Basic test. */
478 (void) memset(one+2, 'y', 0);
479 equal(one, "axxxefgh", 3); /* Zero-length set. */
481 (void) memset(one+5, 0, 1);
482 equal(one, "axxxe", 4); /* Zero fill. */
483 equal(one+6, "gh", 5); /* And the leftover. */
485 (void) memset(one+2, 010045, 1);
486 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
488 /* bcopy - much like memcpy.
489 Berklix manual is silent about overlap, so don't test it. */
491 (void) bcopy("abc", one, 4);
492 equal(one, "abc", 1); /* Simple copy. */
494 (void) strcpy(one, "abcdefgh");
495 (void) bcopy("xyz", one+1, 2);
496 equal(one, "axydefgh", 2); /* Basic test. */
498 (void) strcpy(one, "abc");
499 (void) bcopy("xyz", one, 0);
500 equal(one, "abc", 3); /* Zero-length copy. */
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? */
510 (void) strcpy(one, "abcdef");
512 equal(one, "ab", 1); /* Basic test. */
514 equal(one+4, "ef", 3);
516 (void) strcpy(one, "abcdef");
518 equal(one, "abcdef", 4); /* Zero-length copy. */
520 /* bcmp - somewhat like memcmp. */
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. */
531 char text[] = "This,is,a,test";
534 check (!strcmp ("This", strsep (&list, ",")), 1);
535 check (!strcmp ("is", strsep (&list, ",")), 2);
536 check (!strcmp ("a", strsep (&list, ",")), 3);
537 check (!strcmp ("test", strsep (&list, ",")), 4);
538 check (strsep (&list, ",") == NULL, 5);
541 /* strerror - VERY system-dependent. */
545 f = open("/", O_WRONLY); /* Should always fail. */
546 check(f < 0 && errno > 0 && errno < sys_nerr, 1);
547 equal(strerror(errno), sys_errlist[errno], 2);
554 status = EXIT_SUCCESS;
559 status = EXIT_FAILURE;
560 printf("%Z errors.\n", errors);