1 /* Tester for string functions.
2 Copyright (C) 1995-2024 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, see
17 <https://www.gnu.org/licenses/>. */
23 /* Make sure we don't test the optimized inline functions if we want to
24 test the real implementation. */
25 #if !defined DO_STRING_INLINES
26 #undef __USE_STRING_INLINES
29 #include <sys/cdefs.h>
30 #include <libc-diag.h>
32 /* Triggered by strncpy fortify wrapper when it is enabled. */
33 #if __GNUC_PREREQ (8, 0)
34 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
37 /* When building with fortify enabled, GCC < 12 issues a warning on the
38 fortify strncat wrapper might overflow the destination buffer (the
39 failure is tied to -Werror).
40 Triggered by strncat fortify wrapper when it is enabled. */
41 #if __GNUC_PREREQ (11, 0)
42 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
53 /* This file tests a range of corner cases of string functions,
54 including cases where truncation occurs or where sizes specified
55 are larger than the actual buffers, which result in various
57 DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
58 DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args");
59 #if __GNUC_PREREQ (7, 0)
60 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wrestrict");
61 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
65 #define STREQ(a, b) (strcmp((a), (b)) == 0)
67 const char *it
= "<UNSET>"; /* Routine name for message routines. */
70 /* Complain if condition is not true. */
72 check (int thing
, int number
)
76 printf ("%s flunked test %d\n", it
, number
);
81 /* Complain if first two args don't strcmp as equal. */
83 equal (const char *a
, const char *b
, int number
)
85 check (a
!= NULL
&& b
!= NULL
&& STREQ (a
, b
), number
);
96 check (strcmp ("", "") == 0, 1); /* Trivial case. */
97 check (strcmp ("a", "a") == 0, 2); /* Identity. */
98 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
99 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
100 check (strcmp ("abcd", "abc") > 0, 5);
101 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
102 check (strcmp ("abce", "abcd") > 0, 7);
103 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
104 check (strcmp ("a\203", "a\003") > 0, 9);
107 char buf1
[0x40], buf2
[0x40];
109 for (i
=0; i
< 0x10; i
++)
110 for (j
= 0; j
< 0x10; j
++)
113 for (k
= 0; k
< 0x3f; k
++)
115 buf1
[k
] = '0' ^ (k
& 4);
116 buf2
[k
] = '4' ^ (k
& 4);
118 buf1
[i
] = buf1
[0x3f] = 0;
119 buf2
[j
] = buf2
[0x3f] = 0;
120 for (k
= 0; k
< 0xf; k
++)
122 int cnum
= 0x10+0x10*k
+0x100*j
+0x1000*i
;
123 check (strcmp (buf1
+i
,buf2
+j
) == 0, cnum
);
124 buf1
[i
+k
] = 'A' + i
+ k
;
126 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+1);
127 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+2);
128 buf2
[j
+k
] = 'B' + i
+ k
;
130 check (strcmp (buf1
+i
,buf2
+j
) < 0, cnum
+3);
131 check (strcmp (buf2
+j
,buf1
+i
) > 0, cnum
+4);
132 buf2
[j
+k
] = 'A' + i
+ k
;
133 buf1
[i
] = 'A' + i
+ 0x80;
134 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+5);
135 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+6);
142 #define SIMPLE_COPY(fn, n, str, ntest) \
146 for (__n = 0; __n < (int) sizeof (one); ++__n) \
149 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
150 check (*cp == '0' + (n % 10), ntest); \
151 check (*cp == '\0', ntest); \
159 check (strcpy (one
, "abcd") == one
, 1); /* Returned value. */
160 equal (one
, "abcd", 2); /* Basic test. */
162 (void) strcpy (one
, "x");
163 equal (one
, "x", 3); /* Writeover. */
164 equal (one
+2, "cd", 4); /* Wrote too much? */
166 (void) strcpy (two
, "hi there");
167 (void) strcpy (one
, two
);
168 equal (one
, "hi there", 5); /* Basic test encore. */
169 equal (two
, "hi there", 6); /* Stomped on source? */
171 (void) strcpy (one
, "");
172 equal (one
, "", 7); /* Boundary condition. */
174 for (i
= 0; i
< 16; i
++)
176 (void) strcpy (one
+ i
, "hi there"); /* Unaligned destination. */
177 equal (one
+ i
, "hi there", 8 + (i
* 2));
178 (void) strcpy (two
, one
+ i
); /* Unaligned source. */
179 equal (two
, "hi there", 9 + (i
* 2));
182 SIMPLE_COPY(strcpy
, 0, "", 41);
183 SIMPLE_COPY(strcpy
, 1, "1", 42);
184 SIMPLE_COPY(strcpy
, 2, "22", 43);
185 SIMPLE_COPY(strcpy
, 3, "333", 44);
186 SIMPLE_COPY(strcpy
, 4, "4444", 45);
187 SIMPLE_COPY(strcpy
, 5, "55555", 46);
188 SIMPLE_COPY(strcpy
, 6, "666666", 47);
189 SIMPLE_COPY(strcpy
, 7, "7777777", 48);
190 SIMPLE_COPY(strcpy
, 8, "88888888", 49);
191 SIMPLE_COPY(strcpy
, 9, "999999999", 50);
192 SIMPLE_COPY(strcpy
, 10, "0000000000", 51);
193 SIMPLE_COPY(strcpy
, 11, "11111111111", 52);
194 SIMPLE_COPY(strcpy
, 12, "222222222222", 53);
195 SIMPLE_COPY(strcpy
, 13, "3333333333333", 54);
196 SIMPLE_COPY(strcpy
, 14, "44444444444444", 55);
197 SIMPLE_COPY(strcpy
, 15, "555555555555555", 56);
198 SIMPLE_COPY(strcpy
, 16, "6666666666666666", 57);
200 /* Simple test using implicitly coerced `void *' arguments. */
201 const void *src
= "frobozz";
203 check (strcpy (dst
, src
) == dst
, 1);
204 equal (dst
, "frobozz", 2);
211 check ((stpcpy (one
, "a") - one
) == 1, 1);
214 check ((stpcpy (one
, "ab") - one
) == 2, 3);
215 equal (one
, "ab", 4);
217 check ((stpcpy (one
, "abc") - one
) == 3, 5);
218 equal (one
, "abc", 6);
220 check ((stpcpy (one
, "abcd") - one
) == 4, 7);
221 equal (one
, "abcd", 8);
223 check ((stpcpy (one
, "abcde") - one
) == 5, 9);
224 equal (one
, "abcde", 10);
226 check ((stpcpy (one
, "abcdef") - one
) == 6, 11);
227 equal (one
, "abcdef", 12);
229 check ((stpcpy (one
, "abcdefg") - one
) == 7, 13);
230 equal (one
, "abcdefg", 14);
232 check ((stpcpy (one
, "abcdefgh") - one
) == 8, 15);
233 equal (one
, "abcdefgh", 16);
235 check ((stpcpy (one
, "abcdefghi") - one
) == 9, 17);
236 equal (one
, "abcdefghi", 18);
238 check ((stpcpy (one
, "x") - one
) == 1, 19);
239 equal (one
, "x", 20); /* Writeover. */
240 equal (one
+2, "cdefghi", 21); /* Wrote too much? */
242 check ((stpcpy (one
, "xx") - one
) == 2, 22);
243 equal (one
, "xx", 23); /* Writeover. */
244 equal (one
+3, "defghi", 24); /* Wrote too much? */
246 check ((stpcpy (one
, "xxx") - one
) == 3, 25);
247 equal (one
, "xxx", 26); /* Writeover. */
248 equal (one
+4, "efghi", 27); /* Wrote too much? */
250 check ((stpcpy (one
, "xxxx") - one
) == 4, 28);
251 equal (one
, "xxxx", 29); /* Writeover. */
252 equal (one
+5, "fghi", 30); /* Wrote too much? */
254 check ((stpcpy (one
, "xxxxx") - one
) == 5, 31);
255 equal (one
, "xxxxx", 32); /* Writeover. */
256 equal (one
+6, "ghi", 33); /* Wrote too much? */
258 check ((stpcpy (one
, "xxxxxx") - one
) == 6, 34);
259 equal (one
, "xxxxxx", 35); /* Writeover. */
260 equal (one
+7, "hi", 36); /* Wrote too much? */
262 check ((stpcpy (one
, "xxxxxxx") - one
) == 7, 37);
263 equal (one
, "xxxxxxx", 38); /* Writeover. */
264 equal (one
+8, "i", 39); /* Wrote too much? */
266 check ((stpcpy (stpcpy (stpcpy (one
, "a"), "b"), "c") - one
) == 3, 40);
267 equal (one
, "abc", 41);
268 equal (one
+ 4, "xxx", 42);
270 SIMPLE_COPY(stpcpy
, 0, "", 43);
271 SIMPLE_COPY(stpcpy
, 1, "1", 44);
272 SIMPLE_COPY(stpcpy
, 2, "22", 45);
273 SIMPLE_COPY(stpcpy
, 3, "333", 46);
274 SIMPLE_COPY(stpcpy
, 4, "4444", 47);
275 SIMPLE_COPY(stpcpy
, 5, "55555", 48);
276 SIMPLE_COPY(stpcpy
, 6, "666666", 49);
277 SIMPLE_COPY(stpcpy
, 7, "7777777", 50);
278 SIMPLE_COPY(stpcpy
, 8, "88888888", 51);
279 SIMPLE_COPY(stpcpy
, 9, "999999999", 52);
280 SIMPLE_COPY(stpcpy
, 10, "0000000000", 53);
281 SIMPLE_COPY(stpcpy
, 11, "11111111111", 54);
282 SIMPLE_COPY(stpcpy
, 12, "222222222222", 55);
283 SIMPLE_COPY(stpcpy
, 13, "3333333333333", 56);
284 SIMPLE_COPY(stpcpy
, 14, "44444444444444", 57);
285 SIMPLE_COPY(stpcpy
, 15, "555555555555555", 58);
286 SIMPLE_COPY(stpcpy
, 16, "6666666666666666", 59);
293 memset (one
, 'x', sizeof (one
));
294 check (stpncpy (one
, "abc", 2) == one
+ 2, 1);
295 check (stpncpy (one
, "abc", 3) == one
+ 3, 2);
296 check (stpncpy (one
, "abc", 4) == one
+ 3, 3);
297 check (one
[3] == '\0' && one
[4] == 'x', 4);
298 check (stpncpy (one
, "abcd", 5) == one
+ 4, 5);
299 check (one
[4] == '\0' && one
[5] == 'x', 6);
300 check (stpncpy (one
, "abcd", 6) == one
+ 4, 7);
301 check (one
[4] == '\0' && one
[5] == '\0' && one
[6] == 'x', 8);
308 (void) strcpy (one
, "ijk");
309 check (strcat (one
, "lmn") == one
, 1); /* Returned value. */
310 equal (one
, "ijklmn", 2); /* Basic test. */
312 (void) strcpy (one
, "x");
313 (void) strcat (one
, "yz");
314 equal (one
, "xyz", 3); /* Writeover. */
315 equal (one
+4, "mn", 4); /* Wrote too much? */
317 (void) strcpy (one
, "gh");
318 (void) strcpy (two
, "ef");
319 (void) strcat (one
, two
);
320 equal (one
, "ghef", 5); /* Basic test encore. */
321 equal (two
, "ef", 6); /* Stomped on source? */
323 (void) strcpy (one
, "");
324 (void) strcat (one
, "");
325 equal (one
, "", 7); /* Boundary conditions. */
326 (void) strcpy (one
, "ab");
327 (void) strcat (one
, "");
328 equal (one
, "ab", 8);
329 (void) strcpy (one
, "");
330 (void) strcat (one
, "cd");
331 equal (one
, "cd", 9);
334 char buf1
[80] __attribute__ ((aligned (16)));
335 char buf2
[32] __attribute__ ((aligned (16)));
336 for (size_t n1
= 0; n1
< 16; ++n1
)
337 for (size_t n2
= 0; n2
< 16; ++n2
)
338 for (size_t n3
= 0; n3
< 32; ++n3
)
340 size_t olderrors
= errors
;
342 memset (buf1
, 'b', sizeof (buf1
));
344 memset (buf1
+ n2
, 'a', n3
);
345 buf1
[n2
+ n3
] = '\0';
346 strcpy (buf2
+ n1
, "123");
348 check (strcat (buf1
+ n2
, buf2
+ n1
) == buf1
+ n2
, ntest
);
349 if (errors
== olderrors
)
350 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
353 check (buf1
[i
] == 'b', ntest
);
354 else if (i
< n2
+ n3
)
355 check (buf1
[i
] == 'a', ntest
);
356 else if (i
< n2
+ n3
+ 3)
357 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
358 else if (i
== n2
+ n3
+ 3)
359 check (buf1
[i
] == '\0', ntest
);
361 check (buf1
[i
] == 'b', ntest
);
363 if (errors
!= olderrors
)
365 printf ("n1=%zu, n2=%zu, n3=%zu, buf1=%02hhx",
366 n1
, n2
, n3
, buf1
[0]);
367 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
368 printf (",%02hhx", buf1
[j
]);
369 putchar_unlocked ('\n');
379 /* First test it as strcat, with big counts, then test the count
382 (void) strcpy (one
, "ijk");
383 check (strncat (one
, "lmn", 99) == one
, 1); /* Returned value. */
384 equal (one
, "ijklmn", 2); /* Basic test. */
386 (void) strcpy (one
, "x");
387 (void) strncat (one
, "yz", 99);
388 equal (one
, "xyz", 3); /* Writeover. */
389 equal (one
+4, "mn", 4); /* Wrote too much? */
391 (void) strcpy (one
, "gh");
392 (void) strcpy (two
, "ef");
393 /* When building with fortify enabled, GCC 6 issues an warning the fortify
394 wrapper might overflow the destination buffer. However, GCC does not
395 provide a specific flag to disable the warning (the failure is tied to
396 -Werror). So to avoid disable all errors, only enable the check for
398 #if __GNUC_PREREQ (7, 0)
399 (void) strncat (one
, two
, 99);
400 equal (one
, "ghef", 5); /* Basic test encore. */
402 equal (one
, "gh", 2);
404 equal (two
, "ef", 6); /* Stomped on source? */
406 (void) strcpy (one
, "");
407 (void) strncat (one
, "", 99);
408 equal (one
, "", 7); /* Boundary conditions. */
409 (void) strcpy (one
, "ab");
410 (void) strncat (one
, "", 99);
411 equal (one
, "ab", 8);
412 (void) strcpy (one
, "");
413 (void) strncat (one
, "cd", 99);
414 equal (one
, "cd", 9);
416 (void) strcpy (one
, "ab");
417 (void) strncat (one
, "cdef", 2);
418 equal (one
, "abcd", 10); /* Count-limited. */
420 (void) strncat (one
, "gh", 0);
421 equal (one
, "abcd", 11); /* Zero count. */
423 (void) strncat (one
, "gh", 2);
424 equal (one
, "abcdgh", 12); /* Count and length equal. */
426 (void) strncat (one
, "ij", (size_t)-1); /* set sign bit in count */
427 equal (one
, "abcdghij", 13);
430 char buf1
[80] __attribute__ ((aligned (16)));
431 char buf2
[32] __attribute__ ((aligned (16)));
432 for (size_t n1
= 0; n1
< 16; ++n1
)
433 for (size_t n2
= 0; n2
< 16; ++n2
)
434 for (size_t n3
= 0; n3
< 32; ++n3
)
435 for (size_t n4
= 0; n4
< 16; ++n4
)
437 size_t olderrors
= errors
;
439 memset (buf1
, 'b', sizeof (buf1
));
441 memset (buf1
+ n2
, 'a', n3
);
442 buf1
[n2
+ n3
] = '\0';
443 strcpy (buf2
+ n1
, "123");
445 check (strncat (buf1
+ n2
, buf2
+ n1
, ~((size_t) 0) - n4
)
446 == buf1
+ n2
, ntest
);
447 if (errors
== olderrors
)
448 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
451 check (buf1
[i
] == 'b', ntest
);
452 else if (i
< n2
+ n3
)
453 check (buf1
[i
] == 'a', ntest
);
454 else if (i
< n2
+ n3
+ 3)
455 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
456 else if (i
== n2
+ n3
+ 3)
457 check (buf1
[i
] == '\0', ntest
);
459 check (buf1
[i
] == 'b', ntest
);
461 if (errors
!= olderrors
)
463 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
464 n1
, n2
, n3
, n4
, buf1
[0]);
465 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
466 printf (",%02hhx", buf1
[j
]);
467 putchar_unlocked ('\n');
477 /* First test as strcmp with big counts, then test count code. */
479 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
480 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
481 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
482 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
483 check (strncmp ("abcd", "abc", 99) > 0, 5);
484 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
485 check (strncmp ("abce", "abcd", 99) > 0, 7);
486 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
487 check (strncmp ("a\203", "a\003", 2) > 0, 9);
488 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
489 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
490 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
491 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
492 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
493 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
499 /* Testing is a bit different because of odd semantics. */
501 check (strncpy (one
, "abc", 4) == one
, 1); /* Returned value. */
502 equal (one
, "abc", 2); /* Did the copy go right? */
504 (void) strcpy (one
, "abcdefgh");
505 (void) strncpy (one
, "xyz", 2);
506 equal (one
, "xycdefgh", 3); /* Copy cut by count. */
508 (void) strcpy (one
, "abcdefgh");
509 (void) strncpy (one
, "xyz", 3); /* Copy cut just before NUL. */
510 equal (one
, "xyzdefgh", 4);
512 (void) strcpy (one
, "abcdefgh");
513 (void) strncpy (one
, "xyz", 4); /* Copy just includes NUL. */
514 equal (one
, "xyz", 5);
515 equal (one
+4, "efgh", 6); /* Wrote too much? */
517 (void) strcpy (one
, "abcdefgh");
518 (void) strncpy (one
, "xyz", 5); /* Copy includes padding. */
519 equal (one
, "xyz", 7);
520 equal (one
+4, "", 8);
521 equal (one
+5, "fgh", 9);
523 (void) strcpy (one
, "abc");
524 (void) strncpy (one
, "xyz", 0); /* Zero-length copy. */
525 equal (one
, "abc", 10);
527 (void) strncpy (one
, "", 2); /* Zero-length source. */
529 equal (one
+1, "", 12);
530 equal (one
+2, "c", 13);
532 (void) strcpy (one
, "hi there");
533 (void) strncpy (two
, one
, 9);
534 equal (two
, "hi there", 14); /* Just paranoia. */
535 equal (one
, "hi there", 15); /* Stomped on source? */
542 check (strlen ("") == 0, 1); /* Empty. */
543 check (strlen ("a") == 1, 2); /* Single char. */
544 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
549 for (i
=0; i
< 0x100; i
++)
551 p
= (char *) ((uintptr_t)(buf
+ 0xff) & ~0xff) + i
;
553 strcpy (p
+3, "BAD/WRONG");
554 check (strlen (p
) == 2, 4+i
);
563 check (strnlen ("", 10) == 0, 1); /* Empty. */
564 check (strnlen ("a", 10) == 1, 2); /* Single char. */
565 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
566 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
567 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
568 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
569 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
570 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
571 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
574 for (int i
= 0; i
< 0x100; ++i
)
576 char *p
= (char *) ((uintptr_t)(buf
+ 0xff) & ~0xff) + i
;
578 strcpy (p
+ 3, "BAD/WRONG");
579 check (strnlen (p
, 100) == 2, 10 + i
);
587 check (strchr ("abcd", 'z') == NULL
, 1); /* Not found. */
588 (void) strcpy (one
, "abcd");
589 check (strchr (one
, 'c') == one
+2, 2); /* Basic test. */
590 check (strchr (one
, 'd') == one
+3, 3); /* End of string. */
591 check (strchr (one
, 'a') == one
, 4); /* Beginning. */
592 check (strchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
593 (void) strcpy (one
, "ababa");
594 check (strchr (one
, 'b') == one
+1, 6); /* Finding first. */
595 (void) strcpy (one
, "");
596 check (strchr (one
, 'b') == NULL
, 7); /* Empty string. */
597 check (strchr (one
, '\0') == one
, 8); /* NUL in empty string. */
602 for (i
=0; i
< 0x100; i
++)
604 p
= (char *) ((uintptr_t) (buf
+ 0xff) & ~0xff) + i
;
606 strcpy (p
+3, "BAD/WRONG");
607 check (strchr (p
, '/') == NULL
, 9+i
);
613 test_strchrnul (void)
617 cp
= strchrnul ((os
= "abcd"), 'z');
618 check (*cp
== '\0', 1); /* Not found. */
619 check (cp
== os
+ 4, 2);
620 (void) strcpy (one
, "abcd");
621 check (strchrnul (one
, 'c') == one
+2, 3); /* Basic test. */
622 check (strchrnul (one
, 'd') == one
+3, 4); /* End of string. */
623 check (strchrnul (one
, 'a') == one
, 5); /* Beginning. */
624 check (strchrnul (one
, '\0') == one
+4, 6); /* Finding NUL. */
625 (void) strcpy (one
, "ababa");
626 check (strchrnul (one
, 'b') == one
+1, 7); /* Finding first. */
627 (void) strcpy (one
, "");
628 check (strchrnul (one
, 'b') == one
, 8); /* Empty string. */
629 check (strchrnul (one
, '\0') == one
, 9); /* NUL in empty string. */
634 for (i
=0; i
< 0x100; i
++)
636 p
= (char *) ((uintptr_t) (buf
+ 0xff) & ~0xff) + i
;
638 strcpy (p
+3, "BAD/WRONG");
639 cp
= strchrnul (p
, '/');
640 check (*cp
== '\0', 9+2*i
);
641 check (cp
== p
+2, 10+2*i
);
647 test_rawmemchr (void)
650 (void) strcpy (one
, "abcd");
651 check (rawmemchr (one
, 'c') == one
+2, 1); /* Basic test. */
652 check (rawmemchr (one
, 'd') == one
+3, 2); /* End of string. */
653 check (rawmemchr (one
, 'a') == one
, 3); /* Beginning. */
654 check (rawmemchr (one
, '\0') == one
+4, 4); /* Finding NUL. */
655 (void) strcpy (one
, "ababa");
656 check (rawmemchr (one
, 'b') == one
+1, 5); /* Finding first. */
657 (void) strcpy (one
, "");
658 check (rawmemchr (one
, '\0') == one
, 6); /* NUL in empty string. */
663 for (i
=0; i
< 0x100; i
++)
665 p
= (char *) ((uintptr_t) (buf
+ 0xff) & ~0xff) + i
;
667 strcpy (p
+3, "BAD/WRONG");
668 check (rawmemchr (p
, 'R') == p
+8, 6+i
);
677 check (index ("abcd", 'z') == NULL
, 1); /* Not found. */
678 (void) strcpy (one
, "abcd");
679 check (index (one
, 'c') == one
+2, 2); /* Basic test. */
680 check (index (one
, 'd') == one
+3, 3); /* End of string. */
681 check (index (one
, 'a') == one
, 4); /* Beginning. */
682 check (index (one
, '\0') == one
+4, 5); /* Finding NUL. */
683 (void) strcpy (one
, "ababa");
684 check (index (one
, 'b') == one
+1, 6); /* Finding first. */
685 (void) strcpy (one
, "");
686 check (index (one
, 'b') == NULL
, 7); /* Empty string. */
687 check (index (one
, '\0') == one
, 8); /* NUL in empty string. */
694 check (strrchr ("abcd", 'z') == NULL
, 1); /* Not found. */
695 (void) strcpy (one
, "abcd");
696 check (strrchr (one
, 'c') == one
+2, 2); /* Basic test. */
697 check (strrchr (one
, 'd') == one
+3, 3); /* End of string. */
698 check (strrchr (one
, 'a') == one
, 4); /* Beginning. */
699 check (strrchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
700 (void) strcpy (one
, "ababa");
701 check (strrchr (one
, 'b') == one
+3, 6); /* Finding last. */
702 (void) strcpy (one
, "");
703 check (strrchr (one
, 'b') == NULL
, 7); /* Empty string. */
704 check (strrchr (one
, '\0') == one
, 8); /* NUL in empty string. */
709 for (i
=0; i
< 0x100; i
++)
711 p
= (char *) ((uintptr_t) (buf
+ 0xff) & ~0xff) + i
;
713 strcpy (p
+3, "BAD/WRONG");
714 check (strrchr (p
, '/') == NULL
, 9+i
);
724 check (memrchr ("abcd", 'z', 5) == NULL
, 1); /* Not found. */
725 (void) strcpy (one
, "abcd");
726 l
= strlen (one
) + 1;
727 check (memrchr (one
, 'c', l
) == one
+2, 2); /* Basic test. */
728 check (memrchr (one
, 'd', l
) == one
+3, 3); /* End of string. */
729 check (memrchr (one
, 'a', l
) == one
, 4); /* Beginning. */
730 check (memrchr (one
, '\0', l
) == one
+4, 5); /* Finding NUL. */
731 (void) strcpy (one
, "ababa");
732 l
= strlen (one
) + 1;
733 check (memrchr (one
, 'b', l
) == one
+3, 6); /* Finding last. */
734 (void) strcpy (one
, "");
735 l
= strlen (one
) + 1;
736 check (memrchr (one
, 'b', l
) == NULL
, 7); /* Empty string. */
737 check (memrchr (one
, '\0', l
) == one
, 8); /* NUL in empty string. */
739 /* now test all possible alignment and length combinations to catch
740 bugs due to unrolled loops (assuming unrolling is limited to no
741 more than 128 byte chunks: */
743 char buf
[128 + sizeof (long)];
744 long align
, len
, i
, pos
, n
= 9;
746 for (align
= 0; align
< (long) sizeof (long); ++align
) {
747 for (len
= 0; len
< (long) (sizeof (buf
) - align
); ++len
) {
748 for (i
= 0; i
< len
; ++i
)
749 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
751 for (pos
= len
- 1; pos
>= 0; --pos
) {
753 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
755 check(memrchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, n
++);
756 check(memrchr(buf
+ align
+ pos
+ 1, 'x', len
- (pos
+ 1)) == NULL
,
758 buf
[align
+ pos
] = '-';
769 check (rindex ("abcd", 'z') == NULL
, 1); /* Not found. */
770 (void) strcpy (one
, "abcd");
771 check (rindex (one
, 'c') == one
+2, 2); /* Basic test. */
772 check (rindex (one
, 'd') == one
+3, 3); /* End of string. */
773 check (rindex (one
, 'a') == one
, 4); /* Beginning. */
774 check (rindex (one
, '\0') == one
+4, 5); /* Finding NUL. */
775 (void) strcpy (one
, "ababa");
776 check (rindex (one
, 'b') == one
+3, 6); /* Finding last. */
777 (void) strcpy (one
, "");
778 check (rindex (one
, 'b') == NULL
, 7); /* Empty string. */
779 check (rindex (one
, '\0') == one
, 8); /* NUL in empty string. */
786 check(strpbrk("abcd", "z") == NULL
, 1); /* Not found. */
787 (void) strcpy(one
, "abcd");
788 check(strpbrk(one
, "c") == one
+2, 2); /* Basic test. */
789 check(strpbrk(one
, "d") == one
+3, 3); /* End of string. */
790 check(strpbrk(one
, "a") == one
, 4); /* Beginning. */
791 check(strpbrk(one
, "") == NULL
, 5); /* Empty search list. */
792 check(strpbrk(one
, "cb") == one
+1, 6); /* Multiple search. */
793 (void) strcpy(one
, "abcabdea");
794 check(strpbrk(one
, "b") == one
+1, 7); /* Finding first. */
795 check(strpbrk(one
, "cb") == one
+1, 8); /* With multiple search. */
796 check(strpbrk(one
, "db") == one
+1, 9); /* Another variant. */
797 (void) strcpy(one
, "");
798 check(strpbrk(one
, "bc") == NULL
, 10); /* Empty string. */
799 (void) strcpy(one
, "");
800 check(strpbrk(one
, "bcd") == NULL
, 11); /* Empty string. */
801 (void) strcpy(one
, "");
802 check(strpbrk(one
, "bcde") == NULL
, 12); /* Empty string. */
803 check(strpbrk(one
, "") == NULL
, 13); /* Both strings empty. */
804 (void) strcpy(one
, "abcabdea");
805 check(strpbrk(one
, "befg") == one
+1, 14); /* Finding first. */
806 check(strpbrk(one
, "cbr") == one
+1, 15); /* With multiple search. */
807 check(strpbrk(one
, "db") == one
+1, 16); /* Another variant. */
808 check(strpbrk(one
, "efgh") == one
+6, 17); /* And yet another. */
815 check(strstr("abcd", "z") == NULL
, 1); /* Not found. */
816 check(strstr("abcd", "abx") == NULL
, 2); /* Dead end. */
817 (void) strcpy(one
, "abcd");
818 check(strstr(one
, "c") == one
+2, 3); /* Basic test. */
819 check(strstr(one
, "bc") == one
+1, 4); /* Multichar. */
820 check(strstr(one
, "d") == one
+3, 5); /* End of string. */
821 check(strstr(one
, "cd") == one
+2, 6); /* Tail of string. */
822 check(strstr(one
, "abc") == one
, 7); /* Beginning. */
823 check(strstr(one
, "abcd") == one
, 8); /* Exact match. */
824 check(strstr(one
, "abcde") == NULL
, 9); /* Too long. */
825 check(strstr(one
, "de") == NULL
, 10); /* Past end. */
826 check(strstr(one
, "") == one
, 11); /* Finding empty. */
827 (void) strcpy(one
, "ababa");
828 check(strstr(one
, "ba") == one
+1, 12); /* Finding first. */
829 (void) strcpy(one
, "");
830 check(strstr(one
, "b") == NULL
, 13); /* Empty string. */
831 check(strstr(one
, "") == one
, 14); /* Empty in empty string. */
832 (void) strcpy(one
, "bcbca");
833 check(strstr(one
, "bca") == one
+2, 15); /* False start. */
834 (void) strcpy(one
, "bbbcabbca");
835 check(strstr(one
, "bbca") == one
+1, 16); /* With overlap. */
842 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
843 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
844 check(strspn("abc", "qx") == 0, 3); /* None. */
845 check(strspn("", "ab") == 0, 4); /* Null string. */
846 check(strspn("abc", "") == 0, 5); /* Null search list. */
853 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
854 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
855 check(strcspn("abc", "abc") == 0, 3); /* None. */
856 check(strcspn("", "ab") == 0, 4); /* Null string. */
857 check(strcspn("abc", "") == 3, 5); /* Null search list. */
864 (void) strcpy(one
, "first, second, third");
865 equal(strtok(one
, ", "), "first", 1); /* Basic test. */
866 equal(one
, "first", 2);
867 equal(strtok((char *)NULL
, ", "), "second", 3);
868 equal(strtok((char *)NULL
, ", "), "third", 4);
869 check(strtok((char *)NULL
, ", ") == NULL
, 5);
870 (void) strcpy(one
, ", first, ");
871 equal(strtok(one
, ", "), "first", 6); /* Extra delims, 1 tok. */
872 check(strtok((char *)NULL
, ", ") == NULL
, 7);
873 (void) strcpy(one
, "1a, 1b; 2a, 2b");
874 equal(strtok(one
, ", "), "1a", 8); /* Changing delim lists. */
875 equal(strtok((char *)NULL
, "; "), "1b", 9);
876 equal(strtok((char *)NULL
, ", "), "2a", 10);
877 (void) strcpy(two
, "x-y");
878 equal(strtok(two
, "-"), "x", 11); /* New string before done. */
879 equal(strtok((char *)NULL
, "-"), "y", 12);
880 check(strtok((char *)NULL
, "-") == NULL
, 13);
881 (void) strcpy(one
, "a,b, c,, ,d");
882 equal(strtok(one
, ", "), "a", 14); /* Different separators. */
883 equal(strtok((char *)NULL
, ", "), "b", 15);
884 equal(strtok((char *)NULL
, " ,"), "c", 16); /* Permute list too. */
885 equal(strtok((char *)NULL
, " ,"), "d", 17);
886 check(strtok((char *)NULL
, ", ") == NULL
, 18);
887 check(strtok((char *)NULL
, ", ") == NULL
, 19); /* Persistence. */
888 (void) strcpy(one
, ", ");
889 check(strtok(one
, ", ") == NULL
, 20); /* No tokens. */
890 (void) strcpy(one
, "");
891 check(strtok(one
, ", ") == NULL
, 21); /* Empty string. */
892 (void) strcpy(one
, "abc");
893 equal(strtok(one
, ", "), "abc", 22); /* No delimiters. */
894 check(strtok((char *)NULL
, ", ") == NULL
, 23);
895 (void) strcpy(one
, "abc");
896 equal(strtok(one
, ""), "abc", 24); /* Empty delimiter list. */
897 check(strtok((char *)NULL
, "") == NULL
, 25);
898 (void) strcpy(one
, "abcdefgh");
899 (void) strcpy(one
, "a,b,c");
900 equal(strtok(one
, ","), "a", 26); /* Basics again... */
901 equal(strtok((char *)NULL
, ","), "b", 27);
902 equal(strtok((char *)NULL
, ","), "c", 28);
903 check(strtok((char *)NULL
, ",") == NULL
, 29);
904 equal(one
+6, "gh", 30); /* Stomped past end? */
905 equal(one
, "a", 31); /* Stomped old tokens? */
906 equal(one
+2, "b", 32);
907 equal(one
+4, "c", 33);
914 (void) strcpy(one
, "first, second, third");
915 cp
= NULL
; /* Always initialize cp to make sure it doesn't point to some old data. */
916 equal(strtok_r(one
, ", ", &cp
), "first", 1); /* Basic test. */
917 equal(one
, "first", 2);
918 equal(strtok_r((char *)NULL
, ", ", &cp
), "second", 3);
919 equal(strtok_r((char *)NULL
, ", ", &cp
), "third", 4);
920 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 5);
921 (void) strcpy(one
, ", first, ");
923 equal(strtok_r(one
, ", ", &cp
), "first", 6); /* Extra delims, 1 tok. */
924 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 7);
925 (void) strcpy(one
, "1a, 1b; 2a, 2b");
927 equal(strtok_r(one
, ", ", &cp
), "1a", 8); /* Changing delim lists. */
928 equal(strtok_r((char *)NULL
, "; ", &cp
), "1b", 9);
929 equal(strtok_r((char *)NULL
, ", ", &cp
), "2a", 10);
930 (void) strcpy(two
, "x-y");
932 equal(strtok_r(two
, "-", &cp
), "x", 11); /* New string before done. */
933 equal(strtok_r((char *)NULL
, "-", &cp
), "y", 12);
934 check(strtok_r((char *)NULL
, "-", &cp
) == NULL
, 13);
935 (void) strcpy(one
, "a,b, c,, ,d");
937 equal(strtok_r(one
, ", ", &cp
), "a", 14); /* Different separators. */
938 equal(strtok_r((char *)NULL
, ", ", &cp
), "b", 15);
939 equal(strtok_r((char *)NULL
, " ,", &cp
), "c", 16); /* Permute list too. */
940 equal(strtok_r((char *)NULL
, " ,", &cp
), "d", 17);
941 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 18);
942 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 19); /* Persistence. */
943 (void) strcpy(one
, ", ");
945 check(strtok_r(one
, ", ", &cp
) == NULL
, 20); /* No tokens. */
946 (void) strcpy(one
, "");
948 check(strtok_r(one
, ", ", &cp
) == NULL
, 21); /* Empty string. */
949 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 22); /* Persistence. */
950 (void) strcpy(one
, "abc");
952 equal(strtok_r(one
, ", ", &cp
), "abc", 23); /* No delimiters. */
953 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 24);
954 (void) strcpy(one
, "abc");
956 equal(strtok_r(one
, "", &cp
), "abc", 25); /* Empty delimiter list. */
957 check(strtok_r((char *)NULL
, "", &cp
) == NULL
, 26);
958 (void) strcpy(one
, "abcdefgh");
959 (void) strcpy(one
, "a,b,c");
961 equal(strtok_r(one
, ",", &cp
), "a", 27); /* Basics again... */
962 equal(strtok_r((char *)NULL
, ",", &cp
), "b", 28);
963 equal(strtok_r((char *)NULL
, ",", &cp
), "c", 29);
964 check(strtok_r((char *)NULL
, ",", &cp
) == NULL
, 30);
965 equal(one
+6, "gh", 31); /* Stomped past end? */
966 equal(one
, "a", 32); /* Stomped old tokens? */
967 equal(one
+2, "b", 33);
968 equal(one
+4, "c", 34);
971 check (strtok_r (one
, ":", &cp
) == NULL
, 35); /* Must store pointer in cp. */
972 check (strtok_r (NULL
, ":", &cp
) == NULL
, 36);
980 cp
= strcpy(one
, "first, second, third");
981 equal(strsep(&cp
, ", "), "first", 1); /* Basic test. */
982 equal(one
, "first", 2);
983 equal(strsep(&cp
, ", "), "", 3);
984 equal(strsep(&cp
, ", "), "second", 4);
985 equal(strsep(&cp
, ", "), "", 5);
986 equal(strsep(&cp
, ", "), "third", 6);
987 check(strsep(&cp
, ", ") == NULL
, 7);
988 cp
= strcpy(one
, ", first, ");
989 equal(strsep(&cp
, ", "), "", 8);
990 equal(strsep(&cp
, ", "), "", 9);
991 equal(strsep(&cp
, ", "), "first", 10); /* Extra delims, 1 tok. */
992 equal(strsep(&cp
, ", "), "", 11);
993 equal(strsep(&cp
, ", "), "", 12);
994 check(strsep(&cp
, ", ") == NULL
, 13);
995 cp
= strcpy(one
, "1a, 1b; 2a, 2b");
996 equal(strsep(&cp
, ", "), "1a", 14); /* Changing delim lists. */
997 equal(strsep(&cp
, ", "), "", 15);
998 equal(strsep(&cp
, "; "), "1b", 16);
999 equal(strsep(&cp
, ", "), "", 17);
1000 equal(strsep(&cp
, ", "), "2a", 18);
1001 cp
= strcpy(two
, "x-y");
1002 equal(strsep(&cp
, "-"), "x", 19); /* New string before done. */
1003 equal(strsep(&cp
, "-"), "y", 20);
1004 check(strsep(&cp
, "-") == NULL
, 21);
1005 cp
= strcpy(one
, "a,b, c,, ,d ");
1006 equal(strsep(&cp
, ", "), "a", 22); /* Different separators. */
1007 equal(strsep(&cp
, ", "), "b", 23);
1008 equal(strsep(&cp
, " ,"), "", 24);
1009 equal(strsep(&cp
, " ,"), "c", 25); /* Permute list too. */
1010 equal(strsep(&cp
, " ,"), "", 26);
1011 equal(strsep(&cp
, " ,"), "", 27);
1012 equal(strsep(&cp
, " ,"), "", 28);
1013 equal(strsep(&cp
, " ,"), "d", 29);
1014 equal(strsep(&cp
, " ,"), "", 30);
1015 check(strsep(&cp
, ", ") == NULL
, 31);
1016 check(strsep(&cp
, ", ") == NULL
, 32); /* Persistence. */
1017 cp
= strcpy(one
, ", ");
1018 equal(strsep(&cp
, ", "), "", 33);
1019 equal(strsep(&cp
, ", "), "", 34);
1020 equal(strsep(&cp
, ", "), "", 35);
1021 check(strsep(&cp
, ", ") == NULL
, 36); /* No tokens. */
1022 cp
= strcpy(one
, "");
1023 equal(strsep(&cp
, ", "), "", 37);
1024 check(strsep(&cp
, ", ") == NULL
, 38); /* Empty string. */
1025 cp
= strcpy(one
, "abc");
1026 equal(strsep(&cp
, ", "), "abc", 39); /* No delimiters. */
1027 check(strsep(&cp
, ", ") == NULL
, 40);
1028 cp
= strcpy(one
, "abc");
1029 equal(strsep(&cp
, ""), "abc", 41); /* Empty delimiter list. */
1030 check(strsep(&cp
, "") == NULL
, 42);
1031 (void) strcpy(one
, "abcdefgh");
1032 cp
= strcpy(one
, "a,b,c");
1033 equal(strsep(&cp
, ","), "a", 43); /* Basics again... */
1034 equal(strsep(&cp
, ","), "b", 44);
1035 equal(strsep(&cp
, ","), "c", 45);
1036 check(strsep(&cp
, ",") == NULL
, 46);
1037 equal(one
+6, "gh", 47); /* Stomped past end? */
1038 equal(one
, "a", 48); /* Stomped old tokens? */
1039 equal(one
+2, "b", 49);
1040 equal(one
+4, "c", 50);
1043 char text
[] = "This,is,a,test";
1044 char *list
= strdupa (text
);
1045 equal (strsep (&list
, ","), "This", 51);
1046 equal (strsep (&list
, ","), "is", 52);
1047 equal (strsep (&list
, ","), "a", 53);
1048 equal (strsep (&list
, ","), "test", 54);
1049 check (strsep (&list
, ",") == NULL
, 55);
1052 cp
= strcpy(one
, "a,b, c,, ,d,");
1053 equal(strsep(&cp
, ","), "a", 56); /* Different separators. */
1054 equal(strsep(&cp
, ","), "b", 57);
1055 equal(strsep(&cp
, ","), " c", 58); /* Permute list too. */
1056 equal(strsep(&cp
, ","), "", 59);
1057 equal(strsep(&cp
, ","), " ", 60);
1058 equal(strsep(&cp
, ","), "d", 61);
1059 equal(strsep(&cp
, ","), "", 62);
1060 check(strsep(&cp
, ",") == NULL
, 63);
1061 check(strsep(&cp
, ",") == NULL
, 64); /* Persistence. */
1063 cp
= strcpy(one
, "a,b, c,, ,d,");
1064 equal(strsep(&cp
, "xy,"), "a", 65); /* Different separators. */
1065 equal(strsep(&cp
, "x,y"), "b", 66);
1066 equal(strsep(&cp
, ",xy"), " c", 67); /* Permute list too. */
1067 equal(strsep(&cp
, "xy,"), "", 68);
1068 equal(strsep(&cp
, "x,y"), " ", 69);
1069 equal(strsep(&cp
, ",xy"), "d", 70);
1070 equal(strsep(&cp
, "xy,"), "", 71);
1071 check(strsep(&cp
, "x,y") == NULL
, 72);
1072 check(strsep(&cp
, ",xy") == NULL
, 73); /* Persistence. */
1074 cp
= strcpy(one
, "ABC");
1076 equal(strsep(&cp
, "C"), "AB", 74); /* Access beyond NUL. */
1077 ptr
= strsep(&cp
, ":");
1079 check(ptr
== one
+ 3, 76);
1080 check(cp
== NULL
, 77);
1082 cp
= strcpy(one
, "ABC");
1084 equal(strsep(&cp
, "CD"), "AB", 78); /* Access beyond NUL. */
1085 ptr
= strsep(&cp
, ":.");
1087 check(ptr
== one
+ 3, 80);
1089 cp
= strcpy(one
, "ABC"); /* No token in string. */
1090 equal(strsep(&cp
, ","), "ABC", 81);
1091 check(cp
== NULL
, 82);
1093 *one
= '\0'; /* Empty string. */
1095 ptr
= strsep(&cp
, ",");
1097 check(ptr
== one
, 84);
1098 check(cp
== NULL
, 85);
1100 *one
= '\0'; /* Empty string and no token. */
1102 ptr
= strsep(&cp
, "");
1104 check(ptr
== one
, 87);
1105 check(cp
== NULL
, 88);
1116 check(memcmp("a", "a", 1) == 0, cnt
++); /* Identity. */
1117 check(memcmp("abc", "abc", 3) == 0, cnt
++); /* Multicharacter. */
1118 check(memcmp("abcd", "abcf", 4) < 0, cnt
++); /* Honestly unequal. */
1119 check(memcmp("abcf", "abcd", 4) > 0, cnt
++);
1120 check(memcmp("alph", "cold", 4) < 0, cnt
++);
1121 check(memcmp("a\203", "a\003", 2) > 0, cnt
++);
1122 check(memcmp("a\003", "a\203", 2) < 0, cnt
++);
1123 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt
++);
1124 check(memcmp("abc\203", "abc\003", 4) > 0, cnt
++);
1125 check(memcmp("abc\003", "abc\203", 4) < 0, cnt
++);
1126 check(memcmp("abcf", "abcd", 3) == 0, cnt
++); /* Count limited. */
1127 check(memcmp("abc", "def", 0) == 0, cnt
++); /* Zero count. */
1128 /* Comparisons with shifting 4-byte boundaries. */
1129 for (int i
= 0; i
< 4; ++i
)
1133 memcpy(a
, "--------11112222", 16);
1134 memcpy(b
, "--------33334444", 16);
1135 check(memcmp(b
, a
, 16) > 0, cnt
++);
1136 check(memcmp(a
, b
, 16) < 0, cnt
++);
1144 check(memchr("abcd", 'z', 4) == NULL
, 1); /* Not found. */
1145 (void) strcpy(one
, "abcd");
1146 check(memchr(one
, 'c', 4) == one
+2, 2); /* Basic test. */
1147 check(memchr(one
, ~0xff|'c', 4) == one
+2, 2); /* ignore highorder bits. */
1148 check(memchr(one
, 'd', 4) == one
+3, 3); /* End of string. */
1149 check(memchr(one
, 'a', 4) == one
, 4); /* Beginning. */
1150 check(memchr(one
, '\0', 5) == one
+4, 5); /* Finding NUL. */
1151 (void) strcpy(one
, "ababa");
1152 check(memchr(one
, 'b', 5) == one
+1, 6); /* Finding first. */
1153 check(memchr(one
, 'b', 0) == NULL
, 7); /* Zero count. */
1154 check(memchr(one
, 'a', 1) == one
, 8); /* Singleton case. */
1155 (void) strcpy(one
, "a\203b");
1156 check(memchr(one
, 0203, 3) == one
+1, 9); /* Unsignedness. */
1158 /* now test all possible alignment and length combinations to catch
1159 bugs due to unrolled loops (assuming unrolling is limited to no
1160 more than 128 byte chunks: */
1162 char buf
[128 + sizeof (long)];
1163 long align
, len
, i
, pos
;
1165 for (align
= 0; align
< (long) sizeof (long); ++align
) {
1166 for (len
= 0; len
< (long) (sizeof (buf
) - align
); ++len
) {
1167 for (i
= 0; i
< len
; ++i
) {
1168 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
1170 for (pos
= 0; pos
< len
; ++pos
) {
1172 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
1174 check(memchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, 10);
1175 check(memchr(buf
+ align
, 'x', pos
) == NULL
, 11);
1176 buf
[align
+ pos
] = '-';
1188 check(memcpy(one
, "abc", 4) == one
, 1); /* Returned value. */
1189 equal(one
, "abc", 2); /* Did the copy go right? */
1191 (void) strcpy(one
, "abcdefgh");
1192 (void) memcpy(one
+1, "xyz", 2);
1193 equal(one
, "axydefgh", 3); /* Basic test. */
1195 (void) strcpy(one
, "abc");
1196 (void) memcpy(one
, "xyz", 0);
1197 equal(one
, "abc", 4); /* Zero-length copy. */
1199 (void) strcpy(one
, "hi there");
1200 (void) strcpy(two
, "foo");
1201 (void) memcpy(two
, one
, 9);
1202 equal(two
, "hi there", 5); /* Just paranoia. */
1203 equal(one
, "hi there", 6); /* Stomped on source? */
1205 for (i
= 0; i
< 16; i
++)
1207 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1209 check (memcpy (one
+ i
, "hi there", 9) == one
+ i
,
1210 7 + (i
* 6)); /* Unaligned destination. */
1211 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1212 equal (one
+ i
, "hi there", 9 + (i
* 6));
1213 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1214 check (memcpy (two
, one
+ i
, 9) == two
,
1215 11 + (i
* 6)); /* Unaligned source. */
1216 equal (two
, "hi there", 12 + (i
* 6));
1225 check(mempcpy(one
, "abc", 4) == one
+ 4, 1); /* Returned value. */
1226 equal(one
, "abc", 2); /* Did the copy go right? */
1228 (void) strcpy(one
, "abcdefgh");
1229 (void) mempcpy(one
+1, "xyz", 2);
1230 equal(one
, "axydefgh", 3); /* Basic test. */
1232 (void) strcpy(one
, "abc");
1233 (void) mempcpy(one
, "xyz", 0);
1234 equal(one
, "abc", 4); /* Zero-length copy. */
1236 (void) strcpy(one
, "hi there");
1237 (void) strcpy(two
, "foo");
1238 (void) mempcpy(two
, one
, 9);
1239 equal(two
, "hi there", 5); /* Just paranoia. */
1240 equal(one
, "hi there", 6); /* Stomped on source? */
1242 for (i
= 0; i
< 16; i
++)
1244 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1246 check (mempcpy (one
+ i
, "hi there", 9) == one
+ i
+ 9,
1247 7 + (i
* 6)); /* Unaligned destination. */
1248 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1249 equal (one
+ i
, "hi there", 9 + (i
* 6));
1250 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1251 check (mempcpy (two
, one
+ i
, 9) == two
+ 9,
1252 11 + (i
* 6)); /* Unaligned source. */
1253 equal (two
, "hi there", 12 + (i
* 6));
1261 check(memmove(one
, "abc", 4) == one
, 1); /* Returned value. */
1262 equal(one
, "abc", 2); /* Did the copy go right? */
1264 (void) strcpy(one
, "abcdefgh");
1265 (void) memmove(one
+1, "xyz", 2);
1266 equal(one
, "axydefgh", 3); /* Basic test. */
1268 (void) strcpy(one
, "abc");
1269 (void) memmove(one
, "xyz", 0);
1270 equal(one
, "abc", 4); /* Zero-length copy. */
1272 (void) strcpy(one
, "hi there");
1273 (void) strcpy(two
, "foo");
1274 (void) memmove(two
, one
, 9);
1275 equal(two
, "hi there", 5); /* Just paranoia. */
1276 equal(one
, "hi there", 6); /* Stomped on source? */
1278 (void) strcpy(one
, "abcdefgh");
1279 (void) memmove(one
+1, one
, 9);
1280 equal(one
, "aabcdefgh", 7); /* Overlap, right-to-left. */
1282 (void) strcpy(one
, "abcdefgh");
1283 (void) memmove(one
+1, one
+2, 7);
1284 equal(one
, "acdefgh", 8); /* Overlap, left-to-right. */
1286 (void) strcpy(one
, "abcdefgh");
1287 (void) memmove(one
, one
, 9);
1288 equal(one
, "abcdefgh", 9); /* 100% overlap. */
1294 /* First test like memcpy, then the search part The SVID, the only
1295 place where memccpy is mentioned, says overlap might fail, so we
1296 don't try it. Besides, it's hard to see the rationale for a
1297 non-left-to-right memccpy. */
1299 check(memccpy(one
, "abc", 'q', 4) == NULL
, 1); /* Returned value. */
1300 equal(one
, "abc", 2); /* Did the copy go right? */
1302 (void) strcpy(one
, "abcdefgh");
1303 (void) memccpy(one
+1, "xyz", 'q', 2);
1304 equal(one
, "axydefgh", 3); /* Basic test. */
1306 (void) strcpy(one
, "abc");
1307 (void) memccpy(one
, "xyz", 'q', 0);
1308 equal(one
, "abc", 4); /* Zero-length copy. */
1310 (void) strcpy(one
, "hi there");
1311 (void) strcpy(two
, "foo");
1312 (void) memccpy(two
, one
, 'q', 9);
1313 equal(two
, "hi there", 5); /* Just paranoia. */
1314 equal(one
, "hi there", 6); /* Stomped on source? */
1316 (void) strcpy(one
, "abcdefgh");
1317 (void) strcpy(two
, "horsefeathers");
1318 check(memccpy(two
, one
, 'f', 9) == two
+6, 7); /* Returned value. */
1319 equal(one
, "abcdefgh", 8); /* Source intact? */
1320 equal(two
, "abcdefeathers", 9); /* Copy correct? */
1322 (void) strcpy(one
, "abcd");
1323 (void) strcpy(two
, "bumblebee");
1324 check(memccpy(two
, one
, 'a', 4) == two
+1, 10); /* First char. */
1325 equal(two
, "aumblebee", 11);
1326 check(memccpy(two
, one
, 'd', 4) == two
+4, 12); /* Last char. */
1327 equal(two
, "abcdlebee", 13);
1328 (void) strcpy(one
, "xyz");
1329 check(memccpy(two
, one
, 'x', 1) == two
+1, 14); /* Singleton. */
1330 equal(two
, "xbcdlebee", 15);
1339 (void) strcpy(one
, "abcdefgh");
1340 check(memset(one
+1, 'x', 3) == one
+1, 1); /* Return value. */
1341 equal(one
, "axxxefgh", 2); /* Basic test. */
1343 (void) memset(one
+2, 'y', 0);
1344 equal(one
, "axxxefgh", 3); /* Zero-length set. */
1346 (void) memset(one
+5, 0, 1);
1347 equal(one
, "axxxe", 4); /* Zero fill. */
1348 equal(one
+6, "gh", 5); /* And the leftover. */
1350 (void) memset(one
+2, 010045, 1);
1351 equal(one
, "ax\045xe", 6); /* Unsigned char convert. */
1353 /* Non-8bit fill character. */
1354 memset (one
, 0x101, sizeof (one
));
1355 for (i
= 0; i
< (int) sizeof (one
); ++i
)
1356 check (one
[i
] == '\01', 7);
1358 /* Test for more complex versions of memset, for all alignments and
1359 lengths up to 256. This test takes a little while, perhaps it should
1367 for (i
= 0; i
< 512; i
++)
1369 for (c
= 0; c
<= 'y'; c
+= 'y') /* check for memset(,0,) and
1371 for (j
= 0; j
< 256; j
++)
1372 for (i
= 0; i
< 256; i
++)
1374 memset (data
+ i
, c
, j
);
1375 for (k
= 0; k
< i
; k
++)
1378 for (k
= i
; k
< i
+j
; k
++)
1384 for (k
= i
+j
; k
< 512; k
++)
1390 check (0, 8 + i
+ j
* 256 + (c
!= 0) * 256 * 256);
1398 /* Much like memcpy. Berklix manual is silent about overlap, so
1401 (void) bcopy("abc", one
, 4);
1402 equal(one
, "abc", 1); /* Simple copy. */
1404 (void) strcpy(one
, "abcdefgh");
1405 (void) bcopy("xyz", one
+1, 2);
1406 equal(one
, "axydefgh", 2); /* Basic test. */
1408 (void) strcpy(one
, "abc");
1409 (void) bcopy("xyz", one
, 0);
1410 equal(one
, "abc", 3); /* Zero-length copy. */
1412 (void) strcpy(one
, "hi there");
1413 (void) strcpy(two
, "foo");
1414 (void) bcopy(one
, two
, 9);
1415 equal(two
, "hi there", 4); /* Just paranoia. */
1416 equal(one
, "hi there", 5); /* Stomped on source? */
1423 (void) strcpy(one
, "abcdef");
1425 equal(one
, "ab", 1); /* Basic test. */
1426 equal(one
+3, "", 2);
1427 equal(one
+4, "ef", 3);
1429 (void) strcpy(one
, "abcdef");
1431 equal(one
, "abcdef", 4); /* Zero-length copy. */
1439 p
= strndup("abcdef", 12);
1440 check(p
!= NULL
, 1);
1443 equal(p
, "abcdef", 2);
1444 q
= strndup(p
+ 1, 2);
1445 check(q
!= NULL
, 3);
1451 p
= strndup("abc def", 3);
1452 check(p
!= NULL
, 5);
1462 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1463 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1464 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1465 check(bcmp("abce", "abcd", 4) != 0, 4);
1466 check(bcmp("alph", "beta", 4) != 0, 5);
1467 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1468 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1472 test_memcmpeq (void)
1475 check (__memcmpeq ("a", "a", 1) == 0, 1); /* Identity. */
1476 check (__memcmpeq ("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1477 check (__memcmpeq ("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1478 check (__memcmpeq ("abce", "abcd", 4) != 0, 4);
1479 check (__memcmpeq ("alph", "beta", 4) != 0, 5);
1480 check (__memcmpeq ("abce", "abcd", 3) == 0, 6); /* Count limited. */
1481 check (__memcmpeq ("abc", "def", 0) == 0, 8); /* Zero count. */
1485 test_strerror (void)
1488 check(strerror(EDOM
) != 0, 1);
1489 check(strerror(ERANGE
) != 0, 2);
1490 check(strerror(ENOENT
) != 0, 3);
1494 test_strcasecmp (void)
1497 /* Note that the locale is "C". */
1498 check(strcasecmp("a", "a") == 0, 1);
1499 check(strcasecmp("a", "A") == 0, 2);
1500 check(strcasecmp("A", "a") == 0, 3);
1501 check(strcasecmp("a", "b") < 0, 4);
1502 check(strcasecmp("c", "b") > 0, 5);
1503 check(strcasecmp("abc", "AbC") == 0, 6);
1504 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1505 check(strcasecmp("", "0123456789") < 0, 8);
1506 check(strcasecmp("AbC", "") > 0, 9);
1507 check(strcasecmp("AbC", "A") > 0, 10);
1508 check(strcasecmp("AbC", "Ab") > 0, 11);
1509 check(strcasecmp("AbC", "ab") > 0, 12);
1513 test_strncasecmp (void)
1516 /* Note that the locale is "C". */
1517 check(strncasecmp("a", "a", 5) == 0, 1);
1518 check(strncasecmp("a", "A", 5) == 0, 2);
1519 check(strncasecmp("A", "a", 5) == 0, 3);
1520 check(strncasecmp("a", "b", 5) < 0, 4);
1521 check(strncasecmp("c", "b", 5) > 0, 5);
1522 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1523 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1524 check(strncasecmp("", "0123456789", 10) < 0, 8);
1525 check(strncasecmp("AbC", "", 5) > 0, 9);
1526 check(strncasecmp("AbC", "A", 5) > 0, 10);
1527 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1528 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1529 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1530 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1531 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1532 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1533 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1534 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1535 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1536 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1544 /* Test strcmp first because we use it to test other things. */
1547 /* Test strcpy next because we need it to set up other tests. */
1550 /* A closely related function is stpcpy. */
1583 /* index - just like strchr. */
1592 /* rindex - just like strrchr. */
1595 /* strpbrk - somewhat like strchr. */
1598 /* strstr - somewhat like strchr. */
1607 /* strtok - the hard one. */
1622 /* memcpy - need not work for overlap. */
1625 /* memmove - must work on overlap. */
1643 /* bcmp - somewhat like memcmp. */
1646 /* __memcmpeq - somewhat like memcmp. */
1652 /* strerror - VERY system-dependent. */
1655 /* strcasecmp. Without locale dependencies. */
1658 /* strncasecmp. Without locale dependencies. */
1659 test_strncasecmp ();
1663 status
= EXIT_SUCCESS
;
1668 status
= EXIT_FAILURE
;
1669 printf("%zd errors.\n", errors
);