2003-05-16 Roland McGrath <roland@redhat.com>
[glibc.git] / string / tester.c
blob5f0a85110411059a807f22a94841653f972ebc6a
1 /* Tester for string functions.
2 Copyright (C) 1995-2000, 2001, 2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #ifndef _GNU_SOURCE
21 #define _GNU_SOURCE
22 #endif
24 /* Make sure we don't test the optimized inline functions if we want to
25 test the real implementation. */
26 #if !defined DO_STRING_INLINES
27 #undef __USE_STRING_INLINES
28 #endif
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <strings.h>
35 #include <fcntl.h>
37 #ifndef HAVE_GNU_LD
38 #define _sys_nerr sys_nerr
39 #define _sys_errlist sys_errlist
40 #endif
42 #define STREQ(a, b) (strcmp((a), (b)) == 0)
44 const char *it = "<UNSET>"; /* Routine name for message routines. */
45 size_t errors = 0;
47 /* Complain if condition is not true. */
48 static void
49 check (int thing, int number)
51 if (!thing)
53 printf("%s flunked test %d\n", it, number);
54 ++errors;
58 /* Complain if first two args don't strcmp as equal. */
59 static void
60 equal (const char *a, const char *b, int number)
62 check(a != NULL && b != NULL && STREQ (a, b), number);
65 char one[50];
66 char two[50];
67 char *cp;
69 static void
70 test_strcmp (void)
72 it = "strcmp";
73 check (strcmp ("", "") == 0, 1); /* Trivial case. */
74 check (strcmp ("a", "a") == 0, 2); /* Identity. */
75 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
76 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
77 check (strcmp ("abcd", "abc") > 0, 5);
78 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
79 check (strcmp ("abce", "abcd") > 0, 7);
80 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
81 check (strcmp ("a\203", "a\003") > 0, 9);
84 char buf1[0x40], buf2[0x40];
85 int i, j;
86 for (i=0; i < 0x10; i++)
87 for (j = 0; j < 0x10; j++)
89 int k;
90 for (k = 0; k < 0x3f; k++)
92 buf1[k] = '0' ^ (k & 4);
93 buf2[k] = '4' ^ (k & 4);
95 buf1[i] = buf1[0x3f] = 0;
96 buf2[j] = buf2[0x3f] = 0;
97 for (k = 0; k < 0xf; k++)
99 int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
100 check (strcmp (buf1+i,buf2+j) == 0, cnum);
101 buf1[i+k] = 'A' + i + k;
102 buf1[i+k+1] = 0;
103 check (strcmp (buf1+i,buf2+j) > 0, cnum+1);
104 check (strcmp (buf2+j,buf1+i) < 0, cnum+2);
105 buf2[j+k] = 'B' + i + k;
106 buf2[j+k+1] = 0;
107 check (strcmp (buf1+i,buf2+j) < 0, cnum+3);
108 check (strcmp (buf2+j,buf1+i) > 0, cnum+4);
109 buf2[j+k] = 'A' + i + k;
110 buf1[i] = 'A' + i + 0x80;
111 check (strcmp (buf1+i,buf2+j) > 0, cnum+5);
112 check (strcmp (buf2+j,buf1+i) < 0, cnum+6);
113 buf1[i] = 'A' + i;
119 #define SIMPLE_COPY(fn, n, str, ntest) \
120 do { \
121 int __n; \
122 char *cp; \
123 for (__n = 0; __n < (int) sizeof (one); ++__n) \
124 one[__n] = 'Z'; \
125 fn (one, str); \
126 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
127 check (*cp == '0' + (n % 10), ntest); \
128 check (*cp == '\0', ntest); \
129 } while (0)
131 static void
132 test_strcpy (void)
134 int i;
135 it = "strcpy";
136 check (strcpy (one, "abcd") == one, 1); /* Returned value. */
137 equal (one, "abcd", 2); /* Basic test. */
139 (void) strcpy (one, "x");
140 equal (one, "x", 3); /* Writeover. */
141 equal (one+2, "cd", 4); /* Wrote too much? */
143 (void) strcpy (two, "hi there");
144 (void) strcpy (one, two);
145 equal (one, "hi there", 5); /* Basic test encore. */
146 equal (two, "hi there", 6); /* Stomped on source? */
148 (void) strcpy (one, "");
149 equal (one, "", 7); /* Boundary condition. */
151 for (i = 0; i < 16; i++)
153 (void) strcpy (one + i, "hi there"); /* Unaligned destination. */
154 equal (one + i, "hi there", 8 + (i * 2));
155 (void) strcpy (two, one + i); /* Unaligned source. */
156 equal (two, "hi there", 9 + (i * 2));
159 SIMPLE_COPY(strcpy, 0, "", 41);
160 SIMPLE_COPY(strcpy, 1, "1", 42);
161 SIMPLE_COPY(strcpy, 2, "22", 43);
162 SIMPLE_COPY(strcpy, 3, "333", 44);
163 SIMPLE_COPY(strcpy, 4, "4444", 45);
164 SIMPLE_COPY(strcpy, 5, "55555", 46);
165 SIMPLE_COPY(strcpy, 6, "666666", 47);
166 SIMPLE_COPY(strcpy, 7, "7777777", 48);
167 SIMPLE_COPY(strcpy, 8, "88888888", 49);
168 SIMPLE_COPY(strcpy, 9, "999999999", 50);
169 SIMPLE_COPY(strcpy, 10, "0000000000", 51);
170 SIMPLE_COPY(strcpy, 11, "11111111111", 52);
171 SIMPLE_COPY(strcpy, 12, "222222222222", 53);
172 SIMPLE_COPY(strcpy, 13, "3333333333333", 54);
173 SIMPLE_COPY(strcpy, 14, "44444444444444", 55);
174 SIMPLE_COPY(strcpy, 15, "555555555555555", 56);
175 SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);
177 /* Simple test using implicitly coerced `void *' arguments. */
178 const void *src = "frobozz";
179 void *dst = one;
180 check (strcpy (dst, src) == dst, 1);
181 equal (dst, "frobozz", 2);
184 static void
185 test_stpcpy (void)
187 it = "stpcpy";
188 check ((stpcpy (one, "a") - one) == 1, 1);
189 equal (one, "a", 2);
191 check ((stpcpy (one, "ab") - one) == 2, 3);
192 equal (one, "ab", 4);
194 check ((stpcpy (one, "abc") - one) == 3, 5);
195 equal (one, "abc", 6);
197 check ((stpcpy (one, "abcd") - one) == 4, 7);
198 equal (one, "abcd", 8);
200 check ((stpcpy (one, "abcde") - one) == 5, 9);
201 equal (one, "abcde", 10);
203 check ((stpcpy (one, "abcdef") - one) == 6, 11);
204 equal (one, "abcdef", 12);
206 check ((stpcpy (one, "abcdefg") - one) == 7, 13);
207 equal (one, "abcdefg", 14);
209 check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
210 equal (one, "abcdefgh", 16);
212 check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
213 equal (one, "abcdefghi", 18);
215 check ((stpcpy (one, "x") - one) == 1, 19);
216 equal (one, "x", 20); /* Writeover. */
217 equal (one+2, "cdefghi", 21); /* Wrote too much? */
219 check ((stpcpy (one, "xx") - one) == 2, 22);
220 equal (one, "xx", 23); /* Writeover. */
221 equal (one+3, "defghi", 24); /* Wrote too much? */
223 check ((stpcpy (one, "xxx") - one) == 3, 25);
224 equal (one, "xxx", 26); /* Writeover. */
225 equal (one+4, "efghi", 27); /* Wrote too much? */
227 check ((stpcpy (one, "xxxx") - one) == 4, 28);
228 equal (one, "xxxx", 29); /* Writeover. */
229 equal (one+5, "fghi", 30); /* Wrote too much? */
231 check ((stpcpy (one, "xxxxx") - one) == 5, 31);
232 equal (one, "xxxxx", 32); /* Writeover. */
233 equal (one+6, "ghi", 33); /* Wrote too much? */
235 check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
236 equal (one, "xxxxxx", 35); /* Writeover. */
237 equal (one+7, "hi", 36); /* Wrote too much? */
239 check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
240 equal (one, "xxxxxxx", 38); /* Writeover. */
241 equal (one+8, "i", 39); /* Wrote too much? */
243 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
244 equal (one, "abc", 41);
245 equal (one + 4, "xxx", 42);
247 SIMPLE_COPY(stpcpy, 0, "", 43);
248 SIMPLE_COPY(stpcpy, 1, "1", 44);
249 SIMPLE_COPY(stpcpy, 2, "22", 45);
250 SIMPLE_COPY(stpcpy, 3, "333", 46);
251 SIMPLE_COPY(stpcpy, 4, "4444", 47);
252 SIMPLE_COPY(stpcpy, 5, "55555", 48);
253 SIMPLE_COPY(stpcpy, 6, "666666", 49);
254 SIMPLE_COPY(stpcpy, 7, "7777777", 50);
255 SIMPLE_COPY(stpcpy, 8, "88888888", 51);
256 SIMPLE_COPY(stpcpy, 9, "999999999", 52);
257 SIMPLE_COPY(stpcpy, 10, "0000000000", 53);
258 SIMPLE_COPY(stpcpy, 11, "11111111111", 54);
259 SIMPLE_COPY(stpcpy, 12, "222222222222", 55);
260 SIMPLE_COPY(stpcpy, 13, "3333333333333", 56);
261 SIMPLE_COPY(stpcpy, 14, "44444444444444", 57);
262 SIMPLE_COPY(stpcpy, 15, "555555555555555", 58);
263 SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59);
266 static void
267 test_stpncpy (void)
269 it = "stpncpy";
270 memset (one, 'x', sizeof (one));
271 check (stpncpy (one, "abc", 2) == one + 2, 1);
272 check (stpncpy (one, "abc", 3) == one + 3, 2);
273 check (stpncpy (one, "abc", 4) == one + 3, 3);
274 check (one[3] == '\0' && one[4] == 'x', 4);
275 check (stpncpy (one, "abcd", 5) == one + 4, 5);
276 check (one[4] == '\0' && one[5] == 'x', 6);
277 check (stpncpy (one, "abcd", 6) == one + 4, 7);
278 check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
281 static void
282 test_strcat (void)
284 it = "strcat";
285 (void) strcpy (one, "ijk");
286 check (strcat (one, "lmn") == one, 1); /* Returned value. */
287 equal (one, "ijklmn", 2); /* Basic test. */
289 (void) strcpy (one, "x");
290 (void) strcat (one, "yz");
291 equal (one, "xyz", 3); /* Writeover. */
292 equal (one+4, "mn", 4); /* Wrote too much? */
294 (void) strcpy (one, "gh");
295 (void) strcpy (two, "ef");
296 (void) strcat (one, two);
297 equal (one, "ghef", 5); /* Basic test encore. */
298 equal (two, "ef", 6); /* Stomped on source? */
300 (void) strcpy (one, "");
301 (void) strcat (one, "");
302 equal (one, "", 7); /* Boundary conditions. */
303 (void) strcpy (one, "ab");
304 (void) strcat (one, "");
305 equal (one, "ab", 8);
306 (void) strcpy (one, "");
307 (void) strcat (one, "cd");
308 equal (one, "cd", 9);
311 static void
312 test_strncat (void)
314 /* First test it as strcat, with big counts, then test the count
315 mechanism. */
316 it = "strncat";
317 (void) strcpy (one, "ijk");
318 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
319 equal (one, "ijklmn", 2); /* Basic test. */
321 (void) strcpy (one, "x");
322 (void) strncat (one, "yz", 99);
323 equal (one, "xyz", 3); /* Writeover. */
324 equal (one+4, "mn", 4); /* Wrote too much? */
326 (void) strcpy (one, "gh");
327 (void) strcpy (two, "ef");
328 (void) strncat (one, two, 99);
329 equal (one, "ghef", 5); /* Basic test encore. */
330 equal (two, "ef", 6); /* Stomped on source? */
332 (void) strcpy (one, "");
333 (void) strncat (one, "", 99);
334 equal (one, "", 7); /* Boundary conditions. */
335 (void) strcpy (one, "ab");
336 (void) strncat (one, "", 99);
337 equal (one, "ab", 8);
338 (void) strcpy (one, "");
339 (void) strncat (one, "cd", 99);
340 equal (one, "cd", 9);
342 (void) strcpy (one, "ab");
343 (void) strncat (one, "cdef", 2);
344 equal (one, "abcd", 10); /* Count-limited. */
346 (void) strncat (one, "gh", 0);
347 equal (one, "abcd", 11); /* Zero count. */
349 (void) strncat (one, "gh", 2);
350 equal (one, "abcdgh", 12); /* Count and length equal. */
353 static void
354 test_strncmp (void)
356 /* First test as strcmp with big counts, then test count code. */
357 it = "strncmp";
358 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
359 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
360 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
361 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
362 check (strncmp ("abcd", "abc", 99) > 0, 5);
363 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
364 check (strncmp ("abce", "abcd", 99) > 0, 7);
365 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
366 check (strncmp ("a\203", "a\003", 2) > 0, 9);
367 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
368 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
369 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
370 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
373 static void
374 test_strncpy (void)
376 /* Testing is a bit different because of odd semantics. */
377 it = "strncpy";
378 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
379 equal (one, "abc", 2); /* Did the copy go right? */
381 (void) strcpy (one, "abcdefgh");
382 (void) strncpy (one, "xyz", 2);
383 equal (one, "xycdefgh", 3); /* Copy cut by count. */
385 (void) strcpy (one, "abcdefgh");
386 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
387 equal (one, "xyzdefgh", 4);
389 (void) strcpy (one, "abcdefgh");
390 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
391 equal (one, "xyz", 5);
392 equal (one+4, "efgh", 6); /* Wrote too much? */
394 (void) strcpy (one, "abcdefgh");
395 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
396 equal (one, "xyz", 7);
397 equal (one+4, "", 8);
398 equal (one+5, "fgh", 9);
400 (void) strcpy (one, "abc");
401 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
402 equal (one, "abc", 10);
404 (void) strncpy (one, "", 2); /* Zero-length source. */
405 equal (one, "", 11);
406 equal (one+1, "", 12);
407 equal (one+2, "c", 13);
409 (void) strcpy (one, "hi there");
410 (void) strncpy (two, one, 9);
411 equal (two, "hi there", 14); /* Just paranoia. */
412 equal (one, "hi there", 15); /* Stomped on source? */
415 static void
416 test_strlen (void)
418 it = "strlen";
419 check (strlen ("") == 0, 1); /* Empty. */
420 check (strlen ("a") == 1, 2); /* Single char. */
421 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
423 char buf[4096];
424 int i;
425 char *p;
426 for (i=0; i < 0x100; i++)
428 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
429 strcpy (p, "OK");
430 strcpy (p+3, "BAD/WRONG");
431 check (strlen (p) == 2, 4+i);
436 static void
437 test_strchr (void)
439 it = "strchr";
440 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
441 (void) strcpy (one, "abcd");
442 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
443 check (strchr (one, 'd') == one+3, 3); /* End of string. */
444 check (strchr (one, 'a') == one, 4); /* Beginning. */
445 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
446 (void) strcpy (one, "ababa");
447 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
448 (void) strcpy (one, "");
449 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
450 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
452 char buf[4096];
453 int i;
454 char *p;
455 for (i=0; i < 0x100; i++)
457 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
458 strcpy (p, "OK");
459 strcpy (p+3, "BAD/WRONG");
460 check (strchr (p, '/') == NULL, 9+i);
465 static void
466 test_strchrnul (void)
468 const char *os;
469 it = "strchrnul";
470 cp = strchrnul ((os = "abcd"), 'z');
471 check (*cp == '\0', 1); /* Not found. */
472 check (cp == os + 4, 2);
473 (void) strcpy (one, "abcd");
474 check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */
475 check (strchrnul (one, 'd') == one+3, 4); /* End of string. */
476 check (strchrnul (one, 'a') == one, 5); /* Beginning. */
477 check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */
478 (void) strcpy (one, "ababa");
479 check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */
480 (void) strcpy (one, "");
481 check (strchrnul (one, 'b') == one, 8); /* Empty string. */
482 check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */
484 char buf[4096];
485 int i;
486 char *p;
487 for (i=0; i < 0x100; i++)
489 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
490 strcpy (p, "OK");
491 strcpy (p+3, "BAD/WRONG");
492 cp = strchrnul (p, '/');
493 check (*cp == '\0', 9+2*i);
494 check (cp == p+2, 10+2*i);
499 static void
500 test_rawmemchr (void)
502 it = "rawmemchr";
503 (void) strcpy (one, "abcd");
504 check (rawmemchr (one, 'c') == one+2, 1); /* Basic test. */
505 check (rawmemchr (one, 'd') == one+3, 2); /* End of string. */
506 check (rawmemchr (one, 'a') == one, 3); /* Beginning. */
507 check (rawmemchr (one, '\0') == one+4, 4); /* Finding NUL. */
508 (void) strcpy (one, "ababa");
509 check (rawmemchr (one, 'b') == one+1, 5); /* Finding first. */
510 (void) strcpy (one, "");
511 check (rawmemchr (one, '\0') == one, 6); /* NUL in empty string. */
513 char buf[4096];
514 int i;
515 char *p;
516 for (i=0; i < 0x100; i++)
518 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
519 strcpy (p, "OK");
520 strcpy (p+3, "BAD/WRONG");
521 check (rawmemchr (p, 'R') == p+8, 6+i);
526 static void
527 test_index (void)
529 it = "index";
530 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
531 (void) strcpy (one, "abcd");
532 check (index (one, 'c') == one+2, 2); /* Basic test. */
533 check (index (one, 'd') == one+3, 3); /* End of string. */
534 check (index (one, 'a') == one, 4); /* Beginning. */
535 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
536 (void) strcpy (one, "ababa");
537 check (index (one, 'b') == one+1, 6); /* Finding first. */
538 (void) strcpy (one, "");
539 check (index (one, 'b') == NULL, 7); /* Empty string. */
540 check (index (one, '\0') == one, 8); /* NUL in empty string. */
543 static void
544 test_strrchr (void)
546 it = "strrchr";
547 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
548 (void) strcpy (one, "abcd");
549 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
550 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
551 check (strrchr (one, 'a') == one, 4); /* Beginning. */
552 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
553 (void) strcpy (one, "ababa");
554 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
555 (void) strcpy (one, "");
556 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
557 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
559 char buf[4096];
560 int i;
561 char *p;
562 for (i=0; i < 0x100; i++)
564 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
565 strcpy (p, "OK");
566 strcpy (p+3, "BAD/WRONG");
567 check (strrchr (p, '/') == NULL, 9+i);
572 static void
573 test_memrchr (void)
575 size_t l;
576 it = "memrchr";
577 check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */
578 (void) strcpy (one, "abcd");
579 l = strlen (one) + 1;
580 check (memrchr (one, 'c', l) == one+2, 2); /* Basic test. */
581 check (memrchr (one, 'd', l) == one+3, 3); /* End of string. */
582 check (memrchr (one, 'a', l) == one, 4); /* Beginning. */
583 check (memrchr (one, '\0', l) == one+4, 5); /* Finding NUL. */
584 (void) strcpy (one, "ababa");
585 l = strlen (one) + 1;
586 check (memrchr (one, 'b', l) == one+3, 6); /* Finding last. */
587 (void) strcpy (one, "");
588 l = strlen (one) + 1;
589 check (memrchr (one, 'b', l) == NULL, 7); /* Empty string. */
590 check (memrchr (one, '\0', l) == one, 8); /* NUL in empty string. */
592 /* now test all possible alignment and length combinations to catch
593 bugs due to unrolled loops (assuming unrolling is limited to no
594 more than 128 byte chunks: */
596 char buf[128 + sizeof(long)];
597 long align, len, i, pos;
599 for (align = 0; align < (long) sizeof(long); ++align) {
600 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
601 for (i = 0; i < len; ++i)
602 buf[align + i] = 'x'; /* don't depend on memset... */
604 for (pos = len - 1; pos >= 0; --pos) {
605 #if 0
606 printf("align %d, len %d, pos %d\n", align, len, pos);
607 #endif
608 check(memrchr(buf + align, 'x', len) == buf + align + pos, 9);
609 check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
610 10);
611 buf[align + pos] = '-';
618 static void
619 test_rindex (void)
621 it = "rindex";
622 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
623 (void) strcpy (one, "abcd");
624 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
625 check (rindex (one, 'd') == one+3, 3); /* End of string. */
626 check (rindex (one, 'a') == one, 4); /* Beginning. */
627 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
628 (void) strcpy (one, "ababa");
629 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
630 (void) strcpy (one, "");
631 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
632 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
635 static void
636 test_strpbrk (void)
638 it = "strpbrk";
639 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
640 (void) strcpy(one, "abcd");
641 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
642 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
643 check(strpbrk(one, "a") == one, 4); /* Beginning. */
644 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
645 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
646 (void) strcpy(one, "abcabdea");
647 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
648 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
649 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
650 (void) strcpy(one, "");
651 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
652 (void) strcpy(one, "");
653 check(strpbrk(one, "bcd") == NULL, 11); /* Empty string. */
654 (void) strcpy(one, "");
655 check(strpbrk(one, "bcde") == NULL, 12); /* Empty string. */
656 check(strpbrk(one, "") == NULL, 13); /* Both strings empty. */
657 (void) strcpy(one, "abcabdea");
658 check(strpbrk(one, "befg") == one+1, 14); /* Finding first. */
659 check(strpbrk(one, "cbr") == one+1, 15); /* With multiple search. */
660 check(strpbrk(one, "db") == one+1, 16); /* Another variant. */
661 check(strpbrk(one, "efgh") == one+6, 17); /* And yet another. */
664 static void
665 test_strstr (void)
667 it = "strstr";
668 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
669 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
670 (void) strcpy(one, "abcd");
671 check(strstr(one, "c") == one+2, 3); /* Basic test. */
672 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
673 check(strstr(one, "d") == one+3, 5); /* End of string. */
674 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
675 check(strstr(one, "abc") == one, 7); /* Beginning. */
676 check(strstr(one, "abcd") == one, 8); /* Exact match. */
677 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
678 check(strstr(one, "de") == NULL, 10); /* Past end. */
679 check(strstr(one, "") == one, 11); /* Finding empty. */
680 (void) strcpy(one, "ababa");
681 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
682 (void) strcpy(one, "");
683 check(strstr(one, "b") == NULL, 13); /* Empty string. */
684 check(strstr(one, "") == one, 14); /* Empty in empty string. */
685 (void) strcpy(one, "bcbca");
686 check(strstr(one, "bca") == one+2, 15); /* False start. */
687 (void) strcpy(one, "bbbcabbca");
688 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
691 static void
692 test_strspn (void)
694 it = "strspn";
695 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
696 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
697 check(strspn("abc", "qx") == 0, 3); /* None. */
698 check(strspn("", "ab") == 0, 4); /* Null string. */
699 check(strspn("abc", "") == 0, 5); /* Null search list. */
702 static void
703 test_strcspn (void)
705 it = "strcspn";
706 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
707 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
708 check(strcspn("abc", "abc") == 0, 3); /* None. */
709 check(strcspn("", "ab") == 0, 4); /* Null string. */
710 check(strcspn("abc", "") == 3, 5); /* Null search list. */
713 static void
714 test_strtok (void)
716 it = "strtok";
717 (void) strcpy(one, "first, second, third");
718 equal(strtok(one, ", "), "first", 1); /* Basic test. */
719 equal(one, "first", 2);
720 equal(strtok((char *)NULL, ", "), "second", 3);
721 equal(strtok((char *)NULL, ", "), "third", 4);
722 check(strtok((char *)NULL, ", ") == NULL, 5);
723 (void) strcpy(one, ", first, ");
724 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
725 check(strtok((char *)NULL, ", ") == NULL, 7);
726 (void) strcpy(one, "1a, 1b; 2a, 2b");
727 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
728 equal(strtok((char *)NULL, "; "), "1b", 9);
729 equal(strtok((char *)NULL, ", "), "2a", 10);
730 (void) strcpy(two, "x-y");
731 equal(strtok(two, "-"), "x", 11); /* New string before done. */
732 equal(strtok((char *)NULL, "-"), "y", 12);
733 check(strtok((char *)NULL, "-") == NULL, 13);
734 (void) strcpy(one, "a,b, c,, ,d");
735 equal(strtok(one, ", "), "a", 14); /* Different separators. */
736 equal(strtok((char *)NULL, ", "), "b", 15);
737 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
738 equal(strtok((char *)NULL, " ,"), "d", 17);
739 check(strtok((char *)NULL, ", ") == NULL, 18);
740 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
741 (void) strcpy(one, ", ");
742 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
743 (void) strcpy(one, "");
744 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
745 (void) strcpy(one, "abc");
746 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
747 check(strtok((char *)NULL, ", ") == NULL, 23);
748 (void) strcpy(one, "abc");
749 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
750 check(strtok((char *)NULL, "") == NULL, 25);
751 (void) strcpy(one, "abcdefgh");
752 (void) strcpy(one, "a,b,c");
753 equal(strtok(one, ","), "a", 26); /* Basics again... */
754 equal(strtok((char *)NULL, ","), "b", 27);
755 equal(strtok((char *)NULL, ","), "c", 28);
756 check(strtok((char *)NULL, ",") == NULL, 29);
757 equal(one+6, "gh", 30); /* Stomped past end? */
758 equal(one, "a", 31); /* Stomped old tokens? */
759 equal(one+2, "b", 32);
760 equal(one+4, "c", 33);
763 static void
764 test_strtok_r (void)
766 it = "strtok_r";
767 (void) strcpy(one, "first, second, third");
768 cp = NULL; /* Always initialize cp to make sure it doesn't point to some old data. */
769 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
770 equal(one, "first", 2);
771 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
772 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
773 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
774 (void) strcpy(one, ", first, ");
775 cp = NULL;
776 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
777 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
778 (void) strcpy(one, "1a, 1b; 2a, 2b");
779 cp = NULL;
780 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
781 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
782 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
783 (void) strcpy(two, "x-y");
784 cp = NULL;
785 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
786 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
787 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
788 (void) strcpy(one, "a,b, c,, ,d");
789 cp = NULL;
790 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
791 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
792 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
793 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
794 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
795 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
796 (void) strcpy(one, ", ");
797 cp = NULL;
798 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
799 (void) strcpy(one, "");
800 cp = NULL;
801 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
802 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22); /* Persistence. */
803 (void) strcpy(one, "abc");
804 cp = NULL;
805 equal(strtok_r(one, ", ", &cp), "abc", 23); /* No delimiters. */
806 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
807 (void) strcpy(one, "abc");
808 cp = NULL;
809 equal(strtok_r(one, "", &cp), "abc", 25); /* Empty delimiter list. */
810 check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
811 (void) strcpy(one, "abcdefgh");
812 (void) strcpy(one, "a,b,c");
813 cp = NULL;
814 equal(strtok_r(one, ",", &cp), "a", 27); /* Basics again... */
815 equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
816 equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
817 check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
818 equal(one+6, "gh", 31); /* Stomped past end? */
819 equal(one, "a", 32); /* Stomped old tokens? */
820 equal(one+2, "b", 33);
821 equal(one+4, "c", 34);
824 static void
825 test_strsep (void)
827 char *ptr;
828 it = "strsep";
829 cp = strcpy(one, "first, second, third");
830 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
831 equal(one, "first", 2);
832 equal(strsep(&cp, ", "), "", 3);
833 equal(strsep(&cp, ", "), "second", 4);
834 equal(strsep(&cp, ", "), "", 5);
835 equal(strsep(&cp, ", "), "third", 6);
836 check(strsep(&cp, ", ") == NULL, 7);
837 cp = strcpy(one, ", first, ");
838 equal(strsep(&cp, ", "), "", 8);
839 equal(strsep(&cp, ", "), "", 9);
840 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
841 equal(strsep(&cp, ", "), "", 11);
842 equal(strsep(&cp, ", "), "", 12);
843 check(strsep(&cp, ", ") == NULL, 13);
844 cp = strcpy(one, "1a, 1b; 2a, 2b");
845 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */
846 equal(strsep(&cp, ", "), "", 15);
847 equal(strsep(&cp, "; "), "1b", 16);
848 equal(strsep(&cp, ", "), "", 17);
849 equal(strsep(&cp, ", "), "2a", 18);
850 cp = strcpy(two, "x-y");
851 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */
852 equal(strsep(&cp, "-"), "y", 20);
853 check(strsep(&cp, "-") == NULL, 21);
854 cp = strcpy(one, "a,b, c,, ,d ");
855 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */
856 equal(strsep(&cp, ", "), "b", 23);
857 equal(strsep(&cp, " ,"), "", 24);
858 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */
859 equal(strsep(&cp, " ,"), "", 26);
860 equal(strsep(&cp, " ,"), "", 27);
861 equal(strsep(&cp, " ,"), "", 28);
862 equal(strsep(&cp, " ,"), "d", 29);
863 equal(strsep(&cp, " ,"), "", 30);
864 check(strsep(&cp, ", ") == NULL, 31);
865 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
866 cp = strcpy(one, ", ");
867 equal(strsep(&cp, ", "), "", 33);
868 equal(strsep(&cp, ", "), "", 34);
869 equal(strsep(&cp, ", "), "", 35);
870 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
871 cp = strcpy(one, "");
872 equal(strsep(&cp, ", "), "", 37);
873 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
874 cp = strcpy(one, "abc");
875 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */
876 check(strsep(&cp, ", ") == NULL, 40);
877 cp = strcpy(one, "abc");
878 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */
879 check(strsep(&cp, "") == NULL, 42);
880 (void) strcpy(one, "abcdefgh");
881 cp = strcpy(one, "a,b,c");
882 equal(strsep(&cp, ","), "a", 43); /* Basics again... */
883 equal(strsep(&cp, ","), "b", 44);
884 equal(strsep(&cp, ","), "c", 45);
885 check(strsep(&cp, ",") == NULL, 46);
886 equal(one+6, "gh", 47); /* Stomped past end? */
887 equal(one, "a", 48); /* Stomped old tokens? */
888 equal(one+2, "b", 49);
889 equal(one+4, "c", 50);
892 char text[] = "This,is,a,test";
893 char *list = strdupa (text);
894 equal (strsep (&list, ","), "This", 51);
895 equal (strsep (&list, ","), "is", 52);
896 equal (strsep (&list, ","), "a", 53);
897 equal (strsep (&list, ","), "test", 54);
898 check (strsep (&list, ",") == NULL, 55);
901 cp = strcpy(one, "a,b, c,, ,d,");
902 equal(strsep(&cp, ","), "a", 56); /* Different separators. */
903 equal(strsep(&cp, ","), "b", 57);
904 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */
905 equal(strsep(&cp, ","), "", 59);
906 equal(strsep(&cp, ","), " ", 60);
907 equal(strsep(&cp, ","), "d", 61);
908 equal(strsep(&cp, ","), "", 62);
909 check(strsep(&cp, ",") == NULL, 63);
910 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */
912 cp = strcpy(one, "a,b, c,, ,d,");
913 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */
914 equal(strsep(&cp, "x,y"), "b", 66);
915 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */
916 equal(strsep(&cp, "xy,"), "", 68);
917 equal(strsep(&cp, "x,y"), " ", 69);
918 equal(strsep(&cp, ",xy"), "d", 70);
919 equal(strsep(&cp, "xy,"), "", 71);
920 check(strsep(&cp, "x,y") == NULL, 72);
921 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
923 cp = strcpy(one, "ABC");
924 one[4] = ':';
925 equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */
926 ptr = strsep(&cp, ":");
927 equal(ptr, "", 75);
928 check(ptr == one + 3, 76);
929 check(cp == NULL, 77);
931 cp = strcpy(one, "ABC");
932 one[4] = ':';
933 equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */
934 ptr = strsep(&cp, ":.");
935 equal(ptr, "", 79);
936 check(ptr == one + 3, 80);
938 cp = strcpy(one, "ABC"); /* No token in string. */
939 equal(strsep(&cp, ","), "ABC", 81);
940 check(cp == NULL, 82);
942 *one = '\0'; /* Empty string. */
943 cp = one;
944 ptr = strsep(&cp, ",");
945 equal(ptr, "", 83);
946 check(ptr == one, 84);
947 check(cp == NULL, 85);
949 *one = '\0'; /* Empty string and no token. */
950 cp = one;
951 ptr = strsep(&cp, "");
952 equal(ptr, "", 86);
953 check(ptr == one , 87);
954 check(cp == NULL, 88);
957 static void
958 test_memcmp (void)
960 it = "memcmp";
961 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
962 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
963 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
964 check(memcmp("abce", "abcd", 4) > 0, 4);
965 check(memcmp("alph", "beta", 4) < 0, 5);
966 check(memcmp("a\203", "a\003", 2) > 0, 6);
967 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
968 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
971 static void
972 test_memchr (void)
974 it = "memchr";
975 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
976 (void) strcpy(one, "abcd");
977 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
978 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
979 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
980 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
981 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
982 (void) strcpy(one, "ababa");
983 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
984 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
985 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
986 (void) strcpy(one, "a\203b");
987 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
989 /* now test all possible alignment and length combinations to catch
990 bugs due to unrolled loops (assuming unrolling is limited to no
991 more than 128 byte chunks: */
993 char buf[128 + sizeof(long)];
994 long align, len, i, pos;
996 for (align = 0; align < (long) sizeof(long); ++align) {
997 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
998 for (i = 0; i < len; ++i) {
999 buf[align + i] = 'x'; /* don't depend on memset... */
1001 for (pos = 0; pos < len; ++pos) {
1002 #if 0
1003 printf("align %d, len %d, pos %d\n", align, len, pos);
1004 #endif
1005 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
1006 check(memchr(buf + align, 'x', pos) == NULL, 11);
1007 buf[align + pos] = '-';
1014 static void
1015 test_memcpy (void)
1017 int i;
1018 it = "memcpy";
1019 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
1020 equal(one, "abc", 2); /* Did the copy go right? */
1022 (void) strcpy(one, "abcdefgh");
1023 (void) memcpy(one+1, "xyz", 2);
1024 equal(one, "axydefgh", 3); /* Basic test. */
1026 (void) strcpy(one, "abc");
1027 (void) memcpy(one, "xyz", 0);
1028 equal(one, "abc", 4); /* Zero-length copy. */
1030 (void) strcpy(one, "hi there");
1031 (void) strcpy(two, "foo");
1032 (void) memcpy(two, one, 9);
1033 equal(two, "hi there", 5); /* Just paranoia. */
1034 equal(one, "hi there", 6); /* Stomped on source? */
1036 for (i = 0; i < 16; i++)
1038 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1039 strcpy (one, x);
1040 check (memcpy (one + i, "hi there", 9) == one + i,
1041 7 + (i * 6)); /* Unaligned destination. */
1042 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1043 equal (one + i, "hi there", 9 + (i * 6));
1044 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1045 check (memcpy (two, one + i, 9) == two,
1046 11 + (i * 6)); /* Unaligned source. */
1047 equal (two, "hi there", 12 + (i * 6));
1051 static void
1052 test_mempcpy (void)
1054 int i;
1055 it = "mempcpy";
1056 check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */
1057 equal(one, "abc", 2); /* Did the copy go right? */
1059 (void) strcpy(one, "abcdefgh");
1060 (void) mempcpy(one+1, "xyz", 2);
1061 equal(one, "axydefgh", 3); /* Basic test. */
1063 (void) strcpy(one, "abc");
1064 (void) mempcpy(one, "xyz", 0);
1065 equal(one, "abc", 4); /* Zero-length copy. */
1067 (void) strcpy(one, "hi there");
1068 (void) strcpy(two, "foo");
1069 (void) mempcpy(two, one, 9);
1070 equal(two, "hi there", 5); /* Just paranoia. */
1071 equal(one, "hi there", 6); /* Stomped on source? */
1073 for (i = 0; i < 16; i++)
1075 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1076 strcpy (one, x);
1077 check (mempcpy (one + i, "hi there", 9) == one + i + 9,
1078 7 + (i * 6)); /* Unaligned destination. */
1079 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1080 equal (one + i, "hi there", 9 + (i * 6));
1081 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1082 check (mempcpy (two, one + i, 9) == two + 9,
1083 11 + (i * 6)); /* Unaligned source. */
1084 equal (two, "hi there", 12 + (i * 6));
1088 static void
1089 test_memmove (void)
1091 it = "memmove";
1092 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
1093 equal(one, "abc", 2); /* Did the copy go right? */
1095 (void) strcpy(one, "abcdefgh");
1096 (void) memmove(one+1, "xyz", 2);
1097 equal(one, "axydefgh", 3); /* Basic test. */
1099 (void) strcpy(one, "abc");
1100 (void) memmove(one, "xyz", 0);
1101 equal(one, "abc", 4); /* Zero-length copy. */
1103 (void) strcpy(one, "hi there");
1104 (void) strcpy(two, "foo");
1105 (void) memmove(two, one, 9);
1106 equal(two, "hi there", 5); /* Just paranoia. */
1107 equal(one, "hi there", 6); /* Stomped on source? */
1109 (void) strcpy(one, "abcdefgh");
1110 (void) memmove(one+1, one, 9);
1111 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
1113 (void) strcpy(one, "abcdefgh");
1114 (void) memmove(one+1, one+2, 7);
1115 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
1117 (void) strcpy(one, "abcdefgh");
1118 (void) memmove(one, one, 9);
1119 equal(one, "abcdefgh", 9); /* 100% overlap. */
1122 static void
1123 test_memccpy (void)
1125 /* First test like memcpy, then the search part The SVID, the only
1126 place where memccpy is mentioned, says overlap might fail, so we
1127 don't try it. Besides, it's hard to see the rationale for a
1128 non-left-to-right memccpy. */
1129 it = "memccpy";
1130 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
1131 equal(one, "abc", 2); /* Did the copy go right? */
1133 (void) strcpy(one, "abcdefgh");
1134 (void) memccpy(one+1, "xyz", 'q', 2);
1135 equal(one, "axydefgh", 3); /* Basic test. */
1137 (void) strcpy(one, "abc");
1138 (void) memccpy(one, "xyz", 'q', 0);
1139 equal(one, "abc", 4); /* Zero-length copy. */
1141 (void) strcpy(one, "hi there");
1142 (void) strcpy(two, "foo");
1143 (void) memccpy(two, one, 'q', 9);
1144 equal(two, "hi there", 5); /* Just paranoia. */
1145 equal(one, "hi there", 6); /* Stomped on source? */
1147 (void) strcpy(one, "abcdefgh");
1148 (void) strcpy(two, "horsefeathers");
1149 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
1150 equal(one, "abcdefgh", 8); /* Source intact? */
1151 equal(two, "abcdefeathers", 9); /* Copy correct? */
1153 (void) strcpy(one, "abcd");
1154 (void) strcpy(two, "bumblebee");
1155 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
1156 equal(two, "aumblebee", 11);
1157 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
1158 equal(two, "abcdlebee", 13);
1159 (void) strcpy(one, "xyz");
1160 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
1161 equal(two, "xbcdlebee", 15);
1164 static void
1165 test_memset (void)
1167 int i;
1169 it = "memset";
1170 (void) strcpy(one, "abcdefgh");
1171 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
1172 equal(one, "axxxefgh", 2); /* Basic test. */
1174 (void) memset(one+2, 'y', 0);
1175 equal(one, "axxxefgh", 3); /* Zero-length set. */
1177 (void) memset(one+5, 0, 1);
1178 equal(one, "axxxe", 4); /* Zero fill. */
1179 equal(one+6, "gh", 5); /* And the leftover. */
1181 (void) memset(one+2, 010045, 1);
1182 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
1184 /* Non-8bit fill character. */
1185 memset (one, 0x101, sizeof (one));
1186 for (i = 0; i < (int) sizeof (one); ++i)
1187 check (one[i] == '\01', 7);
1189 /* Test for more complex versions of memset, for all alignments and
1190 lengths up to 256. This test takes a little while, perhaps it should
1191 be made weaker? */
1193 char data[512];
1194 int j;
1195 int k;
1196 int c;
1198 for (i = 0; i < 512; i++)
1199 data[i] = 'x';
1200 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
1201 memset(,'y',) */
1202 for (j = 0; j < 256; j++)
1203 for (i = 0; i < 256; i++)
1205 memset (data + i, c, j);
1206 for (k = 0; k < i; k++)
1207 if (data[k] != 'x')
1208 goto fail;
1209 for (k = i; k < i+j; k++)
1211 if (data[k] != c)
1212 goto fail;
1213 data[k] = 'x';
1215 for (k = i+j; k < 512; k++)
1216 if (data[k] != 'x')
1217 goto fail;
1218 continue;
1220 fail:
1221 check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
1226 static void
1227 test_bcopy (void)
1229 /* Much like memcpy. Berklix manual is silent about overlap, so
1230 don't test it. */
1231 it = "bcopy";
1232 (void) bcopy("abc", one, 4);
1233 equal(one, "abc", 1); /* Simple copy. */
1235 (void) strcpy(one, "abcdefgh");
1236 (void) bcopy("xyz", one+1, 2);
1237 equal(one, "axydefgh", 2); /* Basic test. */
1239 (void) strcpy(one, "abc");
1240 (void) bcopy("xyz", one, 0);
1241 equal(one, "abc", 3); /* Zero-length copy. */
1243 (void) strcpy(one, "hi there");
1244 (void) strcpy(two, "foo");
1245 (void) bcopy(one, two, 9);
1246 equal(two, "hi there", 4); /* Just paranoia. */
1247 equal(one, "hi there", 5); /* Stomped on source? */
1250 static void
1251 test_bzero (void)
1253 it = "bzero";
1254 (void) strcpy(one, "abcdef");
1255 bzero(one+2, 2);
1256 equal(one, "ab", 1); /* Basic test. */
1257 equal(one+3, "", 2);
1258 equal(one+4, "ef", 3);
1260 (void) strcpy(one, "abcdef");
1261 bzero(one+2, 0);
1262 equal(one, "abcdef", 4); /* Zero-length copy. */
1265 static void
1266 test_strndup (void)
1268 char *p, *q;
1269 it = "strndup";
1270 p = strndup("abcdef", 12);
1271 check(p != NULL, 1);
1272 if (p != NULL)
1274 equal(p, "abcdef", 2);
1275 q = strndup(p + 1, 2);
1276 check(q != NULL, 3);
1277 if (q != NULL)
1278 equal(q, "bc", 4);
1279 free (q);
1281 free (p);
1282 p = strndup("abc def", 3);
1283 check(p != NULL, 5);
1284 if (p != NULL)
1285 equal(p, "abc", 6);
1286 free (p);
1289 static void
1290 test_bcmp (void)
1292 it = "bcmp";
1293 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1294 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1295 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1296 check(bcmp("abce", "abcd", 4) != 0, 4);
1297 check(bcmp("alph", "beta", 4) != 0, 5);
1298 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1299 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1302 static void
1303 test_strerror (void)
1305 it = "strerror";
1306 check(strerror(EDOM) != 0, 1);
1307 check(strerror(ERANGE) != 0, 2);
1308 check(strerror(ENOENT) != 0, 3);
1311 static void
1312 test_strcasecmp (void)
1314 it = "strcasecmp";
1315 /* Note that the locale is "C". */
1316 check(strcasecmp("a", "a") == 0, 1);
1317 check(strcasecmp("a", "A") == 0, 2);
1318 check(strcasecmp("A", "a") == 0, 3);
1319 check(strcasecmp("a", "b") < 0, 4);
1320 check(strcasecmp("c", "b") > 0, 5);
1321 check(strcasecmp("abc", "AbC") == 0, 6);
1322 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1323 check(strcasecmp("", "0123456789") < 0, 8);
1324 check(strcasecmp("AbC", "") > 0, 9);
1325 check(strcasecmp("AbC", "A") > 0, 10);
1326 check(strcasecmp("AbC", "Ab") > 0, 11);
1327 check(strcasecmp("AbC", "ab") > 0, 12);
1330 static void
1331 test_strncasecmp (void)
1333 it = "strncasecmp";
1334 /* Note that the locale is "C". */
1335 check(strncasecmp("a", "a", 5) == 0, 1);
1336 check(strncasecmp("a", "A", 5) == 0, 2);
1337 check(strncasecmp("A", "a", 5) == 0, 3);
1338 check(strncasecmp("a", "b", 5) < 0, 4);
1339 check(strncasecmp("c", "b", 5) > 0, 5);
1340 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1341 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1342 check(strncasecmp("", "0123456789", 10) < 0, 8);
1343 check(strncasecmp("AbC", "", 5) > 0, 9);
1344 check(strncasecmp("AbC", "A", 5) > 0, 10);
1345 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1346 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1347 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1348 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1349 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1350 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1351 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1352 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1353 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1354 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1358 main (void)
1360 int status;
1362 /* Test strcmp first because we use it to test other things. */
1363 test_strcmp ();
1365 /* Test strcpy next because we need it to set up other tests. */
1366 test_strcpy ();
1368 /* A closely related function is stpcpy. */
1369 test_stpcpy ();
1371 /* stpncpy. */
1372 test_stpncpy ();
1374 /* strcat. */
1375 test_strcat ();
1377 /* strncat. */
1378 test_strncat ();
1380 /* strncmp. */
1381 test_strncmp ();
1383 /* strncpy. */
1384 test_strncpy ();
1386 /* strlen. */
1387 test_strlen ();
1389 /* strchr. */
1390 test_strchr ();
1392 /* strchrnul. */
1393 test_strchrnul ();
1395 /* rawmemchr. */
1396 test_rawmemchr ();
1398 /* index - just like strchr. */
1399 test_index ();
1401 /* strrchr. */
1402 test_strrchr ();
1404 /* memrchr. */
1405 test_memrchr ();
1407 /* rindex - just like strrchr. */
1408 test_rindex ();
1410 /* strpbrk - somewhat like strchr. */
1411 test_strpbrk ();
1413 /* strstr - somewhat like strchr. */
1414 test_strstr ();
1416 /* strspn. */
1417 test_strspn ();
1419 /* strcspn. */
1420 test_strcspn ();
1422 /* strtok - the hard one. */
1423 test_strtok ();
1425 /* strtok_r. */
1426 test_strtok_r ();
1428 /* strsep. */
1429 test_strsep ();
1431 /* memcmp. */
1432 test_memcmp ();
1434 /* memchr. */
1435 test_memchr ();
1437 /* memcpy - need not work for overlap. */
1438 test_memcpy ();
1440 /* memmove - must work on overlap. */
1441 test_memmove ();
1443 /* mempcpy */
1444 test_mempcpy ();
1446 /* memccpy. */
1447 test_memccpy ();
1449 /* memset. */
1450 test_memset ();
1452 /* bcopy. */
1453 test_bcopy ();
1455 /* bzero. */
1456 test_bzero ();
1458 /* bcmp - somewhat like memcmp. */
1459 test_bcmp ();
1461 /* strndup. */
1462 test_strndup ();
1464 /* strerror - VERY system-dependent. */
1465 test_strerror ();
1467 /* strcasecmp. Without locale dependencies. */
1468 test_strcasecmp ();
1470 /* strncasecmp. Without locale dependencies. */
1471 test_strncasecmp ();
1473 if (errors == 0)
1475 status = EXIT_SUCCESS;
1476 puts("No errors.");
1478 else
1480 status = EXIT_FAILURE;
1481 printf("%Zd errors.\n", errors);
1484 return status;