* Makerules (elfobjdir): Use $(objdir) if set, even in elf subdir.
[glibc.git] / string / tester.c
blob6be3d2dadee34f0ac129584f68f44289368b983c
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 /* strcat. */
75 it = "strcat";
76 (void) strcpy(one, "ijk");
77 check(strcat(one, "lmn") == one, 1); /* Returned value. */
78 equal(one, "ijklmn", 2); /* Basic test. */
80 (void) strcpy(one, "x");
81 (void) strcat(one, "yz");
82 equal(one, "xyz", 3); /* Writeover. */
83 equal(one+4, "mn", 4); /* Wrote too much? */
85 (void) strcpy(one, "gh");
86 (void) strcpy(two, "ef");
87 (void) strcat(one, two);
88 equal(one, "ghef", 5); /* Basic test encore. */
89 equal(two, "ef", 6); /* Stomped on source? */
91 (void) strcpy(one, "");
92 (void) strcat(one, "");
93 equal(one, "", 7); /* Boundary conditions. */
94 (void) strcpy(one, "ab");
95 (void) strcat(one, "");
96 equal(one, "ab", 8);
97 (void) strcpy(one, "");
98 (void) strcat(one, "cd");
99 equal(one, "cd", 9);
101 /* strncat - first test it as strcat, with big counts,
102 then test the count mechanism. */
103 it = "strncat";
104 (void) strcpy(one, "ijk");
105 check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */
106 equal(one, "ijklmn", 2); /* Basic test. */
108 (void) strcpy(one, "x");
109 (void) strncat(one, "yz", 99);
110 equal(one, "xyz", 3); /* Writeover. */
111 equal(one+4, "mn", 4); /* Wrote too much? */
113 (void) strcpy(one, "gh");
114 (void) strcpy(two, "ef");
115 (void) strncat(one, two, 99);
116 equal(one, "ghef", 5); /* Basic test encore. */
117 equal(two, "ef", 6); /* Stomped on source? */
119 (void) strcpy(one, "");
120 (void) strncat(one, "", 99);
121 equal(one, "", 7); /* Boundary conditions. */
122 (void) strcpy(one, "ab");
123 (void) strncat(one, "", 99);
124 equal(one, "ab", 8);
125 (void) strcpy(one, "");
126 (void) strncat(one, "cd", 99);
127 equal(one, "cd", 9);
129 (void) strcpy(one, "ab");
130 (void) strncat(one, "cdef", 2);
131 equal(one, "abcd", 10); /* Count-limited. */
133 (void) strncat(one, "gh", 0);
134 equal(one, "abcd", 11); /* Zero count. */
136 (void) strncat(one, "gh", 2);
137 equal(one, "abcdgh", 12); /* Count and length equal. */
139 /* strncmp - first test as strcmp with big counts,
140 then test count code. */
141 it = "strncmp";
142 check(strncmp("", "", 99) == 0, 1); /* Trivial case. */
143 check(strncmp("a", "a", 99) == 0, 2); /* Identity. */
144 check(strncmp("abc", "abc", 99) == 0, 3); /* Multicharacter. */
145 check(strncmp("abc", "abcd", 99) < 0, 4); /* Length unequal. */
146 check(strncmp("abcd", "abc", 99) > 0, 5);
147 check(strncmp("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
148 check(strncmp("abce", "abcd", 99) > 0, 7);
149 check(strncmp("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
150 check(strncmp("a\203", "a\003", 2) > 0, 9);
151 check(strncmp("abce", "abcd", 3) == 0, 10); /* Count limited. */
152 check(strncmp("abce", "abc", 3) == 0, 11); /* Count == length. */
153 check(strncmp("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
154 check(strncmp("abc", "def", 0) == 0, 13); /* Zero count. */
156 /* strncpy - testing is a bit different because of odd semantics. */
157 it = "strncpy";
158 check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */
159 equal(one, "abc", 2); /* Did the copy go right? */
161 (void) strcpy(one, "abcdefgh");
162 (void) strncpy(one, "xyz", 2);
163 equal(one, "xycdefgh", 3); /* Copy cut by count. */
165 (void) strcpy(one, "abcdefgh");
166 (void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
167 equal(one, "xyzdefgh", 4);
169 (void) strcpy(one, "abcdefgh");
170 (void) strncpy(one, "xyz", 4); /* Copy just includes NUL. */
171 equal(one, "xyz", 5);
172 equal(one+4, "efgh", 6); /* Wrote too much? */
174 (void) strcpy(one, "abcdefgh");
175 (void) strncpy(one, "xyz", 5); /* Copy includes padding. */
176 equal(one, "xyz", 7);
177 equal(one+4, "", 8);
178 equal(one+5, "fgh", 9);
180 (void) strcpy(one, "abc");
181 (void) strncpy(one, "xyz", 0); /* Zero-length copy. */
182 equal(one, "abc", 10);
184 (void) strncpy(one, "", 2); /* Zero-length source. */
185 equal(one, "", 11);
186 equal(one+1, "", 12);
187 equal(one+2, "c", 13);
189 (void) strcpy(one, "hi there");
190 (void) strncpy(two, one, 9);
191 equal(two, "hi there", 14); /* Just paranoia. */
192 equal(one, "hi there", 15); /* Stomped on source? */
194 /* strlen. */
195 it = "strlen";
196 check(strlen("") == 0, 1); /* Empty. */
197 check(strlen("a") == 1, 2); /* Single char. */
198 check(strlen("abcd") == 4, 3); /* Multiple chars. */
200 /* strchr. */
201 it = "strchr";
202 check(strchr("abcd", 'z') == NULL, 1); /* Not found. */
203 (void) strcpy(one, "abcd");
204 check(strchr(one, 'c') == one+2, 2); /* Basic test. */
205 check(strchr(one, 'd') == one+3, 3); /* End of string. */
206 check(strchr(one, 'a') == one, 4); /* Beginning. */
207 check(strchr(one, '\0') == one+4, 5); /* Finding NUL. */
208 (void) strcpy(one, "ababa");
209 check(strchr(one, 'b') == one+1, 6); /* Finding first. */
210 (void) strcpy(one, "");
211 check(strchr(one, 'b') == NULL, 7); /* Empty string. */
212 check(strchr(one, '\0') == one, 8); /* NUL in empty string. */
214 #if 0
215 /* index - just like strchr. */
216 it = "index";
217 check(index("abcd", 'z') == NULL, 1); /* Not found. */
218 (void) strcpy(one, "abcd");
219 check(index(one, 'c') == one+2, 2); /* Basic test. */
220 check(index(one, 'd') == one+3, 3); /* End of string. */
221 check(index(one, 'a') == one, 4); /* Beginning. */
222 check(index(one, '\0') == one+4, 5); /* Finding NUL. */
223 (void) strcpy(one, "ababa");
224 check(index(one, 'b') == one+1, 6); /* Finding first. */
225 (void) strcpy(one, "");
226 check(index(one, 'b') == NULL, 7); /* Empty string. */
227 check(index(one, '\0') == one, 8); /* NUL in empty string. */
228 #endif
230 /* strrchr. */
231 it = "strrchr";
232 check(strrchr("abcd", 'z') == NULL, 1); /* Not found. */
233 (void) strcpy(one, "abcd");
234 check(strrchr(one, 'c') == one+2, 2); /* Basic test. */
235 check(strrchr(one, 'd') == one+3, 3); /* End of string. */
236 check(strrchr(one, 'a') == one, 4); /* Beginning. */
237 check(strrchr(one, '\0') == one+4, 5); /* Finding NUL. */
238 (void) strcpy(one, "ababa");
239 check(strrchr(one, 'b') == one+3, 6); /* Finding last. */
240 (void) strcpy(one, "");
241 check(strrchr(one, 'b') == NULL, 7); /* Empty string. */
242 check(strrchr(one, '\0') == one, 8); /* NUL in empty string. */
244 #if 0
245 /* rindex - just like strrchr. */
246 it = "rindex";
247 check(rindex("abcd", 'z') == NULL, 1); /* Not found. */
248 (void) strcpy(one, "abcd");
249 check(rindex(one, 'c') == one+2, 2); /* Basic test. */
250 check(rindex(one, 'd') == one+3, 3); /* End of string. */
251 check(rindex(one, 'a') == one, 4); /* Beginning. */
252 check(rindex(one, '\0') == one+4, 5); /* Finding NUL. */
253 (void) strcpy(one, "ababa");
254 check(rindex(one, 'b') == one+3, 6); /* Finding last. */
255 (void) strcpy(one, "");
256 check(rindex(one, 'b') == NULL, 7); /* Empty string. */
257 check(rindex(one, '\0') == one, 8); /* NUL in empty string. */
258 #endif
260 /* strpbrk - somewhat like strchr. */
261 it = "strpbrk";
262 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
263 (void) strcpy(one, "abcd");
264 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
265 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
266 check(strpbrk(one, "a") == one, 4); /* Beginning. */
267 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
268 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
269 (void) strcpy(one, "abcabdea");
270 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
271 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
272 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
273 (void) strcpy(one, "");
274 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
275 check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
277 /* strstr - somewhat like strchr. */
278 it = "strstr";
279 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
280 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
281 (void) strcpy(one, "abcd");
282 check(strstr(one, "c") == one+2, 3); /* Basic test. */
283 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
284 check(strstr(one, "d") == one+3, 5); /* End of string. */
285 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
286 check(strstr(one, "abc") == one, 7); /* Beginning. */
287 check(strstr(one, "abcd") == one, 8); /* Exact match. */
288 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
289 check(strstr(one, "de") == NULL, 10); /* Past end. */
290 check(strstr(one, "") == one, 11); /* Finding empty. */
291 (void) strcpy(one, "ababa");
292 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
293 (void) strcpy(one, "");
294 check(strstr(one, "b") == NULL, 13); /* Empty string. */
295 check(strstr(one, "") == one, 14); /* Empty in empty string. */
296 (void) strcpy(one, "bcbca");
297 check(strstr(one, "bca") == one+2, 15); /* False start. */
298 (void) strcpy(one, "bbbcabbca");
299 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
301 /* strspn. */
302 it = "strspn";
303 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
304 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
305 check(strspn("abc", "qx") == 0, 3); /* None. */
306 check(strspn("", "ab") == 0, 4); /* Null string. */
307 check(strspn("abc", "") == 0, 5); /* Null search list. */
309 /* strcspn. */
310 it = "strcspn";
311 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
312 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
313 check(strcspn("abc", "abc") == 0, 3); /* None. */
314 check(strcspn("", "ab") == 0, 4); /* Null string. */
315 check(strcspn("abc", "") == 3, 5); /* Null search list. */
317 /* strtok - the hard one. */
318 it = "strtok";
319 (void) strcpy(one, "first, second, third");
320 equal(strtok(one, ", "), "first", 1); /* Basic test. */
321 equal(one, "first", 2);
322 equal(strtok((char *)NULL, ", "), "second", 3);
323 equal(strtok((char *)NULL, ", "), "third", 4);
324 check(strtok((char *)NULL, ", ") == NULL, 5);
325 (void) strcpy(one, ", first, ");
326 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
327 check(strtok((char *)NULL, ", ") == NULL, 7);
328 (void) strcpy(one, "1a, 1b; 2a, 2b");
329 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
330 equal(strtok((char *)NULL, "; "), "1b", 9);
331 equal(strtok((char *)NULL, ", "), "2a", 10);
332 (void) strcpy(two, "x-y");
333 equal(strtok(two, "-"), "x", 11); /* New string before done. */
334 equal(strtok((char *)NULL, "-"), "y", 12);
335 check(strtok((char *)NULL, "-") == NULL, 13);
336 (void) strcpy(one, "a,b, c,, ,d");
337 equal(strtok(one, ", "), "a", 14); /* Different separators. */
338 equal(strtok((char *)NULL, ", "), "b", 15);
339 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
340 equal(strtok((char *)NULL, " ,"), "d", 17);
341 check(strtok((char *)NULL, ", ") == NULL, 18);
342 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
343 (void) strcpy(one, ", ");
344 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
345 (void) strcpy(one, "");
346 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
347 (void) strcpy(one, "abc");
348 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
349 check(strtok((char *)NULL, ", ") == NULL, 23);
350 (void) strcpy(one, "abc");
351 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
352 check(strtok((char *)NULL, "") == NULL, 25);
353 (void) strcpy(one, "abcdefgh");
354 (void) strcpy(one, "a,b,c");
355 equal(strtok(one, ","), "a", 26); /* Basics again... */
356 equal(strtok((char *)NULL, ","), "b", 27);
357 equal(strtok((char *)NULL, ","), "c", 28);
358 check(strtok((char *)NULL, ",") == NULL, 29);
359 equal(one+6, "gh", 30); /* Stomped past end? */
360 equal(one, "a", 31); /* Stomped old tokens? */
361 equal(one+2, "b", 32);
362 equal(one+4, "c", 33);
364 /* strtok_r. */
365 it = "strtok_r";
366 (void) strcpy(one, "first, second, third");
367 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
368 equal(one, "first", 2);
369 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
370 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
371 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
372 (void) strcpy(one, ", first, ");
373 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
374 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
375 (void) strcpy(one, "1a, 1b; 2a, 2b");
376 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
377 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
378 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
379 (void) strcpy(two, "x-y");
380 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
381 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
382 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
383 (void) strcpy(one, "a,b, c,, ,d");
384 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
385 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
386 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
387 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
388 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
389 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
390 (void) strcpy(one, ", ");
391 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
392 (void) strcpy(one, "");
393 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
394 (void) strcpy(one, "abc");
395 equal(strtok_r(one, ", ", &cp), "abc", 22); /* No delimiters. */
396 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 23);
397 (void) strcpy(one, "abc");
398 equal(strtok_r(one, "", &cp), "abc", 24); /* Empty delimiter list. */
399 check(strtok_r((char *)NULL, "", &cp) == NULL, 25);
400 (void) strcpy(one, "abcdefgh");
401 (void) strcpy(one, "a,b,c");
402 equal(strtok_r(one, ",", &cp), "a", 26); /* Basics again... */
403 equal(strtok_r((char *)NULL, ",", &cp), "b", 27);
404 equal(strtok_r((char *)NULL, ",", &cp), "c", 28);
405 check(strtok_r((char *)NULL, ",", &cp) == NULL, 29);
406 equal(one+6, "gh", 30); /* Stomped past end? */
407 equal(one, "a", 31); /* Stomped old tokens? */
408 equal(one+2, "b", 32);
409 equal(one+4, "c", 33);
411 /* strsep. */
412 it = "strsep";
413 cp = strcpy(one, "first, second, third");
414 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
415 equal(one, "first", 2);
416 equal(strsep(&cp, ", "), "", 3);
417 equal(strsep(&cp, ", "), "second", 4);
418 equal(strsep(&cp, ", "), "", 5);
419 equal(strsep(&cp, ", "), "third", 6);
420 check(strsep(&cp, ", ") == NULL, 7);
421 cp = strcpy(one, ", first, ");
422 equal(strsep(&cp, ", "), "", 8);
423 equal(strsep(&cp, ", "), "", 9);
424 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
425 equal(strsep(&cp, ", "), "", 11);
426 check(strsep(&cp, ", ") == NULL, 12);
427 cp = strcpy(one, "1a, 1b; 2a, 2b");
428 equal(strsep(&cp, ", "), "1a", 13); /* Changing delim lists. */
429 equal(strsep(&cp, ", "), "", 14);
430 equal(strsep(&cp, "; "), "1b", 15);
431 equal(strsep(&cp, ", "), "", 16);
432 equal(strsep(&cp, ", "), "2a", 17);
433 cp = strcpy(two, "x-y");
434 equal(strsep(&cp, "-"), "x", 18); /* New string before done. */
435 equal(strsep(&cp, "-"), "y", 19);
436 check(strsep(&cp, "-") == NULL, 20);
437 cp = strcpy(one, "a,b, c,, ,d");
438 equal(strsep(&cp, ", "), "a", 21); /* Different separators. */
439 equal(strsep(&cp, ", "), "b", 22);
440 equal(strsep(&cp, " ,"), "", 23);
441 equal(strsep(&cp, " ,"), "c", 24); /* Permute list too. */
442 equal(strsep(&cp, " ,"), "", 25);
443 equal(strsep(&cp, " ,"), "", 26);
444 equal(strsep(&cp, " ,"), "", 27);
445 equal(strsep(&cp, " ,"), "d", 28);
446 check(strsep(&cp, ", ") == NULL, 29);
447 check(strsep(&cp, ", ") == NULL, 30); /* Persistence. */
448 cp = strcpy(one, ", ");
449 equal(strsep(&cp, ", "), "", 31);
450 equal(strsep(&cp, ", "), "", 32);
451 check(strsep(&cp, ", ") == NULL, 33); /* No tokens. */
452 cp = strcpy(one, "");
453 check(strsep(&cp, ", ") == NULL, 34); /* Empty string. */
454 cp = strcpy(one, "abc");
455 equal(strsep(&cp, ", "), "abc", 35); /* No delimiters. */
456 check(strsep(&cp, ", ") == NULL, 36);
457 cp = strcpy(one, "abc");
458 equal(strsep(&cp, ""), "abc", 37); /* Empty delimiter list. */
459 check(strsep(&cp, "") == NULL, 38);
460 (void) strcpy(one, "abcdefgh");
461 cp = strcpy(one, "a,b,c");
462 equal(strsep(&cp, ","), "a", 39); /* Basics again... */
463 equal(strsep(&cp, ","), "b", 40);
464 equal(strsep(&cp, ","), "c", 41);
465 check(strsep(&cp, ",") == NULL, 42);
466 equal(one+6, "gh", 43); /* Stomped past end? */
467 equal(one, "a", 44); /* Stomped old tokens? */
468 equal(one+2, "b", 45);
469 equal(one+4, "c", 46);
471 /* memcmp. */
472 it = "memcmp";
473 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
474 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
475 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
476 check(memcmp("abce", "abcd", 4) > 0, 4);
477 check(memcmp("alph", "beta", 4) < 0, 5);
478 check(memcmp("a\203", "a\003", 2) > 0, 6);
479 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
480 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
482 /* memchr. */
483 it = "memchr";
484 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
485 (void) strcpy(one, "abcd");
486 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
487 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
488 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
489 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
490 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
491 (void) strcpy(one, "ababa");
492 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
493 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
494 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
495 (void) strcpy(one, "a\203b");
496 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
498 /* now test all possible alignment and length combinations to catch
499 bugs due to unrolled loops (assuming unrolling is limited to no
500 more than 128 byte chunks: */
502 char buf[128 + sizeof(long)];
503 long align, len, i, pos;
505 for (align = 0; align < sizeof(long); ++align) {
506 for (len = 0; len < sizeof(buf) - align; ++len) {
507 for (i = 0; i < len; ++i) {
508 buf[align + i] = 'x'; /* don't depend on memset... */
510 for (pos = 0; pos < len; ++pos) {
511 #if 0
512 printf("align %d, len %d, pos %d\n", align, len, pos);
513 #endif
514 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
515 check(memchr(buf + align, 'x', pos) == NULL, 11);
516 buf[align + pos] = '-';
522 /* memcpy - need not work for overlap. */
523 it = "memcpy";
524 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
525 equal(one, "abc", 2); /* Did the copy go right? */
527 (void) strcpy(one, "abcdefgh");
528 (void) memcpy(one+1, "xyz", 2);
529 equal(one, "axydefgh", 3); /* Basic test. */
531 (void) strcpy(one, "abc");
532 (void) memcpy(one, "xyz", 0);
533 equal(one, "abc", 4); /* Zero-length copy. */
535 (void) strcpy(one, "hi there");
536 (void) strcpy(two, "foo");
537 (void) memcpy(two, one, 9);
538 equal(two, "hi there", 5); /* Just paranoia. */
539 equal(one, "hi there", 6); /* Stomped on source? */
541 /* memmove - must work on overlap. */
542 it = "memmove";
543 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
544 equal(one, "abc", 2); /* Did the copy go right? */
546 (void) strcpy(one, "abcdefgh");
547 (void) memmove(one+1, "xyz", 2);
548 equal(one, "axydefgh", 3); /* Basic test. */
550 (void) strcpy(one, "abc");
551 (void) memmove(one, "xyz", 0);
552 equal(one, "abc", 4); /* Zero-length copy. */
554 (void) strcpy(one, "hi there");
555 (void) strcpy(two, "foo");
556 (void) memmove(two, one, 9);
557 equal(two, "hi there", 5); /* Just paranoia. */
558 equal(one, "hi there", 6); /* Stomped on source? */
560 (void) strcpy(one, "abcdefgh");
561 (void) memmove(one+1, one, 9);
562 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
564 (void) strcpy(one, "abcdefgh");
565 (void) memmove(one+1, one+2, 7);
566 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
568 (void) strcpy(one, "abcdefgh");
569 (void) memmove(one, one, 9);
570 equal(one, "abcdefgh", 9); /* 100% overlap. */
572 /* memccpy - first test like memcpy, then the search part
573 The SVID, the only place where memccpy is mentioned, says
574 overlap might fail, so we don't try it. Besides, it's hard
575 to see the rationale for a non-left-to-right memccpy. */
576 it = "memccpy";
577 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
578 equal(one, "abc", 2); /* Did the copy go right? */
580 (void) strcpy(one, "abcdefgh");
581 (void) memccpy(one+1, "xyz", 'q', 2);
582 equal(one, "axydefgh", 3); /* Basic test. */
584 (void) strcpy(one, "abc");
585 (void) memccpy(one, "xyz", 'q', 0);
586 equal(one, "abc", 4); /* Zero-length copy. */
588 (void) strcpy(one, "hi there");
589 (void) strcpy(two, "foo");
590 (void) memccpy(two, one, 'q', 9);
591 equal(two, "hi there", 5); /* Just paranoia. */
592 equal(one, "hi there", 6); /* Stomped on source? */
594 (void) strcpy(one, "abcdefgh");
595 (void) strcpy(two, "horsefeathers");
596 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
597 equal(one, "abcdefgh", 8); /* Source intact? */
598 equal(two, "abcdefeathers", 9); /* Copy correct? */
600 (void) strcpy(one, "abcd");
601 (void) strcpy(two, "bumblebee");
602 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
603 equal(two, "aumblebee", 11);
604 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
605 equal(two, "abcdlebee", 13);
606 (void) strcpy(one, "xyz");
607 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
608 equal(two, "xbcdlebee", 15);
610 /* memset. */
611 it = "memset";
612 (void) strcpy(one, "abcdefgh");
613 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
614 equal(one, "axxxefgh", 2); /* Basic test. */
616 (void) memset(one+2, 'y', 0);
617 equal(one, "axxxefgh", 3); /* Zero-length set. */
619 (void) memset(one+5, 0, 1);
620 equal(one, "axxxe", 4); /* Zero fill. */
621 equal(one+6, "gh", 5); /* And the leftover. */
623 (void) memset(one+2, 010045, 1);
624 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
626 /* bcopy - much like memcpy.
627 Berklix manual is silent about overlap, so don't test it. */
628 it = "bcopy";
629 (void) bcopy("abc", one, 4);
630 equal(one, "abc", 1); /* Simple copy. */
632 (void) strcpy(one, "abcdefgh");
633 (void) bcopy("xyz", one+1, 2);
634 equal(one, "axydefgh", 2); /* Basic test. */
636 (void) strcpy(one, "abc");
637 (void) bcopy("xyz", one, 0);
638 equal(one, "abc", 3); /* Zero-length copy. */
640 (void) strcpy(one, "hi there");
641 (void) strcpy(two, "foo");
642 (void) bcopy(one, two, 9);
643 equal(two, "hi there", 4); /* Just paranoia. */
644 equal(one, "hi there", 5); /* Stomped on source? */
646 /* bzero. */
647 it = "bzero";
648 (void) strcpy(one, "abcdef");
649 bzero(one+2, 2);
650 equal(one, "ab", 1); /* Basic test. */
651 equal(one+3, "", 2);
652 equal(one+4, "ef", 3);
654 (void) strcpy(one, "abcdef");
655 bzero(one+2, 0);
656 equal(one, "abcdef", 4); /* Zero-length copy. */
658 #if 0
659 /* bcmp - somewhat like memcmp. */
660 it = "bcmp";
661 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
662 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
663 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
664 check(bcmp("abce", "abcd", 4) != 0, 4);
665 check(bcmp("alph", "beta", 4) != 0, 5);
666 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
667 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
668 #endif
671 char text[] = "This,is,a,test";
672 char *list = text;
673 it = "strsep";
674 check (!strcmp ("This", strsep (&list, ",")), 1);
675 check (!strcmp ("is", strsep (&list, ",")), 2);
676 check (!strcmp ("a", strsep (&list, ",")), 3);
677 check (!strcmp ("test", strsep (&list, ",")), 4);
678 check (strsep (&list, ",") == NULL, 5);
681 /* strerror - VERY system-dependent. */
683 int f;
684 it = "strerror";
685 f = __open("/", O_WRONLY); /* Should always fail. */
686 check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
687 equal(strerror(errno), _sys_errlist[errno], 2);
691 int status;
692 if (errors == 0)
694 status = EXIT_SUCCESS;
695 puts("No errors.");
697 else
699 status = EXIT_FAILURE;
700 printf("%Zd errors.\n", errors);
702 exit(status);