* sysdeps/unix/sysv/linux/fxstatat64.c: Include string.h.
[glibc.git] / string / tester.c
blobf95270efb4f4d27aae8e9f8d022b1a2cc39dcd69
1 /* Tester for string functions.
2 Copyright (C) 1995-2001, 2003, 2005 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. */
349 static void
350 test_strncmp (void)
352 /* First test as strcmp with big counts, then test count code. */
353 it = "strncmp";
354 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
355 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
356 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
357 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
358 check (strncmp ("abcd", "abc", 99) > 0, 5);
359 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
360 check (strncmp ("abce", "abcd", 99) > 0, 7);
361 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
362 check (strncmp ("a\203", "a\003", 2) > 0, 9);
363 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
364 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
365 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
366 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
369 static void
370 test_strncpy (void)
372 /* Testing is a bit different because of odd semantics. */
373 it = "strncpy";
374 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
375 equal (one, "abc", 2); /* Did the copy go right? */
377 (void) strcpy (one, "abcdefgh");
378 (void) strncpy (one, "xyz", 2);
379 equal (one, "xycdefgh", 3); /* Copy cut by count. */
381 (void) strcpy (one, "abcdefgh");
382 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
383 equal (one, "xyzdefgh", 4);
385 (void) strcpy (one, "abcdefgh");
386 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
387 equal (one, "xyz", 5);
388 equal (one+4, "efgh", 6); /* Wrote too much? */
390 (void) strcpy (one, "abcdefgh");
391 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
392 equal (one, "xyz", 7);
393 equal (one+4, "", 8);
394 equal (one+5, "fgh", 9);
396 (void) strcpy (one, "abc");
397 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
398 equal (one, "abc", 10);
400 (void) strncpy (one, "", 2); /* Zero-length source. */
401 equal (one, "", 11);
402 equal (one+1, "", 12);
403 equal (one+2, "c", 13);
405 (void) strcpy (one, "hi there");
406 (void) strncpy (two, one, 9);
407 equal (two, "hi there", 14); /* Just paranoia. */
408 equal (one, "hi there", 15); /* Stomped on source? */
411 static void
412 test_strlen (void)
414 it = "strlen";
415 check (strlen ("") == 0, 1); /* Empty. */
416 check (strlen ("a") == 1, 2); /* Single char. */
417 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
419 char buf[4096];
420 int i;
421 char *p;
422 for (i=0; i < 0x100; i++)
424 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
425 strcpy (p, "OK");
426 strcpy (p+3, "BAD/WRONG");
427 check (strlen (p) == 2, 4+i);
432 static void
433 test_strchr (void)
435 it = "strchr";
436 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
437 (void) strcpy (one, "abcd");
438 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
439 check (strchr (one, 'd') == one+3, 3); /* End of string. */
440 check (strchr (one, 'a') == one, 4); /* Beginning. */
441 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
442 (void) strcpy (one, "ababa");
443 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
444 (void) strcpy (one, "");
445 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
446 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
448 char buf[4096];
449 int i;
450 char *p;
451 for (i=0; i < 0x100; i++)
453 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
454 strcpy (p, "OK");
455 strcpy (p+3, "BAD/WRONG");
456 check (strchr (p, '/') == NULL, 9+i);
461 static void
462 test_strchrnul (void)
464 const char *os;
465 it = "strchrnul";
466 cp = strchrnul ((os = "abcd"), 'z');
467 check (*cp == '\0', 1); /* Not found. */
468 check (cp == os + 4, 2);
469 (void) strcpy (one, "abcd");
470 check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */
471 check (strchrnul (one, 'd') == one+3, 4); /* End of string. */
472 check (strchrnul (one, 'a') == one, 5); /* Beginning. */
473 check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */
474 (void) strcpy (one, "ababa");
475 check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */
476 (void) strcpy (one, "");
477 check (strchrnul (one, 'b') == one, 8); /* Empty string. */
478 check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */
480 char buf[4096];
481 int i;
482 char *p;
483 for (i=0; i < 0x100; i++)
485 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
486 strcpy (p, "OK");
487 strcpy (p+3, "BAD/WRONG");
488 cp = strchrnul (p, '/');
489 check (*cp == '\0', 9+2*i);
490 check (cp == p+2, 10+2*i);
495 static void
496 test_rawmemchr (void)
498 it = "rawmemchr";
499 (void) strcpy (one, "abcd");
500 check (rawmemchr (one, 'c') == one+2, 1); /* Basic test. */
501 check (rawmemchr (one, 'd') == one+3, 2); /* End of string. */
502 check (rawmemchr (one, 'a') == one, 3); /* Beginning. */
503 check (rawmemchr (one, '\0') == one+4, 4); /* Finding NUL. */
504 (void) strcpy (one, "ababa");
505 check (rawmemchr (one, 'b') == one+1, 5); /* Finding first. */
506 (void) strcpy (one, "");
507 check (rawmemchr (one, '\0') == one, 6); /* NUL in empty string. */
509 char buf[4096];
510 int i;
511 char *p;
512 for (i=0; i < 0x100; i++)
514 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
515 strcpy (p, "OK");
516 strcpy (p+3, "BAD/WRONG");
517 check (rawmemchr (p, 'R') == p+8, 6+i);
522 static void
523 test_index (void)
525 it = "index";
526 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
527 (void) strcpy (one, "abcd");
528 check (index (one, 'c') == one+2, 2); /* Basic test. */
529 check (index (one, 'd') == one+3, 3); /* End of string. */
530 check (index (one, 'a') == one, 4); /* Beginning. */
531 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
532 (void) strcpy (one, "ababa");
533 check (index (one, 'b') == one+1, 6); /* Finding first. */
534 (void) strcpy (one, "");
535 check (index (one, 'b') == NULL, 7); /* Empty string. */
536 check (index (one, '\0') == one, 8); /* NUL in empty string. */
539 static void
540 test_strrchr (void)
542 it = "strrchr";
543 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
544 (void) strcpy (one, "abcd");
545 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
546 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
547 check (strrchr (one, 'a') == one, 4); /* Beginning. */
548 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
549 (void) strcpy (one, "ababa");
550 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
551 (void) strcpy (one, "");
552 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
553 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
555 char buf[4096];
556 int i;
557 char *p;
558 for (i=0; i < 0x100; i++)
560 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
561 strcpy (p, "OK");
562 strcpy (p+3, "BAD/WRONG");
563 check (strrchr (p, '/') == NULL, 9+i);
568 static void
569 test_memrchr (void)
571 size_t l;
572 it = "memrchr";
573 check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */
574 (void) strcpy (one, "abcd");
575 l = strlen (one) + 1;
576 check (memrchr (one, 'c', l) == one+2, 2); /* Basic test. */
577 check (memrchr (one, 'd', l) == one+3, 3); /* End of string. */
578 check (memrchr (one, 'a', l) == one, 4); /* Beginning. */
579 check (memrchr (one, '\0', l) == one+4, 5); /* Finding NUL. */
580 (void) strcpy (one, "ababa");
581 l = strlen (one) + 1;
582 check (memrchr (one, 'b', l) == one+3, 6); /* Finding last. */
583 (void) strcpy (one, "");
584 l = strlen (one) + 1;
585 check (memrchr (one, 'b', l) == NULL, 7); /* Empty string. */
586 check (memrchr (one, '\0', l) == one, 8); /* NUL in empty string. */
588 /* now test all possible alignment and length combinations to catch
589 bugs due to unrolled loops (assuming unrolling is limited to no
590 more than 128 byte chunks: */
592 char buf[128 + sizeof(long)];
593 long align, len, i, pos;
595 for (align = 0; align < (long) sizeof(long); ++align) {
596 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
597 for (i = 0; i < len; ++i)
598 buf[align + i] = 'x'; /* don't depend on memset... */
600 for (pos = len - 1; pos >= 0; --pos) {
601 #if 0
602 printf("align %d, len %d, pos %d\n", align, len, pos);
603 #endif
604 check(memrchr(buf + align, 'x', len) == buf + align + pos, 9);
605 check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
606 10);
607 buf[align + pos] = '-';
614 static void
615 test_rindex (void)
617 it = "rindex";
618 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
619 (void) strcpy (one, "abcd");
620 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
621 check (rindex (one, 'd') == one+3, 3); /* End of string. */
622 check (rindex (one, 'a') == one, 4); /* Beginning. */
623 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
624 (void) strcpy (one, "ababa");
625 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
626 (void) strcpy (one, "");
627 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
628 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
631 static void
632 test_strpbrk (void)
634 it = "strpbrk";
635 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
636 (void) strcpy(one, "abcd");
637 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
638 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
639 check(strpbrk(one, "a") == one, 4); /* Beginning. */
640 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
641 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
642 (void) strcpy(one, "abcabdea");
643 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
644 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
645 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
646 (void) strcpy(one, "");
647 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
648 (void) strcpy(one, "");
649 check(strpbrk(one, "bcd") == NULL, 11); /* Empty string. */
650 (void) strcpy(one, "");
651 check(strpbrk(one, "bcde") == NULL, 12); /* Empty string. */
652 check(strpbrk(one, "") == NULL, 13); /* Both strings empty. */
653 (void) strcpy(one, "abcabdea");
654 check(strpbrk(one, "befg") == one+1, 14); /* Finding first. */
655 check(strpbrk(one, "cbr") == one+1, 15); /* With multiple search. */
656 check(strpbrk(one, "db") == one+1, 16); /* Another variant. */
657 check(strpbrk(one, "efgh") == one+6, 17); /* And yet another. */
660 static void
661 test_strstr (void)
663 it = "strstr";
664 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
665 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
666 (void) strcpy(one, "abcd");
667 check(strstr(one, "c") == one+2, 3); /* Basic test. */
668 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
669 check(strstr(one, "d") == one+3, 5); /* End of string. */
670 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
671 check(strstr(one, "abc") == one, 7); /* Beginning. */
672 check(strstr(one, "abcd") == one, 8); /* Exact match. */
673 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
674 check(strstr(one, "de") == NULL, 10); /* Past end. */
675 check(strstr(one, "") == one, 11); /* Finding empty. */
676 (void) strcpy(one, "ababa");
677 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
678 (void) strcpy(one, "");
679 check(strstr(one, "b") == NULL, 13); /* Empty string. */
680 check(strstr(one, "") == one, 14); /* Empty in empty string. */
681 (void) strcpy(one, "bcbca");
682 check(strstr(one, "bca") == one+2, 15); /* False start. */
683 (void) strcpy(one, "bbbcabbca");
684 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
687 static void
688 test_strspn (void)
690 it = "strspn";
691 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
692 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
693 check(strspn("abc", "qx") == 0, 3); /* None. */
694 check(strspn("", "ab") == 0, 4); /* Null string. */
695 check(strspn("abc", "") == 0, 5); /* Null search list. */
698 static void
699 test_strcspn (void)
701 it = "strcspn";
702 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
703 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
704 check(strcspn("abc", "abc") == 0, 3); /* None. */
705 check(strcspn("", "ab") == 0, 4); /* Null string. */
706 check(strcspn("abc", "") == 3, 5); /* Null search list. */
709 static void
710 test_strtok (void)
712 it = "strtok";
713 (void) strcpy(one, "first, second, third");
714 equal(strtok(one, ", "), "first", 1); /* Basic test. */
715 equal(one, "first", 2);
716 equal(strtok((char *)NULL, ", "), "second", 3);
717 equal(strtok((char *)NULL, ", "), "third", 4);
718 check(strtok((char *)NULL, ", ") == NULL, 5);
719 (void) strcpy(one, ", first, ");
720 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
721 check(strtok((char *)NULL, ", ") == NULL, 7);
722 (void) strcpy(one, "1a, 1b; 2a, 2b");
723 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
724 equal(strtok((char *)NULL, "; "), "1b", 9);
725 equal(strtok((char *)NULL, ", "), "2a", 10);
726 (void) strcpy(two, "x-y");
727 equal(strtok(two, "-"), "x", 11); /* New string before done. */
728 equal(strtok((char *)NULL, "-"), "y", 12);
729 check(strtok((char *)NULL, "-") == NULL, 13);
730 (void) strcpy(one, "a,b, c,, ,d");
731 equal(strtok(one, ", "), "a", 14); /* Different separators. */
732 equal(strtok((char *)NULL, ", "), "b", 15);
733 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
734 equal(strtok((char *)NULL, " ,"), "d", 17);
735 check(strtok((char *)NULL, ", ") == NULL, 18);
736 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
737 (void) strcpy(one, ", ");
738 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
739 (void) strcpy(one, "");
740 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
741 (void) strcpy(one, "abc");
742 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
743 check(strtok((char *)NULL, ", ") == NULL, 23);
744 (void) strcpy(one, "abc");
745 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
746 check(strtok((char *)NULL, "") == NULL, 25);
747 (void) strcpy(one, "abcdefgh");
748 (void) strcpy(one, "a,b,c");
749 equal(strtok(one, ","), "a", 26); /* Basics again... */
750 equal(strtok((char *)NULL, ","), "b", 27);
751 equal(strtok((char *)NULL, ","), "c", 28);
752 check(strtok((char *)NULL, ",") == NULL, 29);
753 equal(one+6, "gh", 30); /* Stomped past end? */
754 equal(one, "a", 31); /* Stomped old tokens? */
755 equal(one+2, "b", 32);
756 equal(one+4, "c", 33);
759 static void
760 test_strtok_r (void)
762 it = "strtok_r";
763 (void) strcpy(one, "first, second, third");
764 cp = NULL; /* Always initialize cp to make sure it doesn't point to some old data. */
765 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
766 equal(one, "first", 2);
767 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
768 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
769 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
770 (void) strcpy(one, ", first, ");
771 cp = NULL;
772 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
773 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
774 (void) strcpy(one, "1a, 1b; 2a, 2b");
775 cp = NULL;
776 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
777 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
778 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
779 (void) strcpy(two, "x-y");
780 cp = NULL;
781 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
782 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
783 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
784 (void) strcpy(one, "a,b, c,, ,d");
785 cp = NULL;
786 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
787 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
788 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
789 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
790 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
791 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
792 (void) strcpy(one, ", ");
793 cp = NULL;
794 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
795 (void) strcpy(one, "");
796 cp = NULL;
797 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
798 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22); /* Persistence. */
799 (void) strcpy(one, "abc");
800 cp = NULL;
801 equal(strtok_r(one, ", ", &cp), "abc", 23); /* No delimiters. */
802 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
803 (void) strcpy(one, "abc");
804 cp = NULL;
805 equal(strtok_r(one, "", &cp), "abc", 25); /* Empty delimiter list. */
806 check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
807 (void) strcpy(one, "abcdefgh");
808 (void) strcpy(one, "a,b,c");
809 cp = NULL;
810 equal(strtok_r(one, ",", &cp), "a", 27); /* Basics again... */
811 equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
812 equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
813 check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
814 equal(one+6, "gh", 31); /* Stomped past end? */
815 equal(one, "a", 32); /* Stomped old tokens? */
816 equal(one+2, "b", 33);
817 equal(one+4, "c", 34);
820 static void
821 test_strsep (void)
823 char *ptr;
824 it = "strsep";
825 cp = strcpy(one, "first, second, third");
826 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
827 equal(one, "first", 2);
828 equal(strsep(&cp, ", "), "", 3);
829 equal(strsep(&cp, ", "), "second", 4);
830 equal(strsep(&cp, ", "), "", 5);
831 equal(strsep(&cp, ", "), "third", 6);
832 check(strsep(&cp, ", ") == NULL, 7);
833 cp = strcpy(one, ", first, ");
834 equal(strsep(&cp, ", "), "", 8);
835 equal(strsep(&cp, ", "), "", 9);
836 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
837 equal(strsep(&cp, ", "), "", 11);
838 equal(strsep(&cp, ", "), "", 12);
839 check(strsep(&cp, ", ") == NULL, 13);
840 cp = strcpy(one, "1a, 1b; 2a, 2b");
841 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */
842 equal(strsep(&cp, ", "), "", 15);
843 equal(strsep(&cp, "; "), "1b", 16);
844 equal(strsep(&cp, ", "), "", 17);
845 equal(strsep(&cp, ", "), "2a", 18);
846 cp = strcpy(two, "x-y");
847 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */
848 equal(strsep(&cp, "-"), "y", 20);
849 check(strsep(&cp, "-") == NULL, 21);
850 cp = strcpy(one, "a,b, c,, ,d ");
851 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */
852 equal(strsep(&cp, ", "), "b", 23);
853 equal(strsep(&cp, " ,"), "", 24);
854 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */
855 equal(strsep(&cp, " ,"), "", 26);
856 equal(strsep(&cp, " ,"), "", 27);
857 equal(strsep(&cp, " ,"), "", 28);
858 equal(strsep(&cp, " ,"), "d", 29);
859 equal(strsep(&cp, " ,"), "", 30);
860 check(strsep(&cp, ", ") == NULL, 31);
861 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
862 cp = strcpy(one, ", ");
863 equal(strsep(&cp, ", "), "", 33);
864 equal(strsep(&cp, ", "), "", 34);
865 equal(strsep(&cp, ", "), "", 35);
866 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
867 cp = strcpy(one, "");
868 equal(strsep(&cp, ", "), "", 37);
869 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
870 cp = strcpy(one, "abc");
871 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */
872 check(strsep(&cp, ", ") == NULL, 40);
873 cp = strcpy(one, "abc");
874 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */
875 check(strsep(&cp, "") == NULL, 42);
876 (void) strcpy(one, "abcdefgh");
877 cp = strcpy(one, "a,b,c");
878 equal(strsep(&cp, ","), "a", 43); /* Basics again... */
879 equal(strsep(&cp, ","), "b", 44);
880 equal(strsep(&cp, ","), "c", 45);
881 check(strsep(&cp, ",") == NULL, 46);
882 equal(one+6, "gh", 47); /* Stomped past end? */
883 equal(one, "a", 48); /* Stomped old tokens? */
884 equal(one+2, "b", 49);
885 equal(one+4, "c", 50);
888 char text[] = "This,is,a,test";
889 char *list = strdupa (text);
890 equal (strsep (&list, ","), "This", 51);
891 equal (strsep (&list, ","), "is", 52);
892 equal (strsep (&list, ","), "a", 53);
893 equal (strsep (&list, ","), "test", 54);
894 check (strsep (&list, ",") == NULL, 55);
897 cp = strcpy(one, "a,b, c,, ,d,");
898 equal(strsep(&cp, ","), "a", 56); /* Different separators. */
899 equal(strsep(&cp, ","), "b", 57);
900 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */
901 equal(strsep(&cp, ","), "", 59);
902 equal(strsep(&cp, ","), " ", 60);
903 equal(strsep(&cp, ","), "d", 61);
904 equal(strsep(&cp, ","), "", 62);
905 check(strsep(&cp, ",") == NULL, 63);
906 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */
908 cp = strcpy(one, "a,b, c,, ,d,");
909 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */
910 equal(strsep(&cp, "x,y"), "b", 66);
911 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */
912 equal(strsep(&cp, "xy,"), "", 68);
913 equal(strsep(&cp, "x,y"), " ", 69);
914 equal(strsep(&cp, ",xy"), "d", 70);
915 equal(strsep(&cp, "xy,"), "", 71);
916 check(strsep(&cp, "x,y") == NULL, 72);
917 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
919 cp = strcpy(one, "ABC");
920 one[4] = ':';
921 equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */
922 ptr = strsep(&cp, ":");
923 equal(ptr, "", 75);
924 check(ptr == one + 3, 76);
925 check(cp == NULL, 77);
927 cp = strcpy(one, "ABC");
928 one[4] = ':';
929 equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */
930 ptr = strsep(&cp, ":.");
931 equal(ptr, "", 79);
932 check(ptr == one + 3, 80);
934 cp = strcpy(one, "ABC"); /* No token in string. */
935 equal(strsep(&cp, ","), "ABC", 81);
936 check(cp == NULL, 82);
938 *one = '\0'; /* Empty string. */
939 cp = one;
940 ptr = strsep(&cp, ",");
941 equal(ptr, "", 83);
942 check(ptr == one, 84);
943 check(cp == NULL, 85);
945 *one = '\0'; /* Empty string and no token. */
946 cp = one;
947 ptr = strsep(&cp, "");
948 equal(ptr, "", 86);
949 check(ptr == one , 87);
950 check(cp == NULL, 88);
953 static void
954 test_memcmp (void)
956 it = "memcmp";
957 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
958 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
959 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
960 check(memcmp("abce", "abcd", 4) > 0, 4);
961 check(memcmp("alph", "beta", 4) < 0, 5);
962 check(memcmp("a\203", "a\003", 2) > 0, 6);
963 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
964 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
967 static void
968 test_memchr (void)
970 it = "memchr";
971 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
972 (void) strcpy(one, "abcd");
973 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
974 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
975 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
976 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
977 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
978 (void) strcpy(one, "ababa");
979 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
980 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
981 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
982 (void) strcpy(one, "a\203b");
983 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
985 /* now test all possible alignment and length combinations to catch
986 bugs due to unrolled loops (assuming unrolling is limited to no
987 more than 128 byte chunks: */
989 char buf[128 + sizeof(long)];
990 long align, len, i, pos;
992 for (align = 0; align < (long) sizeof(long); ++align) {
993 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
994 for (i = 0; i < len; ++i) {
995 buf[align + i] = 'x'; /* don't depend on memset... */
997 for (pos = 0; pos < len; ++pos) {
998 #if 0
999 printf("align %d, len %d, pos %d\n", align, len, pos);
1000 #endif
1001 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
1002 check(memchr(buf + align, 'x', pos) == NULL, 11);
1003 buf[align + pos] = '-';
1010 static void
1011 test_memcpy (void)
1013 int i;
1014 it = "memcpy";
1015 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
1016 equal(one, "abc", 2); /* Did the copy go right? */
1018 (void) strcpy(one, "abcdefgh");
1019 (void) memcpy(one+1, "xyz", 2);
1020 equal(one, "axydefgh", 3); /* Basic test. */
1022 (void) strcpy(one, "abc");
1023 (void) memcpy(one, "xyz", 0);
1024 equal(one, "abc", 4); /* Zero-length copy. */
1026 (void) strcpy(one, "hi there");
1027 (void) strcpy(two, "foo");
1028 (void) memcpy(two, one, 9);
1029 equal(two, "hi there", 5); /* Just paranoia. */
1030 equal(one, "hi there", 6); /* Stomped on source? */
1032 for (i = 0; i < 16; i++)
1034 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1035 strcpy (one, x);
1036 check (memcpy (one + i, "hi there", 9) == one + i,
1037 7 + (i * 6)); /* Unaligned destination. */
1038 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1039 equal (one + i, "hi there", 9 + (i * 6));
1040 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1041 check (memcpy (two, one + i, 9) == two,
1042 11 + (i * 6)); /* Unaligned source. */
1043 equal (two, "hi there", 12 + (i * 6));
1047 static void
1048 test_mempcpy (void)
1050 int i;
1051 it = "mempcpy";
1052 check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */
1053 equal(one, "abc", 2); /* Did the copy go right? */
1055 (void) strcpy(one, "abcdefgh");
1056 (void) mempcpy(one+1, "xyz", 2);
1057 equal(one, "axydefgh", 3); /* Basic test. */
1059 (void) strcpy(one, "abc");
1060 (void) mempcpy(one, "xyz", 0);
1061 equal(one, "abc", 4); /* Zero-length copy. */
1063 (void) strcpy(one, "hi there");
1064 (void) strcpy(two, "foo");
1065 (void) mempcpy(two, one, 9);
1066 equal(two, "hi there", 5); /* Just paranoia. */
1067 equal(one, "hi there", 6); /* Stomped on source? */
1069 for (i = 0; i < 16; i++)
1071 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1072 strcpy (one, x);
1073 check (mempcpy (one + i, "hi there", 9) == one + i + 9,
1074 7 + (i * 6)); /* Unaligned destination. */
1075 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1076 equal (one + i, "hi there", 9 + (i * 6));
1077 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1078 check (mempcpy (two, one + i, 9) == two + 9,
1079 11 + (i * 6)); /* Unaligned source. */
1080 equal (two, "hi there", 12 + (i * 6));
1084 static void
1085 test_memmove (void)
1087 it = "memmove";
1088 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
1089 equal(one, "abc", 2); /* Did the copy go right? */
1091 (void) strcpy(one, "abcdefgh");
1092 (void) memmove(one+1, "xyz", 2);
1093 equal(one, "axydefgh", 3); /* Basic test. */
1095 (void) strcpy(one, "abc");
1096 (void) memmove(one, "xyz", 0);
1097 equal(one, "abc", 4); /* Zero-length copy. */
1099 (void) strcpy(one, "hi there");
1100 (void) strcpy(two, "foo");
1101 (void) memmove(two, one, 9);
1102 equal(two, "hi there", 5); /* Just paranoia. */
1103 equal(one, "hi there", 6); /* Stomped on source? */
1105 (void) strcpy(one, "abcdefgh");
1106 (void) memmove(one+1, one, 9);
1107 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
1109 (void) strcpy(one, "abcdefgh");
1110 (void) memmove(one+1, one+2, 7);
1111 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
1113 (void) strcpy(one, "abcdefgh");
1114 (void) memmove(one, one, 9);
1115 equal(one, "abcdefgh", 9); /* 100% overlap. */
1118 static void
1119 test_memccpy (void)
1121 /* First test like memcpy, then the search part The SVID, the only
1122 place where memccpy is mentioned, says overlap might fail, so we
1123 don't try it. Besides, it's hard to see the rationale for a
1124 non-left-to-right memccpy. */
1125 it = "memccpy";
1126 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
1127 equal(one, "abc", 2); /* Did the copy go right? */
1129 (void) strcpy(one, "abcdefgh");
1130 (void) memccpy(one+1, "xyz", 'q', 2);
1131 equal(one, "axydefgh", 3); /* Basic test. */
1133 (void) strcpy(one, "abc");
1134 (void) memccpy(one, "xyz", 'q', 0);
1135 equal(one, "abc", 4); /* Zero-length copy. */
1137 (void) strcpy(one, "hi there");
1138 (void) strcpy(two, "foo");
1139 (void) memccpy(two, one, 'q', 9);
1140 equal(two, "hi there", 5); /* Just paranoia. */
1141 equal(one, "hi there", 6); /* Stomped on source? */
1143 (void) strcpy(one, "abcdefgh");
1144 (void) strcpy(two, "horsefeathers");
1145 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
1146 equal(one, "abcdefgh", 8); /* Source intact? */
1147 equal(two, "abcdefeathers", 9); /* Copy correct? */
1149 (void) strcpy(one, "abcd");
1150 (void) strcpy(two, "bumblebee");
1151 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
1152 equal(two, "aumblebee", 11);
1153 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
1154 equal(two, "abcdlebee", 13);
1155 (void) strcpy(one, "xyz");
1156 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
1157 equal(two, "xbcdlebee", 15);
1160 static void
1161 test_memset (void)
1163 int i;
1165 it = "memset";
1166 (void) strcpy(one, "abcdefgh");
1167 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
1168 equal(one, "axxxefgh", 2); /* Basic test. */
1170 (void) memset(one+2, 'y', 0);
1171 equal(one, "axxxefgh", 3); /* Zero-length set. */
1173 (void) memset(one+5, 0, 1);
1174 equal(one, "axxxe", 4); /* Zero fill. */
1175 equal(one+6, "gh", 5); /* And the leftover. */
1177 (void) memset(one+2, 010045, 1);
1178 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
1180 /* Non-8bit fill character. */
1181 memset (one, 0x101, sizeof (one));
1182 for (i = 0; i < (int) sizeof (one); ++i)
1183 check (one[i] == '\01', 7);
1185 /* Test for more complex versions of memset, for all alignments and
1186 lengths up to 256. This test takes a little while, perhaps it should
1187 be made weaker? */
1189 char data[512];
1190 int j;
1191 int k;
1192 int c;
1194 for (i = 0; i < 512; i++)
1195 data[i] = 'x';
1196 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
1197 memset(,'y',) */
1198 for (j = 0; j < 256; j++)
1199 for (i = 0; i < 256; i++)
1201 memset (data + i, c, j);
1202 for (k = 0; k < i; k++)
1203 if (data[k] != 'x')
1204 goto fail;
1205 for (k = i; k < i+j; k++)
1207 if (data[k] != c)
1208 goto fail;
1209 data[k] = 'x';
1211 for (k = i+j; k < 512; k++)
1212 if (data[k] != 'x')
1213 goto fail;
1214 continue;
1216 fail:
1217 check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
1222 static void
1223 test_bcopy (void)
1225 /* Much like memcpy. Berklix manual is silent about overlap, so
1226 don't test it. */
1227 it = "bcopy";
1228 (void) bcopy("abc", one, 4);
1229 equal(one, "abc", 1); /* Simple copy. */
1231 (void) strcpy(one, "abcdefgh");
1232 (void) bcopy("xyz", one+1, 2);
1233 equal(one, "axydefgh", 2); /* Basic test. */
1235 (void) strcpy(one, "abc");
1236 (void) bcopy("xyz", one, 0);
1237 equal(one, "abc", 3); /* Zero-length copy. */
1239 (void) strcpy(one, "hi there");
1240 (void) strcpy(two, "foo");
1241 (void) bcopy(one, two, 9);
1242 equal(two, "hi there", 4); /* Just paranoia. */
1243 equal(one, "hi there", 5); /* Stomped on source? */
1246 static void
1247 test_bzero (void)
1249 it = "bzero";
1250 (void) strcpy(one, "abcdef");
1251 bzero(one+2, 2);
1252 equal(one, "ab", 1); /* Basic test. */
1253 equal(one+3, "", 2);
1254 equal(one+4, "ef", 3);
1256 (void) strcpy(one, "abcdef");
1257 bzero(one+2, 0);
1258 equal(one, "abcdef", 4); /* Zero-length copy. */
1261 static void
1262 test_strndup (void)
1264 char *p, *q;
1265 it = "strndup";
1266 p = strndup("abcdef", 12);
1267 check(p != NULL, 1);
1268 if (p != NULL)
1270 equal(p, "abcdef", 2);
1271 q = strndup(p + 1, 2);
1272 check(q != NULL, 3);
1273 if (q != NULL)
1274 equal(q, "bc", 4);
1275 free (q);
1277 free (p);
1278 p = strndup("abc def", 3);
1279 check(p != NULL, 5);
1280 if (p != NULL)
1281 equal(p, "abc", 6);
1282 free (p);
1285 static void
1286 test_bcmp (void)
1288 it = "bcmp";
1289 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1290 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1291 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1292 check(bcmp("abce", "abcd", 4) != 0, 4);
1293 check(bcmp("alph", "beta", 4) != 0, 5);
1294 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1295 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1298 static void
1299 test_strerror (void)
1301 it = "strerror";
1302 check(strerror(EDOM) != 0, 1);
1303 check(strerror(ERANGE) != 0, 2);
1304 check(strerror(ENOENT) != 0, 3);
1307 static void
1308 test_strcasecmp (void)
1310 it = "strcasecmp";
1311 /* Note that the locale is "C". */
1312 check(strcasecmp("a", "a") == 0, 1);
1313 check(strcasecmp("a", "A") == 0, 2);
1314 check(strcasecmp("A", "a") == 0, 3);
1315 check(strcasecmp("a", "b") < 0, 4);
1316 check(strcasecmp("c", "b") > 0, 5);
1317 check(strcasecmp("abc", "AbC") == 0, 6);
1318 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1319 check(strcasecmp("", "0123456789") < 0, 8);
1320 check(strcasecmp("AbC", "") > 0, 9);
1321 check(strcasecmp("AbC", "A") > 0, 10);
1322 check(strcasecmp("AbC", "Ab") > 0, 11);
1323 check(strcasecmp("AbC", "ab") > 0, 12);
1326 static void
1327 test_strncasecmp (void)
1329 it = "strncasecmp";
1330 /* Note that the locale is "C". */
1331 check(strncasecmp("a", "a", 5) == 0, 1);
1332 check(strncasecmp("a", "A", 5) == 0, 2);
1333 check(strncasecmp("A", "a", 5) == 0, 3);
1334 check(strncasecmp("a", "b", 5) < 0, 4);
1335 check(strncasecmp("c", "b", 5) > 0, 5);
1336 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1337 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1338 check(strncasecmp("", "0123456789", 10) < 0, 8);
1339 check(strncasecmp("AbC", "", 5) > 0, 9);
1340 check(strncasecmp("AbC", "A", 5) > 0, 10);
1341 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1342 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1343 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1344 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1345 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1346 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1347 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1348 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1349 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1350 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1354 main (void)
1356 int status;
1358 /* Test strcmp first because we use it to test other things. */
1359 test_strcmp ();
1361 /* Test strcpy next because we need it to set up other tests. */
1362 test_strcpy ();
1364 /* A closely related function is stpcpy. */
1365 test_stpcpy ();
1367 /* stpncpy. */
1368 test_stpncpy ();
1370 /* strcat. */
1371 test_strcat ();
1373 /* strncat. */
1374 test_strncat ();
1376 /* strncmp. */
1377 test_strncmp ();
1379 /* strncpy. */
1380 test_strncpy ();
1382 /* strlen. */
1383 test_strlen ();
1385 /* strchr. */
1386 test_strchr ();
1388 /* strchrnul. */
1389 test_strchrnul ();
1391 /* rawmemchr. */
1392 test_rawmemchr ();
1394 /* index - just like strchr. */
1395 test_index ();
1397 /* strrchr. */
1398 test_strrchr ();
1400 /* memrchr. */
1401 test_memrchr ();
1403 /* rindex - just like strrchr. */
1404 test_rindex ();
1406 /* strpbrk - somewhat like strchr. */
1407 test_strpbrk ();
1409 /* strstr - somewhat like strchr. */
1410 test_strstr ();
1412 /* strspn. */
1413 test_strspn ();
1415 /* strcspn. */
1416 test_strcspn ();
1418 /* strtok - the hard one. */
1419 test_strtok ();
1421 /* strtok_r. */
1422 test_strtok_r ();
1424 /* strsep. */
1425 test_strsep ();
1427 /* memcmp. */
1428 test_memcmp ();
1430 /* memchr. */
1431 test_memchr ();
1433 /* memcpy - need not work for overlap. */
1434 test_memcpy ();
1436 /* memmove - must work on overlap. */
1437 test_memmove ();
1439 /* mempcpy */
1440 test_mempcpy ();
1442 /* memccpy. */
1443 test_memccpy ();
1445 /* memset. */
1446 test_memset ();
1448 /* bcopy. */
1449 test_bcopy ();
1451 /* bzero. */
1452 test_bzero ();
1454 /* bcmp - somewhat like memcmp. */
1455 test_bcmp ();
1457 /* strndup. */
1458 test_strndup ();
1460 /* strerror - VERY system-dependent. */
1461 test_strerror ();
1463 /* strcasecmp. Without locale dependencies. */
1464 test_strcasecmp ();
1466 /* strncasecmp. Without locale dependencies. */
1467 test_strncasecmp ();
1469 if (errors == 0)
1471 status = EXIT_SUCCESS;
1472 puts("No errors.");
1474 else
1476 status = EXIT_FAILURE;
1477 printf("%Zd errors.\n", errors);
1480 return status;