1 /* Tester for string functions.
2 Copyright (C) 1995-2020 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");
52 #define STREQ(a, b) (strcmp((a), (b)) == 0)
54 const char *it
= "<UNSET>"; /* Routine name for message routines. */
57 /* Complain if condition is not true. */
59 check (int thing
, int number
)
63 printf ("%s flunked test %d\n", it
, number
);
68 /* Complain if first two args don't strcmp as equal. */
70 equal (const char *a
, const char *b
, int number
)
72 check (a
!= NULL
&& b
!= NULL
&& STREQ (a
, b
), number
);
83 check (strcmp ("", "") == 0, 1); /* Trivial case. */
84 check (strcmp ("a", "a") == 0, 2); /* Identity. */
85 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
86 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
87 check (strcmp ("abcd", "abc") > 0, 5);
88 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
89 check (strcmp ("abce", "abcd") > 0, 7);
90 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
91 check (strcmp ("a\203", "a\003") > 0, 9);
94 char buf1
[0x40], buf2
[0x40];
96 for (i
=0; i
< 0x10; i
++)
97 for (j
= 0; j
< 0x10; j
++)
100 for (k
= 0; k
< 0x3f; k
++)
102 buf1
[k
] = '0' ^ (k
& 4);
103 buf2
[k
] = '4' ^ (k
& 4);
105 buf1
[i
] = buf1
[0x3f] = 0;
106 buf2
[j
] = buf2
[0x3f] = 0;
107 for (k
= 0; k
< 0xf; k
++)
109 int cnum
= 0x10+0x10*k
+0x100*j
+0x1000*i
;
110 check (strcmp (buf1
+i
,buf2
+j
) == 0, cnum
);
111 buf1
[i
+k
] = 'A' + i
+ k
;
113 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+1);
114 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+2);
115 buf2
[j
+k
] = 'B' + i
+ k
;
117 check (strcmp (buf1
+i
,buf2
+j
) < 0, cnum
+3);
118 check (strcmp (buf2
+j
,buf1
+i
) > 0, cnum
+4);
119 buf2
[j
+k
] = 'A' + i
+ k
;
120 buf1
[i
] = 'A' + i
+ 0x80;
121 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+5);
122 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+6);
129 #define SIMPLE_COPY(fn, n, str, ntest) \
133 for (__n = 0; __n < (int) sizeof (one); ++__n) \
136 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
137 check (*cp == '0' + (n % 10), ntest); \
138 check (*cp == '\0', ntest); \
146 check (strcpy (one
, "abcd") == one
, 1); /* Returned value. */
147 equal (one
, "abcd", 2); /* Basic test. */
149 (void) strcpy (one
, "x");
150 equal (one
, "x", 3); /* Writeover. */
151 equal (one
+2, "cd", 4); /* Wrote too much? */
153 (void) strcpy (two
, "hi there");
154 (void) strcpy (one
, two
);
155 equal (one
, "hi there", 5); /* Basic test encore. */
156 equal (two
, "hi there", 6); /* Stomped on source? */
158 (void) strcpy (one
, "");
159 equal (one
, "", 7); /* Boundary condition. */
161 for (i
= 0; i
< 16; i
++)
163 (void) strcpy (one
+ i
, "hi there"); /* Unaligned destination. */
164 equal (one
+ i
, "hi there", 8 + (i
* 2));
165 (void) strcpy (two
, one
+ i
); /* Unaligned source. */
166 equal (two
, "hi there", 9 + (i
* 2));
169 SIMPLE_COPY(strcpy
, 0, "", 41);
170 SIMPLE_COPY(strcpy
, 1, "1", 42);
171 SIMPLE_COPY(strcpy
, 2, "22", 43);
172 SIMPLE_COPY(strcpy
, 3, "333", 44);
173 SIMPLE_COPY(strcpy
, 4, "4444", 45);
174 SIMPLE_COPY(strcpy
, 5, "55555", 46);
175 SIMPLE_COPY(strcpy
, 6, "666666", 47);
176 SIMPLE_COPY(strcpy
, 7, "7777777", 48);
177 SIMPLE_COPY(strcpy
, 8, "88888888", 49);
178 SIMPLE_COPY(strcpy
, 9, "999999999", 50);
179 SIMPLE_COPY(strcpy
, 10, "0000000000", 51);
180 SIMPLE_COPY(strcpy
, 11, "11111111111", 52);
181 SIMPLE_COPY(strcpy
, 12, "222222222222", 53);
182 SIMPLE_COPY(strcpy
, 13, "3333333333333", 54);
183 SIMPLE_COPY(strcpy
, 14, "44444444444444", 55);
184 SIMPLE_COPY(strcpy
, 15, "555555555555555", 56);
185 SIMPLE_COPY(strcpy
, 16, "6666666666666666", 57);
187 /* Simple test using implicitly coerced `void *' arguments. */
188 const void *src
= "frobozz";
190 check (strcpy (dst
, src
) == dst
, 1);
191 equal (dst
, "frobozz", 2);
198 check ((stpcpy (one
, "a") - one
) == 1, 1);
201 check ((stpcpy (one
, "ab") - one
) == 2, 3);
202 equal (one
, "ab", 4);
204 check ((stpcpy (one
, "abc") - one
) == 3, 5);
205 equal (one
, "abc", 6);
207 check ((stpcpy (one
, "abcd") - one
) == 4, 7);
208 equal (one
, "abcd", 8);
210 check ((stpcpy (one
, "abcde") - one
) == 5, 9);
211 equal (one
, "abcde", 10);
213 check ((stpcpy (one
, "abcdef") - one
) == 6, 11);
214 equal (one
, "abcdef", 12);
216 check ((stpcpy (one
, "abcdefg") - one
) == 7, 13);
217 equal (one
, "abcdefg", 14);
219 check ((stpcpy (one
, "abcdefgh") - one
) == 8, 15);
220 equal (one
, "abcdefgh", 16);
222 check ((stpcpy (one
, "abcdefghi") - one
) == 9, 17);
223 equal (one
, "abcdefghi", 18);
225 check ((stpcpy (one
, "x") - one
) == 1, 19);
226 equal (one
, "x", 20); /* Writeover. */
227 equal (one
+2, "cdefghi", 21); /* Wrote too much? */
229 check ((stpcpy (one
, "xx") - one
) == 2, 22);
230 equal (one
, "xx", 23); /* Writeover. */
231 equal (one
+3, "defghi", 24); /* Wrote too much? */
233 check ((stpcpy (one
, "xxx") - one
) == 3, 25);
234 equal (one
, "xxx", 26); /* Writeover. */
235 equal (one
+4, "efghi", 27); /* Wrote too much? */
237 check ((stpcpy (one
, "xxxx") - one
) == 4, 28);
238 equal (one
, "xxxx", 29); /* Writeover. */
239 equal (one
+5, "fghi", 30); /* Wrote too much? */
241 check ((stpcpy (one
, "xxxxx") - one
) == 5, 31);
242 equal (one
, "xxxxx", 32); /* Writeover. */
243 equal (one
+6, "ghi", 33); /* Wrote too much? */
245 check ((stpcpy (one
, "xxxxxx") - one
) == 6, 34);
246 equal (one
, "xxxxxx", 35); /* Writeover. */
247 equal (one
+7, "hi", 36); /* Wrote too much? */
249 check ((stpcpy (one
, "xxxxxxx") - one
) == 7, 37);
250 equal (one
, "xxxxxxx", 38); /* Writeover. */
251 equal (one
+8, "i", 39); /* Wrote too much? */
253 check ((stpcpy (stpcpy (stpcpy (one
, "a"), "b"), "c") - one
) == 3, 40);
254 equal (one
, "abc", 41);
255 equal (one
+ 4, "xxx", 42);
257 SIMPLE_COPY(stpcpy
, 0, "", 43);
258 SIMPLE_COPY(stpcpy
, 1, "1", 44);
259 SIMPLE_COPY(stpcpy
, 2, "22", 45);
260 SIMPLE_COPY(stpcpy
, 3, "333", 46);
261 SIMPLE_COPY(stpcpy
, 4, "4444", 47);
262 SIMPLE_COPY(stpcpy
, 5, "55555", 48);
263 SIMPLE_COPY(stpcpy
, 6, "666666", 49);
264 SIMPLE_COPY(stpcpy
, 7, "7777777", 50);
265 SIMPLE_COPY(stpcpy
, 8, "88888888", 51);
266 SIMPLE_COPY(stpcpy
, 9, "999999999", 52);
267 SIMPLE_COPY(stpcpy
, 10, "0000000000", 53);
268 SIMPLE_COPY(stpcpy
, 11, "11111111111", 54);
269 SIMPLE_COPY(stpcpy
, 12, "222222222222", 55);
270 SIMPLE_COPY(stpcpy
, 13, "3333333333333", 56);
271 SIMPLE_COPY(stpcpy
, 14, "44444444444444", 57);
272 SIMPLE_COPY(stpcpy
, 15, "555555555555555", 58);
273 SIMPLE_COPY(stpcpy
, 16, "6666666666666666", 59);
280 memset (one
, 'x', sizeof (one
));
281 check (stpncpy (one
, "abc", 2) == one
+ 2, 1);
282 check (stpncpy (one
, "abc", 3) == one
+ 3, 2);
283 check (stpncpy (one
, "abc", 4) == one
+ 3, 3);
284 check (one
[3] == '\0' && one
[4] == 'x', 4);
285 check (stpncpy (one
, "abcd", 5) == one
+ 4, 5);
286 check (one
[4] == '\0' && one
[5] == 'x', 6);
287 check (stpncpy (one
, "abcd", 6) == one
+ 4, 7);
288 check (one
[4] == '\0' && one
[5] == '\0' && one
[6] == 'x', 8);
295 (void) strcpy (one
, "ijk");
296 check (strcat (one
, "lmn") == one
, 1); /* Returned value. */
297 equal (one
, "ijklmn", 2); /* Basic test. */
299 (void) strcpy (one
, "x");
300 (void) strcat (one
, "yz");
301 equal (one
, "xyz", 3); /* Writeover. */
302 equal (one
+4, "mn", 4); /* Wrote too much? */
304 (void) strcpy (one
, "gh");
305 (void) strcpy (two
, "ef");
306 (void) strcat (one
, two
);
307 equal (one
, "ghef", 5); /* Basic test encore. */
308 equal (two
, "ef", 6); /* Stomped on source? */
310 (void) strcpy (one
, "");
311 (void) strcat (one
, "");
312 equal (one
, "", 7); /* Boundary conditions. */
313 (void) strcpy (one
, "ab");
314 (void) strcat (one
, "");
315 equal (one
, "ab", 8);
316 (void) strcpy (one
, "");
317 (void) strcat (one
, "cd");
318 equal (one
, "cd", 9);
321 char buf1
[80] __attribute__ ((aligned (16)));
322 char buf2
[32] __attribute__ ((aligned (16)));
323 for (size_t n1
= 0; n1
< 16; ++n1
)
324 for (size_t n2
= 0; n2
< 16; ++n2
)
325 for (size_t n3
= 0; n3
< 32; ++n3
)
327 size_t olderrors
= errors
;
329 memset (buf1
, 'b', sizeof (buf1
));
331 memset (buf1
+ n2
, 'a', n3
);
332 buf1
[n2
+ n3
] = '\0';
333 strcpy (buf2
+ n1
, "123");
335 check (strcat (buf1
+ n2
, buf2
+ n1
) == buf1
+ n2
, ntest
);
336 if (errors
== olderrors
)
337 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
340 check (buf1
[i
] == 'b', ntest
);
341 else if (i
< n2
+ n3
)
342 check (buf1
[i
] == 'a', ntest
);
343 else if (i
< n2
+ n3
+ 3)
344 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
345 else if (i
== n2
+ n3
+ 3)
346 check (buf1
[i
] == '\0', ntest
);
348 check (buf1
[i
] == 'b', ntest
);
350 if (errors
!= olderrors
)
352 printf ("n1=%zu, n2=%zu, n3=%zu, buf1=%02hhx",
353 n1
, n2
, n3
, buf1
[0]);
354 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
355 printf (",%02hhx", buf1
[j
]);
356 putchar_unlocked ('\n');
366 /* First test it as strcat, with big counts, then test the count
369 (void) strcpy (one
, "ijk");
370 check (strncat (one
, "lmn", 99) == one
, 1); /* Returned value. */
371 equal (one
, "ijklmn", 2); /* Basic test. */
373 (void) strcpy (one
, "x");
374 (void) strncat (one
, "yz", 99);
375 equal (one
, "xyz", 3); /* Writeover. */
376 equal (one
+4, "mn", 4); /* Wrote too much? */
378 (void) strcpy (one
, "gh");
379 (void) strcpy (two
, "ef");
380 (void) strncat (one
, two
, 99);
381 equal (one
, "ghef", 5); /* Basic test encore. */
382 equal (two
, "ef", 6); /* Stomped on source? */
384 (void) strcpy (one
, "");
385 (void) strncat (one
, "", 99);
386 equal (one
, "", 7); /* Boundary conditions. */
387 (void) strcpy (one
, "ab");
388 (void) strncat (one
, "", 99);
389 equal (one
, "ab", 8);
390 (void) strcpy (one
, "");
391 (void) strncat (one
, "cd", 99);
392 equal (one
, "cd", 9);
394 (void) strcpy (one
, "ab");
395 (void) strncat (one
, "cdef", 2);
396 equal (one
, "abcd", 10); /* Count-limited. */
398 (void) strncat (one
, "gh", 0);
399 equal (one
, "abcd", 11); /* Zero count. */
401 (void) strncat (one
, "gh", 2);
402 equal (one
, "abcdgh", 12); /* Count and length equal. */
404 (void) strncat (one
, "ij", (size_t)-1); /* set sign bit in count */
405 equal (one
, "abcdghij", 13);
408 char buf1
[80] __attribute__ ((aligned (16)));
409 char buf2
[32] __attribute__ ((aligned (16)));
410 for (size_t n1
= 0; n1
< 16; ++n1
)
411 for (size_t n2
= 0; n2
< 16; ++n2
)
412 for (size_t n3
= 0; n3
< 32; ++n3
)
413 for (size_t n4
= 0; n4
< 16; ++n4
)
415 size_t olderrors
= errors
;
417 memset (buf1
, 'b', sizeof (buf1
));
419 memset (buf1
+ n2
, 'a', n3
);
420 buf1
[n2
+ n3
] = '\0';
421 strcpy (buf2
+ n1
, "123");
423 check (strncat (buf1
+ n2
, buf2
+ n1
, ~((size_t) 0) - n4
)
424 == buf1
+ n2
, ntest
);
425 if (errors
== olderrors
)
426 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
429 check (buf1
[i
] == 'b', ntest
);
430 else if (i
< n2
+ n3
)
431 check (buf1
[i
] == 'a', ntest
);
432 else if (i
< n2
+ n3
+ 3)
433 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
434 else if (i
== n2
+ n3
+ 3)
435 check (buf1
[i
] == '\0', ntest
);
437 check (buf1
[i
] == 'b', ntest
);
439 if (errors
!= olderrors
)
441 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
442 n1
, n2
, n3
, n4
, buf1
[0]);
443 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
444 printf (",%02hhx", buf1
[j
]);
445 putchar_unlocked ('\n');
455 /* First test as strcmp with big counts, then test count code. */
457 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
458 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
459 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
460 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
461 check (strncmp ("abcd", "abc", 99) > 0, 5);
462 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
463 check (strncmp ("abce", "abcd", 99) > 0, 7);
464 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
465 check (strncmp ("a\203", "a\003", 2) > 0, 9);
466 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
467 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
468 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
469 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
470 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
471 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
477 /* Testing is a bit different because of odd semantics. */
479 check (strncpy (one
, "abc", 4) == one
, 1); /* Returned value. */
480 equal (one
, "abc", 2); /* Did the copy go right? */
482 (void) strcpy (one
, "abcdefgh");
483 (void) strncpy (one
, "xyz", 2);
484 equal (one
, "xycdefgh", 3); /* Copy cut by count. */
486 (void) strcpy (one
, "abcdefgh");
487 (void) strncpy (one
, "xyz", 3); /* Copy cut just before NUL. */
488 equal (one
, "xyzdefgh", 4);
490 (void) strcpy (one
, "abcdefgh");
491 (void) strncpy (one
, "xyz", 4); /* Copy just includes NUL. */
492 equal (one
, "xyz", 5);
493 equal (one
+4, "efgh", 6); /* Wrote too much? */
495 (void) strcpy (one
, "abcdefgh");
496 (void) strncpy (one
, "xyz", 5); /* Copy includes padding. */
497 equal (one
, "xyz", 7);
498 equal (one
+4, "", 8);
499 equal (one
+5, "fgh", 9);
501 (void) strcpy (one
, "abc");
502 (void) strncpy (one
, "xyz", 0); /* Zero-length copy. */
503 equal (one
, "abc", 10);
505 (void) strncpy (one
, "", 2); /* Zero-length source. */
507 equal (one
+1, "", 12);
508 equal (one
+2, "c", 13);
510 (void) strcpy (one
, "hi there");
511 (void) strncpy (two
, one
, 9);
512 equal (two
, "hi there", 14); /* Just paranoia. */
513 equal (one
, "hi there", 15); /* Stomped on source? */
520 check (strlen ("") == 0, 1); /* Empty. */
521 check (strlen ("a") == 1, 2); /* Single char. */
522 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
527 for (i
=0; i
< 0x100; i
++)
529 p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
531 strcpy (p
+3, "BAD/WRONG");
532 check (strlen (p
) == 2, 4+i
);
541 check (strnlen ("", 10) == 0, 1); /* Empty. */
542 check (strnlen ("a", 10) == 1, 2); /* Single char. */
543 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
544 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
545 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
546 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
547 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
548 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
549 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
552 for (int i
= 0; i
< 0x100; ++i
)
554 char *p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
556 strcpy (p
+ 3, "BAD/WRONG");
557 check (strnlen (p
, 100) == 2, 10 + i
);
565 check (strchr ("abcd", 'z') == NULL
, 1); /* Not found. */
566 (void) strcpy (one
, "abcd");
567 check (strchr (one
, 'c') == one
+2, 2); /* Basic test. */
568 check (strchr (one
, 'd') == one
+3, 3); /* End of string. */
569 check (strchr (one
, 'a') == one
, 4); /* Beginning. */
570 check (strchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
571 (void) strcpy (one
, "ababa");
572 check (strchr (one
, 'b') == one
+1, 6); /* Finding first. */
573 (void) strcpy (one
, "");
574 check (strchr (one
, 'b') == NULL
, 7); /* Empty string. */
575 check (strchr (one
, '\0') == one
, 8); /* NUL in empty string. */
580 for (i
=0; i
< 0x100; i
++)
582 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
584 strcpy (p
+3, "BAD/WRONG");
585 check (strchr (p
, '/') == NULL
, 9+i
);
591 test_strchrnul (void)
595 cp
= strchrnul ((os
= "abcd"), 'z');
596 check (*cp
== '\0', 1); /* Not found. */
597 check (cp
== os
+ 4, 2);
598 (void) strcpy (one
, "abcd");
599 check (strchrnul (one
, 'c') == one
+2, 3); /* Basic test. */
600 check (strchrnul (one
, 'd') == one
+3, 4); /* End of string. */
601 check (strchrnul (one
, 'a') == one
, 5); /* Beginning. */
602 check (strchrnul (one
, '\0') == one
+4, 6); /* Finding NUL. */
603 (void) strcpy (one
, "ababa");
604 check (strchrnul (one
, 'b') == one
+1, 7); /* Finding first. */
605 (void) strcpy (one
, "");
606 check (strchrnul (one
, 'b') == one
, 8); /* Empty string. */
607 check (strchrnul (one
, '\0') == one
, 9); /* NUL in empty string. */
612 for (i
=0; i
< 0x100; i
++)
614 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
616 strcpy (p
+3, "BAD/WRONG");
617 cp
= strchrnul (p
, '/');
618 check (*cp
== '\0', 9+2*i
);
619 check (cp
== p
+2, 10+2*i
);
625 test_rawmemchr (void)
628 (void) strcpy (one
, "abcd");
629 check (rawmemchr (one
, 'c') == one
+2, 1); /* Basic test. */
630 check (rawmemchr (one
, 'd') == one
+3, 2); /* End of string. */
631 check (rawmemchr (one
, 'a') == one
, 3); /* Beginning. */
632 check (rawmemchr (one
, '\0') == one
+4, 4); /* Finding NUL. */
633 (void) strcpy (one
, "ababa");
634 check (rawmemchr (one
, 'b') == one
+1, 5); /* Finding first. */
635 (void) strcpy (one
, "");
636 check (rawmemchr (one
, '\0') == one
, 6); /* NUL in empty string. */
641 for (i
=0; i
< 0x100; i
++)
643 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
645 strcpy (p
+3, "BAD/WRONG");
646 check (rawmemchr (p
, 'R') == p
+8, 6+i
);
655 check (index ("abcd", 'z') == NULL
, 1); /* Not found. */
656 (void) strcpy (one
, "abcd");
657 check (index (one
, 'c') == one
+2, 2); /* Basic test. */
658 check (index (one
, 'd') == one
+3, 3); /* End of string. */
659 check (index (one
, 'a') == one
, 4); /* Beginning. */
660 check (index (one
, '\0') == one
+4, 5); /* Finding NUL. */
661 (void) strcpy (one
, "ababa");
662 check (index (one
, 'b') == one
+1, 6); /* Finding first. */
663 (void) strcpy (one
, "");
664 check (index (one
, 'b') == NULL
, 7); /* Empty string. */
665 check (index (one
, '\0') == one
, 8); /* NUL in empty string. */
672 check (strrchr ("abcd", 'z') == NULL
, 1); /* Not found. */
673 (void) strcpy (one
, "abcd");
674 check (strrchr (one
, 'c') == one
+2, 2); /* Basic test. */
675 check (strrchr (one
, 'd') == one
+3, 3); /* End of string. */
676 check (strrchr (one
, 'a') == one
, 4); /* Beginning. */
677 check (strrchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
678 (void) strcpy (one
, "ababa");
679 check (strrchr (one
, 'b') == one
+3, 6); /* Finding last. */
680 (void) strcpy (one
, "");
681 check (strrchr (one
, 'b') == NULL
, 7); /* Empty string. */
682 check (strrchr (one
, '\0') == one
, 8); /* NUL in empty string. */
687 for (i
=0; i
< 0x100; i
++)
689 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
691 strcpy (p
+3, "BAD/WRONG");
692 check (strrchr (p
, '/') == NULL
, 9+i
);
702 check (memrchr ("abcd", 'z', 5) == NULL
, 1); /* Not found. */
703 (void) strcpy (one
, "abcd");
704 l
= strlen (one
) + 1;
705 check (memrchr (one
, 'c', l
) == one
+2, 2); /* Basic test. */
706 check (memrchr (one
, 'd', l
) == one
+3, 3); /* End of string. */
707 check (memrchr (one
, 'a', l
) == one
, 4); /* Beginning. */
708 check (memrchr (one
, '\0', l
) == one
+4, 5); /* Finding NUL. */
709 (void) strcpy (one
, "ababa");
710 l
= strlen (one
) + 1;
711 check (memrchr (one
, 'b', l
) == one
+3, 6); /* Finding last. */
712 (void) strcpy (one
, "");
713 l
= strlen (one
) + 1;
714 check (memrchr (one
, 'b', l
) == NULL
, 7); /* Empty string. */
715 check (memrchr (one
, '\0', l
) == one
, 8); /* NUL in empty string. */
717 /* now test all possible alignment and length combinations to catch
718 bugs due to unrolled loops (assuming unrolling is limited to no
719 more than 128 byte chunks: */
721 char buf
[128 + sizeof (long)];
722 long align
, len
, i
, pos
, n
= 9;
724 for (align
= 0; align
< (long) sizeof (long); ++align
) {
725 for (len
= 0; len
< (long) (sizeof (buf
) - align
); ++len
) {
726 for (i
= 0; i
< len
; ++i
)
727 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
729 for (pos
= len
- 1; pos
>= 0; --pos
) {
731 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
733 check(memrchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, n
++);
734 check(memrchr(buf
+ align
+ pos
+ 1, 'x', len
- (pos
+ 1)) == NULL
,
736 buf
[align
+ pos
] = '-';
747 check (rindex ("abcd", 'z') == NULL
, 1); /* Not found. */
748 (void) strcpy (one
, "abcd");
749 check (rindex (one
, 'c') == one
+2, 2); /* Basic test. */
750 check (rindex (one
, 'd') == one
+3, 3); /* End of string. */
751 check (rindex (one
, 'a') == one
, 4); /* Beginning. */
752 check (rindex (one
, '\0') == one
+4, 5); /* Finding NUL. */
753 (void) strcpy (one
, "ababa");
754 check (rindex (one
, 'b') == one
+3, 6); /* Finding last. */
755 (void) strcpy (one
, "");
756 check (rindex (one
, 'b') == NULL
, 7); /* Empty string. */
757 check (rindex (one
, '\0') == one
, 8); /* NUL in empty string. */
764 check(strpbrk("abcd", "z") == NULL
, 1); /* Not found. */
765 (void) strcpy(one
, "abcd");
766 check(strpbrk(one
, "c") == one
+2, 2); /* Basic test. */
767 check(strpbrk(one
, "d") == one
+3, 3); /* End of string. */
768 check(strpbrk(one
, "a") == one
, 4); /* Beginning. */
769 check(strpbrk(one
, "") == NULL
, 5); /* Empty search list. */
770 check(strpbrk(one
, "cb") == one
+1, 6); /* Multiple search. */
771 (void) strcpy(one
, "abcabdea");
772 check(strpbrk(one
, "b") == one
+1, 7); /* Finding first. */
773 check(strpbrk(one
, "cb") == one
+1, 8); /* With multiple search. */
774 check(strpbrk(one
, "db") == one
+1, 9); /* Another variant. */
775 (void) strcpy(one
, "");
776 check(strpbrk(one
, "bc") == NULL
, 10); /* Empty string. */
777 (void) strcpy(one
, "");
778 check(strpbrk(one
, "bcd") == NULL
, 11); /* Empty string. */
779 (void) strcpy(one
, "");
780 check(strpbrk(one
, "bcde") == NULL
, 12); /* Empty string. */
781 check(strpbrk(one
, "") == NULL
, 13); /* Both strings empty. */
782 (void) strcpy(one
, "abcabdea");
783 check(strpbrk(one
, "befg") == one
+1, 14); /* Finding first. */
784 check(strpbrk(one
, "cbr") == one
+1, 15); /* With multiple search. */
785 check(strpbrk(one
, "db") == one
+1, 16); /* Another variant. */
786 check(strpbrk(one
, "efgh") == one
+6, 17); /* And yet another. */
793 check(strstr("abcd", "z") == NULL
, 1); /* Not found. */
794 check(strstr("abcd", "abx") == NULL
, 2); /* Dead end. */
795 (void) strcpy(one
, "abcd");
796 check(strstr(one
, "c") == one
+2, 3); /* Basic test. */
797 check(strstr(one
, "bc") == one
+1, 4); /* Multichar. */
798 check(strstr(one
, "d") == one
+3, 5); /* End of string. */
799 check(strstr(one
, "cd") == one
+2, 6); /* Tail of string. */
800 check(strstr(one
, "abc") == one
, 7); /* Beginning. */
801 check(strstr(one
, "abcd") == one
, 8); /* Exact match. */
802 check(strstr(one
, "abcde") == NULL
, 9); /* Too long. */
803 check(strstr(one
, "de") == NULL
, 10); /* Past end. */
804 check(strstr(one
, "") == one
, 11); /* Finding empty. */
805 (void) strcpy(one
, "ababa");
806 check(strstr(one
, "ba") == one
+1, 12); /* Finding first. */
807 (void) strcpy(one
, "");
808 check(strstr(one
, "b") == NULL
, 13); /* Empty string. */
809 check(strstr(one
, "") == one
, 14); /* Empty in empty string. */
810 (void) strcpy(one
, "bcbca");
811 check(strstr(one
, "bca") == one
+2, 15); /* False start. */
812 (void) strcpy(one
, "bbbcabbca");
813 check(strstr(one
, "bbca") == one
+1, 16); /* With overlap. */
820 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
821 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
822 check(strspn("abc", "qx") == 0, 3); /* None. */
823 check(strspn("", "ab") == 0, 4); /* Null string. */
824 check(strspn("abc", "") == 0, 5); /* Null search list. */
831 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
832 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
833 check(strcspn("abc", "abc") == 0, 3); /* None. */
834 check(strcspn("", "ab") == 0, 4); /* Null string. */
835 check(strcspn("abc", "") == 3, 5); /* Null search list. */
842 (void) strcpy(one
, "first, second, third");
843 equal(strtok(one
, ", "), "first", 1); /* Basic test. */
844 equal(one
, "first", 2);
845 equal(strtok((char *)NULL
, ", "), "second", 3);
846 equal(strtok((char *)NULL
, ", "), "third", 4);
847 check(strtok((char *)NULL
, ", ") == NULL
, 5);
848 (void) strcpy(one
, ", first, ");
849 equal(strtok(one
, ", "), "first", 6); /* Extra delims, 1 tok. */
850 check(strtok((char *)NULL
, ", ") == NULL
, 7);
851 (void) strcpy(one
, "1a, 1b; 2a, 2b");
852 equal(strtok(one
, ", "), "1a", 8); /* Changing delim lists. */
853 equal(strtok((char *)NULL
, "; "), "1b", 9);
854 equal(strtok((char *)NULL
, ", "), "2a", 10);
855 (void) strcpy(two
, "x-y");
856 equal(strtok(two
, "-"), "x", 11); /* New string before done. */
857 equal(strtok((char *)NULL
, "-"), "y", 12);
858 check(strtok((char *)NULL
, "-") == NULL
, 13);
859 (void) strcpy(one
, "a,b, c,, ,d");
860 equal(strtok(one
, ", "), "a", 14); /* Different separators. */
861 equal(strtok((char *)NULL
, ", "), "b", 15);
862 equal(strtok((char *)NULL
, " ,"), "c", 16); /* Permute list too. */
863 equal(strtok((char *)NULL
, " ,"), "d", 17);
864 check(strtok((char *)NULL
, ", ") == NULL
, 18);
865 check(strtok((char *)NULL
, ", ") == NULL
, 19); /* Persistence. */
866 (void) strcpy(one
, ", ");
867 check(strtok(one
, ", ") == NULL
, 20); /* No tokens. */
868 (void) strcpy(one
, "");
869 check(strtok(one
, ", ") == NULL
, 21); /* Empty string. */
870 (void) strcpy(one
, "abc");
871 equal(strtok(one
, ", "), "abc", 22); /* No delimiters. */
872 check(strtok((char *)NULL
, ", ") == NULL
, 23);
873 (void) strcpy(one
, "abc");
874 equal(strtok(one
, ""), "abc", 24); /* Empty delimiter list. */
875 check(strtok((char *)NULL
, "") == NULL
, 25);
876 (void) strcpy(one
, "abcdefgh");
877 (void) strcpy(one
, "a,b,c");
878 equal(strtok(one
, ","), "a", 26); /* Basics again... */
879 equal(strtok((char *)NULL
, ","), "b", 27);
880 equal(strtok((char *)NULL
, ","), "c", 28);
881 check(strtok((char *)NULL
, ",") == NULL
, 29);
882 equal(one
+6, "gh", 30); /* Stomped past end? */
883 equal(one
, "a", 31); /* Stomped old tokens? */
884 equal(one
+2, "b", 32);
885 equal(one
+4, "c", 33);
892 (void) strcpy(one
, "first, second, third");
893 cp
= NULL
; /* Always initialize cp to make sure it doesn't point to some old data. */
894 equal(strtok_r(one
, ", ", &cp
), "first", 1); /* Basic test. */
895 equal(one
, "first", 2);
896 equal(strtok_r((char *)NULL
, ", ", &cp
), "second", 3);
897 equal(strtok_r((char *)NULL
, ", ", &cp
), "third", 4);
898 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 5);
899 (void) strcpy(one
, ", first, ");
901 equal(strtok_r(one
, ", ", &cp
), "first", 6); /* Extra delims, 1 tok. */
902 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 7);
903 (void) strcpy(one
, "1a, 1b; 2a, 2b");
905 equal(strtok_r(one
, ", ", &cp
), "1a", 8); /* Changing delim lists. */
906 equal(strtok_r((char *)NULL
, "; ", &cp
), "1b", 9);
907 equal(strtok_r((char *)NULL
, ", ", &cp
), "2a", 10);
908 (void) strcpy(two
, "x-y");
910 equal(strtok_r(two
, "-", &cp
), "x", 11); /* New string before done. */
911 equal(strtok_r((char *)NULL
, "-", &cp
), "y", 12);
912 check(strtok_r((char *)NULL
, "-", &cp
) == NULL
, 13);
913 (void) strcpy(one
, "a,b, c,, ,d");
915 equal(strtok_r(one
, ", ", &cp
), "a", 14); /* Different separators. */
916 equal(strtok_r((char *)NULL
, ", ", &cp
), "b", 15);
917 equal(strtok_r((char *)NULL
, " ,", &cp
), "c", 16); /* Permute list too. */
918 equal(strtok_r((char *)NULL
, " ,", &cp
), "d", 17);
919 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 18);
920 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 19); /* Persistence. */
921 (void) strcpy(one
, ", ");
923 check(strtok_r(one
, ", ", &cp
) == NULL
, 20); /* No tokens. */
924 (void) strcpy(one
, "");
926 check(strtok_r(one
, ", ", &cp
) == NULL
, 21); /* Empty string. */
927 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 22); /* Persistence. */
928 (void) strcpy(one
, "abc");
930 equal(strtok_r(one
, ", ", &cp
), "abc", 23); /* No delimiters. */
931 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 24);
932 (void) strcpy(one
, "abc");
934 equal(strtok_r(one
, "", &cp
), "abc", 25); /* Empty delimiter list. */
935 check(strtok_r((char *)NULL
, "", &cp
) == NULL
, 26);
936 (void) strcpy(one
, "abcdefgh");
937 (void) strcpy(one
, "a,b,c");
939 equal(strtok_r(one
, ",", &cp
), "a", 27); /* Basics again... */
940 equal(strtok_r((char *)NULL
, ",", &cp
), "b", 28);
941 equal(strtok_r((char *)NULL
, ",", &cp
), "c", 29);
942 check(strtok_r((char *)NULL
, ",", &cp
) == NULL
, 30);
943 equal(one
+6, "gh", 31); /* Stomped past end? */
944 equal(one
, "a", 32); /* Stomped old tokens? */
945 equal(one
+2, "b", 33);
946 equal(one
+4, "c", 34);
949 check (strtok_r (one
, ":", &cp
) == NULL
, 35); /* Must store pointer in cp. */
950 check (strtok_r (NULL
, ":", &cp
) == NULL
, 36);
958 cp
= strcpy(one
, "first, second, third");
959 equal(strsep(&cp
, ", "), "first", 1); /* Basic test. */
960 equal(one
, "first", 2);
961 equal(strsep(&cp
, ", "), "", 3);
962 equal(strsep(&cp
, ", "), "second", 4);
963 equal(strsep(&cp
, ", "), "", 5);
964 equal(strsep(&cp
, ", "), "third", 6);
965 check(strsep(&cp
, ", ") == NULL
, 7);
966 cp
= strcpy(one
, ", first, ");
967 equal(strsep(&cp
, ", "), "", 8);
968 equal(strsep(&cp
, ", "), "", 9);
969 equal(strsep(&cp
, ", "), "first", 10); /* Extra delims, 1 tok. */
970 equal(strsep(&cp
, ", "), "", 11);
971 equal(strsep(&cp
, ", "), "", 12);
972 check(strsep(&cp
, ", ") == NULL
, 13);
973 cp
= strcpy(one
, "1a, 1b; 2a, 2b");
974 equal(strsep(&cp
, ", "), "1a", 14); /* Changing delim lists. */
975 equal(strsep(&cp
, ", "), "", 15);
976 equal(strsep(&cp
, "; "), "1b", 16);
977 equal(strsep(&cp
, ", "), "", 17);
978 equal(strsep(&cp
, ", "), "2a", 18);
979 cp
= strcpy(two
, "x-y");
980 equal(strsep(&cp
, "-"), "x", 19); /* New string before done. */
981 equal(strsep(&cp
, "-"), "y", 20);
982 check(strsep(&cp
, "-") == NULL
, 21);
983 cp
= strcpy(one
, "a,b, c,, ,d ");
984 equal(strsep(&cp
, ", "), "a", 22); /* Different separators. */
985 equal(strsep(&cp
, ", "), "b", 23);
986 equal(strsep(&cp
, " ,"), "", 24);
987 equal(strsep(&cp
, " ,"), "c", 25); /* Permute list too. */
988 equal(strsep(&cp
, " ,"), "", 26);
989 equal(strsep(&cp
, " ,"), "", 27);
990 equal(strsep(&cp
, " ,"), "", 28);
991 equal(strsep(&cp
, " ,"), "d", 29);
992 equal(strsep(&cp
, " ,"), "", 30);
993 check(strsep(&cp
, ", ") == NULL
, 31);
994 check(strsep(&cp
, ", ") == NULL
, 32); /* Persistence. */
995 cp
= strcpy(one
, ", ");
996 equal(strsep(&cp
, ", "), "", 33);
997 equal(strsep(&cp
, ", "), "", 34);
998 equal(strsep(&cp
, ", "), "", 35);
999 check(strsep(&cp
, ", ") == NULL
, 36); /* No tokens. */
1000 cp
= strcpy(one
, "");
1001 equal(strsep(&cp
, ", "), "", 37);
1002 check(strsep(&cp
, ", ") == NULL
, 38); /* Empty string. */
1003 cp
= strcpy(one
, "abc");
1004 equal(strsep(&cp
, ", "), "abc", 39); /* No delimiters. */
1005 check(strsep(&cp
, ", ") == NULL
, 40);
1006 cp
= strcpy(one
, "abc");
1007 equal(strsep(&cp
, ""), "abc", 41); /* Empty delimiter list. */
1008 check(strsep(&cp
, "") == NULL
, 42);
1009 (void) strcpy(one
, "abcdefgh");
1010 cp
= strcpy(one
, "a,b,c");
1011 equal(strsep(&cp
, ","), "a", 43); /* Basics again... */
1012 equal(strsep(&cp
, ","), "b", 44);
1013 equal(strsep(&cp
, ","), "c", 45);
1014 check(strsep(&cp
, ",") == NULL
, 46);
1015 equal(one
+6, "gh", 47); /* Stomped past end? */
1016 equal(one
, "a", 48); /* Stomped old tokens? */
1017 equal(one
+2, "b", 49);
1018 equal(one
+4, "c", 50);
1021 char text
[] = "This,is,a,test";
1022 char *list
= strdupa (text
);
1023 equal (strsep (&list
, ","), "This", 51);
1024 equal (strsep (&list
, ","), "is", 52);
1025 equal (strsep (&list
, ","), "a", 53);
1026 equal (strsep (&list
, ","), "test", 54);
1027 check (strsep (&list
, ",") == NULL
, 55);
1030 cp
= strcpy(one
, "a,b, c,, ,d,");
1031 equal(strsep(&cp
, ","), "a", 56); /* Different separators. */
1032 equal(strsep(&cp
, ","), "b", 57);
1033 equal(strsep(&cp
, ","), " c", 58); /* Permute list too. */
1034 equal(strsep(&cp
, ","), "", 59);
1035 equal(strsep(&cp
, ","), " ", 60);
1036 equal(strsep(&cp
, ","), "d", 61);
1037 equal(strsep(&cp
, ","), "", 62);
1038 check(strsep(&cp
, ",") == NULL
, 63);
1039 check(strsep(&cp
, ",") == NULL
, 64); /* Persistence. */
1041 cp
= strcpy(one
, "a,b, c,, ,d,");
1042 equal(strsep(&cp
, "xy,"), "a", 65); /* Different separators. */
1043 equal(strsep(&cp
, "x,y"), "b", 66);
1044 equal(strsep(&cp
, ",xy"), " c", 67); /* Permute list too. */
1045 equal(strsep(&cp
, "xy,"), "", 68);
1046 equal(strsep(&cp
, "x,y"), " ", 69);
1047 equal(strsep(&cp
, ",xy"), "d", 70);
1048 equal(strsep(&cp
, "xy,"), "", 71);
1049 check(strsep(&cp
, "x,y") == NULL
, 72);
1050 check(strsep(&cp
, ",xy") == NULL
, 73); /* Persistence. */
1052 cp
= strcpy(one
, "ABC");
1054 equal(strsep(&cp
, "C"), "AB", 74); /* Access beyond NUL. */
1055 ptr
= strsep(&cp
, ":");
1057 check(ptr
== one
+ 3, 76);
1058 check(cp
== NULL
, 77);
1060 cp
= strcpy(one
, "ABC");
1062 equal(strsep(&cp
, "CD"), "AB", 78); /* Access beyond NUL. */
1063 ptr
= strsep(&cp
, ":.");
1065 check(ptr
== one
+ 3, 80);
1067 cp
= strcpy(one
, "ABC"); /* No token in string. */
1068 equal(strsep(&cp
, ","), "ABC", 81);
1069 check(cp
== NULL
, 82);
1071 *one
= '\0'; /* Empty string. */
1073 ptr
= strsep(&cp
, ",");
1075 check(ptr
== one
, 84);
1076 check(cp
== NULL
, 85);
1078 *one
= '\0'; /* Empty string and no token. */
1080 ptr
= strsep(&cp
, "");
1082 check(ptr
== one
, 87);
1083 check(cp
== NULL
, 88);
1094 check(memcmp("a", "a", 1) == 0, cnt
++); /* Identity. */
1095 check(memcmp("abc", "abc", 3) == 0, cnt
++); /* Multicharacter. */
1096 check(memcmp("abcd", "abcf", 4) < 0, cnt
++); /* Honestly unequal. */
1097 check(memcmp("abcf", "abcd", 4) > 0, cnt
++);
1098 check(memcmp("alph", "cold", 4) < 0, cnt
++);
1099 check(memcmp("a\203", "a\003", 2) > 0, cnt
++);
1100 check(memcmp("a\003", "a\203", 2) < 0, cnt
++);
1101 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt
++);
1102 check(memcmp("abc\203", "abc\003", 4) > 0, cnt
++);
1103 check(memcmp("abc\003", "abc\203", 4) < 0, cnt
++);
1104 check(memcmp("abcf", "abcd", 3) == 0, cnt
++); /* Count limited. */
1105 check(memcmp("abc", "def", 0) == 0, cnt
++); /* Zero count. */
1106 /* Comparisons with shifting 4-byte boundaries. */
1107 for (int i
= 0; i
< 4; ++i
)
1111 memcpy(a
, "--------11112222", 16);
1112 memcpy(b
, "--------33334444", 16);
1113 check(memcmp(b
, a
, 16) > 0, cnt
++);
1114 check(memcmp(a
, b
, 16) < 0, cnt
++);
1122 check(memchr("abcd", 'z', 4) == NULL
, 1); /* Not found. */
1123 (void) strcpy(one
, "abcd");
1124 check(memchr(one
, 'c', 4) == one
+2, 2); /* Basic test. */
1125 check(memchr(one
, ~0xff|'c', 4) == one
+2, 2); /* ignore highorder bits. */
1126 check(memchr(one
, 'd', 4) == one
+3, 3); /* End of string. */
1127 check(memchr(one
, 'a', 4) == one
, 4); /* Beginning. */
1128 check(memchr(one
, '\0', 5) == one
+4, 5); /* Finding NUL. */
1129 (void) strcpy(one
, "ababa");
1130 check(memchr(one
, 'b', 5) == one
+1, 6); /* Finding first. */
1131 check(memchr(one
, 'b', 0) == NULL
, 7); /* Zero count. */
1132 check(memchr(one
, 'a', 1) == one
, 8); /* Singleton case. */
1133 (void) strcpy(one
, "a\203b");
1134 check(memchr(one
, 0203, 3) == one
+1, 9); /* Unsignedness. */
1136 /* now test all possible alignment and length combinations to catch
1137 bugs due to unrolled loops (assuming unrolling is limited to no
1138 more than 128 byte chunks: */
1140 char buf
[128 + sizeof (long)];
1141 long align
, len
, i
, pos
;
1143 for (align
= 0; align
< (long) sizeof (long); ++align
) {
1144 for (len
= 0; len
< (long) (sizeof (buf
) - align
); ++len
) {
1145 for (i
= 0; i
< len
; ++i
) {
1146 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
1148 for (pos
= 0; pos
< len
; ++pos
) {
1150 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
1152 check(memchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, 10);
1153 check(memchr(buf
+ align
, 'x', pos
) == NULL
, 11);
1154 buf
[align
+ pos
] = '-';
1166 check(memcpy(one
, "abc", 4) == one
, 1); /* Returned value. */
1167 equal(one
, "abc", 2); /* Did the copy go right? */
1169 (void) strcpy(one
, "abcdefgh");
1170 (void) memcpy(one
+1, "xyz", 2);
1171 equal(one
, "axydefgh", 3); /* Basic test. */
1173 (void) strcpy(one
, "abc");
1174 (void) memcpy(one
, "xyz", 0);
1175 equal(one
, "abc", 4); /* Zero-length copy. */
1177 (void) strcpy(one
, "hi there");
1178 (void) strcpy(two
, "foo");
1179 (void) memcpy(two
, one
, 9);
1180 equal(two
, "hi there", 5); /* Just paranoia. */
1181 equal(one
, "hi there", 6); /* Stomped on source? */
1183 for (i
= 0; i
< 16; i
++)
1185 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1187 check (memcpy (one
+ i
, "hi there", 9) == one
+ i
,
1188 7 + (i
* 6)); /* Unaligned destination. */
1189 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1190 equal (one
+ i
, "hi there", 9 + (i
* 6));
1191 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1192 check (memcpy (two
, one
+ i
, 9) == two
,
1193 11 + (i
* 6)); /* Unaligned source. */
1194 equal (two
, "hi there", 12 + (i
* 6));
1203 check(mempcpy(one
, "abc", 4) == one
+ 4, 1); /* Returned value. */
1204 equal(one
, "abc", 2); /* Did the copy go right? */
1206 (void) strcpy(one
, "abcdefgh");
1207 (void) mempcpy(one
+1, "xyz", 2);
1208 equal(one
, "axydefgh", 3); /* Basic test. */
1210 (void) strcpy(one
, "abc");
1211 (void) mempcpy(one
, "xyz", 0);
1212 equal(one
, "abc", 4); /* Zero-length copy. */
1214 (void) strcpy(one
, "hi there");
1215 (void) strcpy(two
, "foo");
1216 (void) mempcpy(two
, one
, 9);
1217 equal(two
, "hi there", 5); /* Just paranoia. */
1218 equal(one
, "hi there", 6); /* Stomped on source? */
1220 for (i
= 0; i
< 16; i
++)
1222 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1224 check (mempcpy (one
+ i
, "hi there", 9) == one
+ i
+ 9,
1225 7 + (i
* 6)); /* Unaligned destination. */
1226 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1227 equal (one
+ i
, "hi there", 9 + (i
* 6));
1228 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1229 check (mempcpy (two
, one
+ i
, 9) == two
+ 9,
1230 11 + (i
* 6)); /* Unaligned source. */
1231 equal (two
, "hi there", 12 + (i
* 6));
1239 check(memmove(one
, "abc", 4) == one
, 1); /* Returned value. */
1240 equal(one
, "abc", 2); /* Did the copy go right? */
1242 (void) strcpy(one
, "abcdefgh");
1243 (void) memmove(one
+1, "xyz", 2);
1244 equal(one
, "axydefgh", 3); /* Basic test. */
1246 (void) strcpy(one
, "abc");
1247 (void) memmove(one
, "xyz", 0);
1248 equal(one
, "abc", 4); /* Zero-length copy. */
1250 (void) strcpy(one
, "hi there");
1251 (void) strcpy(two
, "foo");
1252 (void) memmove(two
, one
, 9);
1253 equal(two
, "hi there", 5); /* Just paranoia. */
1254 equal(one
, "hi there", 6); /* Stomped on source? */
1256 (void) strcpy(one
, "abcdefgh");
1257 (void) memmove(one
+1, one
, 9);
1258 equal(one
, "aabcdefgh", 7); /* Overlap, right-to-left. */
1260 (void) strcpy(one
, "abcdefgh");
1261 (void) memmove(one
+1, one
+2, 7);
1262 equal(one
, "acdefgh", 8); /* Overlap, left-to-right. */
1264 (void) strcpy(one
, "abcdefgh");
1265 (void) memmove(one
, one
, 9);
1266 equal(one
, "abcdefgh", 9); /* 100% overlap. */
1272 /* First test like memcpy, then the search part The SVID, the only
1273 place where memccpy is mentioned, says overlap might fail, so we
1274 don't try it. Besides, it's hard to see the rationale for a
1275 non-left-to-right memccpy. */
1277 check(memccpy(one
, "abc", 'q', 4) == NULL
, 1); /* Returned value. */
1278 equal(one
, "abc", 2); /* Did the copy go right? */
1280 (void) strcpy(one
, "abcdefgh");
1281 (void) memccpy(one
+1, "xyz", 'q', 2);
1282 equal(one
, "axydefgh", 3); /* Basic test. */
1284 (void) strcpy(one
, "abc");
1285 (void) memccpy(one
, "xyz", 'q', 0);
1286 equal(one
, "abc", 4); /* Zero-length copy. */
1288 (void) strcpy(one
, "hi there");
1289 (void) strcpy(two
, "foo");
1290 (void) memccpy(two
, one
, 'q', 9);
1291 equal(two
, "hi there", 5); /* Just paranoia. */
1292 equal(one
, "hi there", 6); /* Stomped on source? */
1294 (void) strcpy(one
, "abcdefgh");
1295 (void) strcpy(two
, "horsefeathers");
1296 check(memccpy(two
, one
, 'f', 9) == two
+6, 7); /* Returned value. */
1297 equal(one
, "abcdefgh", 8); /* Source intact? */
1298 equal(two
, "abcdefeathers", 9); /* Copy correct? */
1300 (void) strcpy(one
, "abcd");
1301 (void) strcpy(two
, "bumblebee");
1302 check(memccpy(two
, one
, 'a', 4) == two
+1, 10); /* First char. */
1303 equal(two
, "aumblebee", 11);
1304 check(memccpy(two
, one
, 'd', 4) == two
+4, 12); /* Last char. */
1305 equal(two
, "abcdlebee", 13);
1306 (void) strcpy(one
, "xyz");
1307 check(memccpy(two
, one
, 'x', 1) == two
+1, 14); /* Singleton. */
1308 equal(two
, "xbcdlebee", 15);
1317 (void) strcpy(one
, "abcdefgh");
1318 check(memset(one
+1, 'x', 3) == one
+1, 1); /* Return value. */
1319 equal(one
, "axxxefgh", 2); /* Basic test. */
1321 (void) memset(one
+2, 'y', 0);
1322 equal(one
, "axxxefgh", 3); /* Zero-length set. */
1324 (void) memset(one
+5, 0, 1);
1325 equal(one
, "axxxe", 4); /* Zero fill. */
1326 equal(one
+6, "gh", 5); /* And the leftover. */
1328 (void) memset(one
+2, 010045, 1);
1329 equal(one
, "ax\045xe", 6); /* Unsigned char convert. */
1331 /* Non-8bit fill character. */
1332 memset (one
, 0x101, sizeof (one
));
1333 for (i
= 0; i
< (int) sizeof (one
); ++i
)
1334 check (one
[i
] == '\01', 7);
1336 /* Test for more complex versions of memset, for all alignments and
1337 lengths up to 256. This test takes a little while, perhaps it should
1345 for (i
= 0; i
< 512; i
++)
1347 for (c
= 0; c
<= 'y'; c
+= 'y') /* check for memset(,0,) and
1349 for (j
= 0; j
< 256; j
++)
1350 for (i
= 0; i
< 256; i
++)
1352 memset (data
+ i
, c
, j
);
1353 for (k
= 0; k
< i
; k
++)
1356 for (k
= i
; k
< i
+j
; k
++)
1362 for (k
= i
+j
; k
< 512; k
++)
1368 check (0, 8 + i
+ j
* 256 + (c
!= 0) * 256 * 256);
1376 /* Much like memcpy. Berklix manual is silent about overlap, so
1379 (void) bcopy("abc", one
, 4);
1380 equal(one
, "abc", 1); /* Simple copy. */
1382 (void) strcpy(one
, "abcdefgh");
1383 (void) bcopy("xyz", one
+1, 2);
1384 equal(one
, "axydefgh", 2); /* Basic test. */
1386 (void) strcpy(one
, "abc");
1387 (void) bcopy("xyz", one
, 0);
1388 equal(one
, "abc", 3); /* Zero-length copy. */
1390 (void) strcpy(one
, "hi there");
1391 (void) strcpy(two
, "foo");
1392 (void) bcopy(one
, two
, 9);
1393 equal(two
, "hi there", 4); /* Just paranoia. */
1394 equal(one
, "hi there", 5); /* Stomped on source? */
1401 (void) strcpy(one
, "abcdef");
1403 equal(one
, "ab", 1); /* Basic test. */
1404 equal(one
+3, "", 2);
1405 equal(one
+4, "ef", 3);
1407 (void) strcpy(one
, "abcdef");
1409 equal(one
, "abcdef", 4); /* Zero-length copy. */
1417 p
= strndup("abcdef", 12);
1418 check(p
!= NULL
, 1);
1421 equal(p
, "abcdef", 2);
1422 q
= strndup(p
+ 1, 2);
1423 check(q
!= NULL
, 3);
1429 p
= strndup("abc def", 3);
1430 check(p
!= NULL
, 5);
1440 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1441 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1442 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1443 check(bcmp("abce", "abcd", 4) != 0, 4);
1444 check(bcmp("alph", "beta", 4) != 0, 5);
1445 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1446 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1450 test_strerror (void)
1453 check(strerror(EDOM
) != 0, 1);
1454 check(strerror(ERANGE
) != 0, 2);
1455 check(strerror(ENOENT
) != 0, 3);
1459 test_strcasecmp (void)
1462 /* Note that the locale is "C". */
1463 check(strcasecmp("a", "a") == 0, 1);
1464 check(strcasecmp("a", "A") == 0, 2);
1465 check(strcasecmp("A", "a") == 0, 3);
1466 check(strcasecmp("a", "b") < 0, 4);
1467 check(strcasecmp("c", "b") > 0, 5);
1468 check(strcasecmp("abc", "AbC") == 0, 6);
1469 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1470 check(strcasecmp("", "0123456789") < 0, 8);
1471 check(strcasecmp("AbC", "") > 0, 9);
1472 check(strcasecmp("AbC", "A") > 0, 10);
1473 check(strcasecmp("AbC", "Ab") > 0, 11);
1474 check(strcasecmp("AbC", "ab") > 0, 12);
1478 test_strncasecmp (void)
1481 /* Note that the locale is "C". */
1482 check(strncasecmp("a", "a", 5) == 0, 1);
1483 check(strncasecmp("a", "A", 5) == 0, 2);
1484 check(strncasecmp("A", "a", 5) == 0, 3);
1485 check(strncasecmp("a", "b", 5) < 0, 4);
1486 check(strncasecmp("c", "b", 5) > 0, 5);
1487 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1488 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1489 check(strncasecmp("", "0123456789", 10) < 0, 8);
1490 check(strncasecmp("AbC", "", 5) > 0, 9);
1491 check(strncasecmp("AbC", "A", 5) > 0, 10);
1492 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1493 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1494 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1495 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1496 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1497 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1498 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1499 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1500 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1501 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1509 /* Test strcmp first because we use it to test other things. */
1512 /* Test strcpy next because we need it to set up other tests. */
1515 /* A closely related function is stpcpy. */
1548 /* index - just like strchr. */
1557 /* rindex - just like strrchr. */
1560 /* strpbrk - somewhat like strchr. */
1563 /* strstr - somewhat like strchr. */
1572 /* strtok - the hard one. */
1587 /* memcpy - need not work for overlap. */
1590 /* memmove - must work on overlap. */
1608 /* bcmp - somewhat like memcmp. */
1614 /* strerror - VERY system-dependent. */
1617 /* strcasecmp. Without locale dependencies. */
1620 /* strncasecmp. Without locale dependencies. */
1621 test_strncasecmp ();
1625 status
= EXIT_SUCCESS
;
1630 status
= EXIT_FAILURE
;
1631 printf("%Zd errors.\n", errors
);