2.9
[glibc/nacl-glibc.git] / string / tester.c
blob773e969a356ee550ce32de7f56f4a68039a92a9d
1 /* Tester for string functions.
2 Copyright (C) 1995-2001, 2003, 2005, 2008 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>
38 #define STREQ(a, b) (strcmp((a), (b)) == 0)
40 const char *it = "<UNSET>"; /* Routine name for message routines. */
41 size_t errors = 0;
43 /* Complain if condition is not true. */
44 static void
45 check (int thing, int number)
47 if (!thing)
49 printf("%s flunked test %d\n", it, number);
50 ++errors;
54 /* Complain if first two args don't strcmp as equal. */
55 static void
56 equal (const char *a, const char *b, int number)
58 check(a != NULL && b != NULL && STREQ (a, b), number);
61 char one[50];
62 char two[50];
63 char *cp;
65 static void
66 test_strcmp (void)
68 it = "strcmp";
69 check (strcmp ("", "") == 0, 1); /* Trivial case. */
70 check (strcmp ("a", "a") == 0, 2); /* Identity. */
71 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
72 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
73 check (strcmp ("abcd", "abc") > 0, 5);
74 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
75 check (strcmp ("abce", "abcd") > 0, 7);
76 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
77 check (strcmp ("a\203", "a\003") > 0, 9);
80 char buf1[0x40], buf2[0x40];
81 int i, j;
82 for (i=0; i < 0x10; i++)
83 for (j = 0; j < 0x10; j++)
85 int k;
86 for (k = 0; k < 0x3f; k++)
88 buf1[k] = '0' ^ (k & 4);
89 buf2[k] = '4' ^ (k & 4);
91 buf1[i] = buf1[0x3f] = 0;
92 buf2[j] = buf2[0x3f] = 0;
93 for (k = 0; k < 0xf; k++)
95 int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
96 check (strcmp (buf1+i,buf2+j) == 0, cnum);
97 buf1[i+k] = 'A' + i + k;
98 buf1[i+k+1] = 0;
99 check (strcmp (buf1+i,buf2+j) > 0, cnum+1);
100 check (strcmp (buf2+j,buf1+i) < 0, cnum+2);
101 buf2[j+k] = 'B' + i + k;
102 buf2[j+k+1] = 0;
103 check (strcmp (buf1+i,buf2+j) < 0, cnum+3);
104 check (strcmp (buf2+j,buf1+i) > 0, cnum+4);
105 buf2[j+k] = 'A' + i + k;
106 buf1[i] = 'A' + i + 0x80;
107 check (strcmp (buf1+i,buf2+j) > 0, cnum+5);
108 check (strcmp (buf2+j,buf1+i) < 0, cnum+6);
109 buf1[i] = 'A' + i;
115 #define SIMPLE_COPY(fn, n, str, ntest) \
116 do { \
117 int __n; \
118 char *cp; \
119 for (__n = 0; __n < (int) sizeof (one); ++__n) \
120 one[__n] = 'Z'; \
121 fn (one, str); \
122 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
123 check (*cp == '0' + (n % 10), ntest); \
124 check (*cp == '\0', ntest); \
125 } while (0)
127 static void
128 test_strcpy (void)
130 int i;
131 it = "strcpy";
132 check (strcpy (one, "abcd") == one, 1); /* Returned value. */
133 equal (one, "abcd", 2); /* Basic test. */
135 (void) strcpy (one, "x");
136 equal (one, "x", 3); /* Writeover. */
137 equal (one+2, "cd", 4); /* Wrote too much? */
139 (void) strcpy (two, "hi there");
140 (void) strcpy (one, two);
141 equal (one, "hi there", 5); /* Basic test encore. */
142 equal (two, "hi there", 6); /* Stomped on source? */
144 (void) strcpy (one, "");
145 equal (one, "", 7); /* Boundary condition. */
147 for (i = 0; i < 16; i++)
149 (void) strcpy (one + i, "hi there"); /* Unaligned destination. */
150 equal (one + i, "hi there", 8 + (i * 2));
151 (void) strcpy (two, one + i); /* Unaligned source. */
152 equal (two, "hi there", 9 + (i * 2));
155 SIMPLE_COPY(strcpy, 0, "", 41);
156 SIMPLE_COPY(strcpy, 1, "1", 42);
157 SIMPLE_COPY(strcpy, 2, "22", 43);
158 SIMPLE_COPY(strcpy, 3, "333", 44);
159 SIMPLE_COPY(strcpy, 4, "4444", 45);
160 SIMPLE_COPY(strcpy, 5, "55555", 46);
161 SIMPLE_COPY(strcpy, 6, "666666", 47);
162 SIMPLE_COPY(strcpy, 7, "7777777", 48);
163 SIMPLE_COPY(strcpy, 8, "88888888", 49);
164 SIMPLE_COPY(strcpy, 9, "999999999", 50);
165 SIMPLE_COPY(strcpy, 10, "0000000000", 51);
166 SIMPLE_COPY(strcpy, 11, "11111111111", 52);
167 SIMPLE_COPY(strcpy, 12, "222222222222", 53);
168 SIMPLE_COPY(strcpy, 13, "3333333333333", 54);
169 SIMPLE_COPY(strcpy, 14, "44444444444444", 55);
170 SIMPLE_COPY(strcpy, 15, "555555555555555", 56);
171 SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);
173 /* Simple test using implicitly coerced `void *' arguments. */
174 const void *src = "frobozz";
175 void *dst = one;
176 check (strcpy (dst, src) == dst, 1);
177 equal (dst, "frobozz", 2);
180 static void
181 test_stpcpy (void)
183 it = "stpcpy";
184 check ((stpcpy (one, "a") - one) == 1, 1);
185 equal (one, "a", 2);
187 check ((stpcpy (one, "ab") - one) == 2, 3);
188 equal (one, "ab", 4);
190 check ((stpcpy (one, "abc") - one) == 3, 5);
191 equal (one, "abc", 6);
193 check ((stpcpy (one, "abcd") - one) == 4, 7);
194 equal (one, "abcd", 8);
196 check ((stpcpy (one, "abcde") - one) == 5, 9);
197 equal (one, "abcde", 10);
199 check ((stpcpy (one, "abcdef") - one) == 6, 11);
200 equal (one, "abcdef", 12);
202 check ((stpcpy (one, "abcdefg") - one) == 7, 13);
203 equal (one, "abcdefg", 14);
205 check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
206 equal (one, "abcdefgh", 16);
208 check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
209 equal (one, "abcdefghi", 18);
211 check ((stpcpy (one, "x") - one) == 1, 19);
212 equal (one, "x", 20); /* Writeover. */
213 equal (one+2, "cdefghi", 21); /* Wrote too much? */
215 check ((stpcpy (one, "xx") - one) == 2, 22);
216 equal (one, "xx", 23); /* Writeover. */
217 equal (one+3, "defghi", 24); /* Wrote too much? */
219 check ((stpcpy (one, "xxx") - one) == 3, 25);
220 equal (one, "xxx", 26); /* Writeover. */
221 equal (one+4, "efghi", 27); /* Wrote too much? */
223 check ((stpcpy (one, "xxxx") - one) == 4, 28);
224 equal (one, "xxxx", 29); /* Writeover. */
225 equal (one+5, "fghi", 30); /* Wrote too much? */
227 check ((stpcpy (one, "xxxxx") - one) == 5, 31);
228 equal (one, "xxxxx", 32); /* Writeover. */
229 equal (one+6, "ghi", 33); /* Wrote too much? */
231 check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
232 equal (one, "xxxxxx", 35); /* Writeover. */
233 equal (one+7, "hi", 36); /* Wrote too much? */
235 check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
236 equal (one, "xxxxxxx", 38); /* Writeover. */
237 equal (one+8, "i", 39); /* Wrote too much? */
239 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
240 equal (one, "abc", 41);
241 equal (one + 4, "xxx", 42);
243 SIMPLE_COPY(stpcpy, 0, "", 43);
244 SIMPLE_COPY(stpcpy, 1, "1", 44);
245 SIMPLE_COPY(stpcpy, 2, "22", 45);
246 SIMPLE_COPY(stpcpy, 3, "333", 46);
247 SIMPLE_COPY(stpcpy, 4, "4444", 47);
248 SIMPLE_COPY(stpcpy, 5, "55555", 48);
249 SIMPLE_COPY(stpcpy, 6, "666666", 49);
250 SIMPLE_COPY(stpcpy, 7, "7777777", 50);
251 SIMPLE_COPY(stpcpy, 8, "88888888", 51);
252 SIMPLE_COPY(stpcpy, 9, "999999999", 52);
253 SIMPLE_COPY(stpcpy, 10, "0000000000", 53);
254 SIMPLE_COPY(stpcpy, 11, "11111111111", 54);
255 SIMPLE_COPY(stpcpy, 12, "222222222222", 55);
256 SIMPLE_COPY(stpcpy, 13, "3333333333333", 56);
257 SIMPLE_COPY(stpcpy, 14, "44444444444444", 57);
258 SIMPLE_COPY(stpcpy, 15, "555555555555555", 58);
259 SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59);
262 static void
263 test_stpncpy (void)
265 it = "stpncpy";
266 memset (one, 'x', sizeof (one));
267 check (stpncpy (one, "abc", 2) == one + 2, 1);
268 check (stpncpy (one, "abc", 3) == one + 3, 2);
269 check (stpncpy (one, "abc", 4) == one + 3, 3);
270 check (one[3] == '\0' && one[4] == 'x', 4);
271 check (stpncpy (one, "abcd", 5) == one + 4, 5);
272 check (one[4] == '\0' && one[5] == 'x', 6);
273 check (stpncpy (one, "abcd", 6) == one + 4, 7);
274 check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
277 static void
278 test_strcat (void)
280 it = "strcat";
281 (void) strcpy (one, "ijk");
282 check (strcat (one, "lmn") == one, 1); /* Returned value. */
283 equal (one, "ijklmn", 2); /* Basic test. */
285 (void) strcpy (one, "x");
286 (void) strcat (one, "yz");
287 equal (one, "xyz", 3); /* Writeover. */
288 equal (one+4, "mn", 4); /* Wrote too much? */
290 (void) strcpy (one, "gh");
291 (void) strcpy (two, "ef");
292 (void) strcat (one, two);
293 equal (one, "ghef", 5); /* Basic test encore. */
294 equal (two, "ef", 6); /* Stomped on source? */
296 (void) strcpy (one, "");
297 (void) strcat (one, "");
298 equal (one, "", 7); /* Boundary conditions. */
299 (void) strcpy (one, "ab");
300 (void) strcat (one, "");
301 equal (one, "ab", 8);
302 (void) strcpy (one, "");
303 (void) strcat (one, "cd");
304 equal (one, "cd", 9);
307 static void
308 test_strncat (void)
310 /* First test it as strcat, with big counts, then test the count
311 mechanism. */
312 it = "strncat";
313 (void) strcpy (one, "ijk");
314 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
315 equal (one, "ijklmn", 2); /* Basic test. */
317 (void) strcpy (one, "x");
318 (void) strncat (one, "yz", 99);
319 equal (one, "xyz", 3); /* Writeover. */
320 equal (one+4, "mn", 4); /* Wrote too much? */
322 (void) strcpy (one, "gh");
323 (void) strcpy (two, "ef");
324 (void) strncat (one, two, 99);
325 equal (one, "ghef", 5); /* Basic test encore. */
326 equal (two, "ef", 6); /* Stomped on source? */
328 (void) strcpy (one, "");
329 (void) strncat (one, "", 99);
330 equal (one, "", 7); /* Boundary conditions. */
331 (void) strcpy (one, "ab");
332 (void) strncat (one, "", 99);
333 equal (one, "ab", 8);
334 (void) strcpy (one, "");
335 (void) strncat (one, "cd", 99);
336 equal (one, "cd", 9);
338 (void) strcpy (one, "ab");
339 (void) strncat (one, "cdef", 2);
340 equal (one, "abcd", 10); /* Count-limited. */
342 (void) strncat (one, "gh", 0);
343 equal (one, "abcd", 11); /* Zero count. */
345 (void) strncat (one, "gh", 2);
346 equal (one, "abcdgh", 12); /* Count and length equal. */
348 (void) strncat (one, "ij", (size_t)-1); /* set sign bit in count */
349 equal (one, "abcdghij", 13);
352 static void
353 test_strncmp (void)
355 /* First test as strcmp with big counts, then test count code. */
356 it = "strncmp";
357 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
358 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
359 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
360 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
361 check (strncmp ("abcd", "abc", 99) > 0, 5);
362 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
363 check (strncmp ("abce", "abcd", 99) > 0, 7);
364 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
365 check (strncmp ("a\203", "a\003", 2) > 0, 9);
366 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
367 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
368 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
369 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
370 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
371 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
374 static void
375 test_strncpy (void)
377 /* Testing is a bit different because of odd semantics. */
378 it = "strncpy";
379 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
380 equal (one, "abc", 2); /* Did the copy go right? */
382 (void) strcpy (one, "abcdefgh");
383 (void) strncpy (one, "xyz", 2);
384 equal (one, "xycdefgh", 3); /* Copy cut by count. */
386 (void) strcpy (one, "abcdefgh");
387 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
388 equal (one, "xyzdefgh", 4);
390 (void) strcpy (one, "abcdefgh");
391 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
392 equal (one, "xyz", 5);
393 equal (one+4, "efgh", 6); /* Wrote too much? */
395 (void) strcpy (one, "abcdefgh");
396 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
397 equal (one, "xyz", 7);
398 equal (one+4, "", 8);
399 equal (one+5, "fgh", 9);
401 (void) strcpy (one, "abc");
402 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
403 equal (one, "abc", 10);
405 (void) strncpy (one, "", 2); /* Zero-length source. */
406 equal (one, "", 11);
407 equal (one+1, "", 12);
408 equal (one+2, "c", 13);
410 (void) strcpy (one, "hi there");
411 (void) strncpy (two, one, 9);
412 equal (two, "hi there", 14); /* Just paranoia. */
413 equal (one, "hi there", 15); /* Stomped on source? */
416 static void
417 test_strlen (void)
419 it = "strlen";
420 check (strlen ("") == 0, 1); /* Empty. */
421 check (strlen ("a") == 1, 2); /* Single char. */
422 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
424 char buf[4096];
425 int i;
426 char *p;
427 for (i=0; i < 0x100; i++)
429 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
430 strcpy (p, "OK");
431 strcpy (p+3, "BAD/WRONG");
432 check (strlen (p) == 2, 4+i);
437 static void
438 test_strnlen (void)
440 it = "strnlen";
441 check (strnlen ("", 10) == 0, 1); /* Empty. */
442 check (strnlen ("a", 10) == 1, 2); /* Single char. */
443 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
444 check (strnlen ("foo", (size_t)-1) == 3, 4); /* limits of n. */
447 char buf[4096];
448 int i;
449 char *p;
450 for (i=0; i < 0x100; i++)
452 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
453 strcpy (p, "OK");
454 strcpy (p+3, "BAD/WRONG");
455 check (strnlen (p, 100) == 2, 5+i);
460 static void
461 test_strchr (void)
463 it = "strchr";
464 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
465 (void) strcpy (one, "abcd");
466 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
467 check (strchr (one, 'd') == one+3, 3); /* End of string. */
468 check (strchr (one, 'a') == one, 4); /* Beginning. */
469 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
470 (void) strcpy (one, "ababa");
471 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
472 (void) strcpy (one, "");
473 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
474 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
476 char buf[4096];
477 int i;
478 char *p;
479 for (i=0; i < 0x100; i++)
481 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
482 strcpy (p, "OK");
483 strcpy (p+3, "BAD/WRONG");
484 check (strchr (p, '/') == NULL, 9+i);
489 static void
490 test_strchrnul (void)
492 const char *os;
493 it = "strchrnul";
494 cp = strchrnul ((os = "abcd"), 'z');
495 check (*cp == '\0', 1); /* Not found. */
496 check (cp == os + 4, 2);
497 (void) strcpy (one, "abcd");
498 check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */
499 check (strchrnul (one, 'd') == one+3, 4); /* End of string. */
500 check (strchrnul (one, 'a') == one, 5); /* Beginning. */
501 check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */
502 (void) strcpy (one, "ababa");
503 check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */
504 (void) strcpy (one, "");
505 check (strchrnul (one, 'b') == one, 8); /* Empty string. */
506 check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */
508 char buf[4096];
509 int i;
510 char *p;
511 for (i=0; i < 0x100; i++)
513 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
514 strcpy (p, "OK");
515 strcpy (p+3, "BAD/WRONG");
516 cp = strchrnul (p, '/');
517 check (*cp == '\0', 9+2*i);
518 check (cp == p+2, 10+2*i);
523 static void
524 test_rawmemchr (void)
526 it = "rawmemchr";
527 (void) strcpy (one, "abcd");
528 check (rawmemchr (one, 'c') == one+2, 1); /* Basic test. */
529 check (rawmemchr (one, 'd') == one+3, 2); /* End of string. */
530 check (rawmemchr (one, 'a') == one, 3); /* Beginning. */
531 check (rawmemchr (one, '\0') == one+4, 4); /* Finding NUL. */
532 (void) strcpy (one, "ababa");
533 check (rawmemchr (one, 'b') == one+1, 5); /* Finding first. */
534 (void) strcpy (one, "");
535 check (rawmemchr (one, '\0') == one, 6); /* NUL in empty string. */
537 char buf[4096];
538 int i;
539 char *p;
540 for (i=0; i < 0x100; i++)
542 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
543 strcpy (p, "OK");
544 strcpy (p+3, "BAD/WRONG");
545 check (rawmemchr (p, 'R') == p+8, 6+i);
550 static void
551 test_index (void)
553 it = "index";
554 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
555 (void) strcpy (one, "abcd");
556 check (index (one, 'c') == one+2, 2); /* Basic test. */
557 check (index (one, 'd') == one+3, 3); /* End of string. */
558 check (index (one, 'a') == one, 4); /* Beginning. */
559 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
560 (void) strcpy (one, "ababa");
561 check (index (one, 'b') == one+1, 6); /* Finding first. */
562 (void) strcpy (one, "");
563 check (index (one, 'b') == NULL, 7); /* Empty string. */
564 check (index (one, '\0') == one, 8); /* NUL in empty string. */
567 static void
568 test_strrchr (void)
570 it = "strrchr";
571 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
572 (void) strcpy (one, "abcd");
573 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
574 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
575 check (strrchr (one, 'a') == one, 4); /* Beginning. */
576 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
577 (void) strcpy (one, "ababa");
578 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
579 (void) strcpy (one, "");
580 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
581 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
583 char buf[4096];
584 int i;
585 char *p;
586 for (i=0; i < 0x100; i++)
588 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
589 strcpy (p, "OK");
590 strcpy (p+3, "BAD/WRONG");
591 check (strrchr (p, '/') == NULL, 9+i);
596 static void
597 test_memrchr (void)
599 size_t l;
600 it = "memrchr";
601 check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */
602 (void) strcpy (one, "abcd");
603 l = strlen (one) + 1;
604 check (memrchr (one, 'c', l) == one+2, 2); /* Basic test. */
605 check (memrchr (one, 'd', l) == one+3, 3); /* End of string. */
606 check (memrchr (one, 'a', l) == one, 4); /* Beginning. */
607 check (memrchr (one, '\0', l) == one+4, 5); /* Finding NUL. */
608 (void) strcpy (one, "ababa");
609 l = strlen (one) + 1;
610 check (memrchr (one, 'b', l) == one+3, 6); /* Finding last. */
611 (void) strcpy (one, "");
612 l = strlen (one) + 1;
613 check (memrchr (one, 'b', l) == NULL, 7); /* Empty string. */
614 check (memrchr (one, '\0', l) == one, 8); /* NUL in empty string. */
616 /* now test all possible alignment and length combinations to catch
617 bugs due to unrolled loops (assuming unrolling is limited to no
618 more than 128 byte chunks: */
620 char buf[128 + sizeof(long)];
621 long align, len, i, pos;
623 for (align = 0; align < (long) sizeof(long); ++align) {
624 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
625 for (i = 0; i < len; ++i)
626 buf[align + i] = 'x'; /* don't depend on memset... */
628 for (pos = len - 1; pos >= 0; --pos) {
629 #if 0
630 printf("align %d, len %d, pos %d\n", align, len, pos);
631 #endif
632 check(memrchr(buf + align, 'x', len) == buf + align + pos, 9);
633 check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
634 10);
635 buf[align + pos] = '-';
642 static void
643 test_rindex (void)
645 it = "rindex";
646 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
647 (void) strcpy (one, "abcd");
648 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
649 check (rindex (one, 'd') == one+3, 3); /* End of string. */
650 check (rindex (one, 'a') == one, 4); /* Beginning. */
651 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
652 (void) strcpy (one, "ababa");
653 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
654 (void) strcpy (one, "");
655 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
656 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
659 static void
660 test_strpbrk (void)
662 it = "strpbrk";
663 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
664 (void) strcpy(one, "abcd");
665 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
666 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
667 check(strpbrk(one, "a") == one, 4); /* Beginning. */
668 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
669 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
670 (void) strcpy(one, "abcabdea");
671 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
672 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
673 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
674 (void) strcpy(one, "");
675 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
676 (void) strcpy(one, "");
677 check(strpbrk(one, "bcd") == NULL, 11); /* Empty string. */
678 (void) strcpy(one, "");
679 check(strpbrk(one, "bcde") == NULL, 12); /* Empty string. */
680 check(strpbrk(one, "") == NULL, 13); /* Both strings empty. */
681 (void) strcpy(one, "abcabdea");
682 check(strpbrk(one, "befg") == one+1, 14); /* Finding first. */
683 check(strpbrk(one, "cbr") == one+1, 15); /* With multiple search. */
684 check(strpbrk(one, "db") == one+1, 16); /* Another variant. */
685 check(strpbrk(one, "efgh") == one+6, 17); /* And yet another. */
688 static void
689 test_strstr (void)
691 it = "strstr";
692 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
693 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
694 (void) strcpy(one, "abcd");
695 check(strstr(one, "c") == one+2, 3); /* Basic test. */
696 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
697 check(strstr(one, "d") == one+3, 5); /* End of string. */
698 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
699 check(strstr(one, "abc") == one, 7); /* Beginning. */
700 check(strstr(one, "abcd") == one, 8); /* Exact match. */
701 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
702 check(strstr(one, "de") == NULL, 10); /* Past end. */
703 check(strstr(one, "") == one, 11); /* Finding empty. */
704 (void) strcpy(one, "ababa");
705 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
706 (void) strcpy(one, "");
707 check(strstr(one, "b") == NULL, 13); /* Empty string. */
708 check(strstr(one, "") == one, 14); /* Empty in empty string. */
709 (void) strcpy(one, "bcbca");
710 check(strstr(one, "bca") == one+2, 15); /* False start. */
711 (void) strcpy(one, "bbbcabbca");
712 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
715 static void
716 test_strspn (void)
718 it = "strspn";
719 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
720 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
721 check(strspn("abc", "qx") == 0, 3); /* None. */
722 check(strspn("", "ab") == 0, 4); /* Null string. */
723 check(strspn("abc", "") == 0, 5); /* Null search list. */
726 static void
727 test_strcspn (void)
729 it = "strcspn";
730 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
731 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
732 check(strcspn("abc", "abc") == 0, 3); /* None. */
733 check(strcspn("", "ab") == 0, 4); /* Null string. */
734 check(strcspn("abc", "") == 3, 5); /* Null search list. */
737 static void
738 test_strtok (void)
740 it = "strtok";
741 (void) strcpy(one, "first, second, third");
742 equal(strtok(one, ", "), "first", 1); /* Basic test. */
743 equal(one, "first", 2);
744 equal(strtok((char *)NULL, ", "), "second", 3);
745 equal(strtok((char *)NULL, ", "), "third", 4);
746 check(strtok((char *)NULL, ", ") == NULL, 5);
747 (void) strcpy(one, ", first, ");
748 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
749 check(strtok((char *)NULL, ", ") == NULL, 7);
750 (void) strcpy(one, "1a, 1b; 2a, 2b");
751 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
752 equal(strtok((char *)NULL, "; "), "1b", 9);
753 equal(strtok((char *)NULL, ", "), "2a", 10);
754 (void) strcpy(two, "x-y");
755 equal(strtok(two, "-"), "x", 11); /* New string before done. */
756 equal(strtok((char *)NULL, "-"), "y", 12);
757 check(strtok((char *)NULL, "-") == NULL, 13);
758 (void) strcpy(one, "a,b, c,, ,d");
759 equal(strtok(one, ", "), "a", 14); /* Different separators. */
760 equal(strtok((char *)NULL, ", "), "b", 15);
761 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
762 equal(strtok((char *)NULL, " ,"), "d", 17);
763 check(strtok((char *)NULL, ", ") == NULL, 18);
764 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
765 (void) strcpy(one, ", ");
766 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
767 (void) strcpy(one, "");
768 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
769 (void) strcpy(one, "abc");
770 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
771 check(strtok((char *)NULL, ", ") == NULL, 23);
772 (void) strcpy(one, "abc");
773 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
774 check(strtok((char *)NULL, "") == NULL, 25);
775 (void) strcpy(one, "abcdefgh");
776 (void) strcpy(one, "a,b,c");
777 equal(strtok(one, ","), "a", 26); /* Basics again... */
778 equal(strtok((char *)NULL, ","), "b", 27);
779 equal(strtok((char *)NULL, ","), "c", 28);
780 check(strtok((char *)NULL, ",") == NULL, 29);
781 equal(one+6, "gh", 30); /* Stomped past end? */
782 equal(one, "a", 31); /* Stomped old tokens? */
783 equal(one+2, "b", 32);
784 equal(one+4, "c", 33);
787 static void
788 test_strtok_r (void)
790 it = "strtok_r";
791 (void) strcpy(one, "first, second, third");
792 cp = NULL; /* Always initialize cp to make sure it doesn't point to some old data. */
793 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
794 equal(one, "first", 2);
795 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
796 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
797 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
798 (void) strcpy(one, ", first, ");
799 cp = NULL;
800 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
801 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
802 (void) strcpy(one, "1a, 1b; 2a, 2b");
803 cp = NULL;
804 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
805 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
806 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
807 (void) strcpy(two, "x-y");
808 cp = NULL;
809 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
810 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
811 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
812 (void) strcpy(one, "a,b, c,, ,d");
813 cp = NULL;
814 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
815 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
816 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
817 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
818 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
819 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
820 (void) strcpy(one, ", ");
821 cp = NULL;
822 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
823 (void) strcpy(one, "");
824 cp = NULL;
825 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
826 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22); /* Persistence. */
827 (void) strcpy(one, "abc");
828 cp = NULL;
829 equal(strtok_r(one, ", ", &cp), "abc", 23); /* No delimiters. */
830 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
831 (void) strcpy(one, "abc");
832 cp = NULL;
833 equal(strtok_r(one, "", &cp), "abc", 25); /* Empty delimiter list. */
834 check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
835 (void) strcpy(one, "abcdefgh");
836 (void) strcpy(one, "a,b,c");
837 cp = NULL;
838 equal(strtok_r(one, ",", &cp), "a", 27); /* Basics again... */
839 equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
840 equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
841 check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
842 equal(one+6, "gh", 31); /* Stomped past end? */
843 equal(one, "a", 32); /* Stomped old tokens? */
844 equal(one+2, "b", 33);
845 equal(one+4, "c", 34);
846 strcpy (one, ":::");
847 cp = NULL;
848 check (strtok_r (one, ":", &cp) == NULL, 35); /* Must store pointer in cp. */
849 check (strtok_r (NULL, ":", &cp) == NULL, 36);
852 static void
853 test_strsep (void)
855 char *ptr;
856 it = "strsep";
857 cp = strcpy(one, "first, second, third");
858 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
859 equal(one, "first", 2);
860 equal(strsep(&cp, ", "), "", 3);
861 equal(strsep(&cp, ", "), "second", 4);
862 equal(strsep(&cp, ", "), "", 5);
863 equal(strsep(&cp, ", "), "third", 6);
864 check(strsep(&cp, ", ") == NULL, 7);
865 cp = strcpy(one, ", first, ");
866 equal(strsep(&cp, ", "), "", 8);
867 equal(strsep(&cp, ", "), "", 9);
868 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
869 equal(strsep(&cp, ", "), "", 11);
870 equal(strsep(&cp, ", "), "", 12);
871 check(strsep(&cp, ", ") == NULL, 13);
872 cp = strcpy(one, "1a, 1b; 2a, 2b");
873 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */
874 equal(strsep(&cp, ", "), "", 15);
875 equal(strsep(&cp, "; "), "1b", 16);
876 equal(strsep(&cp, ", "), "", 17);
877 equal(strsep(&cp, ", "), "2a", 18);
878 cp = strcpy(two, "x-y");
879 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */
880 equal(strsep(&cp, "-"), "y", 20);
881 check(strsep(&cp, "-") == NULL, 21);
882 cp = strcpy(one, "a,b, c,, ,d ");
883 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */
884 equal(strsep(&cp, ", "), "b", 23);
885 equal(strsep(&cp, " ,"), "", 24);
886 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */
887 equal(strsep(&cp, " ,"), "", 26);
888 equal(strsep(&cp, " ,"), "", 27);
889 equal(strsep(&cp, " ,"), "", 28);
890 equal(strsep(&cp, " ,"), "d", 29);
891 equal(strsep(&cp, " ,"), "", 30);
892 check(strsep(&cp, ", ") == NULL, 31);
893 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
894 cp = strcpy(one, ", ");
895 equal(strsep(&cp, ", "), "", 33);
896 equal(strsep(&cp, ", "), "", 34);
897 equal(strsep(&cp, ", "), "", 35);
898 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
899 cp = strcpy(one, "");
900 equal(strsep(&cp, ", "), "", 37);
901 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
902 cp = strcpy(one, "abc");
903 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */
904 check(strsep(&cp, ", ") == NULL, 40);
905 cp = strcpy(one, "abc");
906 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */
907 check(strsep(&cp, "") == NULL, 42);
908 (void) strcpy(one, "abcdefgh");
909 cp = strcpy(one, "a,b,c");
910 equal(strsep(&cp, ","), "a", 43); /* Basics again... */
911 equal(strsep(&cp, ","), "b", 44);
912 equal(strsep(&cp, ","), "c", 45);
913 check(strsep(&cp, ",") == NULL, 46);
914 equal(one+6, "gh", 47); /* Stomped past end? */
915 equal(one, "a", 48); /* Stomped old tokens? */
916 equal(one+2, "b", 49);
917 equal(one+4, "c", 50);
920 char text[] = "This,is,a,test";
921 char *list = strdupa (text);
922 equal (strsep (&list, ","), "This", 51);
923 equal (strsep (&list, ","), "is", 52);
924 equal (strsep (&list, ","), "a", 53);
925 equal (strsep (&list, ","), "test", 54);
926 check (strsep (&list, ",") == NULL, 55);
929 cp = strcpy(one, "a,b, c,, ,d,");
930 equal(strsep(&cp, ","), "a", 56); /* Different separators. */
931 equal(strsep(&cp, ","), "b", 57);
932 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */
933 equal(strsep(&cp, ","), "", 59);
934 equal(strsep(&cp, ","), " ", 60);
935 equal(strsep(&cp, ","), "d", 61);
936 equal(strsep(&cp, ","), "", 62);
937 check(strsep(&cp, ",") == NULL, 63);
938 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */
940 cp = strcpy(one, "a,b, c,, ,d,");
941 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */
942 equal(strsep(&cp, "x,y"), "b", 66);
943 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */
944 equal(strsep(&cp, "xy,"), "", 68);
945 equal(strsep(&cp, "x,y"), " ", 69);
946 equal(strsep(&cp, ",xy"), "d", 70);
947 equal(strsep(&cp, "xy,"), "", 71);
948 check(strsep(&cp, "x,y") == NULL, 72);
949 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
951 cp = strcpy(one, "ABC");
952 one[4] = ':';
953 equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */
954 ptr = strsep(&cp, ":");
955 equal(ptr, "", 75);
956 check(ptr == one + 3, 76);
957 check(cp == NULL, 77);
959 cp = strcpy(one, "ABC");
960 one[4] = ':';
961 equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */
962 ptr = strsep(&cp, ":.");
963 equal(ptr, "", 79);
964 check(ptr == one + 3, 80);
966 cp = strcpy(one, "ABC"); /* No token in string. */
967 equal(strsep(&cp, ","), "ABC", 81);
968 check(cp == NULL, 82);
970 *one = '\0'; /* Empty string. */
971 cp = one;
972 ptr = strsep(&cp, ",");
973 equal(ptr, "", 83);
974 check(ptr == one, 84);
975 check(cp == NULL, 85);
977 *one = '\0'; /* Empty string and no token. */
978 cp = one;
979 ptr = strsep(&cp, "");
980 equal(ptr, "", 86);
981 check(ptr == one , 87);
982 check(cp == NULL, 88);
985 static void
986 test_memcmp (void)
988 int cnt = 1;
989 char one[21];
990 char two[21];
992 it = "memcmp";
993 check(memcmp("a", "a", 1) == 0, cnt++); /* Identity. */
994 check(memcmp("abc", "abc", 3) == 0, cnt++); /* Multicharacter. */
995 check(memcmp("abcd", "abcf", 4) < 0, cnt++); /* Honestly unequal. */
996 check(memcmp("abcf", "abcd", 4) > 0, cnt++);
997 check(memcmp("alph", "cold", 4) < 0, cnt++);
998 check(memcmp("a\203", "a\003", 2) > 0, cnt++);
999 check(memcmp("a\003", "a\203", 2) < 0, cnt++);
1000 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt++);
1001 check(memcmp("abc\203", "abc\003", 4) > 0, cnt++);
1002 check(memcmp("abc\003", "abc\203", 4) < 0, cnt++);
1003 check(memcmp("abcf", "abcd", 3) == 0, cnt++); /* Count limited. */
1004 check(memcmp("abc", "def", 0) == 0, cnt++); /* Zero count. */
1005 /* Comparisons with shifting 4-byte boundaries. */
1006 for (int i = 0; i < 4; ++i)
1008 char *a = one + i;
1009 char *b = two + i;
1010 strncpy(a, "--------11112222", 16);
1011 strncpy(b, "--------33334444", 16);
1012 check(memcmp(b, a, 16) > 0, cnt++);
1013 check(memcmp(a, b, 16) < 0, cnt++);
1017 static void
1018 test_memchr (void)
1020 it = "memchr";
1021 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
1022 (void) strcpy(one, "abcd");
1023 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
1024 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
1025 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
1026 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
1027 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
1028 (void) strcpy(one, "ababa");
1029 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
1030 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
1031 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
1032 (void) strcpy(one, "a\203b");
1033 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
1035 /* now test all possible alignment and length combinations to catch
1036 bugs due to unrolled loops (assuming unrolling is limited to no
1037 more than 128 byte chunks: */
1039 char buf[128 + sizeof(long)];
1040 long align, len, i, pos;
1042 for (align = 0; align < (long) sizeof(long); ++align) {
1043 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
1044 for (i = 0; i < len; ++i) {
1045 buf[align + i] = 'x'; /* don't depend on memset... */
1047 for (pos = 0; pos < len; ++pos) {
1048 #if 0
1049 printf("align %d, len %d, pos %d\n", align, len, pos);
1050 #endif
1051 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
1052 check(memchr(buf + align, 'x', pos) == NULL, 11);
1053 buf[align + pos] = '-';
1060 static void
1061 test_memcpy (void)
1063 int i;
1064 it = "memcpy";
1065 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
1066 equal(one, "abc", 2); /* Did the copy go right? */
1068 (void) strcpy(one, "abcdefgh");
1069 (void) memcpy(one+1, "xyz", 2);
1070 equal(one, "axydefgh", 3); /* Basic test. */
1072 (void) strcpy(one, "abc");
1073 (void) memcpy(one, "xyz", 0);
1074 equal(one, "abc", 4); /* Zero-length copy. */
1076 (void) strcpy(one, "hi there");
1077 (void) strcpy(two, "foo");
1078 (void) memcpy(two, one, 9);
1079 equal(two, "hi there", 5); /* Just paranoia. */
1080 equal(one, "hi there", 6); /* Stomped on source? */
1082 for (i = 0; i < 16; i++)
1084 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1085 strcpy (one, x);
1086 check (memcpy (one + i, "hi there", 9) == one + i,
1087 7 + (i * 6)); /* Unaligned destination. */
1088 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1089 equal (one + i, "hi there", 9 + (i * 6));
1090 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1091 check (memcpy (two, one + i, 9) == two,
1092 11 + (i * 6)); /* Unaligned source. */
1093 equal (two, "hi there", 12 + (i * 6));
1097 static void
1098 test_mempcpy (void)
1100 int i;
1101 it = "mempcpy";
1102 check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */
1103 equal(one, "abc", 2); /* Did the copy go right? */
1105 (void) strcpy(one, "abcdefgh");
1106 (void) mempcpy(one+1, "xyz", 2);
1107 equal(one, "axydefgh", 3); /* Basic test. */
1109 (void) strcpy(one, "abc");
1110 (void) mempcpy(one, "xyz", 0);
1111 equal(one, "abc", 4); /* Zero-length copy. */
1113 (void) strcpy(one, "hi there");
1114 (void) strcpy(two, "foo");
1115 (void) mempcpy(two, one, 9);
1116 equal(two, "hi there", 5); /* Just paranoia. */
1117 equal(one, "hi there", 6); /* Stomped on source? */
1119 for (i = 0; i < 16; i++)
1121 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1122 strcpy (one, x);
1123 check (mempcpy (one + i, "hi there", 9) == one + i + 9,
1124 7 + (i * 6)); /* Unaligned destination. */
1125 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1126 equal (one + i, "hi there", 9 + (i * 6));
1127 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1128 check (mempcpy (two, one + i, 9) == two + 9,
1129 11 + (i * 6)); /* Unaligned source. */
1130 equal (two, "hi there", 12 + (i * 6));
1134 static void
1135 test_memmove (void)
1137 it = "memmove";
1138 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
1139 equal(one, "abc", 2); /* Did the copy go right? */
1141 (void) strcpy(one, "abcdefgh");
1142 (void) memmove(one+1, "xyz", 2);
1143 equal(one, "axydefgh", 3); /* Basic test. */
1145 (void) strcpy(one, "abc");
1146 (void) memmove(one, "xyz", 0);
1147 equal(one, "abc", 4); /* Zero-length copy. */
1149 (void) strcpy(one, "hi there");
1150 (void) strcpy(two, "foo");
1151 (void) memmove(two, one, 9);
1152 equal(two, "hi there", 5); /* Just paranoia. */
1153 equal(one, "hi there", 6); /* Stomped on source? */
1155 (void) strcpy(one, "abcdefgh");
1156 (void) memmove(one+1, one, 9);
1157 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
1159 (void) strcpy(one, "abcdefgh");
1160 (void) memmove(one+1, one+2, 7);
1161 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
1163 (void) strcpy(one, "abcdefgh");
1164 (void) memmove(one, one, 9);
1165 equal(one, "abcdefgh", 9); /* 100% overlap. */
1168 static void
1169 test_memccpy (void)
1171 /* First test like memcpy, then the search part The SVID, the only
1172 place where memccpy is mentioned, says overlap might fail, so we
1173 don't try it. Besides, it's hard to see the rationale for a
1174 non-left-to-right memccpy. */
1175 it = "memccpy";
1176 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
1177 equal(one, "abc", 2); /* Did the copy go right? */
1179 (void) strcpy(one, "abcdefgh");
1180 (void) memccpy(one+1, "xyz", 'q', 2);
1181 equal(one, "axydefgh", 3); /* Basic test. */
1183 (void) strcpy(one, "abc");
1184 (void) memccpy(one, "xyz", 'q', 0);
1185 equal(one, "abc", 4); /* Zero-length copy. */
1187 (void) strcpy(one, "hi there");
1188 (void) strcpy(two, "foo");
1189 (void) memccpy(two, one, 'q', 9);
1190 equal(two, "hi there", 5); /* Just paranoia. */
1191 equal(one, "hi there", 6); /* Stomped on source? */
1193 (void) strcpy(one, "abcdefgh");
1194 (void) strcpy(two, "horsefeathers");
1195 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
1196 equal(one, "abcdefgh", 8); /* Source intact? */
1197 equal(two, "abcdefeathers", 9); /* Copy correct? */
1199 (void) strcpy(one, "abcd");
1200 (void) strcpy(two, "bumblebee");
1201 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
1202 equal(two, "aumblebee", 11);
1203 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
1204 equal(two, "abcdlebee", 13);
1205 (void) strcpy(one, "xyz");
1206 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
1207 equal(two, "xbcdlebee", 15);
1210 static void
1211 test_memset (void)
1213 int i;
1215 it = "memset";
1216 (void) strcpy(one, "abcdefgh");
1217 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
1218 equal(one, "axxxefgh", 2); /* Basic test. */
1220 (void) memset(one+2, 'y', 0);
1221 equal(one, "axxxefgh", 3); /* Zero-length set. */
1223 (void) memset(one+5, 0, 1);
1224 equal(one, "axxxe", 4); /* Zero fill. */
1225 equal(one+6, "gh", 5); /* And the leftover. */
1227 (void) memset(one+2, 010045, 1);
1228 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
1230 /* Non-8bit fill character. */
1231 memset (one, 0x101, sizeof (one));
1232 for (i = 0; i < (int) sizeof (one); ++i)
1233 check (one[i] == '\01', 7);
1235 /* Test for more complex versions of memset, for all alignments and
1236 lengths up to 256. This test takes a little while, perhaps it should
1237 be made weaker? */
1239 char data[512];
1240 int j;
1241 int k;
1242 int c;
1244 for (i = 0; i < 512; i++)
1245 data[i] = 'x';
1246 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
1247 memset(,'y',) */
1248 for (j = 0; j < 256; j++)
1249 for (i = 0; i < 256; i++)
1251 memset (data + i, c, j);
1252 for (k = 0; k < i; k++)
1253 if (data[k] != 'x')
1254 goto fail;
1255 for (k = i; k < i+j; k++)
1257 if (data[k] != c)
1258 goto fail;
1259 data[k] = 'x';
1261 for (k = i+j; k < 512; k++)
1262 if (data[k] != 'x')
1263 goto fail;
1264 continue;
1266 fail:
1267 check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
1272 static void
1273 test_bcopy (void)
1275 /* Much like memcpy. Berklix manual is silent about overlap, so
1276 don't test it. */
1277 it = "bcopy";
1278 (void) bcopy("abc", one, 4);
1279 equal(one, "abc", 1); /* Simple copy. */
1281 (void) strcpy(one, "abcdefgh");
1282 (void) bcopy("xyz", one+1, 2);
1283 equal(one, "axydefgh", 2); /* Basic test. */
1285 (void) strcpy(one, "abc");
1286 (void) bcopy("xyz", one, 0);
1287 equal(one, "abc", 3); /* Zero-length copy. */
1289 (void) strcpy(one, "hi there");
1290 (void) strcpy(two, "foo");
1291 (void) bcopy(one, two, 9);
1292 equal(two, "hi there", 4); /* Just paranoia. */
1293 equal(one, "hi there", 5); /* Stomped on source? */
1296 static void
1297 test_bzero (void)
1299 it = "bzero";
1300 (void) strcpy(one, "abcdef");
1301 bzero(one+2, 2);
1302 equal(one, "ab", 1); /* Basic test. */
1303 equal(one+3, "", 2);
1304 equal(one+4, "ef", 3);
1306 (void) strcpy(one, "abcdef");
1307 bzero(one+2, 0);
1308 equal(one, "abcdef", 4); /* Zero-length copy. */
1311 static void
1312 test_strndup (void)
1314 char *p, *q;
1315 it = "strndup";
1316 p = strndup("abcdef", 12);
1317 check(p != NULL, 1);
1318 if (p != NULL)
1320 equal(p, "abcdef", 2);
1321 q = strndup(p + 1, 2);
1322 check(q != NULL, 3);
1323 if (q != NULL)
1324 equal(q, "bc", 4);
1325 free (q);
1327 free (p);
1328 p = strndup("abc def", 3);
1329 check(p != NULL, 5);
1330 if (p != NULL)
1331 equal(p, "abc", 6);
1332 free (p);
1335 static void
1336 test_bcmp (void)
1338 it = "bcmp";
1339 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1340 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1341 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1342 check(bcmp("abce", "abcd", 4) != 0, 4);
1343 check(bcmp("alph", "beta", 4) != 0, 5);
1344 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1345 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1348 static void
1349 test_strerror (void)
1351 it = "strerror";
1352 check(strerror(EDOM) != 0, 1);
1353 check(strerror(ERANGE) != 0, 2);
1354 check(strerror(ENOENT) != 0, 3);
1357 static void
1358 test_strcasecmp (void)
1360 it = "strcasecmp";
1361 /* Note that the locale is "C". */
1362 check(strcasecmp("a", "a") == 0, 1);
1363 check(strcasecmp("a", "A") == 0, 2);
1364 check(strcasecmp("A", "a") == 0, 3);
1365 check(strcasecmp("a", "b") < 0, 4);
1366 check(strcasecmp("c", "b") > 0, 5);
1367 check(strcasecmp("abc", "AbC") == 0, 6);
1368 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1369 check(strcasecmp("", "0123456789") < 0, 8);
1370 check(strcasecmp("AbC", "") > 0, 9);
1371 check(strcasecmp("AbC", "A") > 0, 10);
1372 check(strcasecmp("AbC", "Ab") > 0, 11);
1373 check(strcasecmp("AbC", "ab") > 0, 12);
1376 static void
1377 test_strncasecmp (void)
1379 it = "strncasecmp";
1380 /* Note that the locale is "C". */
1381 check(strncasecmp("a", "a", 5) == 0, 1);
1382 check(strncasecmp("a", "A", 5) == 0, 2);
1383 check(strncasecmp("A", "a", 5) == 0, 3);
1384 check(strncasecmp("a", "b", 5) < 0, 4);
1385 check(strncasecmp("c", "b", 5) > 0, 5);
1386 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1387 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1388 check(strncasecmp("", "0123456789", 10) < 0, 8);
1389 check(strncasecmp("AbC", "", 5) > 0, 9);
1390 check(strncasecmp("AbC", "A", 5) > 0, 10);
1391 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1392 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1393 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1394 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1395 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1396 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1397 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1398 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1399 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1400 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1404 main (void)
1406 int status;
1408 /* Test strcmp first because we use it to test other things. */
1409 test_strcmp ();
1411 /* Test strcpy next because we need it to set up other tests. */
1412 test_strcpy ();
1414 /* A closely related function is stpcpy. */
1415 test_stpcpy ();
1417 /* stpncpy. */
1418 test_stpncpy ();
1420 /* strcat. */
1421 test_strcat ();
1423 /* strncat. */
1424 test_strncat ();
1426 /* strncmp. */
1427 test_strncmp ();
1429 /* strncpy. */
1430 test_strncpy ();
1432 /* strlen. */
1433 test_strlen ();
1435 /* strnlen. */
1436 test_strnlen ();
1438 /* strchr. */
1439 test_strchr ();
1441 /* strchrnul. */
1442 test_strchrnul ();
1444 /* rawmemchr. */
1445 test_rawmemchr ();
1447 /* index - just like strchr. */
1448 test_index ();
1450 /* strrchr. */
1451 test_strrchr ();
1453 /* memrchr. */
1454 test_memrchr ();
1456 /* rindex - just like strrchr. */
1457 test_rindex ();
1459 /* strpbrk - somewhat like strchr. */
1460 test_strpbrk ();
1462 /* strstr - somewhat like strchr. */
1463 test_strstr ();
1465 /* strspn. */
1466 test_strspn ();
1468 /* strcspn. */
1469 test_strcspn ();
1471 /* strtok - the hard one. */
1472 test_strtok ();
1474 /* strtok_r. */
1475 test_strtok_r ();
1477 /* strsep. */
1478 test_strsep ();
1480 /* memcmp. */
1481 test_memcmp ();
1483 /* memchr. */
1484 test_memchr ();
1486 /* memcpy - need not work for overlap. */
1487 test_memcpy ();
1489 /* memmove - must work on overlap. */
1490 test_memmove ();
1492 /* mempcpy */
1493 test_mempcpy ();
1495 /* memccpy. */
1496 test_memccpy ();
1498 /* memset. */
1499 test_memset ();
1501 /* bcopy. */
1502 test_bcopy ();
1504 /* bzero. */
1505 test_bzero ();
1507 /* bcmp - somewhat like memcmp. */
1508 test_bcmp ();
1510 /* strndup. */
1511 test_strndup ();
1513 /* strerror - VERY system-dependent. */
1514 test_strerror ();
1516 /* strcasecmp. Without locale dependencies. */
1517 test_strcasecmp ();
1519 /* strncasecmp. Without locale dependencies. */
1520 test_strncasecmp ();
1522 if (errors == 0)
1524 status = EXIT_SUCCESS;
1525 puts("No errors.");
1527 else
1529 status = EXIT_FAILURE;
1530 printf("%Zd errors.\n", errors);
1533 return status;