Bug 480126 - Build failure on Raspberry Pi 5 / OS 6.1.0-rpi7-rpi-v8
[valgrind.git] / memcheck / tests / str_tester.c
blob1201bbfc225b27d3364d3e8c65f7f3589ca91cab
1 /* Tester for string functions.
2 Copyright (C) 1995-2000, 2001, 2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #ifndef _GNU_SOURCE
21 #define _GNU_SOURCE
22 #endif
24 /* Make sure we don't test the optimized inline functions if we want to
25 test the real implementation. */
26 #if !defined DO_STRING_INLINES
27 #undef __USE_STRING_INLINES
28 #endif
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <strings.h>
35 #include <fcntl.h>
36 #include "../../config.h"
38 #ifndef HAVE_GNU_LD
39 #define _sys_nerr sys_nerr
40 #define _sys_errlist sys_errlist
41 #endif
43 #define STREQ(a, b) (strcmp((a), (b)) == 0)
45 const char *it = "<UNSET>"; /* Routine name for message routines. */
46 size_t errors = 0;
48 /* Complain if condition is not true. */
49 static void
50 check (int thing, int number)
52 if (!thing)
54 printf("%s flunked test %d\n", it, number);
55 ++errors;
59 /* Complain if first two args don't strcmp as equal. */
60 static void
61 equal (const char *a, const char *b, int number)
63 check(a != NULL && b != NULL && STREQ (a, b), number);
66 char one[50];
67 char two[50];
68 char *cp;
70 static void
71 test_strcmp (void)
73 it = "strcmp";
74 check (strcmp ("", "") == 0, 1); /* Trivial case. */
75 check (strcmp ("a", "a") == 0, 2); /* Identity. */
76 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
77 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
78 check (strcmp ("abcd", "abc") > 0, 5);
79 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
80 check (strcmp ("abce", "abcd") > 0, 7);
81 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
82 check (strcmp ("a\203", "a\003") > 0, 9);
85 char buf1[0x40], buf2[0x40];
86 int i, j;
87 for (i=0; i < 0x10; i++)
88 for (j = 0; j < 0x10; j++)
90 int k;
91 for (k = 0; k < 0x3f; k++)
93 buf1[k] = '0' ^ (k & 4);
94 buf2[k] = '4' ^ (k & 4);
96 buf1[i] = buf1[0x3f] = 0;
97 buf2[j] = buf2[0x3f] = 0;
98 for (k = 0; k < 0xf; k++)
100 int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
101 check (strcmp (buf1+i,buf2+j) == 0, cnum);
102 buf1[i+k] = 'A' + i + k;
103 buf1[i+k+1] = 0;
104 check (strcmp (buf1+i,buf2+j) > 0, cnum+1);
105 check (strcmp (buf2+j,buf1+i) < 0, cnum+2);
106 buf2[j+k] = 'B' + i + k;
107 buf2[j+k+1] = 0;
108 check (strcmp (buf1+i,buf2+j) < 0, cnum+3);
109 check (strcmp (buf2+j,buf1+i) > 0, cnum+4);
110 buf2[j+k] = 'A' + i + k;
111 buf1[i] = 'A' + i + 0x80;
112 check (strcmp (buf1+i,buf2+j) > 0, cnum+5);
113 check (strcmp (buf2+j,buf1+i) < 0, cnum+6);
114 buf1[i] = 'A' + i;
120 #define SIMPLE_COPY(fn, n, str, ntest) \
121 do { \
122 int __n; \
123 char *cp; \
124 for (__n = 0; __n < (int) sizeof (one); ++__n) \
125 one[__n] = 'Z'; \
126 fn (one, str); \
127 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
128 check (*cp == '0' + (n % 10), ntest); \
129 check (*cp == '\0', ntest); \
130 } while (0)
132 static void
133 test_strcpy (void)
135 int i;
136 it = "strcpy";
137 check (strcpy (one, "abcd") == one, 1); /* Returned value. */
138 equal (one, "abcd", 2); /* Basic test. */
140 (void) strcpy (one, "x");
141 equal (one, "x", 3); /* Writeover. */
142 equal (one+2, "cd", 4); /* Wrote too much? */
144 (void) strcpy (two, "hi there");
145 (void) strcpy (one, two);
146 equal (one, "hi there", 5); /* Basic test encore. */
147 equal (two, "hi there", 6); /* Stomped on source? */
149 (void) strcpy (one, "");
150 equal (one, "", 7); /* Boundary condition. */
152 for (i = 0; i < 16; i++)
154 (void) strcpy (one + i, "hi there"); /* Unaligned destination. */
155 equal (one + i, "hi there", 8 + (i * 2));
156 (void) strcpy (two, one + i); /* Unaligned source. */
157 equal (two, "hi there", 9 + (i * 2));
160 SIMPLE_COPY(strcpy, 0, "", 41);
161 SIMPLE_COPY(strcpy, 1, "1", 42);
162 SIMPLE_COPY(strcpy, 2, "22", 43);
163 SIMPLE_COPY(strcpy, 3, "333", 44);
164 SIMPLE_COPY(strcpy, 4, "4444", 45);
165 SIMPLE_COPY(strcpy, 5, "55555", 46);
166 SIMPLE_COPY(strcpy, 6, "666666", 47);
167 SIMPLE_COPY(strcpy, 7, "7777777", 48);
168 SIMPLE_COPY(strcpy, 8, "88888888", 49);
169 SIMPLE_COPY(strcpy, 9, "999999999", 50);
170 SIMPLE_COPY(strcpy, 10, "0000000000", 51);
171 SIMPLE_COPY(strcpy, 11, "11111111111", 52);
172 SIMPLE_COPY(strcpy, 12, "222222222222", 53);
173 SIMPLE_COPY(strcpy, 13, "3333333333333", 54);
174 SIMPLE_COPY(strcpy, 14, "44444444444444", 55);
175 SIMPLE_COPY(strcpy, 15, "555555555555555", 56);
176 SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);
178 /* Simple test using implicitly coerced `void *' arguments. */
179 { const void *src = "frobozz";
180 void *dst = one;
181 check (strcpy (dst, src) == dst, 1);
182 equal (dst, "frobozz", 2);
186 static void
187 test_stpcpy (void)
189 it = "stpcpy";
190 check ((stpcpy (one, "a") - one) == 1, 1);
191 equal (one, "a", 2);
193 check ((stpcpy (one, "ab") - one) == 2, 3);
194 equal (one, "ab", 4);
196 check ((stpcpy (one, "abc") - one) == 3, 5);
197 equal (one, "abc", 6);
199 check ((stpcpy (one, "abcd") - one) == 4, 7);
200 equal (one, "abcd", 8);
202 check ((stpcpy (one, "abcde") - one) == 5, 9);
203 equal (one, "abcde", 10);
205 check ((stpcpy (one, "abcdef") - one) == 6, 11);
206 equal (one, "abcdef", 12);
208 check ((stpcpy (one, "abcdefg") - one) == 7, 13);
209 equal (one, "abcdefg", 14);
211 check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
212 equal (one, "abcdefgh", 16);
214 check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
215 equal (one, "abcdefghi", 18);
217 check ((stpcpy (one, "x") - one) == 1, 19);
218 equal (one, "x", 20); /* Writeover. */
219 equal (one+2, "cdefghi", 21); /* Wrote too much? */
221 check ((stpcpy (one, "xx") - one) == 2, 22);
222 equal (one, "xx", 23); /* Writeover. */
223 equal (one+3, "defghi", 24); /* Wrote too much? */
225 check ((stpcpy (one, "xxx") - one) == 3, 25);
226 equal (one, "xxx", 26); /* Writeover. */
227 equal (one+4, "efghi", 27); /* Wrote too much? */
229 check ((stpcpy (one, "xxxx") - one) == 4, 28);
230 equal (one, "xxxx", 29); /* Writeover. */
231 equal (one+5, "fghi", 30); /* Wrote too much? */
233 check ((stpcpy (one, "xxxxx") - one) == 5, 31);
234 equal (one, "xxxxx", 32); /* Writeover. */
235 equal (one+6, "ghi", 33); /* Wrote too much? */
237 check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
238 equal (one, "xxxxxx", 35); /* Writeover. */
239 equal (one+7, "hi", 36); /* Wrote too much? */
241 check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
242 equal (one, "xxxxxxx", 38); /* Writeover. */
243 equal (one+8, "i", 39); /* Wrote too much? */
245 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
246 equal (one, "abc", 41);
247 equal (one + 4, "xxx", 42);
249 SIMPLE_COPY(stpcpy, 0, "", 43);
250 SIMPLE_COPY(stpcpy, 1, "1", 44);
251 SIMPLE_COPY(stpcpy, 2, "22", 45);
252 SIMPLE_COPY(stpcpy, 3, "333", 46);
253 SIMPLE_COPY(stpcpy, 4, "4444", 47);
254 SIMPLE_COPY(stpcpy, 5, "55555", 48);
255 SIMPLE_COPY(stpcpy, 6, "666666", 49);
256 SIMPLE_COPY(stpcpy, 7, "7777777", 50);
257 SIMPLE_COPY(stpcpy, 8, "88888888", 51);
258 SIMPLE_COPY(stpcpy, 9, "999999999", 52);
259 SIMPLE_COPY(stpcpy, 10, "0000000000", 53);
260 SIMPLE_COPY(stpcpy, 11, "11111111111", 54);
261 SIMPLE_COPY(stpcpy, 12, "222222222222", 55);
262 SIMPLE_COPY(stpcpy, 13, "3333333333333", 56);
263 SIMPLE_COPY(stpcpy, 14, "44444444444444", 57);
264 SIMPLE_COPY(stpcpy, 15, "555555555555555", 58);
265 SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59);
268 #if defined(HAVE_STPNCPY)
269 static void
270 test_stpncpy (void)
272 it = "stpncpy";
273 memset (one, 'x', sizeof (one));
274 check (stpncpy (one, "abc", 2) == one + 2, 1);
275 check (stpncpy (one, "abc", 3) == one + 3, 2);
276 check (stpncpy (one, "abc", 4) == one + 3, 3);
277 check (one[3] == '\0' && one[4] == 'x', 4);
278 check (stpncpy (one, "abcd", 5) == one + 4, 5);
279 check (one[4] == '\0' && one[5] == 'x', 6);
280 check (stpncpy (one, "abcd", 6) == one + 4, 7);
281 check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
283 #endif
285 static void
286 test_strcat (void)
288 it = "strcat";
289 (void) strcpy (one, "ijk");
290 check (strcat (one, "lmn") == one, 1); /* Returned value. */
291 equal (one, "ijklmn", 2); /* Basic test. */
293 (void) strcpy (one, "x");
294 (void) strcat (one, "yz");
295 equal (one, "xyz", 3); /* Writeover. */
296 equal (one+4, "mn", 4); /* Wrote too much? */
298 (void) strcpy (one, "gh");
299 (void) strcpy (two, "ef");
300 (void) strcat (one, two);
301 equal (one, "ghef", 5); /* Basic test encore. */
302 equal (two, "ef", 6); /* Stomped on source? */
304 (void) strcpy (one, "");
305 (void) strcat (one, "");
306 equal (one, "", 7); /* Boundary conditions. */
307 (void) strcpy (one, "ab");
308 (void) strcat (one, "");
309 equal (one, "ab", 8);
310 (void) strcpy (one, "");
311 (void) strcat (one, "cd");
312 equal (one, "cd", 9);
315 static void
316 test_strncat (void)
318 /* First test it as strcat, with big counts, then test the count
319 mechanism. */
320 it = "strncat";
321 (void) strcpy (one, "ijk");
322 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
323 equal (one, "ijklmn", 2); /* Basic test. */
325 (void) strcpy (one, "x");
326 (void) strncat (one, "yz", 99);
327 equal (one, "xyz", 3); /* Writeover. */
328 equal (one+4, "mn", 4); /* Wrote too much? */
330 (void) strcpy (one, "gh");
331 (void) strcpy (two, "ef");
332 (void) strncat (one, two, 99);
333 equal (one, "ghef", 5); /* Basic test encore. */
334 equal (two, "ef", 6); /* Stomped on source? */
336 (void) strcpy (one, "");
337 (void) strncat (one, "", 99);
338 equal (one, "", 7); /* Boundary conditions. */
339 (void) strcpy (one, "ab");
340 (void) strncat (one, "", 99);
341 equal (one, "ab", 8);
342 (void) strcpy (one, "");
343 (void) strncat (one, "cd", 99);
344 equal (one, "cd", 9);
346 (void) strcpy (one, "ab");
347 (void) strncat (one, "cdef", 2);
348 equal (one, "abcd", 10); /* Count-limited. */
350 (void) strncat (one, "gh", 0);
351 equal (one, "abcd", 11); /* Zero count. */
353 (void) strncat (one, "gh", 2);
354 equal (one, "abcdgh", 12); /* Count and length equal. */
357 static void
358 test_strncmp (void)
360 /* First test as strcmp with big counts, then test count code. */
361 it = "strncmp";
362 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
363 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
364 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
365 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
366 check (strncmp ("abcd", "abc", 99) > 0, 5);
367 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
368 check (strncmp ("abce", "abcd", 99) > 0, 7);
369 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
370 check (strncmp ("a\203", "a\003", 2) > 0, 9);
371 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
372 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
373 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
374 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
377 static void
378 test_strncpy (void)
380 /* Testing is a bit different because of odd semantics. */
381 it = "strncpy";
382 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
383 equal (one, "abc", 2); /* Did the copy go right? */
385 (void) strcpy (one, "abcdefgh");
386 (void) strncpy (one, "xyz", 2);
387 equal (one, "xycdefgh", 3); /* Copy cut by count. */
389 (void) strcpy (one, "abcdefgh");
390 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
391 equal (one, "xyzdefgh", 4);
393 (void) strcpy (one, "abcdefgh");
394 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
395 equal (one, "xyz", 5);
396 equal (one+4, "efgh", 6); /* Wrote too much? */
398 (void) strcpy (one, "abcdefgh");
399 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
400 equal (one, "xyz", 7);
401 equal (one+4, "", 8);
402 equal (one+5, "fgh", 9);
404 (void) strcpy (one, "abc");
405 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
406 equal (one, "abc", 10);
408 (void) strncpy (one, "", 2); /* Zero-length source. */
409 equal (one, "", 11);
410 equal (one+1, "", 12);
411 equal (one+2, "c", 13);
413 (void) strcpy (one, "hi there");
414 (void) strncpy (two, one, 9);
415 equal (two, "hi there", 14); /* Just paranoia. */
416 equal (one, "hi there", 15); /* Stomped on source? */
419 static void
420 test_strlen (void)
422 it = "strlen";
423 check (strlen ("") == 0, 1); /* Empty. */
424 check (strlen ("a") == 1, 2); /* Single char. */
425 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
427 char buf[4096];
428 int i;
429 char *p;
430 for (i=0; i < 0x100; i++)
432 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
433 strcpy (p, "OK");
434 strcpy (p+3, "BAD/WRONG");
435 check (strlen (p) == 2, 4+i);
440 static void
441 test_strchr (void)
443 it = "strchr";
444 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
445 (void) strcpy (one, "abcd");
446 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
447 check (strchr (one, 'd') == one+3, 3); /* End of string. */
448 check (strchr (one, 'a') == one, 4); /* Beginning. */
449 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
450 (void) strcpy (one, "ababa");
451 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
452 (void) strcpy (one, "");
453 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
454 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
456 char buf[4096];
457 int i;
458 char *p;
459 for (i=0; i < 0x100; i++)
461 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
462 strcpy (p, "OK");
463 strcpy (p+3, "BAD/WRONG");
464 check (strchr (p, '/') == NULL, 9+i);
469 #if defined(HAVE_STRCHRNUL)
470 static void
471 test_strchrnul (void)
473 const char *os;
474 it = "strchrnul";
475 cp = strchrnul ((os = "abcd"), 'z');
476 check (*cp == '\0', 1); /* Not found. */
477 check (cp == os + 4, 2);
478 (void) strcpy (one, "abcd");
479 check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */
480 check (strchrnul (one, 'd') == one+3, 4); /* End of string. */
481 check (strchrnul (one, 'a') == one, 5); /* Beginning. */
482 check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */
483 (void) strcpy (one, "ababa");
484 check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */
485 (void) strcpy (one, "");
486 check (strchrnul (one, 'b') == one, 8); /* Empty string. */
487 check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */
489 char buf[4096];
490 int i;
491 char *p;
492 for (i=0; i < 0x100; i++)
494 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
495 strcpy (p, "OK");
496 strcpy (p+3, "BAD/WRONG");
497 cp = strchrnul (p, '/');
498 check (*cp == '\0', 9+2*i);
499 check (cp == p+2, 10+2*i);
503 #endif
505 #ifdef HAVE_RAWMEMCHR
506 static void
507 test_rawmemchr (void)
509 it = "rawmemchr";
510 (void) strcpy (one, "abcd");
511 check (rawmemchr (one, 'c') == one+2, 1); /* Basic test. */
512 check (rawmemchr (one, 'd') == one+3, 2); /* End of string. */
513 check (rawmemchr (one, 'a') == one, 3); /* Beginning. */
514 check (rawmemchr (one, '\0') == one+4, 4); /* Finding NUL. */
515 (void) strcpy (one, "ababa");
516 check (rawmemchr (one, 'b') == one+1, 5); /* Finding first. */
517 (void) strcpy (one, "");
518 check (rawmemchr (one, '\0') == one, 6); /* NUL in empty string. */
520 char buf[4096];
521 int i;
522 char *p;
523 for (i=0; i < 0x100; i++)
525 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
526 strcpy (p, "OK");
527 strcpy (p+3, "BAD/WRONG");
528 check (rawmemchr (p, 'R') == p+8, 6+i);
532 #endif
534 static void
535 test_index (void)
537 it = "index";
538 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
539 (void) strcpy (one, "abcd");
540 check (index (one, 'c') == one+2, 2); /* Basic test. */
541 check (index (one, 'd') == one+3, 3); /* End of string. */
542 check (index (one, 'a') == one, 4); /* Beginning. */
543 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
544 (void) strcpy (one, "ababa");
545 check (index (one, 'b') == one+1, 6); /* Finding first. */
546 (void) strcpy (one, "");
547 check (index (one, 'b') == NULL, 7); /* Empty string. */
548 check (index (one, '\0') == one, 8); /* NUL in empty string. */
551 static void
552 test_strrchr (void)
554 it = "strrchr";
555 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
556 (void) strcpy (one, "abcd");
557 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
558 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
559 check (strrchr (one, 'a') == one, 4); /* Beginning. */
560 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
561 (void) strcpy (one, "ababa");
562 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
563 (void) strcpy (one, "");
564 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
565 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
567 char buf[4096];
568 int i;
569 char *p;
570 for (i=0; i < 0x100; i++)
572 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
573 strcpy (p, "OK");
574 strcpy (p+3, "BAD/WRONG");
575 check (strrchr (p, '/') == NULL, 9+i);
580 #if defined(HAVE_MEMRCHR)
581 static void
582 test_memrchr (void)
584 size_t l;
585 it = "memrchr";
586 check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */
587 (void) strcpy (one, "abcd");
588 l = strlen (one) + 1;
589 check (memrchr (one, 'c', l) == one+2, 2); /* Basic test. */
590 check (memrchr (one, 'd', l) == one+3, 3); /* End of string. */
591 check (memrchr (one, 'a', l) == one, 4); /* Beginning. */
592 check (memrchr (one, '\0', l) == one+4, 5); /* Finding NUL. */
593 (void) strcpy (one, "ababa");
594 l = strlen (one) + 1;
595 check (memrchr (one, 'b', l) == one+3, 6); /* Finding last. */
596 (void) strcpy (one, "");
597 l = strlen (one) + 1;
598 check (memrchr (one, 'b', l) == NULL, 7); /* Empty string. */
599 check (memrchr (one, '\0', l) == one, 8); /* NUL in empty string. */
601 /* now test all possible alignment and length combinations to catch
602 bugs due to unrolled loops (assuming unrolling is limited to no
603 more than 128 byte chunks: */
605 char buf[128 + sizeof(long)];
606 long align, len, i, pos;
608 for (align = 0; align < (long) sizeof(long); ++align) {
609 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
610 for (i = 0; i < len; ++i)
611 buf[align + i] = 'x'; /* don't depend on memset... */
613 for (pos = len - 1; pos >= 0; --pos) {
614 #if 0
615 printf("align %d, len %d, pos %d\n", align, len, pos);
616 #endif
617 check(memrchr(buf + align, 'x', len) == buf + align + pos, 9);
618 check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
619 10);
620 buf[align + pos] = '-';
626 #endif
628 static void
629 test_rindex (void)
631 it = "rindex";
632 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
633 (void) strcpy (one, "abcd");
634 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
635 check (rindex (one, 'd') == one+3, 3); /* End of string. */
636 check (rindex (one, 'a') == one, 4); /* Beginning. */
637 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
638 (void) strcpy (one, "ababa");
639 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
640 (void) strcpy (one, "");
641 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
642 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
645 static void
646 test_strpbrk (void)
648 it = "strpbrk";
649 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
650 (void) strcpy(one, "abcd");
651 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
652 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
653 check(strpbrk(one, "a") == one, 4); /* Beginning. */
654 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
655 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
656 (void) strcpy(one, "abcabdea");
657 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
658 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
659 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
660 (void) strcpy(one, "");
661 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
662 (void) strcpy(one, "");
663 check(strpbrk(one, "bcd") == NULL, 11); /* Empty string. */
664 (void) strcpy(one, "");
665 check(strpbrk(one, "bcde") == NULL, 12); /* Empty string. */
666 check(strpbrk(one, "") == NULL, 13); /* Both strings empty. */
667 (void) strcpy(one, "abcabdea");
668 check(strpbrk(one, "befg") == one+1, 14); /* Finding first. */
669 check(strpbrk(one, "cbr") == one+1, 15); /* With multiple search. */
670 check(strpbrk(one, "db") == one+1, 16); /* Another variant. */
671 check(strpbrk(one, "efgh") == one+6, 17); /* And yet another. */
674 static void
675 test_strstr (void)
677 it = "strstr";
678 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
679 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
680 (void) strcpy(one, "abcd");
681 check(strstr(one, "c") == one+2, 3); /* Basic test. */
682 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
683 check(strstr(one, "d") == one+3, 5); /* End of string. */
684 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
685 check(strstr(one, "abc") == one, 7); /* Beginning. */
686 check(strstr(one, "abcd") == one, 8); /* Exact match. */
687 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
688 check(strstr(one, "de") == NULL, 10); /* Past end. */
689 check(strstr(one, "") == one, 11); /* Finding empty. */
690 (void) strcpy(one, "ababa");
691 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
692 (void) strcpy(one, "");
693 check(strstr(one, "b") == NULL, 13); /* Empty string. */
694 check(strstr(one, "") == one, 14); /* Empty in empty string. */
695 (void) strcpy(one, "bcbca");
696 check(strstr(one, "bca") == one+2, 15); /* False start. */
697 (void) strcpy(one, "bbbcabbca");
698 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
701 static void
702 test_strspn (void)
704 it = "strspn";
705 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
706 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
707 check(strspn("abc", "qx") == 0, 3); /* None. */
708 check(strspn("", "ab") == 0, 4); /* Null string. */
709 check(strspn("abc", "") == 0, 5); /* Null search list. */
711 unsigned char work4[4];
712 work4[0] = 0xe2;
713 work4[1] = 0xe3;
714 work4[2] = 0xd9;
715 work4[3] = '\0';
716 /* Check for signed/unsigned mixup */
717 check(strspn((char*)work4, (char*)work4) == 3, 6);
721 static void
722 test_strcspn (void)
724 it = "strcspn";
725 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
726 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
727 check(strcspn("abc", "abc") == 0, 3); /* None. */
728 check(strcspn("", "ab") == 0, 4); /* Null string. */
729 check(strcspn("abc", "") == 3, 5); /* Null search list. */
732 static void
733 test_strtok (void)
735 it = "strtok";
736 (void) strcpy(one, "first, second, third");
737 equal(strtok(one, ", "), "first", 1); /* Basic test. */
738 equal(one, "first", 2);
739 equal(strtok((char *)NULL, ", "), "second", 3);
740 equal(strtok((char *)NULL, ", "), "third", 4);
741 check(strtok((char *)NULL, ", ") == NULL, 5);
742 (void) strcpy(one, ", first, ");
743 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
744 check(strtok((char *)NULL, ", ") == NULL, 7);
745 (void) strcpy(one, "1a, 1b; 2a, 2b");
746 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
747 equal(strtok((char *)NULL, "; "), "1b", 9);
748 equal(strtok((char *)NULL, ", "), "2a", 10);
749 (void) strcpy(two, "x-y");
750 equal(strtok(two, "-"), "x", 11); /* New string before done. */
751 equal(strtok((char *)NULL, "-"), "y", 12);
752 check(strtok((char *)NULL, "-") == NULL, 13);
753 (void) strcpy(one, "a,b, c,, ,d");
754 equal(strtok(one, ", "), "a", 14); /* Different separators. */
755 equal(strtok((char *)NULL, ", "), "b", 15);
756 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
757 equal(strtok((char *)NULL, " ,"), "d", 17);
758 check(strtok((char *)NULL, ", ") == NULL, 18);
759 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
760 (void) strcpy(one, ", ");
761 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
762 (void) strcpy(one, "");
763 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
764 (void) strcpy(one, "abc");
765 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
766 check(strtok((char *)NULL, ", ") == NULL, 23);
767 (void) strcpy(one, "abc");
768 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
769 check(strtok((char *)NULL, "") == NULL, 25);
770 (void) strcpy(one, "abcdefgh");
771 (void) strcpy(one, "a,b,c");
772 equal(strtok(one, ","), "a", 26); /* Basics again... */
773 equal(strtok((char *)NULL, ","), "b", 27);
774 equal(strtok((char *)NULL, ","), "c", 28);
775 check(strtok((char *)NULL, ",") == NULL, 29);
776 equal(one+6, "gh", 30); /* Stomped past end? */
777 equal(one, "a", 31); /* Stomped old tokens? */
778 equal(one+2, "b", 32);
779 equal(one+4, "c", 33);
782 static void
783 test_strtok_r (void)
785 it = "strtok_r";
786 (void) strcpy(one, "first, second, third");
787 cp = NULL; /* Always initialize cp to make sure it doesn't point to some old data. */
788 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
789 equal(one, "first", 2);
790 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
791 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
792 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
793 (void) strcpy(one, ", first, ");
794 cp = NULL;
795 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
796 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
797 (void) strcpy(one, "1a, 1b; 2a, 2b");
798 cp = NULL;
799 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
800 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
801 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
802 (void) strcpy(two, "x-y");
803 cp = NULL;
804 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
805 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
806 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
807 (void) strcpy(one, "a,b, c,, ,d");
808 cp = NULL;
809 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
810 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
811 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
812 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
813 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
814 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
815 (void) strcpy(one, ", ");
816 cp = NULL;
817 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
818 (void) strcpy(one, "");
819 cp = NULL;
820 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
821 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22); /* Persistence. */
822 (void) strcpy(one, "abc");
823 cp = NULL;
824 equal(strtok_r(one, ", ", &cp), "abc", 23); /* No delimiters. */
825 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
826 (void) strcpy(one, "abc");
827 cp = NULL;
828 equal(strtok_r(one, "", &cp), "abc", 25); /* Empty delimiter list. */
829 check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
830 (void) strcpy(one, "abcdefgh");
831 (void) strcpy(one, "a,b,c");
832 cp = NULL;
833 equal(strtok_r(one, ",", &cp), "a", 27); /* Basics again... */
834 equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
835 equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
836 check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
837 equal(one+6, "gh", 31); /* Stomped past end? */
838 equal(one, "a", 32); /* Stomped old tokens? */
839 equal(one+2, "b", 33);
840 equal(one+4, "c", 34);
843 static void
844 test_strsep (void)
846 char *ptr;
847 it = "strsep";
848 cp = strcpy(one, "first, second, third");
849 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
850 equal(one, "first", 2);
851 equal(strsep(&cp, ", "), "", 3);
852 equal(strsep(&cp, ", "), "second", 4);
853 equal(strsep(&cp, ", "), "", 5);
854 equal(strsep(&cp, ", "), "third", 6);
855 check(strsep(&cp, ", ") == NULL, 7);
856 cp = strcpy(one, ", first, ");
857 equal(strsep(&cp, ", "), "", 8);
858 equal(strsep(&cp, ", "), "", 9);
859 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
860 equal(strsep(&cp, ", "), "", 11);
861 equal(strsep(&cp, ", "), "", 12);
862 check(strsep(&cp, ", ") == NULL, 13);
863 cp = strcpy(one, "1a, 1b; 2a, 2b");
864 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */
865 equal(strsep(&cp, ", "), "", 15);
866 equal(strsep(&cp, "; "), "1b", 16);
867 equal(strsep(&cp, ", "), "", 17);
868 equal(strsep(&cp, ", "), "2a", 18);
869 cp = strcpy(two, "x-y");
870 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */
871 equal(strsep(&cp, "-"), "y", 20);
872 check(strsep(&cp, "-") == NULL, 21);
873 cp = strcpy(one, "a,b, c,, ,d ");
874 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */
875 equal(strsep(&cp, ", "), "b", 23);
876 equal(strsep(&cp, " ,"), "", 24);
877 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */
878 equal(strsep(&cp, " ,"), "", 26);
879 equal(strsep(&cp, " ,"), "", 27);
880 equal(strsep(&cp, " ,"), "", 28);
881 equal(strsep(&cp, " ,"), "d", 29);
882 equal(strsep(&cp, " ,"), "", 30);
883 check(strsep(&cp, ", ") == NULL, 31);
884 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
885 cp = strcpy(one, ", ");
886 equal(strsep(&cp, ", "), "", 33);
887 equal(strsep(&cp, ", "), "", 34);
888 equal(strsep(&cp, ", "), "", 35);
889 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
890 cp = strcpy(one, "");
891 equal(strsep(&cp, ", "), "", 37);
892 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
893 cp = strcpy(one, "abc");
894 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */
895 check(strsep(&cp, ", ") == NULL, 40);
896 cp = strcpy(one, "abc");
897 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */
898 check(strsep(&cp, "") == NULL, 42);
899 (void) strcpy(one, "abcdefgh");
900 cp = strcpy(one, "a,b,c");
901 equal(strsep(&cp, ","), "a", 43); /* Basics again... */
902 equal(strsep(&cp, ","), "b", 44);
903 equal(strsep(&cp, ","), "c", 45);
904 check(strsep(&cp, ",") == NULL, 46);
905 equal(one+6, "gh", 47); /* Stomped past end? */
906 equal(one, "a", 48); /* Stomped old tokens? */
907 equal(one+2, "b", 49);
908 equal(one+4, "c", 50);
911 # if !defined(__APPLE__) && !defined(__FreeBSD__)
912 char text[] = "This,is,a,test";
913 char *list = strdupa (text);
914 equal (strsep (&list, ","), "This", 51);
915 equal (strsep (&list, ","), "is", 52);
916 equal (strsep (&list, ","), "a", 53);
917 equal (strsep (&list, ","), "test", 54);
918 check (strsep (&list, ",") == NULL, 55);
919 # endif
922 cp = strcpy(one, "a,b, c,, ,d,");
923 equal(strsep(&cp, ","), "a", 56); /* Different separators. */
924 equal(strsep(&cp, ","), "b", 57);
925 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */
926 equal(strsep(&cp, ","), "", 59);
927 equal(strsep(&cp, ","), " ", 60);
928 equal(strsep(&cp, ","), "d", 61);
929 equal(strsep(&cp, ","), "", 62);
930 check(strsep(&cp, ",") == NULL, 63);
931 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */
933 cp = strcpy(one, "a,b, c,, ,d,");
934 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */
935 equal(strsep(&cp, "x,y"), "b", 66);
936 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */
937 equal(strsep(&cp, "xy,"), "", 68);
938 equal(strsep(&cp, "x,y"), " ", 69);
939 equal(strsep(&cp, ",xy"), "d", 70);
940 equal(strsep(&cp, "xy,"), "", 71);
941 check(strsep(&cp, "x,y") == NULL, 72);
942 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
944 cp = strcpy(one, "ABC");
945 one[4] = ':';
946 equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */
947 ptr = strsep(&cp, ":");
948 equal(ptr, "", 75);
949 check(ptr == one + 3, 76);
950 check(cp == NULL, 77);
952 cp = strcpy(one, "ABC");
953 one[4] = ':';
954 equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */
955 ptr = strsep(&cp, ":.");
956 equal(ptr, "", 79);
957 check(ptr == one + 3, 80);
959 cp = strcpy(one, "ABC"); /* No token in string. */
960 equal(strsep(&cp, ","), "ABC", 81);
961 check(cp == NULL, 82);
963 *one = '\0'; /* Empty string. */
964 cp = one;
965 ptr = strsep(&cp, ",");
966 equal(ptr, "", 83);
967 check(ptr == one, 84);
968 check(cp == NULL, 85);
970 *one = '\0'; /* Empty string and no token. */
971 cp = one;
972 ptr = strsep(&cp, "");
973 equal(ptr, "", 86);
974 check(ptr == one , 87);
975 check(cp == NULL, 88);
978 static void
979 test_memcmp (void)
981 it = "memcmp";
982 check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
983 check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
984 check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
985 check(memcmp("abce", "abcd", 4) > 0, 4);
986 check(memcmp("alph", "beta", 4) < 0, 5);
987 check(memcmp("a\203", "a\003", 2) > 0, 6);
988 check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
989 check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
992 static void
993 test_memchr (void)
995 it = "memchr";
996 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
997 (void) strcpy(one, "abcd");
998 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
999 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
1000 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
1001 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
1002 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
1003 (void) strcpy(one, "ababa");
1004 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
1005 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
1006 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
1007 (void) strcpy(one, "a\203b");
1008 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
1010 /* now test all possible alignment and length combinations to catch
1011 bugs due to unrolled loops (assuming unrolling is limited to no
1012 more than 128 byte chunks: */
1014 char buf[128 + sizeof(long)];
1015 long align, len, i, pos;
1017 for (align = 0; align < (long) sizeof(long); ++align) {
1018 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
1019 for (i = 0; i < len; ++i) {
1020 buf[align + i] = 'x'; /* don't depend on memset... */
1022 for (pos = 0; pos < len; ++pos) {
1023 #if 0
1024 printf("align %d, len %d, pos %d\n", align, len, pos);
1025 #endif
1026 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
1027 check(memchr(buf + align, 'x', pos) == NULL, 11);
1028 buf[align + pos] = '-';
1035 static void
1036 test_memcpy (void)
1038 int i;
1039 it = "memcpy";
1040 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
1041 equal(one, "abc", 2); /* Did the copy go right? */
1043 (void) strcpy(one, "abcdefgh");
1044 (void) memcpy(one+1, "xyz", 2);
1045 equal(one, "axydefgh", 3); /* Basic test. */
1047 (void) strcpy(one, "abc");
1048 (void) memcpy(one, "xyz", 0);
1049 equal(one, "abc", 4); /* Zero-length copy. */
1051 (void) strcpy(one, "hi there");
1052 (void) strcpy(two, "foo");
1053 (void) memcpy(two, one, 9);
1054 equal(two, "hi there", 5); /* Just paranoia. */
1055 equal(one, "hi there", 6); /* Stomped on source? */
1057 for (i = 0; i < 16; i++)
1059 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1060 strcpy (one, x);
1061 check (memcpy (one + i, "hi there", 9) == one + i,
1062 7 + (i * 6)); /* Unaligned destination. */
1063 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1064 equal (one + i, "hi there", 9 + (i * 6));
1065 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1066 check (memcpy (two, one + i, 9) == two,
1067 11 + (i * 6)); /* Unaligned source. */
1068 equal (two, "hi there", 12 + (i * 6));
1072 #if defined(HAVE_MEMPCPY)
1073 static void
1074 test_mempcpy (void)
1076 int i;
1077 it = "mempcpy";
1078 check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */
1079 equal(one, "abc", 2); /* Did the copy go right? */
1081 (void) strcpy(one, "abcdefgh");
1082 (void) mempcpy(one+1, "xyz", 2);
1083 equal(one, "axydefgh", 3); /* Basic test. */
1085 (void) strcpy(one, "abc");
1086 (void) mempcpy(one, "xyz", 0);
1087 equal(one, "abc", 4); /* Zero-length copy. */
1089 (void) strcpy(one, "hi there");
1090 (void) strcpy(two, "foo");
1091 (void) mempcpy(two, one, 9);
1092 equal(two, "hi there", 5); /* Just paranoia. */
1093 equal(one, "hi there", 6); /* Stomped on source? */
1095 for (i = 0; i < 16; i++)
1097 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1098 strcpy (one, x);
1099 check (mempcpy (one + i, "hi there", 9) == one + i + 9,
1100 7 + (i * 6)); /* Unaligned destination. */
1101 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1102 equal (one + i, "hi there", 9 + (i * 6));
1103 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1104 check (mempcpy (two, one + i, 9) == two + 9,
1105 11 + (i * 6)); /* Unaligned source. */
1106 equal (two, "hi there", 12 + (i * 6));
1109 #endif
1111 static void
1112 test_memmove (void)
1114 it = "memmove";
1115 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
1116 equal(one, "abc", 2); /* Did the copy go right? */
1118 (void) strcpy(one, "abcdefgh");
1119 (void) memmove(one+1, "xyz", 2);
1120 equal(one, "axydefgh", 3); /* Basic test. */
1122 (void) strcpy(one, "abc");
1123 (void) memmove(one, "xyz", 0);
1124 equal(one, "abc", 4); /* Zero-length copy. */
1126 (void) strcpy(one, "hi there");
1127 (void) strcpy(two, "foo");
1128 (void) memmove(two, one, 9);
1129 equal(two, "hi there", 5); /* Just paranoia. */
1130 equal(one, "hi there", 6); /* Stomped on source? */
1132 (void) strcpy(one, "abcdefgh");
1133 (void) memmove(one+1, one, 9);
1134 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
1136 (void) strcpy(one, "abcdefgh");
1137 (void) memmove(one+1, one+2, 7);
1138 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
1140 (void) strcpy(one, "abcdefgh");
1141 (void) memmove(one, one, 9);
1142 equal(one, "abcdefgh", 9); /* 100% overlap. */
1145 static void
1146 test_memccpy (void)
1148 /* First test like memcpy, then the search part The SVID, the only
1149 place where memccpy is mentioned, says overlap might fail, so we
1150 don't try it. Besides, it's hard to see the rationale for a
1151 non-left-to-right memccpy. */
1152 it = "memccpy";
1153 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
1154 equal(one, "abc", 2); /* Did the copy go right? */
1156 (void) strcpy(one, "abcdefgh");
1157 (void) memccpy(one+1, "xyz", 'q', 2);
1158 equal(one, "axydefgh", 3); /* Basic test. */
1160 (void) strcpy(one, "abc");
1161 (void) memccpy(one, "xyz", 'q', 0);
1162 equal(one, "abc", 4); /* Zero-length copy. */
1164 (void) strcpy(one, "hi there");
1165 (void) strcpy(two, "foo");
1166 (void) memccpy(two, one, 'q', 9);
1167 equal(two, "hi there", 5); /* Just paranoia. */
1168 equal(one, "hi there", 6); /* Stomped on source? */
1170 (void) strcpy(one, "abcdefgh");
1171 (void) strcpy(two, "horsefeathers");
1172 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
1173 equal(one, "abcdefgh", 8); /* Source intact? */
1174 equal(two, "abcdefeathers", 9); /* Copy correct? */
1176 (void) strcpy(one, "abcd");
1177 (void) strcpy(two, "bumblebee");
1178 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
1179 equal(two, "aumblebee", 11);
1180 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
1181 equal(two, "abcdlebee", 13);
1182 (void) strcpy(one, "xyz");
1183 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
1184 equal(two, "xbcdlebee", 15);
1187 static void
1188 test_memset (void)
1190 int i;
1192 it = "memset";
1193 (void) strcpy(one, "abcdefgh");
1194 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
1195 equal(one, "axxxefgh", 2); /* Basic test. */
1197 (void) memset(one+2, 'y', 0);
1198 equal(one, "axxxefgh", 3); /* Zero-length set. */
1200 (void) memset(one+5, 0, 1);
1201 equal(one, "axxxe", 4); /* Zero fill. */
1202 equal(one+6, "gh", 5); /* And the leftover. */
1204 (void) memset(one+2, 010045, 1);
1205 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
1207 /* Non-8bit fill character. */
1208 memset (one, 0x101, sizeof (one));
1209 for (i = 0; i < (int) sizeof (one); ++i)
1210 check (one[i] == '\01', 7);
1212 /* Test for more complex versions of memset, for all alignments and
1213 lengths up to 256. This test takes a little while, perhaps it should
1214 be made weaker? */
1216 char data[512];
1217 int j;
1218 int k;
1219 int c;
1221 for (i = 0; i < 512; i++)
1222 data[i] = 'x';
1223 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
1224 memset(,'y',) */
1225 for (j = 0; j < 256; j++)
1226 for (i = 0; i < 256; i++)
1228 memset (data + i, c, j);
1229 for (k = 0; k < i; k++)
1230 if (data[k] != 'x')
1231 goto fail;
1232 for (k = i; k < i+j; k++)
1234 if (data[k] != c)
1235 goto fail;
1236 data[k] = 'x';
1238 for (k = i+j; k < 512; k++)
1239 if (data[k] != 'x')
1240 goto fail;
1241 continue;
1243 fail:
1244 check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
1249 static void
1250 test_bcopy (void)
1252 /* Much like memcpy. Berklix manual is silent about overlap, so
1253 don't test it. */
1254 it = "bcopy";
1255 (void) bcopy("abc", one, 4);
1256 equal(one, "abc", 1); /* Simple copy. */
1258 (void) strcpy(one, "abcdefgh");
1259 (void) bcopy("xyz", one+1, 2);
1260 equal(one, "axydefgh", 2); /* Basic test. */
1262 (void) strcpy(one, "abc");
1263 (void) bcopy("xyz", one, 0);
1264 equal(one, "abc", 3); /* Zero-length copy. */
1266 (void) strcpy(one, "hi there");
1267 (void) strcpy(two, "foo");
1268 (void) bcopy(one, two, 9);
1269 equal(two, "hi there", 4); /* Just paranoia. */
1270 equal(one, "hi there", 5); /* Stomped on source? */
1273 static void
1274 test_bzero (void)
1276 it = "bzero";
1277 (void) strcpy(one, "abcdef");
1278 bzero(one+2, 2);
1279 equal(one, "ab", 1); /* Basic test. */
1280 equal(one+3, "", 2);
1281 equal(one+4, "ef", 3);
1283 (void) strcpy(one, "abcdef");
1284 bzero(one+2, 0);
1285 equal(one, "abcdef", 4); /* Zero-length copy. */
1288 #if defined(HAVE_STRNDUP)
1289 static void
1290 test_strndup (void)
1292 char *p, *q;
1293 it = "strndup";
1294 p = strndup("abcdef", 12);
1295 check(p != NULL, 1);
1296 if (p != NULL)
1298 equal(p, "abcdef", 2);
1299 q = strndup(p + 1, 2);
1300 check(q != NULL, 3);
1301 if (q != NULL)
1302 equal(q, "bc", 4);
1303 free (q);
1305 free (p);
1306 p = strndup("abc def", 3);
1307 check(p != NULL, 5);
1308 if (p != NULL)
1309 equal(p, "abc", 6);
1310 free (p);
1312 #endif
1314 static void
1315 test_bcmp (void)
1317 it = "bcmp";
1318 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1319 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1320 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1321 check(bcmp("abce", "abcd", 4) != 0, 4);
1322 check(bcmp("alph", "beta", 4) != 0, 5);
1323 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1324 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1327 static void
1328 test_strerror (void)
1330 it = "strerror";
1331 check(strerror(EDOM) != 0, 1);
1332 check(strerror(ERANGE) != 0, 2);
1333 check(strerror(ENOENT) != 0, 3);
1336 static void
1337 test_strcasecmp (void)
1339 it = "strcasecmp";
1340 /* Note that the locale is "C". */
1341 check(strcasecmp("a", "a") == 0, 1);
1342 check(strcasecmp("a", "A") == 0, 2);
1343 check(strcasecmp("A", "a") == 0, 3);
1344 check(strcasecmp("a", "b") < 0, 4);
1345 check(strcasecmp("c", "b") > 0, 5);
1346 check(strcasecmp("abc", "AbC") == 0, 6);
1347 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1348 check(strcasecmp("", "0123456789") < 0, 8);
1349 check(strcasecmp("AbC", "") > 0, 9);
1350 check(strcasecmp("AbC", "A") > 0, 10);
1351 check(strcasecmp("AbC", "Ab") > 0, 11);
1352 check(strcasecmp("AbC", "ab") > 0, 12);
1355 static void
1356 test_strncasecmp (void)
1358 it = "strncasecmp";
1359 /* Note that the locale is "C". */
1360 check(strncasecmp("a", "a", 5) == 0, 1);
1361 check(strncasecmp("a", "A", 5) == 0, 2);
1362 check(strncasecmp("A", "a", 5) == 0, 3);
1363 check(strncasecmp("a", "b", 5) < 0, 4);
1364 check(strncasecmp("c", "b", 5) > 0, 5);
1365 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1366 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1367 check(strncasecmp("", "0123456789", 10) < 0, 8);
1368 check(strncasecmp("AbC", "", 5) > 0, 9);
1369 check(strncasecmp("AbC", "A", 5) > 0, 10);
1370 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1371 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1372 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1373 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1374 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1375 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1376 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1377 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1378 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1379 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1382 static void
1383 test_strcasestr (void)
1385 it = "strcasestr";
1386 check(strcasestr("abCd", "z") == NULL, 1); /* Not found. */
1387 check(strcasestr("AbcD", "abX") == NULL, 2); /* Dead end. */
1388 (void) strcpy(one, "abCd");
1389 check(strcasestr(one, "c") == one+2, 3); /* Basic test. */
1390 check(strcasestr(one, "Bc") == one+1, 4); /* Multichar. */
1391 check(strcasestr(one, "d") == one+3, 5); /* End of string. */
1392 check(strcasestr(one, "Cd") == one+2, 6); /* Tail of string. */
1393 check(strcasestr(one, "aBc") == one, 7); /* Beginning. */
1394 check(strcasestr(one, "aBcd") == one, 8); /* Exact match. */
1395 check(strcasestr(one, "AbcDe") == NULL, 9); /* Too long. */
1396 check(strcasestr(one, "dE") == NULL, 10); /* Past end. */
1397 check(strcasestr(one, "") == one, 11); /* Finding empty. */
1398 (void) strcpy(one, "abAba");
1399 check(strcasestr(one, "Ba") == one+1, 12); /* Finding first. */
1400 (void) strcpy(one, "");
1401 check(strcasestr(one, "b") == NULL, 13); /* Empty string. */
1402 check(strcasestr(one, "") == one, 14); /* Empty in empty string. */
1403 (void) strcpy(one, "BcbCa");
1404 check(strcasestr(one, "bCa") == one+2, 15); /* False start. */
1405 (void) strcpy(one, "bbBcaBbcA");
1406 check(strcasestr(one, "bbCa") == one+1, 16); /* With overlap. */
1410 main (void)
1412 int status;
1414 /* Test strcmp first because we use it to test other things. */
1415 test_strcmp ();
1417 /* Test strcpy next because we need it to set up other tests. */
1418 test_strcpy ();
1420 /* A closely related function is stpcpy. */
1421 test_stpcpy ();
1423 #if defined(HAVE_STPNCPY)
1424 /* stpncpy. */
1425 test_stpncpy ();
1426 #endif
1428 /* strcat. */
1429 test_strcat ();
1431 /* strncat. */
1432 test_strncat ();
1434 /* strncmp. */
1435 test_strncmp ();
1437 /* strncpy. */
1438 test_strncpy ();
1440 /* strlen. */
1441 test_strlen ();
1443 /* strchr. */
1444 test_strchr ();
1446 # if defined(HAVE_STRCHRNUL)
1447 /* strchrnul. */
1448 test_strchrnul ();
1449 # endif
1451 # ifdef HAVE_RAWMEMCHR
1452 /* rawmemchr. */
1453 test_rawmemchr ();
1454 # endif
1456 /* index - just like strchr. */
1457 test_index ();
1459 /* strrchr. */
1460 test_strrchr ();
1462 # if defined(HAVE_MEMRCHR)
1463 /* memrchr. */
1464 test_memrchr ();
1465 # endif
1467 /* rindex - just like strrchr. */
1468 test_rindex ();
1470 /* strpbrk - somewhat like strchr. */
1471 test_strpbrk ();
1473 /* strstr - somewhat like strchr. */
1474 test_strstr ();
1476 /* strspn. */
1477 test_strspn ();
1479 /* strcspn. */
1480 test_strcspn ();
1482 /* strtok - the hard one. */
1483 test_strtok ();
1485 /* strtok_r. */
1486 test_strtok_r ();
1488 /* strsep. */
1489 test_strsep ();
1491 /* memcmp. */
1492 test_memcmp ();
1494 /* memchr. */
1495 test_memchr ();
1497 /* memcpy - need not work for overlap. */
1498 test_memcpy ();
1500 /* memmove - must work on overlap. */
1501 test_memmove ();
1503 # if defined(HAVE_MEMPCPY)
1504 /* mempcpy */
1505 test_mempcpy ();
1506 # endif
1508 /* memccpy. */
1509 test_memccpy ();
1511 /* memset. */
1512 test_memset ();
1514 /* bcopy. */
1515 test_bcopy ();
1517 /* bzero. */
1518 test_bzero ();
1520 /* bcmp - somewhat like memcmp. */
1521 test_bcmp ();
1523 #if defined(HAVE_STRNDUP)
1524 /* strndup. */
1525 test_strndup ();
1526 #endif
1528 /* strerror - VERY system-dependent. */
1529 test_strerror ();
1531 /* strcasecmp. Without locale dependencies. */
1532 test_strcasecmp ();
1534 /* strncasecmp. Without locale dependencies. */
1535 test_strncasecmp ();
1537 test_strcasestr ();
1539 if (errors == 0)
1541 status = EXIT_SUCCESS;
1542 //puts("No errors.");
1544 else
1546 status = EXIT_FAILURE;
1547 printf("%d errors.\n", (int)errors);
1550 return status;