12 #define _sys_nerr sys_nerr
13 #define _sys_errlist sys_errlist
16 #define STREQ(a, b) (strcmp((a), (b)) == 0)
18 const char *it = "<UNSET>"; /* Routine name for message routines. */
21 /* Complain if condition is not true. */
23 check (int thing, int number)
27 printf("%s flunked test %d\n", it, number);
32 /* Complain if first two args don't strcmp as equal. */
33 void equal (const char *a, const char *b, int number)
35 check(a != NULL && b != NULL && STREQ (a, b), number);
46 /* Test strcmp first because we use it to test other things. */
48 check (strcmp ("", "") == 0, 1); /* Trivial case. */
49 check (strcmp ("a", "a") == 0, 2); /* Identity. */
50 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
51 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
52 check (strcmp ("abcd", "abc") > 0, 5);
53 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
54 check (strcmp ("abce", "abcd") > 0, 7);
55 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
56 check (strcmp ("a\203", "a\003") > 0, 9);
59 char buf1[0x40], buf2[0x40];
61 for (i=0; i < 0x10; i++)
62 for (j = 0; j < 0x10; j++)
65 for (k = 0; k < 0x3f; k++)
67 buf1[j] = '0' ^ (k & 4);
68 buf2[j] = '4' ^ (k & 4);
70 buf1[i] = buf1[0x3f] = 0;
71 buf2[j] = buf2[0x3f] = 0;
72 for (k = 0; k < 0xf; k++)
74 int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
75 check (strcmp (buf1+i,buf2+j) == 0, cnum);
76 buf1[i+k] = 'A' + i + k;
78 check (strcmp (buf1+i,buf2+j) > 0, cnum+1);
79 check (strcmp (buf2+j,buf1+i) < 0, cnum+2);
80 buf2[j+k] = 'B' + i + k;
82 check (strcmp (buf1+i,buf2+j) < 0, cnum+3);
83 check (strcmp (buf2+j,buf1+i) > 0, cnum+4);
84 buf2[j+k] = 'A' + i + k;
85 buf1[i] = 'A' + i + 0x80;
86 check (strcmp (buf1+i,buf2+j) > 0, cnum+5);
87 check (strcmp (buf2+j,buf1+i) < 0, cnum+6);
93 /* Test strcpy next because we need it to set up other tests. */
95 check (strcpy (one, "abcd") == one, 1); /* Returned value. */
96 equal (one, "abcd", 2); /* Basic test. */
98 (void) strcpy (one, "x");
99 equal (one, "x", 3); /* Writeover. */
100 equal (one+2, "cd", 4); /* Wrote too much? */
102 (void) strcpy (two, "hi there");
103 (void) strcpy (one, two);
104 equal (one, "hi there", 5); /* Basic test encore. */
105 equal (two, "hi there", 6); /* Stomped on source? */
107 (void) strcpy (one, "");
108 equal (one, "", 7); /* Boundary condition. */
110 /* A closely related function is stpcpy. */
112 check ((stpcpy (one, "abcde") - one) == 5, 1);
113 equal (one, "abcde", 2);
115 check ((stpcpy (one, "x") - one) == 1, 3);
116 equal (one, "x", 4); /* Writeover. */
117 equal (one+2, "cde", 5); /* Wrote too much? */
119 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 6);
120 equal (one, "abc", 7);
121 equal (one + 4, "e", 8);
126 memset (one, 'x', sizeof (one));
127 check (stpncpy (one, "abc", 2) == one + 2, 1);
128 check (stpncpy (one, "abc", 3) == one + 3, 2);
129 check (stpncpy (one, "abc", 4) == one + 3, 3);
130 check (one[3] == '\0' && one[4] == 'x', 4);
131 check (stpncpy (one, "abcd", 5) == one + 4, 5);
132 check (one[4] == '\0' && one[5] == 'x', 6);
133 check (stpncpy (one, "abcd", 6) == one + 4, 7);
134 check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
138 (void) strcpy (one, "ijk");
139 check (strcat (one, "lmn") == one, 1); /* Returned value. */
140 equal (one, "ijklmn", 2); /* Basic test. */
142 (void) strcpy (one, "x");
143 (void) strcat (one, "yz");
144 equal (one, "xyz", 3); /* Writeover. */
145 equal (one+4, "mn", 4); /* Wrote too much? */
147 (void) strcpy (one, "gh");
148 (void) strcpy (two, "ef");
149 (void) strcat (one, two);
150 equal (one, "ghef", 5); /* Basic test encore. */
151 equal (two, "ef", 6); /* Stomped on source? */
153 (void) strcpy (one, "");
154 (void) strcat (one, "");
155 equal (one, "", 7); /* Boundary conditions. */
156 (void) strcpy (one, "ab");
157 (void) strcat (one, "");
158 equal (one, "ab", 8);
159 (void) strcpy (one, "");
160 (void) strcat (one, "cd");
161 equal (one, "cd", 9);
163 /* strncat - first test it as strcat, with big counts,
164 then test the count mechanism. */
166 (void) strcpy (one, "ijk");
167 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
168 equal (one, "ijklmn", 2); /* Basic test. */
170 (void) strcpy (one, "x");
171 (void) strncat (one, "yz", 99);
172 equal (one, "xyz", 3); /* Writeover. */
173 equal (one+4, "mn", 4); /* Wrote too much? */
175 (void) strcpy (one, "gh");
176 (void) strcpy (two, "ef");
177 (void) strncat (one, two, 99);
178 equal (one, "ghef", 5); /* Basic test encore. */
179 equal (two, "ef", 6); /* Stomped on source? */
181 (void) strcpy (one, "");
182 (void) strncat (one, "", 99);
183 equal (one, "", 7); /* Boundary conditions. */
184 (void) strcpy (one, "ab");
185 (void) strncat (one, "", 99);
186 equal (one, "ab", 8);
187 (void) strcpy (one, "");
188 (void) strncat (one, "cd", 99);
189 equal (one, "cd", 9);
191 (void) strcpy (one, "ab");
192 (void) strncat (one, "cdef", 2);
193 equal (one, "abcd", 10); /* Count-limited. */
195 (void) strncat (one, "gh", 0);
196 equal (one, "abcd", 11); /* Zero count. */
198 (void) strncat (one, "gh", 2);
199 equal (one, "abcdgh", 12); /* Count and length equal. */
201 /* strncmp - first test as strcmp with big counts,
202 then test count code. */
204 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
205 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
206 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
207 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
208 check (strncmp ("abcd", "abc", 99) > 0, 5);
209 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
210 check (strncmp ("abce", "abcd", 99) > 0, 7);
211 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
212 check (strncmp ("a\203", "a\003", 2) > 0, 9);
213 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
214 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
215 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
216 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
218 /* strncpy - testing is a bit different because of odd semantics. */
220 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
221 equal (one, "abc", 2); /* Did the copy go right? */
223 (void) strcpy (one, "abcdefgh");
224 (void) strncpy (one, "xyz", 2);
225 equal (one, "xycdefgh", 3); /* Copy cut by count. */
227 (void) strcpy (one, "abcdefgh");
228 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
229 equal (one, "xyzdefgh", 4);
231 (void) strcpy (one, "abcdefgh");
232 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
233 equal (one, "xyz", 5);
234 equal (one+4, "efgh", 6); /* Wrote too much? */
236 (void) strcpy (one, "abcdefgh");
237 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
238 equal (one, "xyz", 7);
239 equal (one+4, "", 8);
240 equal (one+5, "fgh", 9);
242 (void) strcpy (one, "abc");
243 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
244 equal (one, "abc", 10);
246 (void) strncpy (one, "", 2); /* Zero-length source. */
248 equal (one+1, "", 12);
249 equal (one+2, "c", 13);
251 (void) strcpy (one, "hi there");
252 (void) strncpy (two, one, 9);
253 equal (two, "hi there", 14); /* Just paranoia. */
254 equal (one, "hi there", 15); /* Stomped on source? */
258 check (strlen ("") == 0, 1); /* Empty. */
259 check (strlen ("a") == 1, 2); /* Single char. */
260 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
265 for (i=0; i < 0x100; i++)
267 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
269 strcpy (p+3, "BAD/WRONG");
270 check (strlen (p) == 2, 4+i);
276 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
277 (void) strcpy (one, "abcd");
278 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
279 check (strchr (one, 'd') == one+3, 3); /* End of string. */
280 check (strchr (one, 'a') == one, 4); /* Beginning. */
281 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
282 (void) strcpy (one, "ababa");
283 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
284 (void) strcpy (one, "");
285 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
286 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
291 for (i=0; i < 0x100; i++)
293 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
295 strcpy (p+3, "BAD/WRONG");
296 check (strchr (p, '/') == NULL, 9+i);
301 /* index - just like strchr. */
303 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
304 (void) strcpy (one, "abcd");
305 check (index (one, 'c') == one+2, 2); /* Basic test. */
306 check (index (one, 'd') == one+3, 3); /* End of string. */
307 check (index (one, 'a') == one, 4); /* Beginning. */
308 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
309 (void) strcpy (one, "ababa");
310 check (index (one, 'b') == one+1, 6); /* Finding first. */
311 (void) strcpy (one, "");
312 check (index (one, 'b') == NULL, 7); /* Empty string. */
313 check (index (one, '\0') == one, 8); /* NUL in empty string. */
318 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
319 (void) strcpy (one, "abcd");
320 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
321 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
322 check (strrchr (one, 'a') == one, 4); /* Beginning. */
323 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
324 (void) strcpy (one, "ababa");
325 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
326 (void) strcpy (one, "");
327 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
328 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
333 for (i=0; i < 0x100; i++)
335 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
337 strcpy (p+3, "BAD/WRONG");
338 check (strrchr (p, '/') == NULL, 9+i);
343 /* rindex - just like strrchr. */
345 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
346 (void) strcpy (one, "abcd");
347 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
348 check (rindex (one, 'd') == one+3, 3); /* End of string. */
349 check (rindex (one, 'a') == one, 4); /* Beginning. */
350 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
351 (void) strcpy (one, "ababa");
352 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
353 (void) strcpy (one, "");
354 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
355 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
358 /* strpbrk - somewhat like strchr. */
360 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
361 (void) strcpy(one, "abcd");
362 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
363 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
364 check(strpbrk(one, "a") == one, 4); /* Beginning. */
365 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
366 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
367 (void) strcpy(one, "abcabdea");
368 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
369 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
370 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
371 (void) strcpy(one, "");
372 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
373 check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
375 /* strstr - somewhat like strchr. */
377 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
378 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
379 (void) strcpy(one, "abcd");
380 check(strstr(one, "c") == one+2, 3); /* Basic test. */
381 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
382 check(strstr(one, "d") == one+3, 5); /* End of string. */
383 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
384 check(strstr(one, "abc") == one, 7); /* Beginning. */
385 check(strstr(one, "abcd") == one, 8); /* Exact match. */
386 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
387 check(strstr(one, "de") == NULL, 10); /* Past end. */
388 check(strstr(one, "") == one, 11); /* Finding empty. */
389 (void) strcpy(one, "ababa");
390 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
391 (void) strcpy(one, "");
392 check(strstr(one, "b") == NULL, 13); /* Empty string. */
393 check(strstr(one, "") == one, 14); /* Empty in empty string. */
394 (void) strcpy(one, "bcbca");
395 check(strstr(one, "bca") == one+2, 15); /* False start. */
396 (void) strcpy(one, "bbbcabbca");
397 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
401 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
402 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
403 check(strspn("abc", "qx") == 0, 3); /* None. */
404 check(strspn("", "ab") == 0, 4); /* Null string. */
405 check(strspn("abc", "") == 0, 5); /* Null search list. */
409 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
410 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
411 check(strcspn("abc", "abc") == 0, 3); /* None. */
412 check(strcspn("", "ab") == 0, 4); /* Null string. */
413 check(strcspn("abc", "") == 3, 5); /* Null search list. */
415 /* strtok - the hard one. */
417 (void) strcpy(one, "first, second, third");
418 equal(strtok(one, ", "), "first", 1); /* Basic test. */
419 equal(one, "first", 2);
420 equal(strtok((char *)NULL, ", "), "second", 3);
421 equal(strtok((char *)NULL, ", "), "third", 4);
422 check(strtok((char *)NULL, ", ") == NULL, 5);
423 (void) strcpy(one, ", first, ");
424 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
425 check(strtok((char *)NULL, ", ") == NULL, 7);
426 (void) strcpy(one, "1a, 1b; 2a, 2b");
427 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
428 equal(strtok((char *)NULL, "; "), "1b", 9);
429 equal(strtok((char *)NULL, ", "), "2a", 10);
430 (void) strcpy(two, "x-y");
431 equal(strtok(two, "-"), "x", 11); /* New string before done. */
432 equal(strtok((char *)NULL, "-"), "y", 12);
433 check(strtok((char *)NULL, "-") == NULL, 13);
434 (void) strcpy(one, "a,b, c,, ,d");
435 equal(strtok(one, ", "), "a", 14); /* Different separators. */
436 equal(strtok((char *)NULL, ", "), "b", 15);
437 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
438 equal(strtok((char *)NULL, " ,"), "d", 17);
439 check(strtok((char *)NULL, ", ") == NULL, 18);
440 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
441 (void) strcpy(one, ", ");
442 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
443 (void) strcpy(one, "");
444 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
445 (void) strcpy(one, "abc");
446 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
447 check(strtok((char *)NULL, ", ") == NULL, 23);
448 (void) strcpy(one, "abc");
449 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
450 check(strtok((char *)NULL, "") == NULL, 25);
451 (void) strcpy(one, "abcdefgh");
452 (void) strcpy(one, "a,b,c");
453 equal(strtok(one, ","), "a", 26); /* Basics again... */
454 equal(strtok((char *)NULL, ","), "b", 27);
455 equal(strtok((char *)NULL, ","), "c", 28);
456 check(strtok((char *)NULL, ",") == NULL, 29);
457 equal(one+6, "gh", 30); /* Stomped past end? */
458 equal(one, "a", 31); /* Stomped old tokens? */
459 equal(one+2, "b", 32);
460 equal(one+4, "c", 33);
464 (void) strcpy(one, "first, second, third");
465 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
466 equal(one, "first", 2);
467 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
468 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
469 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
470 (void) strcpy(one, ", first, ");
471 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
472 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
473 (void) strcpy(one, "1a, 1b; 2a, 2b");
474 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
475 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
476 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
477 (void) strcpy(two, "x-y");
478 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
479 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
480 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
481 (void) strcpy(one, "a,b, c,, ,d");
482 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
483 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
484 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
485 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
486 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
487 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
488 (void) strcpy(one, ", ");
489 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
490 (void) strcpy(one, "");
491 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
492 (void) strcpy(one, "abc");
493 equal(strtok_r(one, ", ", &cp), "abc", 22); /* No delimiters. */
494 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 23);
495 (void) strcpy(one, "abc");
496 equal(strtok_r(one, "", &cp), "abc", 24); /* Empty delimiter list. */
497 check(strtok_r((char *)NULL, "", &cp) == NULL, 25);
498 (void) strcpy(one, "abcdefgh");
499 (void) strcpy(one, "a,b,c");
500 equal(strtok_r(one, ",", &cp), "a", 26); /* Basics again... */
501 equal(strtok_r((char *)NULL, ",", &cp), "b", 27);
502 equal(strtok_r((char *)NULL, ",", &cp), "c", 28);
503 check(strtok_r((char *)NULL, ",", &cp) == NULL, 29);
504 equal(one+6, "gh", 30); /* Stomped past end? */
505 equal(one, "a", 31); /* Stomped old tokens? */
506 equal(one+2, "b", 32);
507 equal(one+4, "c", 33);
511 cp = strcpy(one, "first, second, third");
512 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
513 equal(one, "first", 2);
514 equal(strsep(&cp, ", "), "", 3);
515 equal(strsep(&cp, ", "), "second", 4);
516 equal(strsep(&cp, ", "), "", 5);
517 equal(strsep(&cp, ", "), "third", 6);
518 check(strsep(&cp, ", ") == NULL, 7);
519 cp = strcpy(one, ", first, ");
520 equal(strsep(&cp, ", "), "", 8);
521 equal(strsep(&cp, ", "), "", 9);
522 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
523 equal(strsep(&cp, ", "), "", 11);
524 check(strsep(&cp, ", ") == NULL, 12);
525 cp = strcpy(one, "1a, 1b; 2a, 2b");
526 equal(strsep(&cp, ", "), "1a", 13); /* Changing delim lists. */
527 equal(strsep(&cp, ", "), "", 14);
528 equal(strsep(&cp, "; "), "1b", 15);
529 equal(strsep(&cp, ", "), "", 16);
530 equal(strsep(&cp, ", "), "2a", 17);
531 cp = strcpy(two, "x-y");
532 equal(strsep(&cp, "-"), "x", 18); /* New string before done. */
533 equal(strsep(&cp, "-"), "y", 19);
534 check(strsep(&cp, "-") == NULL, 20);
535 cp = strcpy(one, "a,b, c,, ,d");
536 equal(strsep(&cp, ", "), "a", 21); /* Different separators. */
537 equal(strsep(&cp, ", "), "b", 22);
538 equal(strsep(&cp, " ,"), "", 23);
539 equal(strsep(&cp, " ,"), "c", 24); /* Permute list too. */
540 equal(strsep(&cp, " ,"), "", 25);
541 equal(strsep(&cp, " ,"), "", 26);
542 equal(strsep(&cp, " ,"), "", 27);
543 equal(strsep(&cp, " ,"), "d", 28);
544 check(strsep(&cp, ", ") == NULL, 29);
545 check(strsep(&cp, ", ") == NULL, 30); /* Persistence. */
546 cp = strcpy(one, ", ");
547 equal(strsep(&cp, ", "), "", 31);
548 equal(strsep(&cp, ", "), "", 32);
549 check(strsep(&cp, ", ") == NULL, 33); /* No tokens. */
550 cp = strcpy(one, "");
551 check(strsep(&cp, ", ") == NULL, 34); /* Empty string. */
552 cp = strcpy(one, "abc");
553 equal(strsep(&cp, ", "), "abc", 35); /* No delimiters. */
554 check(strsep(&cp, ", ") == NULL, 36);
555 cp = strcpy(one, "abc");
556 equal(strsep(&cp, ""), "abc", 37); /* Empty delimiter list. */
557 check(strsep(&cp, "") == NULL, 38);
558 (void) strcpy(one, "abcdefgh");
559 cp = strcpy(one, "a,b,c");
560 equal(strsep(&cp, ","), "a", 39); /* Basics again... */
561 equal(strsep(&cp, ","), "b", 40);
562 equal(strsep(&cp, ","), "c", 41);
563 check(strsep(&cp, ",") == NULL, 42);
564 equal(one+6, "gh", 43); /* Stomped past end? */
565 equal(one, "a", 44); /* Stomped old tokens? */
566 equal(one+2, "b", 45);
567 equal(one+4, "c", 46);
571 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
572 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
573 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
574 check(memcmp("abce", "abcd", 4) > 0, 4);
575 check(memcmp("alph", "beta", 4) < 0, 5);
576 check(memcmp("a\203", "a\003", 2) > 0, 6);
577 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
578 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
582 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
583 (void) strcpy(one, "abcd");
584 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
585 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
586 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
587 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
588 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
589 (void) strcpy(one, "ababa");
590 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
591 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
592 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
593 (void) strcpy(one, "a\203b");
594 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
596 /* now test all possible alignment and length combinations to catch
597 bugs due to unrolled loops (assuming unrolling is limited to no
598 more than 128 byte chunks: */
600 char buf[128 + sizeof(long)];
601 long align, len, i, pos;
603 for (align = 0; align < (long) sizeof(long); ++align) {
604 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
605 for (i = 0; i < len; ++i) {
606 buf[align + i] = 'x'; /* don't depend on memset... */
608 for (pos = 0; pos < len; ++pos) {
610 printf("align %d, len %d, pos %d\n", align, len, pos);
612 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
613 check(memchr(buf + align, 'x', pos) == NULL, 11);
614 buf[align + pos] = '-';
620 /* memcpy - need not work for overlap. */
622 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
623 equal(one, "abc", 2); /* Did the copy go right? */
625 (void) strcpy(one, "abcdefgh");
626 (void) memcpy(one+1, "xyz", 2);
627 equal(one, "axydefgh", 3); /* Basic test. */
629 (void) strcpy(one, "abc");
630 (void) memcpy(one, "xyz", 0);
631 equal(one, "abc", 4); /* Zero-length copy. */
633 (void) strcpy(one, "hi there");
634 (void) strcpy(two, "foo");
635 (void) memcpy(two, one, 9);
636 equal(two, "hi there", 5); /* Just paranoia. */
637 equal(one, "hi there", 6); /* Stomped on source? */
639 /* memmove - must work on overlap. */
641 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
642 equal(one, "abc", 2); /* Did the copy go right? */
644 (void) strcpy(one, "abcdefgh");
645 (void) memmove(one+1, "xyz", 2);
646 equal(one, "axydefgh", 3); /* Basic test. */
648 (void) strcpy(one, "abc");
649 (void) memmove(one, "xyz", 0);
650 equal(one, "abc", 4); /* Zero-length copy. */
652 (void) strcpy(one, "hi there");
653 (void) strcpy(two, "foo");
654 (void) memmove(two, one, 9);
655 equal(two, "hi there", 5); /* Just paranoia. */
656 equal(one, "hi there", 6); /* Stomped on source? */
658 (void) strcpy(one, "abcdefgh");
659 (void) memmove(one+1, one, 9);
660 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
662 (void) strcpy(one, "abcdefgh");
663 (void) memmove(one+1, one+2, 7);
664 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
666 (void) strcpy(one, "abcdefgh");
667 (void) memmove(one, one, 9);
668 equal(one, "abcdefgh", 9); /* 100% overlap. */
670 /* memccpy - first test like memcpy, then the search part
671 The SVID, the only place where memccpy is mentioned, says
672 overlap might fail, so we don't try it. Besides, it's hard
673 to see the rationale for a non-left-to-right memccpy. */
675 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
676 equal(one, "abc", 2); /* Did the copy go right? */
678 (void) strcpy(one, "abcdefgh");
679 (void) memccpy(one+1, "xyz", 'q', 2);
680 equal(one, "axydefgh", 3); /* Basic test. */
682 (void) strcpy(one, "abc");
683 (void) memccpy(one, "xyz", 'q', 0);
684 equal(one, "abc", 4); /* Zero-length copy. */
686 (void) strcpy(one, "hi there");
687 (void) strcpy(two, "foo");
688 (void) memccpy(two, one, 'q', 9);
689 equal(two, "hi there", 5); /* Just paranoia. */
690 equal(one, "hi there", 6); /* Stomped on source? */
692 (void) strcpy(one, "abcdefgh");
693 (void) strcpy(two, "horsefeathers");
694 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
695 equal(one, "abcdefgh", 8); /* Source intact? */
696 equal(two, "abcdefeathers", 9); /* Copy correct? */
698 (void) strcpy(one, "abcd");
699 (void) strcpy(two, "bumblebee");
700 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
701 equal(two, "aumblebee", 11);
702 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
703 equal(two, "abcdlebee", 13);
704 (void) strcpy(one, "xyz");
705 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
706 equal(two, "xbcdlebee", 15);
710 (void) strcpy(one, "abcdefgh");
711 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
712 equal(one, "axxxefgh", 2); /* Basic test. */
714 (void) memset(one+2, 'y', 0);
715 equal(one, "axxxefgh", 3); /* Zero-length set. */
717 (void) memset(one+5, 0, 1);
718 equal(one, "axxxe", 4); /* Zero fill. */
719 equal(one+6, "gh", 5); /* And the leftover. */
721 (void) memset(one+2, 010045, 1);
722 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
724 /* Test for more complex versions of memset, for all alignments and
725 lengths up to 256. This test takes a little while, perhaps it should
734 for (i = 0; i < 512; i++)
736 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
738 for (j = 0; j < 256; j++)
739 for (i = 0; i < 256; i++)
742 for (k = 0; k < i; k++)
745 for (k = i; k < i+j; k++)
751 for (k = i+j; k < 512; k++)
757 check(0,7+i+j*256+(c != 0)*256*256);
761 /* bcopy - much like memcpy.
762 Berklix manual is silent about overlap, so don't test it. */
764 (void) bcopy("abc", one, 4);
765 equal(one, "abc", 1); /* Simple copy. */
767 (void) strcpy(one, "abcdefgh");
768 (void) bcopy("xyz", one+1, 2);
769 equal(one, "axydefgh", 2); /* Basic test. */
771 (void) strcpy(one, "abc");
772 (void) bcopy("xyz", one, 0);
773 equal(one, "abc", 3); /* Zero-length copy. */
775 (void) strcpy(one, "hi there");
776 (void) strcpy(two, "foo");
777 (void) bcopy(one, two, 9);
778 equal(two, "hi there", 4); /* Just paranoia. */
779 equal(one, "hi there", 5); /* Stomped on source? */
783 (void) strcpy(one, "abcdef");
785 equal(one, "ab", 1); /* Basic test. */
787 equal(one+4, "ef", 3);
789 (void) strcpy(one, "abcdef");
791 equal(one, "abcdef", 4); /* Zero-length copy. */
794 /* bcmp - somewhat like memcmp. */
796 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
797 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
798 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
799 check(bcmp("abce", "abcd", 4) != 0, 4);
800 check(bcmp("alph", "beta", 4) != 0, 5);
801 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
802 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
806 char text[] = "This,is,a,test";
809 check (!strcmp ("This", strsep (&list, ",")), 1);
810 check (!strcmp ("is", strsep (&list, ",")), 2);
811 check (!strcmp ("a", strsep (&list, ",")), 3);
812 check (!strcmp ("test", strsep (&list, ",")), 4);
813 check (strsep (&list, ",") == NULL, 5);
816 /* strerror - VERY system-dependent. */
820 f = __open("/", O_WRONLY); /* Should always fail. */
821 check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
822 equal(strerror(errno), _sys_errlist[errno], 2);
829 status = EXIT_SUCCESS;
834 status = EXIT_FAILURE;
835 printf("%Zd errors.\n", errors);