update from main archive 961001
[glibc.git] / string / tester.c
blobb8155397379f5ee177ed5712baa7e1657795b38a
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>
9 #ifndef HAVE_GNU_LD
10 #define _sys_nerr sys_nerr
11 #define _sys_errlist sys_errlist
12 #endif
14 #define STREQ(a, b) (strcmp((a), (b)) == 0)
16 CONST char *it = "<UNSET>"; /* Routine name for message routines. */
17 size_t errors = 0;
19 /* Complain if condition is not true. */
20 void
21 DEFUN(check, (thing, number), int thing AND int number)
23 if (!thing)
25 printf("%s flunked test %d\n", it, number);
26 ++errors;
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)
34 check(a != NULL && b != NULL && STREQ(a, b), number);
37 char one[50];
38 char two[50];
40 int
41 DEFUN(main, (argc, argv), int argc AND char **argv)
43 char *cp;
45 /* Test strcmp first because we use it to test other things. */
46 it = "strcmp";
47 check(strcmp("", "") == 0, 1); /* Trivial case. */
48 check(strcmp("a", "a") == 0, 2); /* Identity. */
49 check(strcmp("abc", "abc") == 0, 3); /* Multicharacter. */
50 check(strcmp("abc", "abcd") < 0, 4); /* Length mismatches. */
51 check(strcmp("abcd", "abc") > 0, 5);
52 check(strcmp("abcd", "abce") < 0, 6); /* Honest miscompares. */
53 check(strcmp("abce", "abcd") > 0, 7);
54 check(strcmp("a\203", "a") > 0, 8); /* Tricky if char signed. */
55 check(strcmp("a\203", "a\003") > 0, 9);
57 /* Test strcpy next because we need it to set up other tests. */
58 it = "strcpy";
59 check(strcpy(one, "abcd") == one, 1); /* Returned value. */
60 equal(one, "abcd", 2); /* Basic test. */
62 (void) strcpy(one, "x");
63 equal(one, "x", 3); /* Writeover. */
64 equal(one+2, "cd", 4); /* Wrote too much? */
66 (void) strcpy(two, "hi there");
67 (void) strcpy(one, two);
68 equal(one, "hi there", 5); /* Basic test encore. */
69 equal(two, "hi there", 6); /* Stomped on source? */
71 (void) strcpy(one, "");
72 equal(one, "", 7); /* Boundary condition. */
74 /* stpncpy. */
75 it = "stpncpy";
77 memset(one, 'x', sizeof(one));
78 check(stpncpy(one, "abc", 2) == one + 2, 1);
79 check(stpncpy(one, "abc", 3) == one + 3, 2);
80 check(stpncpy(one, "abc", 4) == one + 3, 3);
81 check(one[3] == '\0' && one[4] == 'x', 4);
82 check(stpncpy(one, "abcd", 5) == one + 4, 5);
83 check(one[4] == '\0' && one[5] == 'x', 6);
84 check(stpncpy(one, "abcd", 6) == one + 4, 7);
85 check(one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
87 /* strcat. */
88 it = "strcat";
89 (void) strcpy(one, "ijk");
90 check(strcat(one, "lmn") == one, 1); /* Returned value. */
91 equal(one, "ijklmn", 2); /* Basic test. */
93 (void) strcpy(one, "x");
94 (void) strcat(one, "yz");
95 equal(one, "xyz", 3); /* Writeover. */
96 equal(one+4, "mn", 4); /* Wrote too much? */
98 (void) strcpy(one, "gh");
99 (void) strcpy(two, "ef");
100 (void) strcat(one, two);
101 equal(one, "ghef", 5); /* Basic test encore. */
102 equal(two, "ef", 6); /* Stomped on source? */
104 (void) strcpy(one, "");
105 (void) strcat(one, "");
106 equal(one, "", 7); /* Boundary conditions. */
107 (void) strcpy(one, "ab");
108 (void) strcat(one, "");
109 equal(one, "ab", 8);
110 (void) strcpy(one, "");
111 (void) strcat(one, "cd");
112 equal(one, "cd", 9);
114 /* strncat - first test it as strcat, with big counts,
115 then test the count mechanism. */
116 it = "strncat";
117 (void) strcpy(one, "ijk");
118 check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */
119 equal(one, "ijklmn", 2); /* Basic test. */
121 (void) strcpy(one, "x");
122 (void) strncat(one, "yz", 99);
123 equal(one, "xyz", 3); /* Writeover. */
124 equal(one+4, "mn", 4); /* Wrote too much? */
126 (void) strcpy(one, "gh");
127 (void) strcpy(two, "ef");
128 (void) strncat(one, two, 99);
129 equal(one, "ghef", 5); /* Basic test encore. */
130 equal(two, "ef", 6); /* Stomped on source? */
132 (void) strcpy(one, "");
133 (void) strncat(one, "", 99);
134 equal(one, "", 7); /* Boundary conditions. */
135 (void) strcpy(one, "ab");
136 (void) strncat(one, "", 99);
137 equal(one, "ab", 8);
138 (void) strcpy(one, "");
139 (void) strncat(one, "cd", 99);
140 equal(one, "cd", 9);
142 (void) strcpy(one, "ab");
143 (void) strncat(one, "cdef", 2);
144 equal(one, "abcd", 10); /* Count-limited. */
146 (void) strncat(one, "gh", 0);
147 equal(one, "abcd", 11); /* Zero count. */
149 (void) strncat(one, "gh", 2);
150 equal(one, "abcdgh", 12); /* Count and length equal. */
152 /* strncmp - first test as strcmp with big counts,
153 then test count code. */
154 it = "strncmp";
155 check(strncmp("", "", 99) == 0, 1); /* Trivial case. */
156 check(strncmp("a", "a", 99) == 0, 2); /* Identity. */
157 check(strncmp("abc", "abc", 99) == 0, 3); /* Multicharacter. */
158 check(strncmp("abc", "abcd", 99) < 0, 4); /* Length unequal. */
159 check(strncmp("abcd", "abc", 99) > 0, 5);
160 check(strncmp("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
161 check(strncmp("abce", "abcd", 99) > 0, 7);
162 check(strncmp("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
163 check(strncmp("a\203", "a\003", 2) > 0, 9);
164 check(strncmp("abce", "abcd", 3) == 0, 10); /* Count limited. */
165 check(strncmp("abce", "abc", 3) == 0, 11); /* Count == length. */
166 check(strncmp("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
167 check(strncmp("abc", "def", 0) == 0, 13); /* Zero count. */
169 /* strncpy - testing is a bit different because of odd semantics. */
170 it = "strncpy";
171 check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */
172 equal(one, "abc", 2); /* Did the copy go right? */
174 (void) strcpy(one, "abcdefgh");
175 (void) strncpy(one, "xyz", 2);
176 equal(one, "xycdefgh", 3); /* Copy cut by count. */
178 (void) strcpy(one, "abcdefgh");
179 (void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
180 equal(one, "xyzdefgh", 4);
182 (void) strcpy(one, "abcdefgh");
183 (void) strncpy(one, "xyz", 4); /* Copy just includes NUL. */
184 equal(one, "xyz", 5);
185 equal(one+4, "efgh", 6); /* Wrote too much? */
187 (void) strcpy(one, "abcdefgh");
188 (void) strncpy(one, "xyz", 5); /* Copy includes padding. */
189 equal(one, "xyz", 7);
190 equal(one+4, "", 8);
191 equal(one+5, "fgh", 9);
193 (void) strcpy(one, "abc");
194 (void) strncpy(one, "xyz", 0); /* Zero-length copy. */
195 equal(one, "abc", 10);
197 (void) strncpy(one, "", 2); /* Zero-length source. */
198 equal(one, "", 11);
199 equal(one+1, "", 12);
200 equal(one+2, "c", 13);
202 (void) strcpy(one, "hi there");
203 (void) strncpy(two, one, 9);
204 equal(two, "hi there", 14); /* Just paranoia. */
205 equal(one, "hi there", 15); /* Stomped on source? */
207 /* strlen. */
208 it = "strlen";
209 check(strlen("") == 0, 1); /* Empty. */
210 check(strlen("a") == 1, 2); /* Single char. */
211 check(strlen("abcd") == 4, 3); /* Multiple chars. */
213 char buf[4096];
214 int i;
215 char *p;
216 for (i=0; i < 0x100; i++)
218 p = (char *)((unsigned long int)(buf + 0xff) & ~0xff) + i;
219 strcpy (p, "OK");
220 strcpy (p+3, "BAD/WRONG");
221 check(strlen(p) == 2, 4+i);
225 /* strchr. */
226 it = "strchr";
227 check(strchr("abcd", 'z') == NULL, 1); /* Not found. */
228 (void) strcpy(one, "abcd");
229 check(strchr(one, 'c') == one+2, 2); /* Basic test. */
230 check(strchr(one, 'd') == one+3, 3); /* End of string. */
231 check(strchr(one, 'a') == one, 4); /* Beginning. */
232 check(strchr(one, '\0') == one+4, 5); /* Finding NUL. */
233 (void) strcpy(one, "ababa");
234 check(strchr(one, 'b') == one+1, 6); /* Finding first. */
235 (void) strcpy(one, "");
236 check(strchr(one, 'b') == NULL, 7); /* Empty string. */
237 check(strchr(one, '\0') == one, 8); /* NUL in empty string. */
239 char buf[4096];
240 int i;
241 char *p;
242 for (i=0; i < 0x100; i++)
244 p = (char *)((unsigned long int)(buf + 0xff) & ~0xff) + i;
245 strcpy (p, "OK");
246 strcpy (p+3, "BAD/WRONG");
247 check(strchr(p, '/') == NULL, 9+i);
251 #if 0
252 /* index - just like strchr. */
253 it = "index";
254 check(index("abcd", 'z') == NULL, 1); /* Not found. */
255 (void) strcpy(one, "abcd");
256 check(index(one, 'c') == one+2, 2); /* Basic test. */
257 check(index(one, 'd') == one+3, 3); /* End of string. */
258 check(index(one, 'a') == one, 4); /* Beginning. */
259 check(index(one, '\0') == one+4, 5); /* Finding NUL. */
260 (void) strcpy(one, "ababa");
261 check(index(one, 'b') == one+1, 6); /* Finding first. */
262 (void) strcpy(one, "");
263 check(index(one, 'b') == NULL, 7); /* Empty string. */
264 check(index(one, '\0') == one, 8); /* NUL in empty string. */
265 #endif
267 /* strrchr. */
268 it = "strrchr";
269 check(strrchr("abcd", 'z') == NULL, 1); /* Not found. */
270 (void) strcpy(one, "abcd");
271 check(strrchr(one, 'c') == one+2, 2); /* Basic test. */
272 check(strrchr(one, 'd') == one+3, 3); /* End of string. */
273 check(strrchr(one, 'a') == one, 4); /* Beginning. */
274 check(strrchr(one, '\0') == one+4, 5); /* Finding NUL. */
275 (void) strcpy(one, "ababa");
276 check(strrchr(one, 'b') == one+3, 6); /* Finding last. */
277 (void) strcpy(one, "");
278 check(strrchr(one, 'b') == NULL, 7); /* Empty string. */
279 check(strrchr(one, '\0') == one, 8); /* NUL in empty string. */
281 char buf[4096];
282 int i;
283 char *p;
284 for (i=0; i < 0x100; i++)
286 p = (char *)((unsigned long int)(buf + 0xff) & ~0xff) + i;
287 strcpy (p, "OK");
288 strcpy (p+3, "BAD/WRONG");
289 check(strrchr(p, '/') == NULL, 9+i);
293 #if 0
294 /* rindex - just like strrchr. */
295 it = "rindex";
296 check(rindex("abcd", 'z') == NULL, 1); /* Not found. */
297 (void) strcpy(one, "abcd");
298 check(rindex(one, 'c') == one+2, 2); /* Basic test. */
299 check(rindex(one, 'd') == one+3, 3); /* End of string. */
300 check(rindex(one, 'a') == one, 4); /* Beginning. */
301 check(rindex(one, '\0') == one+4, 5); /* Finding NUL. */
302 (void) strcpy(one, "ababa");
303 check(rindex(one, 'b') == one+3, 6); /* Finding last. */
304 (void) strcpy(one, "");
305 check(rindex(one, 'b') == NULL, 7); /* Empty string. */
306 check(rindex(one, '\0') == one, 8); /* NUL in empty string. */
307 #endif
309 /* strpbrk - somewhat like strchr. */
310 it = "strpbrk";
311 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
312 (void) strcpy(one, "abcd");
313 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
314 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
315 check(strpbrk(one, "a") == one, 4); /* Beginning. */
316 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
317 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
318 (void) strcpy(one, "abcabdea");
319 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
320 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
321 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
322 (void) strcpy(one, "");
323 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
324 check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
326 /* strstr - somewhat like strchr. */
327 it = "strstr";
328 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
329 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
330 (void) strcpy(one, "abcd");
331 check(strstr(one, "c") == one+2, 3); /* Basic test. */
332 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
333 check(strstr(one, "d") == one+3, 5); /* End of string. */
334 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
335 check(strstr(one, "abc") == one, 7); /* Beginning. */
336 check(strstr(one, "abcd") == one, 8); /* Exact match. */
337 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
338 check(strstr(one, "de") == NULL, 10); /* Past end. */
339 check(strstr(one, "") == one, 11); /* Finding empty. */
340 (void) strcpy(one, "ababa");
341 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
342 (void) strcpy(one, "");
343 check(strstr(one, "b") == NULL, 13); /* Empty string. */
344 check(strstr(one, "") == one, 14); /* Empty in empty string. */
345 (void) strcpy(one, "bcbca");
346 check(strstr(one, "bca") == one+2, 15); /* False start. */
347 (void) strcpy(one, "bbbcabbca");
348 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
350 /* strspn. */
351 it = "strspn";
352 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
353 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
354 check(strspn("abc", "qx") == 0, 3); /* None. */
355 check(strspn("", "ab") == 0, 4); /* Null string. */
356 check(strspn("abc", "") == 0, 5); /* Null search list. */
358 /* strcspn. */
359 it = "strcspn";
360 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
361 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
362 check(strcspn("abc", "abc") == 0, 3); /* None. */
363 check(strcspn("", "ab") == 0, 4); /* Null string. */
364 check(strcspn("abc", "") == 3, 5); /* Null search list. */
366 /* strtok - the hard one. */
367 it = "strtok";
368 (void) strcpy(one, "first, second, third");
369 equal(strtok(one, ", "), "first", 1); /* Basic test. */
370 equal(one, "first", 2);
371 equal(strtok((char *)NULL, ", "), "second", 3);
372 equal(strtok((char *)NULL, ", "), "third", 4);
373 check(strtok((char *)NULL, ", ") == NULL, 5);
374 (void) strcpy(one, ", first, ");
375 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
376 check(strtok((char *)NULL, ", ") == NULL, 7);
377 (void) strcpy(one, "1a, 1b; 2a, 2b");
378 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
379 equal(strtok((char *)NULL, "; "), "1b", 9);
380 equal(strtok((char *)NULL, ", "), "2a", 10);
381 (void) strcpy(two, "x-y");
382 equal(strtok(two, "-"), "x", 11); /* New string before done. */
383 equal(strtok((char *)NULL, "-"), "y", 12);
384 check(strtok((char *)NULL, "-") == NULL, 13);
385 (void) strcpy(one, "a,b, c,, ,d");
386 equal(strtok(one, ", "), "a", 14); /* Different separators. */
387 equal(strtok((char *)NULL, ", "), "b", 15);
388 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
389 equal(strtok((char *)NULL, " ,"), "d", 17);
390 check(strtok((char *)NULL, ", ") == NULL, 18);
391 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
392 (void) strcpy(one, ", ");
393 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
394 (void) strcpy(one, "");
395 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
396 (void) strcpy(one, "abc");
397 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
398 check(strtok((char *)NULL, ", ") == NULL, 23);
399 (void) strcpy(one, "abc");
400 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
401 check(strtok((char *)NULL, "") == NULL, 25);
402 (void) strcpy(one, "abcdefgh");
403 (void) strcpy(one, "a,b,c");
404 equal(strtok(one, ","), "a", 26); /* Basics again... */
405 equal(strtok((char *)NULL, ","), "b", 27);
406 equal(strtok((char *)NULL, ","), "c", 28);
407 check(strtok((char *)NULL, ",") == NULL, 29);
408 equal(one+6, "gh", 30); /* Stomped past end? */
409 equal(one, "a", 31); /* Stomped old tokens? */
410 equal(one+2, "b", 32);
411 equal(one+4, "c", 33);
413 /* strtok_r. */
414 it = "strtok_r";
415 (void) strcpy(one, "first, second, third");
416 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
417 equal(one, "first", 2);
418 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
419 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
420 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
421 (void) strcpy(one, ", first, ");
422 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
423 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
424 (void) strcpy(one, "1a, 1b; 2a, 2b");
425 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
426 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
427 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
428 (void) strcpy(two, "x-y");
429 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
430 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
431 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
432 (void) strcpy(one, "a,b, c,, ,d");
433 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
434 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
435 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
436 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
437 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
438 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
439 (void) strcpy(one, ", ");
440 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
441 (void) strcpy(one, "");
442 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
443 (void) strcpy(one, "abc");
444 equal(strtok_r(one, ", ", &cp), "abc", 22); /* No delimiters. */
445 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 23);
446 (void) strcpy(one, "abc");
447 equal(strtok_r(one, "", &cp), "abc", 24); /* Empty delimiter list. */
448 check(strtok_r((char *)NULL, "", &cp) == NULL, 25);
449 (void) strcpy(one, "abcdefgh");
450 (void) strcpy(one, "a,b,c");
451 equal(strtok_r(one, ",", &cp), "a", 26); /* Basics again... */
452 equal(strtok_r((char *)NULL, ",", &cp), "b", 27);
453 equal(strtok_r((char *)NULL, ",", &cp), "c", 28);
454 check(strtok_r((char *)NULL, ",", &cp) == NULL, 29);
455 equal(one+6, "gh", 30); /* Stomped past end? */
456 equal(one, "a", 31); /* Stomped old tokens? */
457 equal(one+2, "b", 32);
458 equal(one+4, "c", 33);
460 /* strsep. */
461 it = "strsep";
462 cp = strcpy(one, "first, second, third");
463 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
464 equal(one, "first", 2);
465 equal(strsep(&cp, ", "), "", 3);
466 equal(strsep(&cp, ", "), "second", 4);
467 equal(strsep(&cp, ", "), "", 5);
468 equal(strsep(&cp, ", "), "third", 6);
469 check(strsep(&cp, ", ") == NULL, 7);
470 cp = strcpy(one, ", first, ");
471 equal(strsep(&cp, ", "), "", 8);
472 equal(strsep(&cp, ", "), "", 9);
473 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
474 equal(strsep(&cp, ", "), "", 11);
475 check(strsep(&cp, ", ") == NULL, 12);
476 cp = strcpy(one, "1a, 1b; 2a, 2b");
477 equal(strsep(&cp, ", "), "1a", 13); /* Changing delim lists. */
478 equal(strsep(&cp, ", "), "", 14);
479 equal(strsep(&cp, "; "), "1b", 15);
480 equal(strsep(&cp, ", "), "", 16);
481 equal(strsep(&cp, ", "), "2a", 17);
482 cp = strcpy(two, "x-y");
483 equal(strsep(&cp, "-"), "x", 18); /* New string before done. */
484 equal(strsep(&cp, "-"), "y", 19);
485 check(strsep(&cp, "-") == NULL, 20);
486 cp = strcpy(one, "a,b, c,, ,d");
487 equal(strsep(&cp, ", "), "a", 21); /* Different separators. */
488 equal(strsep(&cp, ", "), "b", 22);
489 equal(strsep(&cp, " ,"), "", 23);
490 equal(strsep(&cp, " ,"), "c", 24); /* Permute list too. */
491 equal(strsep(&cp, " ,"), "", 25);
492 equal(strsep(&cp, " ,"), "", 26);
493 equal(strsep(&cp, " ,"), "", 27);
494 equal(strsep(&cp, " ,"), "d", 28);
495 check(strsep(&cp, ", ") == NULL, 29);
496 check(strsep(&cp, ", ") == NULL, 30); /* Persistence. */
497 cp = strcpy(one, ", ");
498 equal(strsep(&cp, ", "), "", 31);
499 equal(strsep(&cp, ", "), "", 32);
500 check(strsep(&cp, ", ") == NULL, 33); /* No tokens. */
501 cp = strcpy(one, "");
502 check(strsep(&cp, ", ") == NULL, 34); /* Empty string. */
503 cp = strcpy(one, "abc");
504 equal(strsep(&cp, ", "), "abc", 35); /* No delimiters. */
505 check(strsep(&cp, ", ") == NULL, 36);
506 cp = strcpy(one, "abc");
507 equal(strsep(&cp, ""), "abc", 37); /* Empty delimiter list. */
508 check(strsep(&cp, "") == NULL, 38);
509 (void) strcpy(one, "abcdefgh");
510 cp = strcpy(one, "a,b,c");
511 equal(strsep(&cp, ","), "a", 39); /* Basics again... */
512 equal(strsep(&cp, ","), "b", 40);
513 equal(strsep(&cp, ","), "c", 41);
514 check(strsep(&cp, ",") == NULL, 42);
515 equal(one+6, "gh", 43); /* Stomped past end? */
516 equal(one, "a", 44); /* Stomped old tokens? */
517 equal(one+2, "b", 45);
518 equal(one+4, "c", 46);
520 /* memcmp. */
521 it = "memcmp";
522 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
523 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
524 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
525 check(memcmp("abce", "abcd", 4) > 0, 4);
526 check(memcmp("alph", "beta", 4) < 0, 5);
527 check(memcmp("a\203", "a\003", 2) > 0, 6);
528 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
529 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
531 /* memchr. */
532 it = "memchr";
533 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
534 (void) strcpy(one, "abcd");
535 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
536 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
537 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
538 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
539 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
540 (void) strcpy(one, "ababa");
541 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
542 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
543 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
544 (void) strcpy(one, "a\203b");
545 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
547 /* now test all possible alignment and length combinations to catch
548 bugs due to unrolled loops (assuming unrolling is limited to no
549 more than 128 byte chunks: */
551 char buf[128 + sizeof(long)];
552 long align, len, i, pos;
554 for (align = 0; align < (long) sizeof(long); ++align) {
555 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
556 for (i = 0; i < len; ++i) {
557 buf[align + i] = 'x'; /* don't depend on memset... */
559 for (pos = 0; pos < len; ++pos) {
560 #if 0
561 printf("align %d, len %d, pos %d\n", align, len, pos);
562 #endif
563 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
564 check(memchr(buf + align, 'x', pos) == NULL, 11);
565 buf[align + pos] = '-';
571 /* memcpy - need not work for overlap. */
572 it = "memcpy";
573 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
574 equal(one, "abc", 2); /* Did the copy go right? */
576 (void) strcpy(one, "abcdefgh");
577 (void) memcpy(one+1, "xyz", 2);
578 equal(one, "axydefgh", 3); /* Basic test. */
580 (void) strcpy(one, "abc");
581 (void) memcpy(one, "xyz", 0);
582 equal(one, "abc", 4); /* Zero-length copy. */
584 (void) strcpy(one, "hi there");
585 (void) strcpy(two, "foo");
586 (void) memcpy(two, one, 9);
587 equal(two, "hi there", 5); /* Just paranoia. */
588 equal(one, "hi there", 6); /* Stomped on source? */
590 /* memmove - must work on overlap. */
591 it = "memmove";
592 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
593 equal(one, "abc", 2); /* Did the copy go right? */
595 (void) strcpy(one, "abcdefgh");
596 (void) memmove(one+1, "xyz", 2);
597 equal(one, "axydefgh", 3); /* Basic test. */
599 (void) strcpy(one, "abc");
600 (void) memmove(one, "xyz", 0);
601 equal(one, "abc", 4); /* Zero-length copy. */
603 (void) strcpy(one, "hi there");
604 (void) strcpy(two, "foo");
605 (void) memmove(two, one, 9);
606 equal(two, "hi there", 5); /* Just paranoia. */
607 equal(one, "hi there", 6); /* Stomped on source? */
609 (void) strcpy(one, "abcdefgh");
610 (void) memmove(one+1, one, 9);
611 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
613 (void) strcpy(one, "abcdefgh");
614 (void) memmove(one+1, one+2, 7);
615 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
617 (void) strcpy(one, "abcdefgh");
618 (void) memmove(one, one, 9);
619 equal(one, "abcdefgh", 9); /* 100% overlap. */
621 /* memccpy - first test like memcpy, then the search part
622 The SVID, the only place where memccpy is mentioned, says
623 overlap might fail, so we don't try it. Besides, it's hard
624 to see the rationale for a non-left-to-right memccpy. */
625 it = "memccpy";
626 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
627 equal(one, "abc", 2); /* Did the copy go right? */
629 (void) strcpy(one, "abcdefgh");
630 (void) memccpy(one+1, "xyz", 'q', 2);
631 equal(one, "axydefgh", 3); /* Basic test. */
633 (void) strcpy(one, "abc");
634 (void) memccpy(one, "xyz", 'q', 0);
635 equal(one, "abc", 4); /* Zero-length copy. */
637 (void) strcpy(one, "hi there");
638 (void) strcpy(two, "foo");
639 (void) memccpy(two, one, 'q', 9);
640 equal(two, "hi there", 5); /* Just paranoia. */
641 equal(one, "hi there", 6); /* Stomped on source? */
643 (void) strcpy(one, "abcdefgh");
644 (void) strcpy(two, "horsefeathers");
645 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
646 equal(one, "abcdefgh", 8); /* Source intact? */
647 equal(two, "abcdefeathers", 9); /* Copy correct? */
649 (void) strcpy(one, "abcd");
650 (void) strcpy(two, "bumblebee");
651 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
652 equal(two, "aumblebee", 11);
653 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
654 equal(two, "abcdlebee", 13);
655 (void) strcpy(one, "xyz");
656 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
657 equal(two, "xbcdlebee", 15);
659 /* memset. */
660 it = "memset";
661 (void) strcpy(one, "abcdefgh");
662 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
663 equal(one, "axxxefgh", 2); /* Basic test. */
665 (void) memset(one+2, 'y', 0);
666 equal(one, "axxxefgh", 3); /* Zero-length set. */
668 (void) memset(one+5, 0, 1);
669 equal(one, "axxxe", 4); /* Zero fill. */
670 equal(one+6, "gh", 5); /* And the leftover. */
672 (void) memset(one+2, 010045, 1);
673 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
675 /* bcopy - much like memcpy.
676 Berklix manual is silent about overlap, so don't test it. */
677 it = "bcopy";
678 (void) bcopy("abc", one, 4);
679 equal(one, "abc", 1); /* Simple copy. */
681 (void) strcpy(one, "abcdefgh");
682 (void) bcopy("xyz", one+1, 2);
683 equal(one, "axydefgh", 2); /* Basic test. */
685 (void) strcpy(one, "abc");
686 (void) bcopy("xyz", one, 0);
687 equal(one, "abc", 3); /* Zero-length copy. */
689 (void) strcpy(one, "hi there");
690 (void) strcpy(two, "foo");
691 (void) bcopy(one, two, 9);
692 equal(two, "hi there", 4); /* Just paranoia. */
693 equal(one, "hi there", 5); /* Stomped on source? */
695 /* bzero. */
696 it = "bzero";
697 (void) strcpy(one, "abcdef");
698 bzero(one+2, 2);
699 equal(one, "ab", 1); /* Basic test. */
700 equal(one+3, "", 2);
701 equal(one+4, "ef", 3);
703 (void) strcpy(one, "abcdef");
704 bzero(one+2, 0);
705 equal(one, "abcdef", 4); /* Zero-length copy. */
707 #if 0
708 /* bcmp - somewhat like memcmp. */
709 it = "bcmp";
710 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
711 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
712 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
713 check(bcmp("abce", "abcd", 4) != 0, 4);
714 check(bcmp("alph", "beta", 4) != 0, 5);
715 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
716 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
717 #endif
720 char text[] = "This,is,a,test";
721 char *list = text;
722 it = "strsep";
723 check (!strcmp ("This", strsep (&list, ",")), 1);
724 check (!strcmp ("is", strsep (&list, ",")), 2);
725 check (!strcmp ("a", strsep (&list, ",")), 3);
726 check (!strcmp ("test", strsep (&list, ",")), 4);
727 check (strsep (&list, ",") == NULL, 5);
730 /* strerror - VERY system-dependent. */
732 int f;
733 it = "strerror";
734 f = __open("/", O_WRONLY); /* Should always fail. */
735 check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
736 equal(strerror(errno), _sys_errlist[errno], 2);
740 int status;
741 if (errors == 0)
743 status = EXIT_SUCCESS;
744 puts("No errors.");
746 else
748 status = EXIT_FAILURE;
749 printf("%Zd errors.\n", errors);
751 exit(status);