1 /* Tester for string functions.
2 Copyright (C) 1995-2023 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
36 #include <libc-diag.h>
38 /* This file tests a range of corner cases of string functions,
39 including cases where truncation occurs or where sizes specified
40 are larger than the actual buffers, which result in various
42 DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
43 DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args");
44 #if __GNUC_PREREQ (7, 0)
45 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wrestrict");
46 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
48 #if __GNUC_PREREQ (8, 0)
49 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
51 #if __GNUC_PREREQ (11, 0)
52 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
56 #define STREQ(a, b) (strcmp((a), (b)) == 0)
58 const char *it
= "<UNSET>"; /* Routine name for message routines. */
61 /* Complain if condition is not true. */
63 check (int thing
, int number
)
67 printf ("%s flunked test %d\n", it
, number
);
72 /* Complain if first two args don't strcmp as equal. */
74 equal (const char *a
, const char *b
, int number
)
76 check (a
!= NULL
&& b
!= NULL
&& STREQ (a
, b
), number
);
87 check (strcmp ("", "") == 0, 1); /* Trivial case. */
88 check (strcmp ("a", "a") == 0, 2); /* Identity. */
89 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
90 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
91 check (strcmp ("abcd", "abc") > 0, 5);
92 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
93 check (strcmp ("abce", "abcd") > 0, 7);
94 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
95 check (strcmp ("a\203", "a\003") > 0, 9);
98 char buf1
[0x40], buf2
[0x40];
100 for (i
=0; i
< 0x10; i
++)
101 for (j
= 0; j
< 0x10; j
++)
104 for (k
= 0; k
< 0x3f; k
++)
106 buf1
[k
] = '0' ^ (k
& 4);
107 buf2
[k
] = '4' ^ (k
& 4);
109 buf1
[i
] = buf1
[0x3f] = 0;
110 buf2
[j
] = buf2
[0x3f] = 0;
111 for (k
= 0; k
< 0xf; k
++)
113 int cnum
= 0x10+0x10*k
+0x100*j
+0x1000*i
;
114 check (strcmp (buf1
+i
,buf2
+j
) == 0, cnum
);
115 buf1
[i
+k
] = 'A' + i
+ k
;
117 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+1);
118 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+2);
119 buf2
[j
+k
] = 'B' + i
+ k
;
121 check (strcmp (buf1
+i
,buf2
+j
) < 0, cnum
+3);
122 check (strcmp (buf2
+j
,buf1
+i
) > 0, cnum
+4);
123 buf2
[j
+k
] = 'A' + i
+ k
;
124 buf1
[i
] = 'A' + i
+ 0x80;
125 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+5);
126 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+6);
133 #define SIMPLE_COPY(fn, n, str, ntest) \
137 for (__n = 0; __n < (int) sizeof (one); ++__n) \
140 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
141 check (*cp == '0' + (n % 10), ntest); \
142 check (*cp == '\0', ntest); \
150 check (strcpy (one
, "abcd") == one
, 1); /* Returned value. */
151 equal (one
, "abcd", 2); /* Basic test. */
153 (void) strcpy (one
, "x");
154 equal (one
, "x", 3); /* Writeover. */
155 equal (one
+2, "cd", 4); /* Wrote too much? */
157 (void) strcpy (two
, "hi there");
158 (void) strcpy (one
, two
);
159 equal (one
, "hi there", 5); /* Basic test encore. */
160 equal (two
, "hi there", 6); /* Stomped on source? */
162 (void) strcpy (one
, "");
163 equal (one
, "", 7); /* Boundary condition. */
165 for (i
= 0; i
< 16; i
++)
167 (void) strcpy (one
+ i
, "hi there"); /* Unaligned destination. */
168 equal (one
+ i
, "hi there", 8 + (i
* 2));
169 (void) strcpy (two
, one
+ i
); /* Unaligned source. */
170 equal (two
, "hi there", 9 + (i
* 2));
173 SIMPLE_COPY(strcpy
, 0, "", 41);
174 SIMPLE_COPY(strcpy
, 1, "1", 42);
175 SIMPLE_COPY(strcpy
, 2, "22", 43);
176 SIMPLE_COPY(strcpy
, 3, "333", 44);
177 SIMPLE_COPY(strcpy
, 4, "4444", 45);
178 SIMPLE_COPY(strcpy
, 5, "55555", 46);
179 SIMPLE_COPY(strcpy
, 6, "666666", 47);
180 SIMPLE_COPY(strcpy
, 7, "7777777", 48);
181 SIMPLE_COPY(strcpy
, 8, "88888888", 49);
182 SIMPLE_COPY(strcpy
, 9, "999999999", 50);
183 SIMPLE_COPY(strcpy
, 10, "0000000000", 51);
184 SIMPLE_COPY(strcpy
, 11, "11111111111", 52);
185 SIMPLE_COPY(strcpy
, 12, "222222222222", 53);
186 SIMPLE_COPY(strcpy
, 13, "3333333333333", 54);
187 SIMPLE_COPY(strcpy
, 14, "44444444444444", 55);
188 SIMPLE_COPY(strcpy
, 15, "555555555555555", 56);
189 SIMPLE_COPY(strcpy
, 16, "6666666666666666", 57);
191 /* Simple test using implicitly coerced `void *' arguments. */
192 const void *src
= "frobozz";
194 check (strcpy (dst
, src
) == dst
, 1);
195 equal (dst
, "frobozz", 2);
202 check ((stpcpy (one
, "a") - one
) == 1, 1);
205 check ((stpcpy (one
, "ab") - one
) == 2, 3);
206 equal (one
, "ab", 4);
208 check ((stpcpy (one
, "abc") - one
) == 3, 5);
209 equal (one
, "abc", 6);
211 check ((stpcpy (one
, "abcd") - one
) == 4, 7);
212 equal (one
, "abcd", 8);
214 check ((stpcpy (one
, "abcde") - one
) == 5, 9);
215 equal (one
, "abcde", 10);
217 check ((stpcpy (one
, "abcdef") - one
) == 6, 11);
218 equal (one
, "abcdef", 12);
220 check ((stpcpy (one
, "abcdefg") - one
) == 7, 13);
221 equal (one
, "abcdefg", 14);
223 check ((stpcpy (one
, "abcdefgh") - one
) == 8, 15);
224 equal (one
, "abcdefgh", 16);
226 check ((stpcpy (one
, "abcdefghi") - one
) == 9, 17);
227 equal (one
, "abcdefghi", 18);
229 check ((stpcpy (one
, "x") - one
) == 1, 19);
230 equal (one
, "x", 20); /* Writeover. */
231 equal (one
+2, "cdefghi", 21); /* Wrote too much? */
233 check ((stpcpy (one
, "xx") - one
) == 2, 22);
234 equal (one
, "xx", 23); /* Writeover. */
235 equal (one
+3, "defghi", 24); /* Wrote too much? */
237 check ((stpcpy (one
, "xxx") - one
) == 3, 25);
238 equal (one
, "xxx", 26); /* Writeover. */
239 equal (one
+4, "efghi", 27); /* Wrote too much? */
241 check ((stpcpy (one
, "xxxx") - one
) == 4, 28);
242 equal (one
, "xxxx", 29); /* Writeover. */
243 equal (one
+5, "fghi", 30); /* Wrote too much? */
245 check ((stpcpy (one
, "xxxxx") - one
) == 5, 31);
246 equal (one
, "xxxxx", 32); /* Writeover. */
247 equal (one
+6, "ghi", 33); /* Wrote too much? */
249 check ((stpcpy (one
, "xxxxxx") - one
) == 6, 34);
250 equal (one
, "xxxxxx", 35); /* Writeover. */
251 equal (one
+7, "hi", 36); /* Wrote too much? */
253 check ((stpcpy (one
, "xxxxxxx") - one
) == 7, 37);
254 equal (one
, "xxxxxxx", 38); /* Writeover. */
255 equal (one
+8, "i", 39); /* Wrote too much? */
257 check ((stpcpy (stpcpy (stpcpy (one
, "a"), "b"), "c") - one
) == 3, 40);
258 equal (one
, "abc", 41);
259 equal (one
+ 4, "xxx", 42);
261 SIMPLE_COPY(stpcpy
, 0, "", 43);
262 SIMPLE_COPY(stpcpy
, 1, "1", 44);
263 SIMPLE_COPY(stpcpy
, 2, "22", 45);
264 SIMPLE_COPY(stpcpy
, 3, "333", 46);
265 SIMPLE_COPY(stpcpy
, 4, "4444", 47);
266 SIMPLE_COPY(stpcpy
, 5, "55555", 48);
267 SIMPLE_COPY(stpcpy
, 6, "666666", 49);
268 SIMPLE_COPY(stpcpy
, 7, "7777777", 50);
269 SIMPLE_COPY(stpcpy
, 8, "88888888", 51);
270 SIMPLE_COPY(stpcpy
, 9, "999999999", 52);
271 SIMPLE_COPY(stpcpy
, 10, "0000000000", 53);
272 SIMPLE_COPY(stpcpy
, 11, "11111111111", 54);
273 SIMPLE_COPY(stpcpy
, 12, "222222222222", 55);
274 SIMPLE_COPY(stpcpy
, 13, "3333333333333", 56);
275 SIMPLE_COPY(stpcpy
, 14, "44444444444444", 57);
276 SIMPLE_COPY(stpcpy
, 15, "555555555555555", 58);
277 SIMPLE_COPY(stpcpy
, 16, "6666666666666666", 59);
284 memset (one
, 'x', sizeof (one
));
285 check (stpncpy (one
, "abc", 2) == one
+ 2, 1);
286 check (stpncpy (one
, "abc", 3) == one
+ 3, 2);
287 check (stpncpy (one
, "abc", 4) == one
+ 3, 3);
288 check (one
[3] == '\0' && one
[4] == 'x', 4);
289 check (stpncpy (one
, "abcd", 5) == one
+ 4, 5);
290 check (one
[4] == '\0' && one
[5] == 'x', 6);
291 check (stpncpy (one
, "abcd", 6) == one
+ 4, 7);
292 check (one
[4] == '\0' && one
[5] == '\0' && one
[6] == 'x', 8);
299 (void) strcpy (one
, "ijk");
300 check (strcat (one
, "lmn") == one
, 1); /* Returned value. */
301 equal (one
, "ijklmn", 2); /* Basic test. */
303 (void) strcpy (one
, "x");
304 (void) strcat (one
, "yz");
305 equal (one
, "xyz", 3); /* Writeover. */
306 equal (one
+4, "mn", 4); /* Wrote too much? */
308 (void) strcpy (one
, "gh");
309 (void) strcpy (two
, "ef");
310 (void) strcat (one
, two
);
311 equal (one
, "ghef", 5); /* Basic test encore. */
312 equal (two
, "ef", 6); /* Stomped on source? */
314 (void) strcpy (one
, "");
315 (void) strcat (one
, "");
316 equal (one
, "", 7); /* Boundary conditions. */
317 (void) strcpy (one
, "ab");
318 (void) strcat (one
, "");
319 equal (one
, "ab", 8);
320 (void) strcpy (one
, "");
321 (void) strcat (one
, "cd");
322 equal (one
, "cd", 9);
325 char buf1
[80] __attribute__ ((aligned (16)));
326 char buf2
[32] __attribute__ ((aligned (16)));
327 for (size_t n1
= 0; n1
< 16; ++n1
)
328 for (size_t n2
= 0; n2
< 16; ++n2
)
329 for (size_t n3
= 0; n3
< 32; ++n3
)
331 size_t olderrors
= errors
;
333 memset (buf1
, 'b', sizeof (buf1
));
335 memset (buf1
+ n2
, 'a', n3
);
336 buf1
[n2
+ n3
] = '\0';
337 strcpy (buf2
+ n1
, "123");
339 check (strcat (buf1
+ n2
, buf2
+ n1
) == buf1
+ n2
, ntest
);
340 if (errors
== olderrors
)
341 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
344 check (buf1
[i
] == 'b', ntest
);
345 else if (i
< n2
+ n3
)
346 check (buf1
[i
] == 'a', ntest
);
347 else if (i
< n2
+ n3
+ 3)
348 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
349 else if (i
== n2
+ n3
+ 3)
350 check (buf1
[i
] == '\0', ntest
);
352 check (buf1
[i
] == 'b', ntest
);
354 if (errors
!= olderrors
)
356 printf ("n1=%zu, n2=%zu, n3=%zu, buf1=%02hhx",
357 n1
, n2
, n3
, buf1
[0]);
358 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
359 printf (",%02hhx", buf1
[j
]);
360 putchar_unlocked ('\n');
370 /* First test it as strcat, with big counts, then test the count
373 (void) strcpy (one
, "ijk");
374 check (strncat (one
, "lmn", 99) == one
, 1); /* Returned value. */
375 equal (one
, "ijklmn", 2); /* Basic test. */
377 (void) strcpy (one
, "x");
378 (void) strncat (one
, "yz", 99);
379 equal (one
, "xyz", 3); /* Writeover. */
380 equal (one
+4, "mn", 4); /* Wrote too much? */
382 (void) strcpy (one
, "gh");
383 (void) strcpy (two
, "ef");
384 (void) strncat (one
, two
, 99);
385 equal (one
, "ghef", 5); /* Basic test encore. */
386 equal (two
, "ef", 6); /* Stomped on source? */
388 (void) strcpy (one
, "");
389 (void) strncat (one
, "", 99);
390 equal (one
, "", 7); /* Boundary conditions. */
391 (void) strcpy (one
, "ab");
392 (void) strncat (one
, "", 99);
393 equal (one
, "ab", 8);
394 (void) strcpy (one
, "");
395 (void) strncat (one
, "cd", 99);
396 equal (one
, "cd", 9);
398 (void) strcpy (one
, "ab");
399 (void) strncat (one
, "cdef", 2);
400 equal (one
, "abcd", 10); /* Count-limited. */
402 (void) strncat (one
, "gh", 0);
403 equal (one
, "abcd", 11); /* Zero count. */
405 (void) strncat (one
, "gh", 2);
406 equal (one
, "abcdgh", 12); /* Count and length equal. */
408 (void) strncat (one
, "ij", (size_t)-1); /* set sign bit in count */
409 equal (one
, "abcdghij", 13);
412 char buf1
[80] __attribute__ ((aligned (16)));
413 char buf2
[32] __attribute__ ((aligned (16)));
414 for (size_t n1
= 0; n1
< 16; ++n1
)
415 for (size_t n2
= 0; n2
< 16; ++n2
)
416 for (size_t n3
= 0; n3
< 32; ++n3
)
417 for (size_t n4
= 0; n4
< 16; ++n4
)
419 size_t olderrors
= errors
;
421 memset (buf1
, 'b', sizeof (buf1
));
423 memset (buf1
+ n2
, 'a', n3
);
424 buf1
[n2
+ n3
] = '\0';
425 strcpy (buf2
+ n1
, "123");
427 check (strncat (buf1
+ n2
, buf2
+ n1
, ~((size_t) 0) - n4
)
428 == buf1
+ n2
, ntest
);
429 if (errors
== olderrors
)
430 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
433 check (buf1
[i
] == 'b', ntest
);
434 else if (i
< n2
+ n3
)
435 check (buf1
[i
] == 'a', ntest
);
436 else if (i
< n2
+ n3
+ 3)
437 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
438 else if (i
== n2
+ n3
+ 3)
439 check (buf1
[i
] == '\0', ntest
);
441 check (buf1
[i
] == 'b', ntest
);
443 if (errors
!= olderrors
)
445 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
446 n1
, n2
, n3
, n4
, buf1
[0]);
447 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
448 printf (",%02hhx", buf1
[j
]);
449 putchar_unlocked ('\n');
459 /* First test as strcmp with big counts, then test count code. */
461 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
462 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
463 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
464 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
465 check (strncmp ("abcd", "abc", 99) > 0, 5);
466 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
467 check (strncmp ("abce", "abcd", 99) > 0, 7);
468 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
469 check (strncmp ("a\203", "a\003", 2) > 0, 9);
470 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
471 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
472 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
473 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
474 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
475 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
481 /* Testing is a bit different because of odd semantics. */
483 check (strncpy (one
, "abc", 4) == one
, 1); /* Returned value. */
484 equal (one
, "abc", 2); /* Did the copy go right? */
486 (void) strcpy (one
, "abcdefgh");
487 (void) strncpy (one
, "xyz", 2);
488 equal (one
, "xycdefgh", 3); /* Copy cut by count. */
490 (void) strcpy (one
, "abcdefgh");
491 (void) strncpy (one
, "xyz", 3); /* Copy cut just before NUL. */
492 equal (one
, "xyzdefgh", 4);
494 (void) strcpy (one
, "abcdefgh");
495 (void) strncpy (one
, "xyz", 4); /* Copy just includes NUL. */
496 equal (one
, "xyz", 5);
497 equal (one
+4, "efgh", 6); /* Wrote too much? */
499 (void) strcpy (one
, "abcdefgh");
500 (void) strncpy (one
, "xyz", 5); /* Copy includes padding. */
501 equal (one
, "xyz", 7);
502 equal (one
+4, "", 8);
503 equal (one
+5, "fgh", 9);
505 (void) strcpy (one
, "abc");
506 (void) strncpy (one
, "xyz", 0); /* Zero-length copy. */
507 equal (one
, "abc", 10);
509 (void) strncpy (one
, "", 2); /* Zero-length source. */
511 equal (one
+1, "", 12);
512 equal (one
+2, "c", 13);
514 (void) strcpy (one
, "hi there");
515 (void) strncpy (two
, one
, 9);
516 equal (two
, "hi there", 14); /* Just paranoia. */
517 equal (one
, "hi there", 15); /* Stomped on source? */
524 check (strlen ("") == 0, 1); /* Empty. */
525 check (strlen ("a") == 1, 2); /* Single char. */
526 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
531 for (i
=0; i
< 0x100; i
++)
533 p
= (char *) ((uintptr_t)(buf
+ 0xff) & ~0xff) + i
;
535 strcpy (p
+3, "BAD/WRONG");
536 check (strlen (p
) == 2, 4+i
);
545 check (strnlen ("", 10) == 0, 1); /* Empty. */
546 check (strnlen ("a", 10) == 1, 2); /* Single char. */
547 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
548 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
549 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
550 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
551 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
552 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
553 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
556 for (int i
= 0; i
< 0x100; ++i
)
558 char *p
= (char *) ((uintptr_t)(buf
+ 0xff) & ~0xff) + i
;
560 strcpy (p
+ 3, "BAD/WRONG");
561 check (strnlen (p
, 100) == 2, 10 + i
);
569 check (strchr ("abcd", 'z') == NULL
, 1); /* Not found. */
570 (void) strcpy (one
, "abcd");
571 check (strchr (one
, 'c') == one
+2, 2); /* Basic test. */
572 check (strchr (one
, 'd') == one
+3, 3); /* End of string. */
573 check (strchr (one
, 'a') == one
, 4); /* Beginning. */
574 check (strchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
575 (void) strcpy (one
, "ababa");
576 check (strchr (one
, 'b') == one
+1, 6); /* Finding first. */
577 (void) strcpy (one
, "");
578 check (strchr (one
, 'b') == NULL
, 7); /* Empty string. */
579 check (strchr (one
, '\0') == one
, 8); /* NUL in empty string. */
584 for (i
=0; i
< 0x100; i
++)
586 p
= (char *) ((uintptr_t) (buf
+ 0xff) & ~0xff) + i
;
588 strcpy (p
+3, "BAD/WRONG");
589 check (strchr (p
, '/') == NULL
, 9+i
);
595 test_strchrnul (void)
599 cp
= strchrnul ((os
= "abcd"), 'z');
600 check (*cp
== '\0', 1); /* Not found. */
601 check (cp
== os
+ 4, 2);
602 (void) strcpy (one
, "abcd");
603 check (strchrnul (one
, 'c') == one
+2, 3); /* Basic test. */
604 check (strchrnul (one
, 'd') == one
+3, 4); /* End of string. */
605 check (strchrnul (one
, 'a') == one
, 5); /* Beginning. */
606 check (strchrnul (one
, '\0') == one
+4, 6); /* Finding NUL. */
607 (void) strcpy (one
, "ababa");
608 check (strchrnul (one
, 'b') == one
+1, 7); /* Finding first. */
609 (void) strcpy (one
, "");
610 check (strchrnul (one
, 'b') == one
, 8); /* Empty string. */
611 check (strchrnul (one
, '\0') == one
, 9); /* NUL in empty string. */
616 for (i
=0; i
< 0x100; i
++)
618 p
= (char *) ((uintptr_t) (buf
+ 0xff) & ~0xff) + i
;
620 strcpy (p
+3, "BAD/WRONG");
621 cp
= strchrnul (p
, '/');
622 check (*cp
== '\0', 9+2*i
);
623 check (cp
== p
+2, 10+2*i
);
629 test_rawmemchr (void)
632 (void) strcpy (one
, "abcd");
633 check (rawmemchr (one
, 'c') == one
+2, 1); /* Basic test. */
634 check (rawmemchr (one
, 'd') == one
+3, 2); /* End of string. */
635 check (rawmemchr (one
, 'a') == one
, 3); /* Beginning. */
636 check (rawmemchr (one
, '\0') == one
+4, 4); /* Finding NUL. */
637 (void) strcpy (one
, "ababa");
638 check (rawmemchr (one
, 'b') == one
+1, 5); /* Finding first. */
639 (void) strcpy (one
, "");
640 check (rawmemchr (one
, '\0') == one
, 6); /* NUL in empty string. */
645 for (i
=0; i
< 0x100; i
++)
647 p
= (char *) ((uintptr_t) (buf
+ 0xff) & ~0xff) + i
;
649 strcpy (p
+3, "BAD/WRONG");
650 check (rawmemchr (p
, 'R') == p
+8, 6+i
);
659 check (index ("abcd", 'z') == NULL
, 1); /* Not found. */
660 (void) strcpy (one
, "abcd");
661 check (index (one
, 'c') == one
+2, 2); /* Basic test. */
662 check (index (one
, 'd') == one
+3, 3); /* End of string. */
663 check (index (one
, 'a') == one
, 4); /* Beginning. */
664 check (index (one
, '\0') == one
+4, 5); /* Finding NUL. */
665 (void) strcpy (one
, "ababa");
666 check (index (one
, 'b') == one
+1, 6); /* Finding first. */
667 (void) strcpy (one
, "");
668 check (index (one
, 'b') == NULL
, 7); /* Empty string. */
669 check (index (one
, '\0') == one
, 8); /* NUL in empty string. */
676 check (strrchr ("abcd", 'z') == NULL
, 1); /* Not found. */
677 (void) strcpy (one
, "abcd");
678 check (strrchr (one
, 'c') == one
+2, 2); /* Basic test. */
679 check (strrchr (one
, 'd') == one
+3, 3); /* End of string. */
680 check (strrchr (one
, 'a') == one
, 4); /* Beginning. */
681 check (strrchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
682 (void) strcpy (one
, "ababa");
683 check (strrchr (one
, 'b') == one
+3, 6); /* Finding last. */
684 (void) strcpy (one
, "");
685 check (strrchr (one
, 'b') == NULL
, 7); /* Empty string. */
686 check (strrchr (one
, '\0') == one
, 8); /* NUL in empty string. */
691 for (i
=0; i
< 0x100; i
++)
693 p
= (char *) ((uintptr_t) (buf
+ 0xff) & ~0xff) + i
;
695 strcpy (p
+3, "BAD/WRONG");
696 check (strrchr (p
, '/') == NULL
, 9+i
);
706 check (memrchr ("abcd", 'z', 5) == NULL
, 1); /* Not found. */
707 (void) strcpy (one
, "abcd");
708 l
= strlen (one
) + 1;
709 check (memrchr (one
, 'c', l
) == one
+2, 2); /* Basic test. */
710 check (memrchr (one
, 'd', l
) == one
+3, 3); /* End of string. */
711 check (memrchr (one
, 'a', l
) == one
, 4); /* Beginning. */
712 check (memrchr (one
, '\0', l
) == one
+4, 5); /* Finding NUL. */
713 (void) strcpy (one
, "ababa");
714 l
= strlen (one
) + 1;
715 check (memrchr (one
, 'b', l
) == one
+3, 6); /* Finding last. */
716 (void) strcpy (one
, "");
717 l
= strlen (one
) + 1;
718 check (memrchr (one
, 'b', l
) == NULL
, 7); /* Empty string. */
719 check (memrchr (one
, '\0', l
) == one
, 8); /* NUL in empty string. */
721 /* now test all possible alignment and length combinations to catch
722 bugs due to unrolled loops (assuming unrolling is limited to no
723 more than 128 byte chunks: */
725 char buf
[128 + sizeof (long)];
726 long align
, len
, i
, pos
, n
= 9;
728 for (align
= 0; align
< (long) sizeof (long); ++align
) {
729 for (len
= 0; len
< (long) (sizeof (buf
) - align
); ++len
) {
730 for (i
= 0; i
< len
; ++i
)
731 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
733 for (pos
= len
- 1; pos
>= 0; --pos
) {
735 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
737 check(memrchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, n
++);
738 check(memrchr(buf
+ align
+ pos
+ 1, 'x', len
- (pos
+ 1)) == NULL
,
740 buf
[align
+ pos
] = '-';
751 check (rindex ("abcd", 'z') == NULL
, 1); /* Not found. */
752 (void) strcpy (one
, "abcd");
753 check (rindex (one
, 'c') == one
+2, 2); /* Basic test. */
754 check (rindex (one
, 'd') == one
+3, 3); /* End of string. */
755 check (rindex (one
, 'a') == one
, 4); /* Beginning. */
756 check (rindex (one
, '\0') == one
+4, 5); /* Finding NUL. */
757 (void) strcpy (one
, "ababa");
758 check (rindex (one
, 'b') == one
+3, 6); /* Finding last. */
759 (void) strcpy (one
, "");
760 check (rindex (one
, 'b') == NULL
, 7); /* Empty string. */
761 check (rindex (one
, '\0') == one
, 8); /* NUL in empty string. */
768 check(strpbrk("abcd", "z") == NULL
, 1); /* Not found. */
769 (void) strcpy(one
, "abcd");
770 check(strpbrk(one
, "c") == one
+2, 2); /* Basic test. */
771 check(strpbrk(one
, "d") == one
+3, 3); /* End of string. */
772 check(strpbrk(one
, "a") == one
, 4); /* Beginning. */
773 check(strpbrk(one
, "") == NULL
, 5); /* Empty search list. */
774 check(strpbrk(one
, "cb") == one
+1, 6); /* Multiple search. */
775 (void) strcpy(one
, "abcabdea");
776 check(strpbrk(one
, "b") == one
+1, 7); /* Finding first. */
777 check(strpbrk(one
, "cb") == one
+1, 8); /* With multiple search. */
778 check(strpbrk(one
, "db") == one
+1, 9); /* Another variant. */
779 (void) strcpy(one
, "");
780 check(strpbrk(one
, "bc") == NULL
, 10); /* Empty string. */
781 (void) strcpy(one
, "");
782 check(strpbrk(one
, "bcd") == NULL
, 11); /* Empty string. */
783 (void) strcpy(one
, "");
784 check(strpbrk(one
, "bcde") == NULL
, 12); /* Empty string. */
785 check(strpbrk(one
, "") == NULL
, 13); /* Both strings empty. */
786 (void) strcpy(one
, "abcabdea");
787 check(strpbrk(one
, "befg") == one
+1, 14); /* Finding first. */
788 check(strpbrk(one
, "cbr") == one
+1, 15); /* With multiple search. */
789 check(strpbrk(one
, "db") == one
+1, 16); /* Another variant. */
790 check(strpbrk(one
, "efgh") == one
+6, 17); /* And yet another. */
797 check(strstr("abcd", "z") == NULL
, 1); /* Not found. */
798 check(strstr("abcd", "abx") == NULL
, 2); /* Dead end. */
799 (void) strcpy(one
, "abcd");
800 check(strstr(one
, "c") == one
+2, 3); /* Basic test. */
801 check(strstr(one
, "bc") == one
+1, 4); /* Multichar. */
802 check(strstr(one
, "d") == one
+3, 5); /* End of string. */
803 check(strstr(one
, "cd") == one
+2, 6); /* Tail of string. */
804 check(strstr(one
, "abc") == one
, 7); /* Beginning. */
805 check(strstr(one
, "abcd") == one
, 8); /* Exact match. */
806 check(strstr(one
, "abcde") == NULL
, 9); /* Too long. */
807 check(strstr(one
, "de") == NULL
, 10); /* Past end. */
808 check(strstr(one
, "") == one
, 11); /* Finding empty. */
809 (void) strcpy(one
, "ababa");
810 check(strstr(one
, "ba") == one
+1, 12); /* Finding first. */
811 (void) strcpy(one
, "");
812 check(strstr(one
, "b") == NULL
, 13); /* Empty string. */
813 check(strstr(one
, "") == one
, 14); /* Empty in empty string. */
814 (void) strcpy(one
, "bcbca");
815 check(strstr(one
, "bca") == one
+2, 15); /* False start. */
816 (void) strcpy(one
, "bbbcabbca");
817 check(strstr(one
, "bbca") == one
+1, 16); /* With overlap. */
824 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
825 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
826 check(strspn("abc", "qx") == 0, 3); /* None. */
827 check(strspn("", "ab") == 0, 4); /* Null string. */
828 check(strspn("abc", "") == 0, 5); /* Null search list. */
835 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
836 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
837 check(strcspn("abc", "abc") == 0, 3); /* None. */
838 check(strcspn("", "ab") == 0, 4); /* Null string. */
839 check(strcspn("abc", "") == 3, 5); /* Null search list. */
846 (void) strcpy(one
, "first, second, third");
847 equal(strtok(one
, ", "), "first", 1); /* Basic test. */
848 equal(one
, "first", 2);
849 equal(strtok((char *)NULL
, ", "), "second", 3);
850 equal(strtok((char *)NULL
, ", "), "third", 4);
851 check(strtok((char *)NULL
, ", ") == NULL
, 5);
852 (void) strcpy(one
, ", first, ");
853 equal(strtok(one
, ", "), "first", 6); /* Extra delims, 1 tok. */
854 check(strtok((char *)NULL
, ", ") == NULL
, 7);
855 (void) strcpy(one
, "1a, 1b; 2a, 2b");
856 equal(strtok(one
, ", "), "1a", 8); /* Changing delim lists. */
857 equal(strtok((char *)NULL
, "; "), "1b", 9);
858 equal(strtok((char *)NULL
, ", "), "2a", 10);
859 (void) strcpy(two
, "x-y");
860 equal(strtok(two
, "-"), "x", 11); /* New string before done. */
861 equal(strtok((char *)NULL
, "-"), "y", 12);
862 check(strtok((char *)NULL
, "-") == NULL
, 13);
863 (void) strcpy(one
, "a,b, c,, ,d");
864 equal(strtok(one
, ", "), "a", 14); /* Different separators. */
865 equal(strtok((char *)NULL
, ", "), "b", 15);
866 equal(strtok((char *)NULL
, " ,"), "c", 16); /* Permute list too. */
867 equal(strtok((char *)NULL
, " ,"), "d", 17);
868 check(strtok((char *)NULL
, ", ") == NULL
, 18);
869 check(strtok((char *)NULL
, ", ") == NULL
, 19); /* Persistence. */
870 (void) strcpy(one
, ", ");
871 check(strtok(one
, ", ") == NULL
, 20); /* No tokens. */
872 (void) strcpy(one
, "");
873 check(strtok(one
, ", ") == NULL
, 21); /* Empty string. */
874 (void) strcpy(one
, "abc");
875 equal(strtok(one
, ", "), "abc", 22); /* No delimiters. */
876 check(strtok((char *)NULL
, ", ") == NULL
, 23);
877 (void) strcpy(one
, "abc");
878 equal(strtok(one
, ""), "abc", 24); /* Empty delimiter list. */
879 check(strtok((char *)NULL
, "") == NULL
, 25);
880 (void) strcpy(one
, "abcdefgh");
881 (void) strcpy(one
, "a,b,c");
882 equal(strtok(one
, ","), "a", 26); /* Basics again... */
883 equal(strtok((char *)NULL
, ","), "b", 27);
884 equal(strtok((char *)NULL
, ","), "c", 28);
885 check(strtok((char *)NULL
, ",") == NULL
, 29);
886 equal(one
+6, "gh", 30); /* Stomped past end? */
887 equal(one
, "a", 31); /* Stomped old tokens? */
888 equal(one
+2, "b", 32);
889 equal(one
+4, "c", 33);
896 (void) strcpy(one
, "first, second, third");
897 cp
= NULL
; /* Always initialize cp to make sure it doesn't point to some old data. */
898 equal(strtok_r(one
, ", ", &cp
), "first", 1); /* Basic test. */
899 equal(one
, "first", 2);
900 equal(strtok_r((char *)NULL
, ", ", &cp
), "second", 3);
901 equal(strtok_r((char *)NULL
, ", ", &cp
), "third", 4);
902 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 5);
903 (void) strcpy(one
, ", first, ");
905 equal(strtok_r(one
, ", ", &cp
), "first", 6); /* Extra delims, 1 tok. */
906 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 7);
907 (void) strcpy(one
, "1a, 1b; 2a, 2b");
909 equal(strtok_r(one
, ", ", &cp
), "1a", 8); /* Changing delim lists. */
910 equal(strtok_r((char *)NULL
, "; ", &cp
), "1b", 9);
911 equal(strtok_r((char *)NULL
, ", ", &cp
), "2a", 10);
912 (void) strcpy(two
, "x-y");
914 equal(strtok_r(two
, "-", &cp
), "x", 11); /* New string before done. */
915 equal(strtok_r((char *)NULL
, "-", &cp
), "y", 12);
916 check(strtok_r((char *)NULL
, "-", &cp
) == NULL
, 13);
917 (void) strcpy(one
, "a,b, c,, ,d");
919 equal(strtok_r(one
, ", ", &cp
), "a", 14); /* Different separators. */
920 equal(strtok_r((char *)NULL
, ", ", &cp
), "b", 15);
921 equal(strtok_r((char *)NULL
, " ,", &cp
), "c", 16); /* Permute list too. */
922 equal(strtok_r((char *)NULL
, " ,", &cp
), "d", 17);
923 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 18);
924 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 19); /* Persistence. */
925 (void) strcpy(one
, ", ");
927 check(strtok_r(one
, ", ", &cp
) == NULL
, 20); /* No tokens. */
928 (void) strcpy(one
, "");
930 check(strtok_r(one
, ", ", &cp
) == NULL
, 21); /* Empty string. */
931 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 22); /* Persistence. */
932 (void) strcpy(one
, "abc");
934 equal(strtok_r(one
, ", ", &cp
), "abc", 23); /* No delimiters. */
935 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 24);
936 (void) strcpy(one
, "abc");
938 equal(strtok_r(one
, "", &cp
), "abc", 25); /* Empty delimiter list. */
939 check(strtok_r((char *)NULL
, "", &cp
) == NULL
, 26);
940 (void) strcpy(one
, "abcdefgh");
941 (void) strcpy(one
, "a,b,c");
943 equal(strtok_r(one
, ",", &cp
), "a", 27); /* Basics again... */
944 equal(strtok_r((char *)NULL
, ",", &cp
), "b", 28);
945 equal(strtok_r((char *)NULL
, ",", &cp
), "c", 29);
946 check(strtok_r((char *)NULL
, ",", &cp
) == NULL
, 30);
947 equal(one
+6, "gh", 31); /* Stomped past end? */
948 equal(one
, "a", 32); /* Stomped old tokens? */
949 equal(one
+2, "b", 33);
950 equal(one
+4, "c", 34);
953 check (strtok_r (one
, ":", &cp
) == NULL
, 35); /* Must store pointer in cp. */
954 check (strtok_r (NULL
, ":", &cp
) == NULL
, 36);
962 cp
= strcpy(one
, "first, second, third");
963 equal(strsep(&cp
, ", "), "first", 1); /* Basic test. */
964 equal(one
, "first", 2);
965 equal(strsep(&cp
, ", "), "", 3);
966 equal(strsep(&cp
, ", "), "second", 4);
967 equal(strsep(&cp
, ", "), "", 5);
968 equal(strsep(&cp
, ", "), "third", 6);
969 check(strsep(&cp
, ", ") == NULL
, 7);
970 cp
= strcpy(one
, ", first, ");
971 equal(strsep(&cp
, ", "), "", 8);
972 equal(strsep(&cp
, ", "), "", 9);
973 equal(strsep(&cp
, ", "), "first", 10); /* Extra delims, 1 tok. */
974 equal(strsep(&cp
, ", "), "", 11);
975 equal(strsep(&cp
, ", "), "", 12);
976 check(strsep(&cp
, ", ") == NULL
, 13);
977 cp
= strcpy(one
, "1a, 1b; 2a, 2b");
978 equal(strsep(&cp
, ", "), "1a", 14); /* Changing delim lists. */
979 equal(strsep(&cp
, ", "), "", 15);
980 equal(strsep(&cp
, "; "), "1b", 16);
981 equal(strsep(&cp
, ", "), "", 17);
982 equal(strsep(&cp
, ", "), "2a", 18);
983 cp
= strcpy(two
, "x-y");
984 equal(strsep(&cp
, "-"), "x", 19); /* New string before done. */
985 equal(strsep(&cp
, "-"), "y", 20);
986 check(strsep(&cp
, "-") == NULL
, 21);
987 cp
= strcpy(one
, "a,b, c,, ,d ");
988 equal(strsep(&cp
, ", "), "a", 22); /* Different separators. */
989 equal(strsep(&cp
, ", "), "b", 23);
990 equal(strsep(&cp
, " ,"), "", 24);
991 equal(strsep(&cp
, " ,"), "c", 25); /* Permute list too. */
992 equal(strsep(&cp
, " ,"), "", 26);
993 equal(strsep(&cp
, " ,"), "", 27);
994 equal(strsep(&cp
, " ,"), "", 28);
995 equal(strsep(&cp
, " ,"), "d", 29);
996 equal(strsep(&cp
, " ,"), "", 30);
997 check(strsep(&cp
, ", ") == NULL
, 31);
998 check(strsep(&cp
, ", ") == NULL
, 32); /* Persistence. */
999 cp
= strcpy(one
, ", ");
1000 equal(strsep(&cp
, ", "), "", 33);
1001 equal(strsep(&cp
, ", "), "", 34);
1002 equal(strsep(&cp
, ", "), "", 35);
1003 check(strsep(&cp
, ", ") == NULL
, 36); /* No tokens. */
1004 cp
= strcpy(one
, "");
1005 equal(strsep(&cp
, ", "), "", 37);
1006 check(strsep(&cp
, ", ") == NULL
, 38); /* Empty string. */
1007 cp
= strcpy(one
, "abc");
1008 equal(strsep(&cp
, ", "), "abc", 39); /* No delimiters. */
1009 check(strsep(&cp
, ", ") == NULL
, 40);
1010 cp
= strcpy(one
, "abc");
1011 equal(strsep(&cp
, ""), "abc", 41); /* Empty delimiter list. */
1012 check(strsep(&cp
, "") == NULL
, 42);
1013 (void) strcpy(one
, "abcdefgh");
1014 cp
= strcpy(one
, "a,b,c");
1015 equal(strsep(&cp
, ","), "a", 43); /* Basics again... */
1016 equal(strsep(&cp
, ","), "b", 44);
1017 equal(strsep(&cp
, ","), "c", 45);
1018 check(strsep(&cp
, ",") == NULL
, 46);
1019 equal(one
+6, "gh", 47); /* Stomped past end? */
1020 equal(one
, "a", 48); /* Stomped old tokens? */
1021 equal(one
+2, "b", 49);
1022 equal(one
+4, "c", 50);
1025 char text
[] = "This,is,a,test";
1026 char *list
= strdupa (text
);
1027 equal (strsep (&list
, ","), "This", 51);
1028 equal (strsep (&list
, ","), "is", 52);
1029 equal (strsep (&list
, ","), "a", 53);
1030 equal (strsep (&list
, ","), "test", 54);
1031 check (strsep (&list
, ",") == NULL
, 55);
1034 cp
= strcpy(one
, "a,b, c,, ,d,");
1035 equal(strsep(&cp
, ","), "a", 56); /* Different separators. */
1036 equal(strsep(&cp
, ","), "b", 57);
1037 equal(strsep(&cp
, ","), " c", 58); /* Permute list too. */
1038 equal(strsep(&cp
, ","), "", 59);
1039 equal(strsep(&cp
, ","), " ", 60);
1040 equal(strsep(&cp
, ","), "d", 61);
1041 equal(strsep(&cp
, ","), "", 62);
1042 check(strsep(&cp
, ",") == NULL
, 63);
1043 check(strsep(&cp
, ",") == NULL
, 64); /* Persistence. */
1045 cp
= strcpy(one
, "a,b, c,, ,d,");
1046 equal(strsep(&cp
, "xy,"), "a", 65); /* Different separators. */
1047 equal(strsep(&cp
, "x,y"), "b", 66);
1048 equal(strsep(&cp
, ",xy"), " c", 67); /* Permute list too. */
1049 equal(strsep(&cp
, "xy,"), "", 68);
1050 equal(strsep(&cp
, "x,y"), " ", 69);
1051 equal(strsep(&cp
, ",xy"), "d", 70);
1052 equal(strsep(&cp
, "xy,"), "", 71);
1053 check(strsep(&cp
, "x,y") == NULL
, 72);
1054 check(strsep(&cp
, ",xy") == NULL
, 73); /* Persistence. */
1056 cp
= strcpy(one
, "ABC");
1058 equal(strsep(&cp
, "C"), "AB", 74); /* Access beyond NUL. */
1059 ptr
= strsep(&cp
, ":");
1061 check(ptr
== one
+ 3, 76);
1062 check(cp
== NULL
, 77);
1064 cp
= strcpy(one
, "ABC");
1066 equal(strsep(&cp
, "CD"), "AB", 78); /* Access beyond NUL. */
1067 ptr
= strsep(&cp
, ":.");
1069 check(ptr
== one
+ 3, 80);
1071 cp
= strcpy(one
, "ABC"); /* No token in string. */
1072 equal(strsep(&cp
, ","), "ABC", 81);
1073 check(cp
== NULL
, 82);
1075 *one
= '\0'; /* Empty string. */
1077 ptr
= strsep(&cp
, ",");
1079 check(ptr
== one
, 84);
1080 check(cp
== NULL
, 85);
1082 *one
= '\0'; /* Empty string and no token. */
1084 ptr
= strsep(&cp
, "");
1086 check(ptr
== one
, 87);
1087 check(cp
== NULL
, 88);
1098 check(memcmp("a", "a", 1) == 0, cnt
++); /* Identity. */
1099 check(memcmp("abc", "abc", 3) == 0, cnt
++); /* Multicharacter. */
1100 check(memcmp("abcd", "abcf", 4) < 0, cnt
++); /* Honestly unequal. */
1101 check(memcmp("abcf", "abcd", 4) > 0, cnt
++);
1102 check(memcmp("alph", "cold", 4) < 0, cnt
++);
1103 check(memcmp("a\203", "a\003", 2) > 0, cnt
++);
1104 check(memcmp("a\003", "a\203", 2) < 0, cnt
++);
1105 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt
++);
1106 check(memcmp("abc\203", "abc\003", 4) > 0, cnt
++);
1107 check(memcmp("abc\003", "abc\203", 4) < 0, cnt
++);
1108 check(memcmp("abcf", "abcd", 3) == 0, cnt
++); /* Count limited. */
1109 check(memcmp("abc", "def", 0) == 0, cnt
++); /* Zero count. */
1110 /* Comparisons with shifting 4-byte boundaries. */
1111 for (int i
= 0; i
< 4; ++i
)
1115 memcpy(a
, "--------11112222", 16);
1116 memcpy(b
, "--------33334444", 16);
1117 check(memcmp(b
, a
, 16) > 0, cnt
++);
1118 check(memcmp(a
, b
, 16) < 0, cnt
++);
1126 check(memchr("abcd", 'z', 4) == NULL
, 1); /* Not found. */
1127 (void) strcpy(one
, "abcd");
1128 check(memchr(one
, 'c', 4) == one
+2, 2); /* Basic test. */
1129 check(memchr(one
, ~0xff|'c', 4) == one
+2, 2); /* ignore highorder bits. */
1130 check(memchr(one
, 'd', 4) == one
+3, 3); /* End of string. */
1131 check(memchr(one
, 'a', 4) == one
, 4); /* Beginning. */
1132 check(memchr(one
, '\0', 5) == one
+4, 5); /* Finding NUL. */
1133 (void) strcpy(one
, "ababa");
1134 check(memchr(one
, 'b', 5) == one
+1, 6); /* Finding first. */
1135 check(memchr(one
, 'b', 0) == NULL
, 7); /* Zero count. */
1136 check(memchr(one
, 'a', 1) == one
, 8); /* Singleton case. */
1137 (void) strcpy(one
, "a\203b");
1138 check(memchr(one
, 0203, 3) == one
+1, 9); /* Unsignedness. */
1140 /* now test all possible alignment and length combinations to catch
1141 bugs due to unrolled loops (assuming unrolling is limited to no
1142 more than 128 byte chunks: */
1144 char buf
[128 + sizeof (long)];
1145 long align
, len
, i
, pos
;
1147 for (align
= 0; align
< (long) sizeof (long); ++align
) {
1148 for (len
= 0; len
< (long) (sizeof (buf
) - align
); ++len
) {
1149 for (i
= 0; i
< len
; ++i
) {
1150 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
1152 for (pos
= 0; pos
< len
; ++pos
) {
1154 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
1156 check(memchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, 10);
1157 check(memchr(buf
+ align
, 'x', pos
) == NULL
, 11);
1158 buf
[align
+ pos
] = '-';
1170 check(memcpy(one
, "abc", 4) == one
, 1); /* Returned value. */
1171 equal(one
, "abc", 2); /* Did the copy go right? */
1173 (void) strcpy(one
, "abcdefgh");
1174 (void) memcpy(one
+1, "xyz", 2);
1175 equal(one
, "axydefgh", 3); /* Basic test. */
1177 (void) strcpy(one
, "abc");
1178 (void) memcpy(one
, "xyz", 0);
1179 equal(one
, "abc", 4); /* Zero-length copy. */
1181 (void) strcpy(one
, "hi there");
1182 (void) strcpy(two
, "foo");
1183 (void) memcpy(two
, one
, 9);
1184 equal(two
, "hi there", 5); /* Just paranoia. */
1185 equal(one
, "hi there", 6); /* Stomped on source? */
1187 for (i
= 0; i
< 16; i
++)
1189 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1191 check (memcpy (one
+ i
, "hi there", 9) == one
+ i
,
1192 7 + (i
* 6)); /* Unaligned destination. */
1193 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1194 equal (one
+ i
, "hi there", 9 + (i
* 6));
1195 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1196 check (memcpy (two
, one
+ i
, 9) == two
,
1197 11 + (i
* 6)); /* Unaligned source. */
1198 equal (two
, "hi there", 12 + (i
* 6));
1207 check(mempcpy(one
, "abc", 4) == one
+ 4, 1); /* Returned value. */
1208 equal(one
, "abc", 2); /* Did the copy go right? */
1210 (void) strcpy(one
, "abcdefgh");
1211 (void) mempcpy(one
+1, "xyz", 2);
1212 equal(one
, "axydefgh", 3); /* Basic test. */
1214 (void) strcpy(one
, "abc");
1215 (void) mempcpy(one
, "xyz", 0);
1216 equal(one
, "abc", 4); /* Zero-length copy. */
1218 (void) strcpy(one
, "hi there");
1219 (void) strcpy(two
, "foo");
1220 (void) mempcpy(two
, one
, 9);
1221 equal(two
, "hi there", 5); /* Just paranoia. */
1222 equal(one
, "hi there", 6); /* Stomped on source? */
1224 for (i
= 0; i
< 16; i
++)
1226 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1228 check (mempcpy (one
+ i
, "hi there", 9) == one
+ i
+ 9,
1229 7 + (i
* 6)); /* Unaligned destination. */
1230 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1231 equal (one
+ i
, "hi there", 9 + (i
* 6));
1232 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1233 check (mempcpy (two
, one
+ i
, 9) == two
+ 9,
1234 11 + (i
* 6)); /* Unaligned source. */
1235 equal (two
, "hi there", 12 + (i
* 6));
1243 check(memmove(one
, "abc", 4) == one
, 1); /* Returned value. */
1244 equal(one
, "abc", 2); /* Did the copy go right? */
1246 (void) strcpy(one
, "abcdefgh");
1247 (void) memmove(one
+1, "xyz", 2);
1248 equal(one
, "axydefgh", 3); /* Basic test. */
1250 (void) strcpy(one
, "abc");
1251 (void) memmove(one
, "xyz", 0);
1252 equal(one
, "abc", 4); /* Zero-length copy. */
1254 (void) strcpy(one
, "hi there");
1255 (void) strcpy(two
, "foo");
1256 (void) memmove(two
, one
, 9);
1257 equal(two
, "hi there", 5); /* Just paranoia. */
1258 equal(one
, "hi there", 6); /* Stomped on source? */
1260 (void) strcpy(one
, "abcdefgh");
1261 (void) memmove(one
+1, one
, 9);
1262 equal(one
, "aabcdefgh", 7); /* Overlap, right-to-left. */
1264 (void) strcpy(one
, "abcdefgh");
1265 (void) memmove(one
+1, one
+2, 7);
1266 equal(one
, "acdefgh", 8); /* Overlap, left-to-right. */
1268 (void) strcpy(one
, "abcdefgh");
1269 (void) memmove(one
, one
, 9);
1270 equal(one
, "abcdefgh", 9); /* 100% overlap. */
1276 /* First test like memcpy, then the search part The SVID, the only
1277 place where memccpy is mentioned, says overlap might fail, so we
1278 don't try it. Besides, it's hard to see the rationale for a
1279 non-left-to-right memccpy. */
1281 check(memccpy(one
, "abc", 'q', 4) == NULL
, 1); /* Returned value. */
1282 equal(one
, "abc", 2); /* Did the copy go right? */
1284 (void) strcpy(one
, "abcdefgh");
1285 (void) memccpy(one
+1, "xyz", 'q', 2);
1286 equal(one
, "axydefgh", 3); /* Basic test. */
1288 (void) strcpy(one
, "abc");
1289 (void) memccpy(one
, "xyz", 'q', 0);
1290 equal(one
, "abc", 4); /* Zero-length copy. */
1292 (void) strcpy(one
, "hi there");
1293 (void) strcpy(two
, "foo");
1294 (void) memccpy(two
, one
, 'q', 9);
1295 equal(two
, "hi there", 5); /* Just paranoia. */
1296 equal(one
, "hi there", 6); /* Stomped on source? */
1298 (void) strcpy(one
, "abcdefgh");
1299 (void) strcpy(two
, "horsefeathers");
1300 check(memccpy(two
, one
, 'f', 9) == two
+6, 7); /* Returned value. */
1301 equal(one
, "abcdefgh", 8); /* Source intact? */
1302 equal(two
, "abcdefeathers", 9); /* Copy correct? */
1304 (void) strcpy(one
, "abcd");
1305 (void) strcpy(two
, "bumblebee");
1306 check(memccpy(two
, one
, 'a', 4) == two
+1, 10); /* First char. */
1307 equal(two
, "aumblebee", 11);
1308 check(memccpy(two
, one
, 'd', 4) == two
+4, 12); /* Last char. */
1309 equal(two
, "abcdlebee", 13);
1310 (void) strcpy(one
, "xyz");
1311 check(memccpy(two
, one
, 'x', 1) == two
+1, 14); /* Singleton. */
1312 equal(two
, "xbcdlebee", 15);
1321 (void) strcpy(one
, "abcdefgh");
1322 check(memset(one
+1, 'x', 3) == one
+1, 1); /* Return value. */
1323 equal(one
, "axxxefgh", 2); /* Basic test. */
1325 (void) memset(one
+2, 'y', 0);
1326 equal(one
, "axxxefgh", 3); /* Zero-length set. */
1328 (void) memset(one
+5, 0, 1);
1329 equal(one
, "axxxe", 4); /* Zero fill. */
1330 equal(one
+6, "gh", 5); /* And the leftover. */
1332 (void) memset(one
+2, 010045, 1);
1333 equal(one
, "ax\045xe", 6); /* Unsigned char convert. */
1335 /* Non-8bit fill character. */
1336 memset (one
, 0x101, sizeof (one
));
1337 for (i
= 0; i
< (int) sizeof (one
); ++i
)
1338 check (one
[i
] == '\01', 7);
1340 /* Test for more complex versions of memset, for all alignments and
1341 lengths up to 256. This test takes a little while, perhaps it should
1349 for (i
= 0; i
< 512; i
++)
1351 for (c
= 0; c
<= 'y'; c
+= 'y') /* check for memset(,0,) and
1353 for (j
= 0; j
< 256; j
++)
1354 for (i
= 0; i
< 256; i
++)
1356 memset (data
+ i
, c
, j
);
1357 for (k
= 0; k
< i
; k
++)
1360 for (k
= i
; k
< i
+j
; k
++)
1366 for (k
= i
+j
; k
< 512; k
++)
1372 check (0, 8 + i
+ j
* 256 + (c
!= 0) * 256 * 256);
1380 /* Much like memcpy. Berklix manual is silent about overlap, so
1383 (void) bcopy("abc", one
, 4);
1384 equal(one
, "abc", 1); /* Simple copy. */
1386 (void) strcpy(one
, "abcdefgh");
1387 (void) bcopy("xyz", one
+1, 2);
1388 equal(one
, "axydefgh", 2); /* Basic test. */
1390 (void) strcpy(one
, "abc");
1391 (void) bcopy("xyz", one
, 0);
1392 equal(one
, "abc", 3); /* Zero-length copy. */
1394 (void) strcpy(one
, "hi there");
1395 (void) strcpy(two
, "foo");
1396 (void) bcopy(one
, two
, 9);
1397 equal(two
, "hi there", 4); /* Just paranoia. */
1398 equal(one
, "hi there", 5); /* Stomped on source? */
1405 (void) strcpy(one
, "abcdef");
1407 equal(one
, "ab", 1); /* Basic test. */
1408 equal(one
+3, "", 2);
1409 equal(one
+4, "ef", 3);
1411 (void) strcpy(one
, "abcdef");
1413 equal(one
, "abcdef", 4); /* Zero-length copy. */
1421 p
= strndup("abcdef", 12);
1422 check(p
!= NULL
, 1);
1425 equal(p
, "abcdef", 2);
1426 q
= strndup(p
+ 1, 2);
1427 check(q
!= NULL
, 3);
1433 p
= strndup("abc def", 3);
1434 check(p
!= NULL
, 5);
1444 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1445 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1446 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1447 check(bcmp("abce", "abcd", 4) != 0, 4);
1448 check(bcmp("alph", "beta", 4) != 0, 5);
1449 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1450 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1454 test_memcmpeq (void)
1457 check (__memcmpeq ("a", "a", 1) == 0, 1); /* Identity. */
1458 check (__memcmpeq ("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1459 check (__memcmpeq ("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1460 check (__memcmpeq ("abce", "abcd", 4) != 0, 4);
1461 check (__memcmpeq ("alph", "beta", 4) != 0, 5);
1462 check (__memcmpeq ("abce", "abcd", 3) == 0, 6); /* Count limited. */
1463 check (__memcmpeq ("abc", "def", 0) == 0, 8); /* Zero count. */
1467 test_strerror (void)
1470 check(strerror(EDOM
) != 0, 1);
1471 check(strerror(ERANGE
) != 0, 2);
1472 check(strerror(ENOENT
) != 0, 3);
1476 test_strcasecmp (void)
1479 /* Note that the locale is "C". */
1480 check(strcasecmp("a", "a") == 0, 1);
1481 check(strcasecmp("a", "A") == 0, 2);
1482 check(strcasecmp("A", "a") == 0, 3);
1483 check(strcasecmp("a", "b") < 0, 4);
1484 check(strcasecmp("c", "b") > 0, 5);
1485 check(strcasecmp("abc", "AbC") == 0, 6);
1486 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1487 check(strcasecmp("", "0123456789") < 0, 8);
1488 check(strcasecmp("AbC", "") > 0, 9);
1489 check(strcasecmp("AbC", "A") > 0, 10);
1490 check(strcasecmp("AbC", "Ab") > 0, 11);
1491 check(strcasecmp("AbC", "ab") > 0, 12);
1495 test_strncasecmp (void)
1498 /* Note that the locale is "C". */
1499 check(strncasecmp("a", "a", 5) == 0, 1);
1500 check(strncasecmp("a", "A", 5) == 0, 2);
1501 check(strncasecmp("A", "a", 5) == 0, 3);
1502 check(strncasecmp("a", "b", 5) < 0, 4);
1503 check(strncasecmp("c", "b", 5) > 0, 5);
1504 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1505 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1506 check(strncasecmp("", "0123456789", 10) < 0, 8);
1507 check(strncasecmp("AbC", "", 5) > 0, 9);
1508 check(strncasecmp("AbC", "A", 5) > 0, 10);
1509 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1510 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1511 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1512 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1513 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1514 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1515 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1516 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1517 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1518 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1526 /* Test strcmp first because we use it to test other things. */
1529 /* Test strcpy next because we need it to set up other tests. */
1532 /* A closely related function is stpcpy. */
1565 /* index - just like strchr. */
1574 /* rindex - just like strrchr. */
1577 /* strpbrk - somewhat like strchr. */
1580 /* strstr - somewhat like strchr. */
1589 /* strtok - the hard one. */
1604 /* memcpy - need not work for overlap. */
1607 /* memmove - must work on overlap. */
1625 /* bcmp - somewhat like memcmp. */
1628 /* __memcmpeq - somewhat like memcmp. */
1634 /* strerror - VERY system-dependent. */
1637 /* strcasecmp. Without locale dependencies. */
1640 /* strncasecmp. Without locale dependencies. */
1641 test_strncasecmp ();
1645 status
= EXIT_SUCCESS
;
1650 status
= EXIT_FAILURE
;
1651 printf("%zd errors.\n", errors
);