(MSG_*): Also define as macros.
[glibc.git] / string / tester.c
blob0c3ccc1524401132f47ba71eedbc47a4f453862e
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 equal(strsep(&cp, ", "), "", 12);
476 check(strsep(&cp, ", ") == NULL, 13);
477 cp = strcpy(one, "1a, 1b; 2a, 2b");
478 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */
479 equal(strsep(&cp, ", "), "", 15);
480 equal(strsep(&cp, "; "), "1b", 16);
481 equal(strsep(&cp, ", "), "", 17);
482 equal(strsep(&cp, ", "), "2a", 18);
483 cp = strcpy(two, "x-y");
484 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */
485 equal(strsep(&cp, "-"), "y", 20);
486 check(strsep(&cp, "-") == NULL, 21);
487 cp = strcpy(one, "a,b, c,, ,d ");
488 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */
489 equal(strsep(&cp, ", "), "b", 23);
490 equal(strsep(&cp, " ,"), "", 24);
491 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */
492 equal(strsep(&cp, " ,"), "", 26);
493 equal(strsep(&cp, " ,"), "", 27);
494 equal(strsep(&cp, " ,"), "", 28);
495 equal(strsep(&cp, " ,"), "d", 29);
496 equal(strsep(&cp, " ,"), "", 30);
497 check(strsep(&cp, ", ") == NULL, 31);
498 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
499 cp = strcpy(one, ", ");
500 equal(strsep(&cp, ", "), "", 33);
501 equal(strsep(&cp, ", "), "", 34);
502 equal(strsep(&cp, ", "), "", 35);
503 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
504 cp = strcpy(one, "");
505 equal(strsep(&cp, ", "), "", 37);
506 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
507 cp = strcpy(one, "abc");
508 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */
509 check(strsep(&cp, ", ") == NULL, 40);
510 cp = strcpy(one, "abc");
511 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */
512 check(strsep(&cp, "") == NULL, 42);
513 (void) strcpy(one, "abcdefgh");
514 cp = strcpy(one, "a,b,c");
515 equal(strsep(&cp, ","), "a", 43); /* Basics again... */
516 equal(strsep(&cp, ","), "b", 44);
517 equal(strsep(&cp, ","), "c", 45);
518 check(strsep(&cp, ",") == NULL, 46);
519 equal(one+6, "gh", 47); /* Stomped past end? */
520 equal(one, "a", 48); /* Stomped old tokens? */
521 equal(one+2, "b", 49);
522 equal(one+4, "c", 50);
525 char text[] = "This,is,a,test";
526 char *list = strdupa (text);
527 equal (strsep (&list, ","), "This", 51);
528 equal (strsep (&list, ","), "is", 52);
529 equal (strsep (&list, ","), "a", 53);
530 equal (strsep (&list, ","), "test", 54);
531 check (strsep (&list, ",") == NULL, 55);
534 cp = strcpy(one, "a,b, c,, ,d,");
535 equal(strsep(&cp, ","), "a", 56); /* Different separators. */
536 equal(strsep(&cp, ","), "b", 57);
537 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */
538 equal(strsep(&cp, ","), "", 59);
539 equal(strsep(&cp, ","), " ", 60);
540 equal(strsep(&cp, ","), "d", 61);
541 equal(strsep(&cp, ","), "", 62);
542 check(strsep(&cp, ",") == NULL, 63);
543 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */
545 cp = strcpy(one, "a,b, c,, ,d,");
546 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */
547 equal(strsep(&cp, "x,y"), "b", 66);
548 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */
549 equal(strsep(&cp, "xy,"), "", 68);
550 equal(strsep(&cp, "x,y"), " ", 69);
551 equal(strsep(&cp, ",xy"), "d", 70);
552 equal(strsep(&cp, "xy,"), "", 71);
553 check(strsep(&cp, "x,y") == NULL, 72);
554 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
556 /* memcmp. */
557 it = "memcmp";
558 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
559 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
560 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
561 check(memcmp("abce", "abcd", 4) > 0, 4);
562 check(memcmp("alph", "beta", 4) < 0, 5);
563 check(memcmp("a\203", "a\003", 2) > 0, 6);
564 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
565 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
567 /* memchr. */
568 it = "memchr";
569 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
570 (void) strcpy(one, "abcd");
571 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
572 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
573 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
574 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
575 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
576 (void) strcpy(one, "ababa");
577 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
578 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
579 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
580 (void) strcpy(one, "a\203b");
581 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
583 /* now test all possible alignment and length combinations to catch
584 bugs due to unrolled loops (assuming unrolling is limited to no
585 more than 128 byte chunks: */
587 char buf[128 + sizeof(long)];
588 long align, len, i, pos;
590 for (align = 0; align < (long) sizeof(long); ++align) {
591 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
592 for (i = 0; i < len; ++i) {
593 buf[align + i] = 'x'; /* don't depend on memset... */
595 for (pos = 0; pos < len; ++pos) {
596 #if 0
597 printf("align %d, len %d, pos %d\n", align, len, pos);
598 #endif
599 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
600 check(memchr(buf + align, 'x', pos) == NULL, 11);
601 buf[align + pos] = '-';
607 /* memcpy - need not work for overlap. */
608 it = "memcpy";
609 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
610 equal(one, "abc", 2); /* Did the copy go right? */
612 (void) strcpy(one, "abcdefgh");
613 (void) memcpy(one+1, "xyz", 2);
614 equal(one, "axydefgh", 3); /* Basic test. */
616 (void) strcpy(one, "abc");
617 (void) memcpy(one, "xyz", 0);
618 equal(one, "abc", 4); /* Zero-length copy. */
620 (void) strcpy(one, "hi there");
621 (void) strcpy(two, "foo");
622 (void) memcpy(two, one, 9);
623 equal(two, "hi there", 5); /* Just paranoia. */
624 equal(one, "hi there", 6); /* Stomped on source? */
626 /* memmove - must work on overlap. */
627 it = "memmove";
628 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
629 equal(one, "abc", 2); /* Did the copy go right? */
631 (void) strcpy(one, "abcdefgh");
632 (void) memmove(one+1, "xyz", 2);
633 equal(one, "axydefgh", 3); /* Basic test. */
635 (void) strcpy(one, "abc");
636 (void) memmove(one, "xyz", 0);
637 equal(one, "abc", 4); /* Zero-length copy. */
639 (void) strcpy(one, "hi there");
640 (void) strcpy(two, "foo");
641 (void) memmove(two, one, 9);
642 equal(two, "hi there", 5); /* Just paranoia. */
643 equal(one, "hi there", 6); /* Stomped on source? */
645 (void) strcpy(one, "abcdefgh");
646 (void) memmove(one+1, one, 9);
647 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
649 (void) strcpy(one, "abcdefgh");
650 (void) memmove(one+1, one+2, 7);
651 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
653 (void) strcpy(one, "abcdefgh");
654 (void) memmove(one, one, 9);
655 equal(one, "abcdefgh", 9); /* 100% overlap. */
657 /* memccpy - first test like memcpy, then the search part
658 The SVID, the only place where memccpy is mentioned, says
659 overlap might fail, so we don't try it. Besides, it's hard
660 to see the rationale for a non-left-to-right memccpy. */
661 it = "memccpy";
662 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
663 equal(one, "abc", 2); /* Did the copy go right? */
665 (void) strcpy(one, "abcdefgh");
666 (void) memccpy(one+1, "xyz", 'q', 2);
667 equal(one, "axydefgh", 3); /* Basic test. */
669 (void) strcpy(one, "abc");
670 (void) memccpy(one, "xyz", 'q', 0);
671 equal(one, "abc", 4); /* Zero-length copy. */
673 (void) strcpy(one, "hi there");
674 (void) strcpy(two, "foo");
675 (void) memccpy(two, one, 'q', 9);
676 equal(two, "hi there", 5); /* Just paranoia. */
677 equal(one, "hi there", 6); /* Stomped on source? */
679 (void) strcpy(one, "abcdefgh");
680 (void) strcpy(two, "horsefeathers");
681 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
682 equal(one, "abcdefgh", 8); /* Source intact? */
683 equal(two, "abcdefeathers", 9); /* Copy correct? */
685 (void) strcpy(one, "abcd");
686 (void) strcpy(two, "bumblebee");
687 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
688 equal(two, "aumblebee", 11);
689 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
690 equal(two, "abcdlebee", 13);
691 (void) strcpy(one, "xyz");
692 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
693 equal(two, "xbcdlebee", 15);
695 /* memset. */
696 it = "memset";
697 (void) strcpy(one, "abcdefgh");
698 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
699 equal(one, "axxxefgh", 2); /* Basic test. */
701 (void) memset(one+2, 'y', 0);
702 equal(one, "axxxefgh", 3); /* Zero-length set. */
704 (void) memset(one+5, 0, 1);
705 equal(one, "axxxe", 4); /* Zero fill. */
706 equal(one+6, "gh", 5); /* And the leftover. */
708 (void) memset(one+2, 010045, 1);
709 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
711 /* bcopy - much like memcpy.
712 Berklix manual is silent about overlap, so don't test it. */
713 it = "bcopy";
714 (void) bcopy("abc", one, 4);
715 equal(one, "abc", 1); /* Simple copy. */
717 (void) strcpy(one, "abcdefgh");
718 (void) bcopy("xyz", one+1, 2);
719 equal(one, "axydefgh", 2); /* Basic test. */
721 (void) strcpy(one, "abc");
722 (void) bcopy("xyz", one, 0);
723 equal(one, "abc", 3); /* Zero-length copy. */
725 (void) strcpy(one, "hi there");
726 (void) strcpy(two, "foo");
727 (void) bcopy(one, two, 9);
728 equal(two, "hi there", 4); /* Just paranoia. */
729 equal(one, "hi there", 5); /* Stomped on source? */
731 /* bzero. */
732 it = "bzero";
733 (void) strcpy(one, "abcdef");
734 bzero(one+2, 2);
735 equal(one, "ab", 1); /* Basic test. */
736 equal(one+3, "", 2);
737 equal(one+4, "ef", 3);
739 (void) strcpy(one, "abcdef");
740 bzero(one+2, 0);
741 equal(one, "abcdef", 4); /* Zero-length copy. */
743 #if 0
744 /* bcmp - somewhat like memcmp. */
745 it = "bcmp";
746 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
747 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
748 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
749 check(bcmp("abce", "abcd", 4) != 0, 4);
750 check(bcmp("alph", "beta", 4) != 0, 5);
751 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
752 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
753 #endif
756 char text[] = "This,is,a,test";
757 char *list = text;
758 it = "strsep";
759 check (!strcmp ("This", strsep (&list, ",")), 1);
760 check (!strcmp ("is", strsep (&list, ",")), 2);
761 check (!strcmp ("a", strsep (&list, ",")), 3);
762 check (!strcmp ("test", strsep (&list, ",")), 4);
763 check (strsep (&list, ",") == NULL, 5);
766 /* strerror - VERY system-dependent. */
768 int f;
769 it = "strerror";
770 f = __open("/", O_WRONLY); /* Should always fail. */
771 check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
772 equal(strerror(errno), _sys_errlist[errno], 2);
776 int status;
777 if (errors == 0)
779 status = EXIT_SUCCESS;
780 puts("No errors.");
782 else
784 status = EXIT_FAILURE;
785 printf("%Zd errors.\n", errors);
787 exit(status);