1 /* Tester for string functions.
2 Copyright (C) 1995-2022 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
35 #include <libc-diag.h>
37 /* This file tests a range of corner cases of string functions,
38 including cases where truncation occurs or where sizes specified
39 are larger than the actual buffers, which result in various
41 DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
42 DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args");
43 #if __GNUC_PREREQ (7, 0)
44 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wrestrict");
45 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
47 #if __GNUC_PREREQ (8, 0)
48 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
50 #if __GNUC_PREREQ (11, 0)
51 DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
55 #define STREQ(a, b) (strcmp((a), (b)) == 0)
57 const char *it
= "<UNSET>"; /* Routine name for message routines. */
60 /* Complain if condition is not true. */
62 check (int thing
, int number
)
66 printf ("%s flunked test %d\n", it
, number
);
71 /* Complain if first two args don't strcmp as equal. */
73 equal (const char *a
, const char *b
, int number
)
75 check (a
!= NULL
&& b
!= NULL
&& STREQ (a
, b
), number
);
86 check (strcmp ("", "") == 0, 1); /* Trivial case. */
87 check (strcmp ("a", "a") == 0, 2); /* Identity. */
88 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
89 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
90 check (strcmp ("abcd", "abc") > 0, 5);
91 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
92 check (strcmp ("abce", "abcd") > 0, 7);
93 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
94 check (strcmp ("a\203", "a\003") > 0, 9);
97 char buf1
[0x40], buf2
[0x40];
99 for (i
=0; i
< 0x10; i
++)
100 for (j
= 0; j
< 0x10; j
++)
103 for (k
= 0; k
< 0x3f; k
++)
105 buf1
[k
] = '0' ^ (k
& 4);
106 buf2
[k
] = '4' ^ (k
& 4);
108 buf1
[i
] = buf1
[0x3f] = 0;
109 buf2
[j
] = buf2
[0x3f] = 0;
110 for (k
= 0; k
< 0xf; k
++)
112 int cnum
= 0x10+0x10*k
+0x100*j
+0x1000*i
;
113 check (strcmp (buf1
+i
,buf2
+j
) == 0, cnum
);
114 buf1
[i
+k
] = 'A' + i
+ k
;
116 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+1);
117 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+2);
118 buf2
[j
+k
] = 'B' + i
+ k
;
120 check (strcmp (buf1
+i
,buf2
+j
) < 0, cnum
+3);
121 check (strcmp (buf2
+j
,buf1
+i
) > 0, cnum
+4);
122 buf2
[j
+k
] = 'A' + i
+ k
;
123 buf1
[i
] = 'A' + i
+ 0x80;
124 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+5);
125 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+6);
132 #define SIMPLE_COPY(fn, n, str, ntest) \
136 for (__n = 0; __n < (int) sizeof (one); ++__n) \
139 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
140 check (*cp == '0' + (n % 10), ntest); \
141 check (*cp == '\0', ntest); \
149 check (strcpy (one
, "abcd") == one
, 1); /* Returned value. */
150 equal (one
, "abcd", 2); /* Basic test. */
152 (void) strcpy (one
, "x");
153 equal (one
, "x", 3); /* Writeover. */
154 equal (one
+2, "cd", 4); /* Wrote too much? */
156 (void) strcpy (two
, "hi there");
157 (void) strcpy (one
, two
);
158 equal (one
, "hi there", 5); /* Basic test encore. */
159 equal (two
, "hi there", 6); /* Stomped on source? */
161 (void) strcpy (one
, "");
162 equal (one
, "", 7); /* Boundary condition. */
164 for (i
= 0; i
< 16; i
++)
166 (void) strcpy (one
+ i
, "hi there"); /* Unaligned destination. */
167 equal (one
+ i
, "hi there", 8 + (i
* 2));
168 (void) strcpy (two
, one
+ i
); /* Unaligned source. */
169 equal (two
, "hi there", 9 + (i
* 2));
172 SIMPLE_COPY(strcpy
, 0, "", 41);
173 SIMPLE_COPY(strcpy
, 1, "1", 42);
174 SIMPLE_COPY(strcpy
, 2, "22", 43);
175 SIMPLE_COPY(strcpy
, 3, "333", 44);
176 SIMPLE_COPY(strcpy
, 4, "4444", 45);
177 SIMPLE_COPY(strcpy
, 5, "55555", 46);
178 SIMPLE_COPY(strcpy
, 6, "666666", 47);
179 SIMPLE_COPY(strcpy
, 7, "7777777", 48);
180 SIMPLE_COPY(strcpy
, 8, "88888888", 49);
181 SIMPLE_COPY(strcpy
, 9, "999999999", 50);
182 SIMPLE_COPY(strcpy
, 10, "0000000000", 51);
183 SIMPLE_COPY(strcpy
, 11, "11111111111", 52);
184 SIMPLE_COPY(strcpy
, 12, "222222222222", 53);
185 SIMPLE_COPY(strcpy
, 13, "3333333333333", 54);
186 SIMPLE_COPY(strcpy
, 14, "44444444444444", 55);
187 SIMPLE_COPY(strcpy
, 15, "555555555555555", 56);
188 SIMPLE_COPY(strcpy
, 16, "6666666666666666", 57);
190 /* Simple test using implicitly coerced `void *' arguments. */
191 const void *src
= "frobozz";
193 check (strcpy (dst
, src
) == dst
, 1);
194 equal (dst
, "frobozz", 2);
201 check ((stpcpy (one
, "a") - one
) == 1, 1);
204 check ((stpcpy (one
, "ab") - one
) == 2, 3);
205 equal (one
, "ab", 4);
207 check ((stpcpy (one
, "abc") - one
) == 3, 5);
208 equal (one
, "abc", 6);
210 check ((stpcpy (one
, "abcd") - one
) == 4, 7);
211 equal (one
, "abcd", 8);
213 check ((stpcpy (one
, "abcde") - one
) == 5, 9);
214 equal (one
, "abcde", 10);
216 check ((stpcpy (one
, "abcdef") - one
) == 6, 11);
217 equal (one
, "abcdef", 12);
219 check ((stpcpy (one
, "abcdefg") - one
) == 7, 13);
220 equal (one
, "abcdefg", 14);
222 check ((stpcpy (one
, "abcdefgh") - one
) == 8, 15);
223 equal (one
, "abcdefgh", 16);
225 check ((stpcpy (one
, "abcdefghi") - one
) == 9, 17);
226 equal (one
, "abcdefghi", 18);
228 check ((stpcpy (one
, "x") - one
) == 1, 19);
229 equal (one
, "x", 20); /* Writeover. */
230 equal (one
+2, "cdefghi", 21); /* Wrote too much? */
232 check ((stpcpy (one
, "xx") - one
) == 2, 22);
233 equal (one
, "xx", 23); /* Writeover. */
234 equal (one
+3, "defghi", 24); /* Wrote too much? */
236 check ((stpcpy (one
, "xxx") - one
) == 3, 25);
237 equal (one
, "xxx", 26); /* Writeover. */
238 equal (one
+4, "efghi", 27); /* Wrote too much? */
240 check ((stpcpy (one
, "xxxx") - one
) == 4, 28);
241 equal (one
, "xxxx", 29); /* Writeover. */
242 equal (one
+5, "fghi", 30); /* Wrote too much? */
244 check ((stpcpy (one
, "xxxxx") - one
) == 5, 31);
245 equal (one
, "xxxxx", 32); /* Writeover. */
246 equal (one
+6, "ghi", 33); /* Wrote too much? */
248 check ((stpcpy (one
, "xxxxxx") - one
) == 6, 34);
249 equal (one
, "xxxxxx", 35); /* Writeover. */
250 equal (one
+7, "hi", 36); /* Wrote too much? */
252 check ((stpcpy (one
, "xxxxxxx") - one
) == 7, 37);
253 equal (one
, "xxxxxxx", 38); /* Writeover. */
254 equal (one
+8, "i", 39); /* Wrote too much? */
256 check ((stpcpy (stpcpy (stpcpy (one
, "a"), "b"), "c") - one
) == 3, 40);
257 equal (one
, "abc", 41);
258 equal (one
+ 4, "xxx", 42);
260 SIMPLE_COPY(stpcpy
, 0, "", 43);
261 SIMPLE_COPY(stpcpy
, 1, "1", 44);
262 SIMPLE_COPY(stpcpy
, 2, "22", 45);
263 SIMPLE_COPY(stpcpy
, 3, "333", 46);
264 SIMPLE_COPY(stpcpy
, 4, "4444", 47);
265 SIMPLE_COPY(stpcpy
, 5, "55555", 48);
266 SIMPLE_COPY(stpcpy
, 6, "666666", 49);
267 SIMPLE_COPY(stpcpy
, 7, "7777777", 50);
268 SIMPLE_COPY(stpcpy
, 8, "88888888", 51);
269 SIMPLE_COPY(stpcpy
, 9, "999999999", 52);
270 SIMPLE_COPY(stpcpy
, 10, "0000000000", 53);
271 SIMPLE_COPY(stpcpy
, 11, "11111111111", 54);
272 SIMPLE_COPY(stpcpy
, 12, "222222222222", 55);
273 SIMPLE_COPY(stpcpy
, 13, "3333333333333", 56);
274 SIMPLE_COPY(stpcpy
, 14, "44444444444444", 57);
275 SIMPLE_COPY(stpcpy
, 15, "555555555555555", 58);
276 SIMPLE_COPY(stpcpy
, 16, "6666666666666666", 59);
283 memset (one
, 'x', sizeof (one
));
284 check (stpncpy (one
, "abc", 2) == one
+ 2, 1);
285 check (stpncpy (one
, "abc", 3) == one
+ 3, 2);
286 check (stpncpy (one
, "abc", 4) == one
+ 3, 3);
287 check (one
[3] == '\0' && one
[4] == 'x', 4);
288 check (stpncpy (one
, "abcd", 5) == one
+ 4, 5);
289 check (one
[4] == '\0' && one
[5] == 'x', 6);
290 check (stpncpy (one
, "abcd", 6) == one
+ 4, 7);
291 check (one
[4] == '\0' && one
[5] == '\0' && one
[6] == 'x', 8);
298 (void) strcpy (one
, "ijk");
299 check (strcat (one
, "lmn") == one
, 1); /* Returned value. */
300 equal (one
, "ijklmn", 2); /* Basic test. */
302 (void) strcpy (one
, "x");
303 (void) strcat (one
, "yz");
304 equal (one
, "xyz", 3); /* Writeover. */
305 equal (one
+4, "mn", 4); /* Wrote too much? */
307 (void) strcpy (one
, "gh");
308 (void) strcpy (two
, "ef");
309 (void) strcat (one
, two
);
310 equal (one
, "ghef", 5); /* Basic test encore. */
311 equal (two
, "ef", 6); /* Stomped on source? */
313 (void) strcpy (one
, "");
314 (void) strcat (one
, "");
315 equal (one
, "", 7); /* Boundary conditions. */
316 (void) strcpy (one
, "ab");
317 (void) strcat (one
, "");
318 equal (one
, "ab", 8);
319 (void) strcpy (one
, "");
320 (void) strcat (one
, "cd");
321 equal (one
, "cd", 9);
324 char buf1
[80] __attribute__ ((aligned (16)));
325 char buf2
[32] __attribute__ ((aligned (16)));
326 for (size_t n1
= 0; n1
< 16; ++n1
)
327 for (size_t n2
= 0; n2
< 16; ++n2
)
328 for (size_t n3
= 0; n3
< 32; ++n3
)
330 size_t olderrors
= errors
;
332 memset (buf1
, 'b', sizeof (buf1
));
334 memset (buf1
+ n2
, 'a', n3
);
335 buf1
[n2
+ n3
] = '\0';
336 strcpy (buf2
+ n1
, "123");
338 check (strcat (buf1
+ n2
, buf2
+ n1
) == buf1
+ n2
, ntest
);
339 if (errors
== olderrors
)
340 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
343 check (buf1
[i
] == 'b', ntest
);
344 else if (i
< n2
+ n3
)
345 check (buf1
[i
] == 'a', ntest
);
346 else if (i
< n2
+ n3
+ 3)
347 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
348 else if (i
== n2
+ n3
+ 3)
349 check (buf1
[i
] == '\0', ntest
);
351 check (buf1
[i
] == 'b', ntest
);
353 if (errors
!= olderrors
)
355 printf ("n1=%zu, n2=%zu, n3=%zu, buf1=%02hhx",
356 n1
, n2
, n3
, buf1
[0]);
357 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
358 printf (",%02hhx", buf1
[j
]);
359 putchar_unlocked ('\n');
369 /* First test it as strcat, with big counts, then test the count
372 (void) strcpy (one
, "ijk");
373 check (strncat (one
, "lmn", 99) == one
, 1); /* Returned value. */
374 equal (one
, "ijklmn", 2); /* Basic test. */
376 (void) strcpy (one
, "x");
377 (void) strncat (one
, "yz", 99);
378 equal (one
, "xyz", 3); /* Writeover. */
379 equal (one
+4, "mn", 4); /* Wrote too much? */
381 (void) strcpy (one
, "gh");
382 (void) strcpy (two
, "ef");
383 (void) strncat (one
, two
, 99);
384 equal (one
, "ghef", 5); /* Basic test encore. */
385 equal (two
, "ef", 6); /* Stomped on source? */
387 (void) strcpy (one
, "");
388 (void) strncat (one
, "", 99);
389 equal (one
, "", 7); /* Boundary conditions. */
390 (void) strcpy (one
, "ab");
391 (void) strncat (one
, "", 99);
392 equal (one
, "ab", 8);
393 (void) strcpy (one
, "");
394 (void) strncat (one
, "cd", 99);
395 equal (one
, "cd", 9);
397 (void) strcpy (one
, "ab");
398 (void) strncat (one
, "cdef", 2);
399 equal (one
, "abcd", 10); /* Count-limited. */
401 (void) strncat (one
, "gh", 0);
402 equal (one
, "abcd", 11); /* Zero count. */
404 (void) strncat (one
, "gh", 2);
405 equal (one
, "abcdgh", 12); /* Count and length equal. */
407 (void) strncat (one
, "ij", (size_t)-1); /* set sign bit in count */
408 equal (one
, "abcdghij", 13);
411 char buf1
[80] __attribute__ ((aligned (16)));
412 char buf2
[32] __attribute__ ((aligned (16)));
413 for (size_t n1
= 0; n1
< 16; ++n1
)
414 for (size_t n2
= 0; n2
< 16; ++n2
)
415 for (size_t n3
= 0; n3
< 32; ++n3
)
416 for (size_t n4
= 0; n4
< 16; ++n4
)
418 size_t olderrors
= errors
;
420 memset (buf1
, 'b', sizeof (buf1
));
422 memset (buf1
+ n2
, 'a', n3
);
423 buf1
[n2
+ n3
] = '\0';
424 strcpy (buf2
+ n1
, "123");
426 check (strncat (buf1
+ n2
, buf2
+ n1
, ~((size_t) 0) - n4
)
427 == buf1
+ n2
, ntest
);
428 if (errors
== olderrors
)
429 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
432 check (buf1
[i
] == 'b', ntest
);
433 else if (i
< n2
+ n3
)
434 check (buf1
[i
] == 'a', ntest
);
435 else if (i
< n2
+ n3
+ 3)
436 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
437 else if (i
== n2
+ n3
+ 3)
438 check (buf1
[i
] == '\0', ntest
);
440 check (buf1
[i
] == 'b', ntest
);
442 if (errors
!= olderrors
)
444 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
445 n1
, n2
, n3
, n4
, buf1
[0]);
446 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
447 printf (",%02hhx", buf1
[j
]);
448 putchar_unlocked ('\n');
458 /* First test as strcmp with big counts, then test count code. */
460 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
461 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
462 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
463 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
464 check (strncmp ("abcd", "abc", 99) > 0, 5);
465 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
466 check (strncmp ("abce", "abcd", 99) > 0, 7);
467 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
468 check (strncmp ("a\203", "a\003", 2) > 0, 9);
469 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
470 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
471 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
472 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
473 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
474 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
480 /* Testing is a bit different because of odd semantics. */
482 check (strncpy (one
, "abc", 4) == one
, 1); /* Returned value. */
483 equal (one
, "abc", 2); /* Did the copy go right? */
485 (void) strcpy (one
, "abcdefgh");
486 (void) strncpy (one
, "xyz", 2);
487 equal (one
, "xycdefgh", 3); /* Copy cut by count. */
489 (void) strcpy (one
, "abcdefgh");
490 (void) strncpy (one
, "xyz", 3); /* Copy cut just before NUL. */
491 equal (one
, "xyzdefgh", 4);
493 (void) strcpy (one
, "abcdefgh");
494 (void) strncpy (one
, "xyz", 4); /* Copy just includes NUL. */
495 equal (one
, "xyz", 5);
496 equal (one
+4, "efgh", 6); /* Wrote too much? */
498 (void) strcpy (one
, "abcdefgh");
499 (void) strncpy (one
, "xyz", 5); /* Copy includes padding. */
500 equal (one
, "xyz", 7);
501 equal (one
+4, "", 8);
502 equal (one
+5, "fgh", 9);
504 (void) strcpy (one
, "abc");
505 (void) strncpy (one
, "xyz", 0); /* Zero-length copy. */
506 equal (one
, "abc", 10);
508 (void) strncpy (one
, "", 2); /* Zero-length source. */
510 equal (one
+1, "", 12);
511 equal (one
+2, "c", 13);
513 (void) strcpy (one
, "hi there");
514 (void) strncpy (two
, one
, 9);
515 equal (two
, "hi there", 14); /* Just paranoia. */
516 equal (one
, "hi there", 15); /* Stomped on source? */
523 check (strlen ("") == 0, 1); /* Empty. */
524 check (strlen ("a") == 1, 2); /* Single char. */
525 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
530 for (i
=0; i
< 0x100; i
++)
532 p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
534 strcpy (p
+3, "BAD/WRONG");
535 check (strlen (p
) == 2, 4+i
);
544 check (strnlen ("", 10) == 0, 1); /* Empty. */
545 check (strnlen ("a", 10) == 1, 2); /* Single char. */
546 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
547 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
548 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
549 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
550 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
551 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
552 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
555 for (int i
= 0; i
< 0x100; ++i
)
557 char *p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
559 strcpy (p
+ 3, "BAD/WRONG");
560 check (strnlen (p
, 100) == 2, 10 + i
);
568 check (strchr ("abcd", 'z') == NULL
, 1); /* Not found. */
569 (void) strcpy (one
, "abcd");
570 check (strchr (one
, 'c') == one
+2, 2); /* Basic test. */
571 check (strchr (one
, 'd') == one
+3, 3); /* End of string. */
572 check (strchr (one
, 'a') == one
, 4); /* Beginning. */
573 check (strchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
574 (void) strcpy (one
, "ababa");
575 check (strchr (one
, 'b') == one
+1, 6); /* Finding first. */
576 (void) strcpy (one
, "");
577 check (strchr (one
, 'b') == NULL
, 7); /* Empty string. */
578 check (strchr (one
, '\0') == one
, 8); /* NUL in empty string. */
583 for (i
=0; i
< 0x100; i
++)
585 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
587 strcpy (p
+3, "BAD/WRONG");
588 check (strchr (p
, '/') == NULL
, 9+i
);
594 test_strchrnul (void)
598 cp
= strchrnul ((os
= "abcd"), 'z');
599 check (*cp
== '\0', 1); /* Not found. */
600 check (cp
== os
+ 4, 2);
601 (void) strcpy (one
, "abcd");
602 check (strchrnul (one
, 'c') == one
+2, 3); /* Basic test. */
603 check (strchrnul (one
, 'd') == one
+3, 4); /* End of string. */
604 check (strchrnul (one
, 'a') == one
, 5); /* Beginning. */
605 check (strchrnul (one
, '\0') == one
+4, 6); /* Finding NUL. */
606 (void) strcpy (one
, "ababa");
607 check (strchrnul (one
, 'b') == one
+1, 7); /* Finding first. */
608 (void) strcpy (one
, "");
609 check (strchrnul (one
, 'b') == one
, 8); /* Empty string. */
610 check (strchrnul (one
, '\0') == one
, 9); /* NUL in empty string. */
615 for (i
=0; i
< 0x100; i
++)
617 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
619 strcpy (p
+3, "BAD/WRONG");
620 cp
= strchrnul (p
, '/');
621 check (*cp
== '\0', 9+2*i
);
622 check (cp
== p
+2, 10+2*i
);
628 test_rawmemchr (void)
631 (void) strcpy (one
, "abcd");
632 check (rawmemchr (one
, 'c') == one
+2, 1); /* Basic test. */
633 check (rawmemchr (one
, 'd') == one
+3, 2); /* End of string. */
634 check (rawmemchr (one
, 'a') == one
, 3); /* Beginning. */
635 check (rawmemchr (one
, '\0') == one
+4, 4); /* Finding NUL. */
636 (void) strcpy (one
, "ababa");
637 check (rawmemchr (one
, 'b') == one
+1, 5); /* Finding first. */
638 (void) strcpy (one
, "");
639 check (rawmemchr (one
, '\0') == one
, 6); /* NUL in empty string. */
644 for (i
=0; i
< 0x100; i
++)
646 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
648 strcpy (p
+3, "BAD/WRONG");
649 check (rawmemchr (p
, 'R') == p
+8, 6+i
);
658 check (index ("abcd", 'z') == NULL
, 1); /* Not found. */
659 (void) strcpy (one
, "abcd");
660 check (index (one
, 'c') == one
+2, 2); /* Basic test. */
661 check (index (one
, 'd') == one
+3, 3); /* End of string. */
662 check (index (one
, 'a') == one
, 4); /* Beginning. */
663 check (index (one
, '\0') == one
+4, 5); /* Finding NUL. */
664 (void) strcpy (one
, "ababa");
665 check (index (one
, 'b') == one
+1, 6); /* Finding first. */
666 (void) strcpy (one
, "");
667 check (index (one
, 'b') == NULL
, 7); /* Empty string. */
668 check (index (one
, '\0') == one
, 8); /* NUL in empty string. */
675 check (strrchr ("abcd", 'z') == NULL
, 1); /* Not found. */
676 (void) strcpy (one
, "abcd");
677 check (strrchr (one
, 'c') == one
+2, 2); /* Basic test. */
678 check (strrchr (one
, 'd') == one
+3, 3); /* End of string. */
679 check (strrchr (one
, 'a') == one
, 4); /* Beginning. */
680 check (strrchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
681 (void) strcpy (one
, "ababa");
682 check (strrchr (one
, 'b') == one
+3, 6); /* Finding last. */
683 (void) strcpy (one
, "");
684 check (strrchr (one
, 'b') == NULL
, 7); /* Empty string. */
685 check (strrchr (one
, '\0') == one
, 8); /* NUL in empty string. */
690 for (i
=0; i
< 0x100; i
++)
692 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
694 strcpy (p
+3, "BAD/WRONG");
695 check (strrchr (p
, '/') == NULL
, 9+i
);
705 check (memrchr ("abcd", 'z', 5) == NULL
, 1); /* Not found. */
706 (void) strcpy (one
, "abcd");
707 l
= strlen (one
) + 1;
708 check (memrchr (one
, 'c', l
) == one
+2, 2); /* Basic test. */
709 check (memrchr (one
, 'd', l
) == one
+3, 3); /* End of string. */
710 check (memrchr (one
, 'a', l
) == one
, 4); /* Beginning. */
711 check (memrchr (one
, '\0', l
) == one
+4, 5); /* Finding NUL. */
712 (void) strcpy (one
, "ababa");
713 l
= strlen (one
) + 1;
714 check (memrchr (one
, 'b', l
) == one
+3, 6); /* Finding last. */
715 (void) strcpy (one
, "");
716 l
= strlen (one
) + 1;
717 check (memrchr (one
, 'b', l
) == NULL
, 7); /* Empty string. */
718 check (memrchr (one
, '\0', l
) == one
, 8); /* NUL in empty string. */
720 /* now test all possible alignment and length combinations to catch
721 bugs due to unrolled loops (assuming unrolling is limited to no
722 more than 128 byte chunks: */
724 char buf
[128 + sizeof (long)];
725 long align
, len
, i
, pos
, n
= 9;
727 for (align
= 0; align
< (long) sizeof (long); ++align
) {
728 for (len
= 0; len
< (long) (sizeof (buf
) - align
); ++len
) {
729 for (i
= 0; i
< len
; ++i
)
730 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
732 for (pos
= len
- 1; pos
>= 0; --pos
) {
734 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
736 check(memrchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, n
++);
737 check(memrchr(buf
+ align
+ pos
+ 1, 'x', len
- (pos
+ 1)) == NULL
,
739 buf
[align
+ pos
] = '-';
750 check (rindex ("abcd", 'z') == NULL
, 1); /* Not found. */
751 (void) strcpy (one
, "abcd");
752 check (rindex (one
, 'c') == one
+2, 2); /* Basic test. */
753 check (rindex (one
, 'd') == one
+3, 3); /* End of string. */
754 check (rindex (one
, 'a') == one
, 4); /* Beginning. */
755 check (rindex (one
, '\0') == one
+4, 5); /* Finding NUL. */
756 (void) strcpy (one
, "ababa");
757 check (rindex (one
, 'b') == one
+3, 6); /* Finding last. */
758 (void) strcpy (one
, "");
759 check (rindex (one
, 'b') == NULL
, 7); /* Empty string. */
760 check (rindex (one
, '\0') == one
, 8); /* NUL in empty string. */
767 check(strpbrk("abcd", "z") == NULL
, 1); /* Not found. */
768 (void) strcpy(one
, "abcd");
769 check(strpbrk(one
, "c") == one
+2, 2); /* Basic test. */
770 check(strpbrk(one
, "d") == one
+3, 3); /* End of string. */
771 check(strpbrk(one
, "a") == one
, 4); /* Beginning. */
772 check(strpbrk(one
, "") == NULL
, 5); /* Empty search list. */
773 check(strpbrk(one
, "cb") == one
+1, 6); /* Multiple search. */
774 (void) strcpy(one
, "abcabdea");
775 check(strpbrk(one
, "b") == one
+1, 7); /* Finding first. */
776 check(strpbrk(one
, "cb") == one
+1, 8); /* With multiple search. */
777 check(strpbrk(one
, "db") == one
+1, 9); /* Another variant. */
778 (void) strcpy(one
, "");
779 check(strpbrk(one
, "bc") == NULL
, 10); /* Empty string. */
780 (void) strcpy(one
, "");
781 check(strpbrk(one
, "bcd") == NULL
, 11); /* Empty string. */
782 (void) strcpy(one
, "");
783 check(strpbrk(one
, "bcde") == NULL
, 12); /* Empty string. */
784 check(strpbrk(one
, "") == NULL
, 13); /* Both strings empty. */
785 (void) strcpy(one
, "abcabdea");
786 check(strpbrk(one
, "befg") == one
+1, 14); /* Finding first. */
787 check(strpbrk(one
, "cbr") == one
+1, 15); /* With multiple search. */
788 check(strpbrk(one
, "db") == one
+1, 16); /* Another variant. */
789 check(strpbrk(one
, "efgh") == one
+6, 17); /* And yet another. */
796 check(strstr("abcd", "z") == NULL
, 1); /* Not found. */
797 check(strstr("abcd", "abx") == NULL
, 2); /* Dead end. */
798 (void) strcpy(one
, "abcd");
799 check(strstr(one
, "c") == one
+2, 3); /* Basic test. */
800 check(strstr(one
, "bc") == one
+1, 4); /* Multichar. */
801 check(strstr(one
, "d") == one
+3, 5); /* End of string. */
802 check(strstr(one
, "cd") == one
+2, 6); /* Tail of string. */
803 check(strstr(one
, "abc") == one
, 7); /* Beginning. */
804 check(strstr(one
, "abcd") == one
, 8); /* Exact match. */
805 check(strstr(one
, "abcde") == NULL
, 9); /* Too long. */
806 check(strstr(one
, "de") == NULL
, 10); /* Past end. */
807 check(strstr(one
, "") == one
, 11); /* Finding empty. */
808 (void) strcpy(one
, "ababa");
809 check(strstr(one
, "ba") == one
+1, 12); /* Finding first. */
810 (void) strcpy(one
, "");
811 check(strstr(one
, "b") == NULL
, 13); /* Empty string. */
812 check(strstr(one
, "") == one
, 14); /* Empty in empty string. */
813 (void) strcpy(one
, "bcbca");
814 check(strstr(one
, "bca") == one
+2, 15); /* False start. */
815 (void) strcpy(one
, "bbbcabbca");
816 check(strstr(one
, "bbca") == one
+1, 16); /* With overlap. */
823 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
824 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
825 check(strspn("abc", "qx") == 0, 3); /* None. */
826 check(strspn("", "ab") == 0, 4); /* Null string. */
827 check(strspn("abc", "") == 0, 5); /* Null search list. */
834 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
835 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
836 check(strcspn("abc", "abc") == 0, 3); /* None. */
837 check(strcspn("", "ab") == 0, 4); /* Null string. */
838 check(strcspn("abc", "") == 3, 5); /* Null search list. */
845 (void) strcpy(one
, "first, second, third");
846 equal(strtok(one
, ", "), "first", 1); /* Basic test. */
847 equal(one
, "first", 2);
848 equal(strtok((char *)NULL
, ", "), "second", 3);
849 equal(strtok((char *)NULL
, ", "), "third", 4);
850 check(strtok((char *)NULL
, ", ") == NULL
, 5);
851 (void) strcpy(one
, ", first, ");
852 equal(strtok(one
, ", "), "first", 6); /* Extra delims, 1 tok. */
853 check(strtok((char *)NULL
, ", ") == NULL
, 7);
854 (void) strcpy(one
, "1a, 1b; 2a, 2b");
855 equal(strtok(one
, ", "), "1a", 8); /* Changing delim lists. */
856 equal(strtok((char *)NULL
, "; "), "1b", 9);
857 equal(strtok((char *)NULL
, ", "), "2a", 10);
858 (void) strcpy(two
, "x-y");
859 equal(strtok(two
, "-"), "x", 11); /* New string before done. */
860 equal(strtok((char *)NULL
, "-"), "y", 12);
861 check(strtok((char *)NULL
, "-") == NULL
, 13);
862 (void) strcpy(one
, "a,b, c,, ,d");
863 equal(strtok(one
, ", "), "a", 14); /* Different separators. */
864 equal(strtok((char *)NULL
, ", "), "b", 15);
865 equal(strtok((char *)NULL
, " ,"), "c", 16); /* Permute list too. */
866 equal(strtok((char *)NULL
, " ,"), "d", 17);
867 check(strtok((char *)NULL
, ", ") == NULL
, 18);
868 check(strtok((char *)NULL
, ", ") == NULL
, 19); /* Persistence. */
869 (void) strcpy(one
, ", ");
870 check(strtok(one
, ", ") == NULL
, 20); /* No tokens. */
871 (void) strcpy(one
, "");
872 check(strtok(one
, ", ") == NULL
, 21); /* Empty string. */
873 (void) strcpy(one
, "abc");
874 equal(strtok(one
, ", "), "abc", 22); /* No delimiters. */
875 check(strtok((char *)NULL
, ", ") == NULL
, 23);
876 (void) strcpy(one
, "abc");
877 equal(strtok(one
, ""), "abc", 24); /* Empty delimiter list. */
878 check(strtok((char *)NULL
, "") == NULL
, 25);
879 (void) strcpy(one
, "abcdefgh");
880 (void) strcpy(one
, "a,b,c");
881 equal(strtok(one
, ","), "a", 26); /* Basics again... */
882 equal(strtok((char *)NULL
, ","), "b", 27);
883 equal(strtok((char *)NULL
, ","), "c", 28);
884 check(strtok((char *)NULL
, ",") == NULL
, 29);
885 equal(one
+6, "gh", 30); /* Stomped past end? */
886 equal(one
, "a", 31); /* Stomped old tokens? */
887 equal(one
+2, "b", 32);
888 equal(one
+4, "c", 33);
895 (void) strcpy(one
, "first, second, third");
896 cp
= NULL
; /* Always initialize cp to make sure it doesn't point to some old data. */
897 equal(strtok_r(one
, ", ", &cp
), "first", 1); /* Basic test. */
898 equal(one
, "first", 2);
899 equal(strtok_r((char *)NULL
, ", ", &cp
), "second", 3);
900 equal(strtok_r((char *)NULL
, ", ", &cp
), "third", 4);
901 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 5);
902 (void) strcpy(one
, ", first, ");
904 equal(strtok_r(one
, ", ", &cp
), "first", 6); /* Extra delims, 1 tok. */
905 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 7);
906 (void) strcpy(one
, "1a, 1b; 2a, 2b");
908 equal(strtok_r(one
, ", ", &cp
), "1a", 8); /* Changing delim lists. */
909 equal(strtok_r((char *)NULL
, "; ", &cp
), "1b", 9);
910 equal(strtok_r((char *)NULL
, ", ", &cp
), "2a", 10);
911 (void) strcpy(two
, "x-y");
913 equal(strtok_r(two
, "-", &cp
), "x", 11); /* New string before done. */
914 equal(strtok_r((char *)NULL
, "-", &cp
), "y", 12);
915 check(strtok_r((char *)NULL
, "-", &cp
) == NULL
, 13);
916 (void) strcpy(one
, "a,b, c,, ,d");
918 equal(strtok_r(one
, ", ", &cp
), "a", 14); /* Different separators. */
919 equal(strtok_r((char *)NULL
, ", ", &cp
), "b", 15);
920 equal(strtok_r((char *)NULL
, " ,", &cp
), "c", 16); /* Permute list too. */
921 equal(strtok_r((char *)NULL
, " ,", &cp
), "d", 17);
922 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 18);
923 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 19); /* Persistence. */
924 (void) strcpy(one
, ", ");
926 check(strtok_r(one
, ", ", &cp
) == NULL
, 20); /* No tokens. */
927 (void) strcpy(one
, "");
929 check(strtok_r(one
, ", ", &cp
) == NULL
, 21); /* Empty string. */
930 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 22); /* Persistence. */
931 (void) strcpy(one
, "abc");
933 equal(strtok_r(one
, ", ", &cp
), "abc", 23); /* No delimiters. */
934 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 24);
935 (void) strcpy(one
, "abc");
937 equal(strtok_r(one
, "", &cp
), "abc", 25); /* Empty delimiter list. */
938 check(strtok_r((char *)NULL
, "", &cp
) == NULL
, 26);
939 (void) strcpy(one
, "abcdefgh");
940 (void) strcpy(one
, "a,b,c");
942 equal(strtok_r(one
, ",", &cp
), "a", 27); /* Basics again... */
943 equal(strtok_r((char *)NULL
, ",", &cp
), "b", 28);
944 equal(strtok_r((char *)NULL
, ",", &cp
), "c", 29);
945 check(strtok_r((char *)NULL
, ",", &cp
) == NULL
, 30);
946 equal(one
+6, "gh", 31); /* Stomped past end? */
947 equal(one
, "a", 32); /* Stomped old tokens? */
948 equal(one
+2, "b", 33);
949 equal(one
+4, "c", 34);
952 check (strtok_r (one
, ":", &cp
) == NULL
, 35); /* Must store pointer in cp. */
953 check (strtok_r (NULL
, ":", &cp
) == NULL
, 36);
961 cp
= strcpy(one
, "first, second, third");
962 equal(strsep(&cp
, ", "), "first", 1); /* Basic test. */
963 equal(one
, "first", 2);
964 equal(strsep(&cp
, ", "), "", 3);
965 equal(strsep(&cp
, ", "), "second", 4);
966 equal(strsep(&cp
, ", "), "", 5);
967 equal(strsep(&cp
, ", "), "third", 6);
968 check(strsep(&cp
, ", ") == NULL
, 7);
969 cp
= strcpy(one
, ", first, ");
970 equal(strsep(&cp
, ", "), "", 8);
971 equal(strsep(&cp
, ", "), "", 9);
972 equal(strsep(&cp
, ", "), "first", 10); /* Extra delims, 1 tok. */
973 equal(strsep(&cp
, ", "), "", 11);
974 equal(strsep(&cp
, ", "), "", 12);
975 check(strsep(&cp
, ", ") == NULL
, 13);
976 cp
= strcpy(one
, "1a, 1b; 2a, 2b");
977 equal(strsep(&cp
, ", "), "1a", 14); /* Changing delim lists. */
978 equal(strsep(&cp
, ", "), "", 15);
979 equal(strsep(&cp
, "; "), "1b", 16);
980 equal(strsep(&cp
, ", "), "", 17);
981 equal(strsep(&cp
, ", "), "2a", 18);
982 cp
= strcpy(two
, "x-y");
983 equal(strsep(&cp
, "-"), "x", 19); /* New string before done. */
984 equal(strsep(&cp
, "-"), "y", 20);
985 check(strsep(&cp
, "-") == NULL
, 21);
986 cp
= strcpy(one
, "a,b, c,, ,d ");
987 equal(strsep(&cp
, ", "), "a", 22); /* Different separators. */
988 equal(strsep(&cp
, ", "), "b", 23);
989 equal(strsep(&cp
, " ,"), "", 24);
990 equal(strsep(&cp
, " ,"), "c", 25); /* Permute list too. */
991 equal(strsep(&cp
, " ,"), "", 26);
992 equal(strsep(&cp
, " ,"), "", 27);
993 equal(strsep(&cp
, " ,"), "", 28);
994 equal(strsep(&cp
, " ,"), "d", 29);
995 equal(strsep(&cp
, " ,"), "", 30);
996 check(strsep(&cp
, ", ") == NULL
, 31);
997 check(strsep(&cp
, ", ") == NULL
, 32); /* Persistence. */
998 cp
= strcpy(one
, ", ");
999 equal(strsep(&cp
, ", "), "", 33);
1000 equal(strsep(&cp
, ", "), "", 34);
1001 equal(strsep(&cp
, ", "), "", 35);
1002 check(strsep(&cp
, ", ") == NULL
, 36); /* No tokens. */
1003 cp
= strcpy(one
, "");
1004 equal(strsep(&cp
, ", "), "", 37);
1005 check(strsep(&cp
, ", ") == NULL
, 38); /* Empty string. */
1006 cp
= strcpy(one
, "abc");
1007 equal(strsep(&cp
, ", "), "abc", 39); /* No delimiters. */
1008 check(strsep(&cp
, ", ") == NULL
, 40);
1009 cp
= strcpy(one
, "abc");
1010 equal(strsep(&cp
, ""), "abc", 41); /* Empty delimiter list. */
1011 check(strsep(&cp
, "") == NULL
, 42);
1012 (void) strcpy(one
, "abcdefgh");
1013 cp
= strcpy(one
, "a,b,c");
1014 equal(strsep(&cp
, ","), "a", 43); /* Basics again... */
1015 equal(strsep(&cp
, ","), "b", 44);
1016 equal(strsep(&cp
, ","), "c", 45);
1017 check(strsep(&cp
, ",") == NULL
, 46);
1018 equal(one
+6, "gh", 47); /* Stomped past end? */
1019 equal(one
, "a", 48); /* Stomped old tokens? */
1020 equal(one
+2, "b", 49);
1021 equal(one
+4, "c", 50);
1024 char text
[] = "This,is,a,test";
1025 char *list
= strdupa (text
);
1026 equal (strsep (&list
, ","), "This", 51);
1027 equal (strsep (&list
, ","), "is", 52);
1028 equal (strsep (&list
, ","), "a", 53);
1029 equal (strsep (&list
, ","), "test", 54);
1030 check (strsep (&list
, ",") == NULL
, 55);
1033 cp
= strcpy(one
, "a,b, c,, ,d,");
1034 equal(strsep(&cp
, ","), "a", 56); /* Different separators. */
1035 equal(strsep(&cp
, ","), "b", 57);
1036 equal(strsep(&cp
, ","), " c", 58); /* Permute list too. */
1037 equal(strsep(&cp
, ","), "", 59);
1038 equal(strsep(&cp
, ","), " ", 60);
1039 equal(strsep(&cp
, ","), "d", 61);
1040 equal(strsep(&cp
, ","), "", 62);
1041 check(strsep(&cp
, ",") == NULL
, 63);
1042 check(strsep(&cp
, ",") == NULL
, 64); /* Persistence. */
1044 cp
= strcpy(one
, "a,b, c,, ,d,");
1045 equal(strsep(&cp
, "xy,"), "a", 65); /* Different separators. */
1046 equal(strsep(&cp
, "x,y"), "b", 66);
1047 equal(strsep(&cp
, ",xy"), " c", 67); /* Permute list too. */
1048 equal(strsep(&cp
, "xy,"), "", 68);
1049 equal(strsep(&cp
, "x,y"), " ", 69);
1050 equal(strsep(&cp
, ",xy"), "d", 70);
1051 equal(strsep(&cp
, "xy,"), "", 71);
1052 check(strsep(&cp
, "x,y") == NULL
, 72);
1053 check(strsep(&cp
, ",xy") == NULL
, 73); /* Persistence. */
1055 cp
= strcpy(one
, "ABC");
1057 equal(strsep(&cp
, "C"), "AB", 74); /* Access beyond NUL. */
1058 ptr
= strsep(&cp
, ":");
1060 check(ptr
== one
+ 3, 76);
1061 check(cp
== NULL
, 77);
1063 cp
= strcpy(one
, "ABC");
1065 equal(strsep(&cp
, "CD"), "AB", 78); /* Access beyond NUL. */
1066 ptr
= strsep(&cp
, ":.");
1068 check(ptr
== one
+ 3, 80);
1070 cp
= strcpy(one
, "ABC"); /* No token in string. */
1071 equal(strsep(&cp
, ","), "ABC", 81);
1072 check(cp
== NULL
, 82);
1074 *one
= '\0'; /* Empty string. */
1076 ptr
= strsep(&cp
, ",");
1078 check(ptr
== one
, 84);
1079 check(cp
== NULL
, 85);
1081 *one
= '\0'; /* Empty string and no token. */
1083 ptr
= strsep(&cp
, "");
1085 check(ptr
== one
, 87);
1086 check(cp
== NULL
, 88);
1097 check(memcmp("a", "a", 1) == 0, cnt
++); /* Identity. */
1098 check(memcmp("abc", "abc", 3) == 0, cnt
++); /* Multicharacter. */
1099 check(memcmp("abcd", "abcf", 4) < 0, cnt
++); /* Honestly unequal. */
1100 check(memcmp("abcf", "abcd", 4) > 0, cnt
++);
1101 check(memcmp("alph", "cold", 4) < 0, cnt
++);
1102 check(memcmp("a\203", "a\003", 2) > 0, cnt
++);
1103 check(memcmp("a\003", "a\203", 2) < 0, cnt
++);
1104 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt
++);
1105 check(memcmp("abc\203", "abc\003", 4) > 0, cnt
++);
1106 check(memcmp("abc\003", "abc\203", 4) < 0, cnt
++);
1107 check(memcmp("abcf", "abcd", 3) == 0, cnt
++); /* Count limited. */
1108 check(memcmp("abc", "def", 0) == 0, cnt
++); /* Zero count. */
1109 /* Comparisons with shifting 4-byte boundaries. */
1110 for (int i
= 0; i
< 4; ++i
)
1114 memcpy(a
, "--------11112222", 16);
1115 memcpy(b
, "--------33334444", 16);
1116 check(memcmp(b
, a
, 16) > 0, cnt
++);
1117 check(memcmp(a
, b
, 16) < 0, cnt
++);
1125 check(memchr("abcd", 'z', 4) == NULL
, 1); /* Not found. */
1126 (void) strcpy(one
, "abcd");
1127 check(memchr(one
, 'c', 4) == one
+2, 2); /* Basic test. */
1128 check(memchr(one
, ~0xff|'c', 4) == one
+2, 2); /* ignore highorder bits. */
1129 check(memchr(one
, 'd', 4) == one
+3, 3); /* End of string. */
1130 check(memchr(one
, 'a', 4) == one
, 4); /* Beginning. */
1131 check(memchr(one
, '\0', 5) == one
+4, 5); /* Finding NUL. */
1132 (void) strcpy(one
, "ababa");
1133 check(memchr(one
, 'b', 5) == one
+1, 6); /* Finding first. */
1134 check(memchr(one
, 'b', 0) == NULL
, 7); /* Zero count. */
1135 check(memchr(one
, 'a', 1) == one
, 8); /* Singleton case. */
1136 (void) strcpy(one
, "a\203b");
1137 check(memchr(one
, 0203, 3) == one
+1, 9); /* Unsignedness. */
1139 /* now test all possible alignment and length combinations to catch
1140 bugs due to unrolled loops (assuming unrolling is limited to no
1141 more than 128 byte chunks: */
1143 char buf
[128 + sizeof (long)];
1144 long align
, len
, i
, pos
;
1146 for (align
= 0; align
< (long) sizeof (long); ++align
) {
1147 for (len
= 0; len
< (long) (sizeof (buf
) - align
); ++len
) {
1148 for (i
= 0; i
< len
; ++i
) {
1149 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
1151 for (pos
= 0; pos
< len
; ++pos
) {
1153 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
1155 check(memchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, 10);
1156 check(memchr(buf
+ align
, 'x', pos
) == NULL
, 11);
1157 buf
[align
+ pos
] = '-';
1169 check(memcpy(one
, "abc", 4) == one
, 1); /* Returned value. */
1170 equal(one
, "abc", 2); /* Did the copy go right? */
1172 (void) strcpy(one
, "abcdefgh");
1173 (void) memcpy(one
+1, "xyz", 2);
1174 equal(one
, "axydefgh", 3); /* Basic test. */
1176 (void) strcpy(one
, "abc");
1177 (void) memcpy(one
, "xyz", 0);
1178 equal(one
, "abc", 4); /* Zero-length copy. */
1180 (void) strcpy(one
, "hi there");
1181 (void) strcpy(two
, "foo");
1182 (void) memcpy(two
, one
, 9);
1183 equal(two
, "hi there", 5); /* Just paranoia. */
1184 equal(one
, "hi there", 6); /* Stomped on source? */
1186 for (i
= 0; i
< 16; i
++)
1188 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1190 check (memcpy (one
+ i
, "hi there", 9) == one
+ i
,
1191 7 + (i
* 6)); /* Unaligned destination. */
1192 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1193 equal (one
+ i
, "hi there", 9 + (i
* 6));
1194 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1195 check (memcpy (two
, one
+ i
, 9) == two
,
1196 11 + (i
* 6)); /* Unaligned source. */
1197 equal (two
, "hi there", 12 + (i
* 6));
1206 check(mempcpy(one
, "abc", 4) == one
+ 4, 1); /* Returned value. */
1207 equal(one
, "abc", 2); /* Did the copy go right? */
1209 (void) strcpy(one
, "abcdefgh");
1210 (void) mempcpy(one
+1, "xyz", 2);
1211 equal(one
, "axydefgh", 3); /* Basic test. */
1213 (void) strcpy(one
, "abc");
1214 (void) mempcpy(one
, "xyz", 0);
1215 equal(one
, "abc", 4); /* Zero-length copy. */
1217 (void) strcpy(one
, "hi there");
1218 (void) strcpy(two
, "foo");
1219 (void) mempcpy(two
, one
, 9);
1220 equal(two
, "hi there", 5); /* Just paranoia. */
1221 equal(one
, "hi there", 6); /* Stomped on source? */
1223 for (i
= 0; i
< 16; i
++)
1225 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1227 check (mempcpy (one
+ i
, "hi there", 9) == one
+ i
+ 9,
1228 7 + (i
* 6)); /* Unaligned destination. */
1229 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1230 equal (one
+ i
, "hi there", 9 + (i
* 6));
1231 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1232 check (mempcpy (two
, one
+ i
, 9) == two
+ 9,
1233 11 + (i
* 6)); /* Unaligned source. */
1234 equal (two
, "hi there", 12 + (i
* 6));
1242 check(memmove(one
, "abc", 4) == one
, 1); /* Returned value. */
1243 equal(one
, "abc", 2); /* Did the copy go right? */
1245 (void) strcpy(one
, "abcdefgh");
1246 (void) memmove(one
+1, "xyz", 2);
1247 equal(one
, "axydefgh", 3); /* Basic test. */
1249 (void) strcpy(one
, "abc");
1250 (void) memmove(one
, "xyz", 0);
1251 equal(one
, "abc", 4); /* Zero-length copy. */
1253 (void) strcpy(one
, "hi there");
1254 (void) strcpy(two
, "foo");
1255 (void) memmove(two
, one
, 9);
1256 equal(two
, "hi there", 5); /* Just paranoia. */
1257 equal(one
, "hi there", 6); /* Stomped on source? */
1259 (void) strcpy(one
, "abcdefgh");
1260 (void) memmove(one
+1, one
, 9);
1261 equal(one
, "aabcdefgh", 7); /* Overlap, right-to-left. */
1263 (void) strcpy(one
, "abcdefgh");
1264 (void) memmove(one
+1, one
+2, 7);
1265 equal(one
, "acdefgh", 8); /* Overlap, left-to-right. */
1267 (void) strcpy(one
, "abcdefgh");
1268 (void) memmove(one
, one
, 9);
1269 equal(one
, "abcdefgh", 9); /* 100% overlap. */
1275 /* First test like memcpy, then the search part The SVID, the only
1276 place where memccpy is mentioned, says overlap might fail, so we
1277 don't try it. Besides, it's hard to see the rationale for a
1278 non-left-to-right memccpy. */
1280 check(memccpy(one
, "abc", 'q', 4) == NULL
, 1); /* Returned value. */
1281 equal(one
, "abc", 2); /* Did the copy go right? */
1283 (void) strcpy(one
, "abcdefgh");
1284 (void) memccpy(one
+1, "xyz", 'q', 2);
1285 equal(one
, "axydefgh", 3); /* Basic test. */
1287 (void) strcpy(one
, "abc");
1288 (void) memccpy(one
, "xyz", 'q', 0);
1289 equal(one
, "abc", 4); /* Zero-length copy. */
1291 (void) strcpy(one
, "hi there");
1292 (void) strcpy(two
, "foo");
1293 (void) memccpy(two
, one
, 'q', 9);
1294 equal(two
, "hi there", 5); /* Just paranoia. */
1295 equal(one
, "hi there", 6); /* Stomped on source? */
1297 (void) strcpy(one
, "abcdefgh");
1298 (void) strcpy(two
, "horsefeathers");
1299 check(memccpy(two
, one
, 'f', 9) == two
+6, 7); /* Returned value. */
1300 equal(one
, "abcdefgh", 8); /* Source intact? */
1301 equal(two
, "abcdefeathers", 9); /* Copy correct? */
1303 (void) strcpy(one
, "abcd");
1304 (void) strcpy(two
, "bumblebee");
1305 check(memccpy(two
, one
, 'a', 4) == two
+1, 10); /* First char. */
1306 equal(two
, "aumblebee", 11);
1307 check(memccpy(two
, one
, 'd', 4) == two
+4, 12); /* Last char. */
1308 equal(two
, "abcdlebee", 13);
1309 (void) strcpy(one
, "xyz");
1310 check(memccpy(two
, one
, 'x', 1) == two
+1, 14); /* Singleton. */
1311 equal(two
, "xbcdlebee", 15);
1320 (void) strcpy(one
, "abcdefgh");
1321 check(memset(one
+1, 'x', 3) == one
+1, 1); /* Return value. */
1322 equal(one
, "axxxefgh", 2); /* Basic test. */
1324 (void) memset(one
+2, 'y', 0);
1325 equal(one
, "axxxefgh", 3); /* Zero-length set. */
1327 (void) memset(one
+5, 0, 1);
1328 equal(one
, "axxxe", 4); /* Zero fill. */
1329 equal(one
+6, "gh", 5); /* And the leftover. */
1331 (void) memset(one
+2, 010045, 1);
1332 equal(one
, "ax\045xe", 6); /* Unsigned char convert. */
1334 /* Non-8bit fill character. */
1335 memset (one
, 0x101, sizeof (one
));
1336 for (i
= 0; i
< (int) sizeof (one
); ++i
)
1337 check (one
[i
] == '\01', 7);
1339 /* Test for more complex versions of memset, for all alignments and
1340 lengths up to 256. This test takes a little while, perhaps it should
1348 for (i
= 0; i
< 512; i
++)
1350 for (c
= 0; c
<= 'y'; c
+= 'y') /* check for memset(,0,) and
1352 for (j
= 0; j
< 256; j
++)
1353 for (i
= 0; i
< 256; i
++)
1355 memset (data
+ i
, c
, j
);
1356 for (k
= 0; k
< i
; k
++)
1359 for (k
= i
; k
< i
+j
; k
++)
1365 for (k
= i
+j
; k
< 512; k
++)
1371 check (0, 8 + i
+ j
* 256 + (c
!= 0) * 256 * 256);
1379 /* Much like memcpy. Berklix manual is silent about overlap, so
1382 (void) bcopy("abc", one
, 4);
1383 equal(one
, "abc", 1); /* Simple copy. */
1385 (void) strcpy(one
, "abcdefgh");
1386 (void) bcopy("xyz", one
+1, 2);
1387 equal(one
, "axydefgh", 2); /* Basic test. */
1389 (void) strcpy(one
, "abc");
1390 (void) bcopy("xyz", one
, 0);
1391 equal(one
, "abc", 3); /* Zero-length copy. */
1393 (void) strcpy(one
, "hi there");
1394 (void) strcpy(two
, "foo");
1395 (void) bcopy(one
, two
, 9);
1396 equal(two
, "hi there", 4); /* Just paranoia. */
1397 equal(one
, "hi there", 5); /* Stomped on source? */
1404 (void) strcpy(one
, "abcdef");
1406 equal(one
, "ab", 1); /* Basic test. */
1407 equal(one
+3, "", 2);
1408 equal(one
+4, "ef", 3);
1410 (void) strcpy(one
, "abcdef");
1412 equal(one
, "abcdef", 4); /* Zero-length copy. */
1420 p
= strndup("abcdef", 12);
1421 check(p
!= NULL
, 1);
1424 equal(p
, "abcdef", 2);
1425 q
= strndup(p
+ 1, 2);
1426 check(q
!= NULL
, 3);
1432 p
= strndup("abc def", 3);
1433 check(p
!= NULL
, 5);
1443 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1444 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1445 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1446 check(bcmp("abce", "abcd", 4) != 0, 4);
1447 check(bcmp("alph", "beta", 4) != 0, 5);
1448 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1449 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1453 test_memcmpeq (void)
1456 check (__memcmpeq ("a", "a", 1) == 0, 1); /* Identity. */
1457 check (__memcmpeq ("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1458 check (__memcmpeq ("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1459 check (__memcmpeq ("abce", "abcd", 4) != 0, 4);
1460 check (__memcmpeq ("alph", "beta", 4) != 0, 5);
1461 check (__memcmpeq ("abce", "abcd", 3) == 0, 6); /* Count limited. */
1462 check (__memcmpeq ("abc", "def", 0) == 0, 8); /* Zero count. */
1466 test_strerror (void)
1469 check(strerror(EDOM
) != 0, 1);
1470 check(strerror(ERANGE
) != 0, 2);
1471 check(strerror(ENOENT
) != 0, 3);
1475 test_strcasecmp (void)
1478 /* Note that the locale is "C". */
1479 check(strcasecmp("a", "a") == 0, 1);
1480 check(strcasecmp("a", "A") == 0, 2);
1481 check(strcasecmp("A", "a") == 0, 3);
1482 check(strcasecmp("a", "b") < 0, 4);
1483 check(strcasecmp("c", "b") > 0, 5);
1484 check(strcasecmp("abc", "AbC") == 0, 6);
1485 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1486 check(strcasecmp("", "0123456789") < 0, 8);
1487 check(strcasecmp("AbC", "") > 0, 9);
1488 check(strcasecmp("AbC", "A") > 0, 10);
1489 check(strcasecmp("AbC", "Ab") > 0, 11);
1490 check(strcasecmp("AbC", "ab") > 0, 12);
1494 test_strncasecmp (void)
1497 /* Note that the locale is "C". */
1498 check(strncasecmp("a", "a", 5) == 0, 1);
1499 check(strncasecmp("a", "A", 5) == 0, 2);
1500 check(strncasecmp("A", "a", 5) == 0, 3);
1501 check(strncasecmp("a", "b", 5) < 0, 4);
1502 check(strncasecmp("c", "b", 5) > 0, 5);
1503 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1504 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1505 check(strncasecmp("", "0123456789", 10) < 0, 8);
1506 check(strncasecmp("AbC", "", 5) > 0, 9);
1507 check(strncasecmp("AbC", "A", 5) > 0, 10);
1508 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1509 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1510 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1511 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1512 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1513 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1514 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1515 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1516 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1517 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1525 /* Test strcmp first because we use it to test other things. */
1528 /* Test strcpy next because we need it to set up other tests. */
1531 /* A closely related function is stpcpy. */
1564 /* index - just like strchr. */
1573 /* rindex - just like strrchr. */
1576 /* strpbrk - somewhat like strchr. */
1579 /* strstr - somewhat like strchr. */
1588 /* strtok - the hard one. */
1603 /* memcpy - need not work for overlap. */
1606 /* memmove - must work on overlap. */
1624 /* bcmp - somewhat like memcmp. */
1627 /* __memcmpeq - somewhat like memcmp. */
1633 /* strerror - VERY system-dependent. */
1636 /* strcasecmp. Without locale dependencies. */
1639 /* strncasecmp. Without locale dependencies. */
1640 test_strncasecmp ();
1644 status
= EXIT_SUCCESS
;
1649 status
= EXIT_FAILURE
;
1650 printf("%zd errors.\n", errors
);