1 /* Tester for string functions.
2 Copyright (C) 1995-2017 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 <http://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>
38 #define STREQ(a, b) (strcmp((a), (b)) == 0)
40 const char *it
= "<UNSET>"; /* Routine name for message routines. */
43 /* Complain if condition is not true. */
45 check (int thing
, int number
)
49 printf ("%s flunked test %d\n", it
, number
);
54 /* Complain if first two args don't strcmp as equal. */
56 equal (const char *a
, const char *b
, int number
)
58 check (a
!= NULL
&& b
!= NULL
&& STREQ (a
, b
), number
);
69 check (strcmp ("", "") == 0, 1); /* Trivial case. */
70 check (strcmp ("a", "a") == 0, 2); /* Identity. */
71 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
72 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
73 check (strcmp ("abcd", "abc") > 0, 5);
74 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
75 check (strcmp ("abce", "abcd") > 0, 7);
76 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
77 check (strcmp ("a\203", "a\003") > 0, 9);
80 char buf1
[0x40], buf2
[0x40];
82 for (i
=0; i
< 0x10; i
++)
83 for (j
= 0; j
< 0x10; j
++)
86 for (k
= 0; k
< 0x3f; k
++)
88 buf1
[k
] = '0' ^ (k
& 4);
89 buf2
[k
] = '4' ^ (k
& 4);
91 buf1
[i
] = buf1
[0x3f] = 0;
92 buf2
[j
] = buf2
[0x3f] = 0;
93 for (k
= 0; k
< 0xf; k
++)
95 int cnum
= 0x10+0x10*k
+0x100*j
+0x1000*i
;
96 check (strcmp (buf1
+i
,buf2
+j
) == 0, cnum
);
97 buf1
[i
+k
] = 'A' + i
+ k
;
99 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+1);
100 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+2);
101 buf2
[j
+k
] = 'B' + i
+ k
;
103 check (strcmp (buf1
+i
,buf2
+j
) < 0, cnum
+3);
104 check (strcmp (buf2
+j
,buf1
+i
) > 0, cnum
+4);
105 buf2
[j
+k
] = 'A' + i
+ k
;
106 buf1
[i
] = 'A' + i
+ 0x80;
107 check (strcmp (buf1
+i
,buf2
+j
) > 0, cnum
+5);
108 check (strcmp (buf2
+j
,buf1
+i
) < 0, cnum
+6);
115 #define SIMPLE_COPY(fn, n, str, ntest) \
119 for (__n = 0; __n < (int) sizeof (one); ++__n) \
122 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
123 check (*cp == '0' + (n % 10), ntest); \
124 check (*cp == '\0', ntest); \
132 check (strcpy (one
, "abcd") == one
, 1); /* Returned value. */
133 equal (one
, "abcd", 2); /* Basic test. */
135 (void) strcpy (one
, "x");
136 equal (one
, "x", 3); /* Writeover. */
137 equal (one
+2, "cd", 4); /* Wrote too much? */
139 (void) strcpy (two
, "hi there");
140 (void) strcpy (one
, two
);
141 equal (one
, "hi there", 5); /* Basic test encore. */
142 equal (two
, "hi there", 6); /* Stomped on source? */
144 (void) strcpy (one
, "");
145 equal (one
, "", 7); /* Boundary condition. */
147 for (i
= 0; i
< 16; i
++)
149 (void) strcpy (one
+ i
, "hi there"); /* Unaligned destination. */
150 equal (one
+ i
, "hi there", 8 + (i
* 2));
151 (void) strcpy (two
, one
+ i
); /* Unaligned source. */
152 equal (two
, "hi there", 9 + (i
* 2));
155 SIMPLE_COPY(strcpy
, 0, "", 41);
156 SIMPLE_COPY(strcpy
, 1, "1", 42);
157 SIMPLE_COPY(strcpy
, 2, "22", 43);
158 SIMPLE_COPY(strcpy
, 3, "333", 44);
159 SIMPLE_COPY(strcpy
, 4, "4444", 45);
160 SIMPLE_COPY(strcpy
, 5, "55555", 46);
161 SIMPLE_COPY(strcpy
, 6, "666666", 47);
162 SIMPLE_COPY(strcpy
, 7, "7777777", 48);
163 SIMPLE_COPY(strcpy
, 8, "88888888", 49);
164 SIMPLE_COPY(strcpy
, 9, "999999999", 50);
165 SIMPLE_COPY(strcpy
, 10, "0000000000", 51);
166 SIMPLE_COPY(strcpy
, 11, "11111111111", 52);
167 SIMPLE_COPY(strcpy
, 12, "222222222222", 53);
168 SIMPLE_COPY(strcpy
, 13, "3333333333333", 54);
169 SIMPLE_COPY(strcpy
, 14, "44444444444444", 55);
170 SIMPLE_COPY(strcpy
, 15, "555555555555555", 56);
171 SIMPLE_COPY(strcpy
, 16, "6666666666666666", 57);
173 /* Simple test using implicitly coerced `void *' arguments. */
174 const void *src
= "frobozz";
176 check (strcpy (dst
, src
) == dst
, 1);
177 equal (dst
, "frobozz", 2);
184 check ((stpcpy (one
, "a") - one
) == 1, 1);
187 check ((stpcpy (one
, "ab") - one
) == 2, 3);
188 equal (one
, "ab", 4);
190 check ((stpcpy (one
, "abc") - one
) == 3, 5);
191 equal (one
, "abc", 6);
193 check ((stpcpy (one
, "abcd") - one
) == 4, 7);
194 equal (one
, "abcd", 8);
196 check ((stpcpy (one
, "abcde") - one
) == 5, 9);
197 equal (one
, "abcde", 10);
199 check ((stpcpy (one
, "abcdef") - one
) == 6, 11);
200 equal (one
, "abcdef", 12);
202 check ((stpcpy (one
, "abcdefg") - one
) == 7, 13);
203 equal (one
, "abcdefg", 14);
205 check ((stpcpy (one
, "abcdefgh") - one
) == 8, 15);
206 equal (one
, "abcdefgh", 16);
208 check ((stpcpy (one
, "abcdefghi") - one
) == 9, 17);
209 equal (one
, "abcdefghi", 18);
211 check ((stpcpy (one
, "x") - one
) == 1, 19);
212 equal (one
, "x", 20); /* Writeover. */
213 equal (one
+2, "cdefghi", 21); /* Wrote too much? */
215 check ((stpcpy (one
, "xx") - one
) == 2, 22);
216 equal (one
, "xx", 23); /* Writeover. */
217 equal (one
+3, "defghi", 24); /* Wrote too much? */
219 check ((stpcpy (one
, "xxx") - one
) == 3, 25);
220 equal (one
, "xxx", 26); /* Writeover. */
221 equal (one
+4, "efghi", 27); /* Wrote too much? */
223 check ((stpcpy (one
, "xxxx") - one
) == 4, 28);
224 equal (one
, "xxxx", 29); /* Writeover. */
225 equal (one
+5, "fghi", 30); /* Wrote too much? */
227 check ((stpcpy (one
, "xxxxx") - one
) == 5, 31);
228 equal (one
, "xxxxx", 32); /* Writeover. */
229 equal (one
+6, "ghi", 33); /* Wrote too much? */
231 check ((stpcpy (one
, "xxxxxx") - one
) == 6, 34);
232 equal (one
, "xxxxxx", 35); /* Writeover. */
233 equal (one
+7, "hi", 36); /* Wrote too much? */
235 check ((stpcpy (one
, "xxxxxxx") - one
) == 7, 37);
236 equal (one
, "xxxxxxx", 38); /* Writeover. */
237 equal (one
+8, "i", 39); /* Wrote too much? */
239 check ((stpcpy (stpcpy (stpcpy (one
, "a"), "b"), "c") - one
) == 3, 40);
240 equal (one
, "abc", 41);
241 equal (one
+ 4, "xxx", 42);
243 SIMPLE_COPY(stpcpy
, 0, "", 43);
244 SIMPLE_COPY(stpcpy
, 1, "1", 44);
245 SIMPLE_COPY(stpcpy
, 2, "22", 45);
246 SIMPLE_COPY(stpcpy
, 3, "333", 46);
247 SIMPLE_COPY(stpcpy
, 4, "4444", 47);
248 SIMPLE_COPY(stpcpy
, 5, "55555", 48);
249 SIMPLE_COPY(stpcpy
, 6, "666666", 49);
250 SIMPLE_COPY(stpcpy
, 7, "7777777", 50);
251 SIMPLE_COPY(stpcpy
, 8, "88888888", 51);
252 SIMPLE_COPY(stpcpy
, 9, "999999999", 52);
253 SIMPLE_COPY(stpcpy
, 10, "0000000000", 53);
254 SIMPLE_COPY(stpcpy
, 11, "11111111111", 54);
255 SIMPLE_COPY(stpcpy
, 12, "222222222222", 55);
256 SIMPLE_COPY(stpcpy
, 13, "3333333333333", 56);
257 SIMPLE_COPY(stpcpy
, 14, "44444444444444", 57);
258 SIMPLE_COPY(stpcpy
, 15, "555555555555555", 58);
259 SIMPLE_COPY(stpcpy
, 16, "6666666666666666", 59);
266 memset (one
, 'x', sizeof (one
));
267 check (stpncpy (one
, "abc", 2) == one
+ 2, 1);
268 check (stpncpy (one
, "abc", 3) == one
+ 3, 2);
269 check (stpncpy (one
, "abc", 4) == one
+ 3, 3);
270 check (one
[3] == '\0' && one
[4] == 'x', 4);
271 check (stpncpy (one
, "abcd", 5) == one
+ 4, 5);
272 check (one
[4] == '\0' && one
[5] == 'x', 6);
273 check (stpncpy (one
, "abcd", 6) == one
+ 4, 7);
274 check (one
[4] == '\0' && one
[5] == '\0' && one
[6] == 'x', 8);
281 (void) strcpy (one
, "ijk");
282 check (strcat (one
, "lmn") == one
, 1); /* Returned value. */
283 equal (one
, "ijklmn", 2); /* Basic test. */
285 (void) strcpy (one
, "x");
286 (void) strcat (one
, "yz");
287 equal (one
, "xyz", 3); /* Writeover. */
288 equal (one
+4, "mn", 4); /* Wrote too much? */
290 (void) strcpy (one
, "gh");
291 (void) strcpy (two
, "ef");
292 (void) strcat (one
, two
);
293 equal (one
, "ghef", 5); /* Basic test encore. */
294 equal (two
, "ef", 6); /* Stomped on source? */
296 (void) strcpy (one
, "");
297 (void) strcat (one
, "");
298 equal (one
, "", 7); /* Boundary conditions. */
299 (void) strcpy (one
, "ab");
300 (void) strcat (one
, "");
301 equal (one
, "ab", 8);
302 (void) strcpy (one
, "");
303 (void) strcat (one
, "cd");
304 equal (one
, "cd", 9);
307 char buf1
[80] __attribute__ ((aligned (16)));
308 char buf2
[32] __attribute__ ((aligned (16)));
309 for (size_t n1
= 0; n1
< 16; ++n1
)
310 for (size_t n2
= 0; n2
< 16; ++n2
)
311 for (size_t n3
= 0; n3
< 32; ++n3
)
313 size_t olderrors
= errors
;
315 memset (buf1
, 'b', sizeof (buf1
));
317 memset (buf1
+ n2
, 'a', n3
);
318 buf1
[n2
+ n3
] = '\0';
319 strcpy (buf2
+ n1
, "123");
321 check (strcat (buf1
+ n2
, buf2
+ n1
) == buf1
+ n2
, ntest
);
322 if (errors
== olderrors
)
323 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
326 check (buf1
[i
] == 'b', ntest
);
327 else if (i
< n2
+ n3
)
328 check (buf1
[i
] == 'a', ntest
);
329 else if (i
< n2
+ n3
+ 3)
330 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
331 else if (i
== n2
+ n3
+ 3)
332 check (buf1
[i
] == '\0', ntest
);
334 check (buf1
[i
] == 'b', ntest
);
336 if (errors
!= olderrors
)
338 printf ("n1=%zu, n2=%zu, n3=%zu, buf1=%02hhx",
339 n1
, n2
, n3
, buf1
[0]);
340 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
341 printf (",%02hhx", buf1
[j
]);
342 putchar_unlocked ('\n');
352 /* First test it as strcat, with big counts, then test the count
355 (void) strcpy (one
, "ijk");
356 DIAG_PUSH_NEEDS_COMMENT
;
357 #if __GNUC_PREREQ (7, 0)
358 /* GCC 7 warns about the size passed to strncat being larger than
359 the size of the buffer; this is deliberately tested here.. */
360 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
362 check (strncat (one
, "lmn", 99) == one
, 1); /* Returned value. */
363 DIAG_POP_NEEDS_COMMENT
;
364 equal (one
, "ijklmn", 2); /* Basic test. */
366 (void) strcpy (one
, "x");
367 DIAG_PUSH_NEEDS_COMMENT
;
368 #if __GNUC_PREREQ (7, 0)
369 /* GCC 7 warns about the size passed to strncat being larger than
370 the size of the buffer; this is deliberately tested here.. */
371 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
373 (void) strncat (one
, "yz", 99);
374 DIAG_POP_NEEDS_COMMENT
;
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 DIAG_PUSH_NEEDS_COMMENT
;
381 #if __GNUC_PREREQ (7, 0)
382 /* GCC 7 warns about the size passed to strncat being larger than
383 the size of the buffer; this is deliberately tested here.. */
384 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
386 (void) strncat (one
, two
, 99);
387 DIAG_POP_NEEDS_COMMENT
;
388 equal (one
, "ghef", 5); /* Basic test encore. */
389 equal (two
, "ef", 6); /* Stomped on source? */
391 (void) strcpy (one
, "");
392 DIAG_PUSH_NEEDS_COMMENT
;
393 #if __GNUC_PREREQ (7, 0)
394 /* GCC 7 warns about the size passed to strncat being larger than
395 the size of the buffer; this is deliberately tested here.. */
396 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
398 (void) strncat (one
, "", 99);
399 DIAG_POP_NEEDS_COMMENT
;
400 equal (one
, "", 7); /* Boundary conditions. */
401 (void) strcpy (one
, "ab");
402 DIAG_PUSH_NEEDS_COMMENT
;
403 #if __GNUC_PREREQ (7, 0)
404 /* GCC 7 warns about the size passed to strncat being larger than
405 the size of the buffer; this is deliberately tested here.. */
406 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
408 (void) strncat (one
, "", 99);
409 DIAG_POP_NEEDS_COMMENT
;
410 equal (one
, "ab", 8);
411 (void) strcpy (one
, "");
412 DIAG_PUSH_NEEDS_COMMENT
;
413 #if __GNUC_PREREQ (7, 0)
414 /* GCC 7 warns about the size passed to strncat being larger than
415 the size of the buffer; this is deliberately tested here.. */
416 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
418 (void) strncat (one
, "cd", 99);
419 DIAG_POP_NEEDS_COMMENT
;
420 equal (one
, "cd", 9);
422 (void) strcpy (one
, "ab");
423 (void) strncat (one
, "cdef", 2);
424 equal (one
, "abcd", 10); /* Count-limited. */
426 (void) strncat (one
, "gh", 0);
427 equal (one
, "abcd", 11); /* Zero count. */
429 (void) strncat (one
, "gh", 2);
430 equal (one
, "abcdgh", 12); /* Count and length equal. */
432 DIAG_PUSH_NEEDS_COMMENT
;
433 #if __GNUC_PREREQ (7, 0)
434 /* GCC 7 warns about the size passed to strncat being larger than
435 the size of the buffer; this is deliberately tested here.. */
436 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
438 (void) strncat (one
, "ij", (size_t)-1); /* set sign bit in count */
439 DIAG_POP_NEEDS_COMMENT
;
440 equal (one
, "abcdghij", 13);
443 char buf1
[80] __attribute__ ((aligned (16)));
444 char buf2
[32] __attribute__ ((aligned (16)));
445 for (size_t n1
= 0; n1
< 16; ++n1
)
446 for (size_t n2
= 0; n2
< 16; ++n2
)
447 for (size_t n3
= 0; n3
< 32; ++n3
)
448 for (size_t n4
= 0; n4
< 16; ++n4
)
450 size_t olderrors
= errors
;
452 memset (buf1
, 'b', sizeof (buf1
));
454 memset (buf1
+ n2
, 'a', n3
);
455 buf1
[n2
+ n3
] = '\0';
456 strcpy (buf2
+ n1
, "123");
458 DIAG_PUSH_NEEDS_COMMENT
;
459 #if __GNUC_PREREQ (7, 0)
460 /* GCC 7 warns about the size passed to strncat being
461 larger than the size of the buffer; this is
462 deliberately tested here.. */
463 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
465 check (strncat (buf1
+ n2
, buf2
+ n1
, ~((size_t) 0) - n4
)
466 == buf1
+ n2
, ntest
);
467 DIAG_POP_NEEDS_COMMENT
;
468 if (errors
== olderrors
)
469 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
472 check (buf1
[i
] == 'b', ntest
);
473 else if (i
< n2
+ n3
)
474 check (buf1
[i
] == 'a', ntest
);
475 else if (i
< n2
+ n3
+ 3)
476 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
477 else if (i
== n2
+ n3
+ 3)
478 check (buf1
[i
] == '\0', ntest
);
480 check (buf1
[i
] == 'b', ntest
);
482 if (errors
!= olderrors
)
484 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
485 n1
, n2
, n3
, n4
, buf1
[0]);
486 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
487 printf (",%02hhx", buf1
[j
]);
488 putchar_unlocked ('\n');
498 /* First test as strcmp with big counts, then test count code. */
500 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
501 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
502 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
503 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
504 check (strncmp ("abcd", "abc", 99) > 0, 5);
505 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
506 check (strncmp ("abce", "abcd", 99) > 0, 7);
507 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
508 check (strncmp ("a\203", "a\003", 2) > 0, 9);
509 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
510 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
511 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
512 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
513 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
514 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
520 /* Testing is a bit different because of odd semantics. */
522 check (strncpy (one
, "abc", 4) == one
, 1); /* Returned value. */
523 equal (one
, "abc", 2); /* Did the copy go right? */
525 (void) strcpy (one
, "abcdefgh");
526 (void) strncpy (one
, "xyz", 2);
527 equal (one
, "xycdefgh", 3); /* Copy cut by count. */
529 (void) strcpy (one
, "abcdefgh");
530 (void) strncpy (one
, "xyz", 3); /* Copy cut just before NUL. */
531 equal (one
, "xyzdefgh", 4);
533 (void) strcpy (one
, "abcdefgh");
534 (void) strncpy (one
, "xyz", 4); /* Copy just includes NUL. */
535 equal (one
, "xyz", 5);
536 equal (one
+4, "efgh", 6); /* Wrote too much? */
538 (void) strcpy (one
, "abcdefgh");
539 (void) strncpy (one
, "xyz", 5); /* Copy includes padding. */
540 equal (one
, "xyz", 7);
541 equal (one
+4, "", 8);
542 equal (one
+5, "fgh", 9);
544 (void) strcpy (one
, "abc");
545 (void) strncpy (one
, "xyz", 0); /* Zero-length copy. */
546 equal (one
, "abc", 10);
548 (void) strncpy (one
, "", 2); /* Zero-length source. */
550 equal (one
+1, "", 12);
551 equal (one
+2, "c", 13);
553 (void) strcpy (one
, "hi there");
554 (void) strncpy (two
, one
, 9);
555 equal (two
, "hi there", 14); /* Just paranoia. */
556 equal (one
, "hi there", 15); /* Stomped on source? */
563 check (strlen ("") == 0, 1); /* Empty. */
564 check (strlen ("a") == 1, 2); /* Single char. */
565 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
570 for (i
=0; i
< 0x100; i
++)
572 p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
574 strcpy (p
+3, "BAD/WRONG");
575 check (strlen (p
) == 2, 4+i
);
584 check (strnlen ("", 10) == 0, 1); /* Empty. */
585 check (strnlen ("a", 10) == 1, 2); /* Single char. */
586 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
587 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
588 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
589 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
590 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
591 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
592 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
595 for (int i
= 0; i
< 0x100; ++i
)
597 char *p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
599 strcpy (p
+ 3, "BAD/WRONG");
600 check (strnlen (p
, 100) == 2, 10 + i
);
608 check (strchr ("abcd", 'z') == NULL
, 1); /* Not found. */
609 (void) strcpy (one
, "abcd");
610 check (strchr (one
, 'c') == one
+2, 2); /* Basic test. */
611 check (strchr (one
, 'd') == one
+3, 3); /* End of string. */
612 check (strchr (one
, 'a') == one
, 4); /* Beginning. */
613 check (strchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
614 (void) strcpy (one
, "ababa");
615 check (strchr (one
, 'b') == one
+1, 6); /* Finding first. */
616 (void) strcpy (one
, "");
617 check (strchr (one
, 'b') == NULL
, 7); /* Empty string. */
618 check (strchr (one
, '\0') == one
, 8); /* NUL in empty string. */
623 for (i
=0; i
< 0x100; i
++)
625 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
627 strcpy (p
+3, "BAD/WRONG");
628 check (strchr (p
, '/') == NULL
, 9+i
);
634 test_strchrnul (void)
638 cp
= strchrnul ((os
= "abcd"), 'z');
639 check (*cp
== '\0', 1); /* Not found. */
640 check (cp
== os
+ 4, 2);
641 (void) strcpy (one
, "abcd");
642 check (strchrnul (one
, 'c') == one
+2, 3); /* Basic test. */
643 check (strchrnul (one
, 'd') == one
+3, 4); /* End of string. */
644 check (strchrnul (one
, 'a') == one
, 5); /* Beginning. */
645 check (strchrnul (one
, '\0') == one
+4, 6); /* Finding NUL. */
646 (void) strcpy (one
, "ababa");
647 check (strchrnul (one
, 'b') == one
+1, 7); /* Finding first. */
648 (void) strcpy (one
, "");
649 check (strchrnul (one
, 'b') == one
, 8); /* Empty string. */
650 check (strchrnul (one
, '\0') == one
, 9); /* NUL in empty string. */
655 for (i
=0; i
< 0x100; i
++)
657 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
659 strcpy (p
+3, "BAD/WRONG");
660 cp
= strchrnul (p
, '/');
661 check (*cp
== '\0', 9+2*i
);
662 check (cp
== p
+2, 10+2*i
);
668 test_rawmemchr (void)
671 (void) strcpy (one
, "abcd");
672 check (rawmemchr (one
, 'c') == one
+2, 1); /* Basic test. */
673 check (rawmemchr (one
, 'd') == one
+3, 2); /* End of string. */
674 check (rawmemchr (one
, 'a') == one
, 3); /* Beginning. */
675 check (rawmemchr (one
, '\0') == one
+4, 4); /* Finding NUL. */
676 (void) strcpy (one
, "ababa");
677 check (rawmemchr (one
, 'b') == one
+1, 5); /* Finding first. */
678 (void) strcpy (one
, "");
679 check (rawmemchr (one
, '\0') == one
, 6); /* NUL in empty string. */
684 for (i
=0; i
< 0x100; i
++)
686 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
688 strcpy (p
+3, "BAD/WRONG");
689 check (rawmemchr (p
, 'R') == p
+8, 6+i
);
698 check (index ("abcd", 'z') == NULL
, 1); /* Not found. */
699 (void) strcpy (one
, "abcd");
700 check (index (one
, 'c') == one
+2, 2); /* Basic test. */
701 check (index (one
, 'd') == one
+3, 3); /* End of string. */
702 check (index (one
, 'a') == one
, 4); /* Beginning. */
703 check (index (one
, '\0') == one
+4, 5); /* Finding NUL. */
704 (void) strcpy (one
, "ababa");
705 check (index (one
, 'b') == one
+1, 6); /* Finding first. */
706 (void) strcpy (one
, "");
707 check (index (one
, 'b') == NULL
, 7); /* Empty string. */
708 check (index (one
, '\0') == one
, 8); /* NUL in empty string. */
715 check (strrchr ("abcd", 'z') == NULL
, 1); /* Not found. */
716 (void) strcpy (one
, "abcd");
717 check (strrchr (one
, 'c') == one
+2, 2); /* Basic test. */
718 check (strrchr (one
, 'd') == one
+3, 3); /* End of string. */
719 check (strrchr (one
, 'a') == one
, 4); /* Beginning. */
720 check (strrchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
721 (void) strcpy (one
, "ababa");
722 check (strrchr (one
, 'b') == one
+3, 6); /* Finding last. */
723 (void) strcpy (one
, "");
724 check (strrchr (one
, 'b') == NULL
, 7); /* Empty string. */
725 check (strrchr (one
, '\0') == one
, 8); /* NUL in empty string. */
730 for (i
=0; i
< 0x100; i
++)
732 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
734 strcpy (p
+3, "BAD/WRONG");
735 check (strrchr (p
, '/') == NULL
, 9+i
);
745 check (memrchr ("abcd", 'z', 5) == NULL
, 1); /* Not found. */
746 (void) strcpy (one
, "abcd");
747 l
= strlen (one
) + 1;
748 check (memrchr (one
, 'c', l
) == one
+2, 2); /* Basic test. */
749 check (memrchr (one
, 'd', l
) == one
+3, 3); /* End of string. */
750 check (memrchr (one
, 'a', l
) == one
, 4); /* Beginning. */
751 check (memrchr (one
, '\0', l
) == one
+4, 5); /* Finding NUL. */
752 (void) strcpy (one
, "ababa");
753 l
= strlen (one
) + 1;
754 check (memrchr (one
, 'b', l
) == one
+3, 6); /* Finding last. */
755 (void) strcpy (one
, "");
756 l
= strlen (one
) + 1;
757 check (memrchr (one
, 'b', l
) == NULL
, 7); /* Empty string. */
758 check (memrchr (one
, '\0', l
) == one
, 8); /* NUL in empty string. */
760 /* now test all possible alignment and length combinations to catch
761 bugs due to unrolled loops (assuming unrolling is limited to no
762 more than 128 byte chunks: */
764 char buf
[128 + sizeof(long)];
765 long align
, len
, i
, pos
, n
= 9;
767 for (align
= 0; align
< (long) sizeof(long); ++align
) {
768 for (len
= 0; len
< (long) (sizeof(buf
) - align
); ++len
) {
769 for (i
= 0; i
< len
; ++i
)
770 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
772 for (pos
= len
- 1; pos
>= 0; --pos
) {
774 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
776 check(memrchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, n
++);
777 check(memrchr(buf
+ align
+ pos
+ 1, 'x', len
- (pos
+ 1)) == NULL
,
779 buf
[align
+ pos
] = '-';
790 check (rindex ("abcd", 'z') == NULL
, 1); /* Not found. */
791 (void) strcpy (one
, "abcd");
792 check (rindex (one
, 'c') == one
+2, 2); /* Basic test. */
793 check (rindex (one
, 'd') == one
+3, 3); /* End of string. */
794 check (rindex (one
, 'a') == one
, 4); /* Beginning. */
795 check (rindex (one
, '\0') == one
+4, 5); /* Finding NUL. */
796 (void) strcpy (one
, "ababa");
797 check (rindex (one
, 'b') == one
+3, 6); /* Finding last. */
798 (void) strcpy (one
, "");
799 check (rindex (one
, 'b') == NULL
, 7); /* Empty string. */
800 check (rindex (one
, '\0') == one
, 8); /* NUL in empty string. */
807 check(strpbrk("abcd", "z") == NULL
, 1); /* Not found. */
808 (void) strcpy(one
, "abcd");
809 check(strpbrk(one
, "c") == one
+2, 2); /* Basic test. */
810 check(strpbrk(one
, "d") == one
+3, 3); /* End of string. */
811 check(strpbrk(one
, "a") == one
, 4); /* Beginning. */
812 check(strpbrk(one
, "") == NULL
, 5); /* Empty search list. */
813 check(strpbrk(one
, "cb") == one
+1, 6); /* Multiple search. */
814 (void) strcpy(one
, "abcabdea");
815 check(strpbrk(one
, "b") == one
+1, 7); /* Finding first. */
816 check(strpbrk(one
, "cb") == one
+1, 8); /* With multiple search. */
817 check(strpbrk(one
, "db") == one
+1, 9); /* Another variant. */
818 (void) strcpy(one
, "");
819 check(strpbrk(one
, "bc") == NULL
, 10); /* Empty string. */
820 (void) strcpy(one
, "");
821 check(strpbrk(one
, "bcd") == NULL
, 11); /* Empty string. */
822 (void) strcpy(one
, "");
823 check(strpbrk(one
, "bcde") == NULL
, 12); /* Empty string. */
824 check(strpbrk(one
, "") == NULL
, 13); /* Both strings empty. */
825 (void) strcpy(one
, "abcabdea");
826 check(strpbrk(one
, "befg") == one
+1, 14); /* Finding first. */
827 check(strpbrk(one
, "cbr") == one
+1, 15); /* With multiple search. */
828 check(strpbrk(one
, "db") == one
+1, 16); /* Another variant. */
829 check(strpbrk(one
, "efgh") == one
+6, 17); /* And yet another. */
836 check(strstr("abcd", "z") == NULL
, 1); /* Not found. */
837 check(strstr("abcd", "abx") == NULL
, 2); /* Dead end. */
838 (void) strcpy(one
, "abcd");
839 check(strstr(one
, "c") == one
+2, 3); /* Basic test. */
840 check(strstr(one
, "bc") == one
+1, 4); /* Multichar. */
841 check(strstr(one
, "d") == one
+3, 5); /* End of string. */
842 check(strstr(one
, "cd") == one
+2, 6); /* Tail of string. */
843 check(strstr(one
, "abc") == one
, 7); /* Beginning. */
844 check(strstr(one
, "abcd") == one
, 8); /* Exact match. */
845 check(strstr(one
, "abcde") == NULL
, 9); /* Too long. */
846 check(strstr(one
, "de") == NULL
, 10); /* Past end. */
847 check(strstr(one
, "") == one
, 11); /* Finding empty. */
848 (void) strcpy(one
, "ababa");
849 check(strstr(one
, "ba") == one
+1, 12); /* Finding first. */
850 (void) strcpy(one
, "");
851 check(strstr(one
, "b") == NULL
, 13); /* Empty string. */
852 check(strstr(one
, "") == one
, 14); /* Empty in empty string. */
853 (void) strcpy(one
, "bcbca");
854 check(strstr(one
, "bca") == one
+2, 15); /* False start. */
855 (void) strcpy(one
, "bbbcabbca");
856 check(strstr(one
, "bbca") == one
+1, 16); /* With overlap. */
863 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
864 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
865 check(strspn("abc", "qx") == 0, 3); /* None. */
866 check(strspn("", "ab") == 0, 4); /* Null string. */
867 check(strspn("abc", "") == 0, 5); /* Null search list. */
874 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
875 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
876 check(strcspn("abc", "abc") == 0, 3); /* None. */
877 check(strcspn("", "ab") == 0, 4); /* Null string. */
878 check(strcspn("abc", "") == 3, 5); /* Null search list. */
885 (void) strcpy(one
, "first, second, third");
886 equal(strtok(one
, ", "), "first", 1); /* Basic test. */
887 equal(one
, "first", 2);
888 equal(strtok((char *)NULL
, ", "), "second", 3);
889 equal(strtok((char *)NULL
, ", "), "third", 4);
890 check(strtok((char *)NULL
, ", ") == NULL
, 5);
891 (void) strcpy(one
, ", first, ");
892 equal(strtok(one
, ", "), "first", 6); /* Extra delims, 1 tok. */
893 check(strtok((char *)NULL
, ", ") == NULL
, 7);
894 (void) strcpy(one
, "1a, 1b; 2a, 2b");
895 equal(strtok(one
, ", "), "1a", 8); /* Changing delim lists. */
896 equal(strtok((char *)NULL
, "; "), "1b", 9);
897 equal(strtok((char *)NULL
, ", "), "2a", 10);
898 (void) strcpy(two
, "x-y");
899 equal(strtok(two
, "-"), "x", 11); /* New string before done. */
900 equal(strtok((char *)NULL
, "-"), "y", 12);
901 check(strtok((char *)NULL
, "-") == NULL
, 13);
902 (void) strcpy(one
, "a,b, c,, ,d");
903 equal(strtok(one
, ", "), "a", 14); /* Different separators. */
904 equal(strtok((char *)NULL
, ", "), "b", 15);
905 equal(strtok((char *)NULL
, " ,"), "c", 16); /* Permute list too. */
906 equal(strtok((char *)NULL
, " ,"), "d", 17);
907 check(strtok((char *)NULL
, ", ") == NULL
, 18);
908 check(strtok((char *)NULL
, ", ") == NULL
, 19); /* Persistence. */
909 (void) strcpy(one
, ", ");
910 check(strtok(one
, ", ") == NULL
, 20); /* No tokens. */
911 (void) strcpy(one
, "");
912 check(strtok(one
, ", ") == NULL
, 21); /* Empty string. */
913 (void) strcpy(one
, "abc");
914 equal(strtok(one
, ", "), "abc", 22); /* No delimiters. */
915 check(strtok((char *)NULL
, ", ") == NULL
, 23);
916 (void) strcpy(one
, "abc");
917 equal(strtok(one
, ""), "abc", 24); /* Empty delimiter list. */
918 check(strtok((char *)NULL
, "") == NULL
, 25);
919 (void) strcpy(one
, "abcdefgh");
920 (void) strcpy(one
, "a,b,c");
921 equal(strtok(one
, ","), "a", 26); /* Basics again... */
922 equal(strtok((char *)NULL
, ","), "b", 27);
923 equal(strtok((char *)NULL
, ","), "c", 28);
924 check(strtok((char *)NULL
, ",") == NULL
, 29);
925 equal(one
+6, "gh", 30); /* Stomped past end? */
926 equal(one
, "a", 31); /* Stomped old tokens? */
927 equal(one
+2, "b", 32);
928 equal(one
+4, "c", 33);
935 (void) strcpy(one
, "first, second, third");
936 cp
= NULL
; /* Always initialize cp to make sure it doesn't point to some old data. */
937 equal(strtok_r(one
, ", ", &cp
), "first", 1); /* Basic test. */
938 equal(one
, "first", 2);
939 equal(strtok_r((char *)NULL
, ", ", &cp
), "second", 3);
940 equal(strtok_r((char *)NULL
, ", ", &cp
), "third", 4);
941 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 5);
942 (void) strcpy(one
, ", first, ");
944 equal(strtok_r(one
, ", ", &cp
), "first", 6); /* Extra delims, 1 tok. */
945 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 7);
946 (void) strcpy(one
, "1a, 1b; 2a, 2b");
948 equal(strtok_r(one
, ", ", &cp
), "1a", 8); /* Changing delim lists. */
949 equal(strtok_r((char *)NULL
, "; ", &cp
), "1b", 9);
950 equal(strtok_r((char *)NULL
, ", ", &cp
), "2a", 10);
951 (void) strcpy(two
, "x-y");
953 equal(strtok_r(two
, "-", &cp
), "x", 11); /* New string before done. */
954 equal(strtok_r((char *)NULL
, "-", &cp
), "y", 12);
955 check(strtok_r((char *)NULL
, "-", &cp
) == NULL
, 13);
956 (void) strcpy(one
, "a,b, c,, ,d");
958 equal(strtok_r(one
, ", ", &cp
), "a", 14); /* Different separators. */
959 equal(strtok_r((char *)NULL
, ", ", &cp
), "b", 15);
960 equal(strtok_r((char *)NULL
, " ,", &cp
), "c", 16); /* Permute list too. */
961 equal(strtok_r((char *)NULL
, " ,", &cp
), "d", 17);
962 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 18);
963 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 19); /* Persistence. */
964 (void) strcpy(one
, ", ");
966 check(strtok_r(one
, ", ", &cp
) == NULL
, 20); /* No tokens. */
967 (void) strcpy(one
, "");
969 check(strtok_r(one
, ", ", &cp
) == NULL
, 21); /* Empty string. */
970 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 22); /* Persistence. */
971 (void) strcpy(one
, "abc");
973 equal(strtok_r(one
, ", ", &cp
), "abc", 23); /* No delimiters. */
974 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 24);
975 (void) strcpy(one
, "abc");
977 equal(strtok_r(one
, "", &cp
), "abc", 25); /* Empty delimiter list. */
978 check(strtok_r((char *)NULL
, "", &cp
) == NULL
, 26);
979 (void) strcpy(one
, "abcdefgh");
980 (void) strcpy(one
, "a,b,c");
982 equal(strtok_r(one
, ",", &cp
), "a", 27); /* Basics again... */
983 equal(strtok_r((char *)NULL
, ",", &cp
), "b", 28);
984 equal(strtok_r((char *)NULL
, ",", &cp
), "c", 29);
985 check(strtok_r((char *)NULL
, ",", &cp
) == NULL
, 30);
986 equal(one
+6, "gh", 31); /* Stomped past end? */
987 equal(one
, "a", 32); /* Stomped old tokens? */
988 equal(one
+2, "b", 33);
989 equal(one
+4, "c", 34);
992 check (strtok_r (one
, ":", &cp
) == NULL
, 35); /* Must store pointer in cp. */
993 check (strtok_r (NULL
, ":", &cp
) == NULL
, 36);
1001 cp
= strcpy(one
, "first, second, third");
1002 equal(strsep(&cp
, ", "), "first", 1); /* Basic test. */
1003 equal(one
, "first", 2);
1004 equal(strsep(&cp
, ", "), "", 3);
1005 equal(strsep(&cp
, ", "), "second", 4);
1006 equal(strsep(&cp
, ", "), "", 5);
1007 equal(strsep(&cp
, ", "), "third", 6);
1008 check(strsep(&cp
, ", ") == NULL
, 7);
1009 cp
= strcpy(one
, ", first, ");
1010 equal(strsep(&cp
, ", "), "", 8);
1011 equal(strsep(&cp
, ", "), "", 9);
1012 equal(strsep(&cp
, ", "), "first", 10); /* Extra delims, 1 tok. */
1013 equal(strsep(&cp
, ", "), "", 11);
1014 equal(strsep(&cp
, ", "), "", 12);
1015 check(strsep(&cp
, ", ") == NULL
, 13);
1016 cp
= strcpy(one
, "1a, 1b; 2a, 2b");
1017 equal(strsep(&cp
, ", "), "1a", 14); /* Changing delim lists. */
1018 equal(strsep(&cp
, ", "), "", 15);
1019 equal(strsep(&cp
, "; "), "1b", 16);
1020 equal(strsep(&cp
, ", "), "", 17);
1021 equal(strsep(&cp
, ", "), "2a", 18);
1022 cp
= strcpy(two
, "x-y");
1023 equal(strsep(&cp
, "-"), "x", 19); /* New string before done. */
1024 equal(strsep(&cp
, "-"), "y", 20);
1025 check(strsep(&cp
, "-") == NULL
, 21);
1026 cp
= strcpy(one
, "a,b, c,, ,d ");
1027 equal(strsep(&cp
, ", "), "a", 22); /* Different separators. */
1028 equal(strsep(&cp
, ", "), "b", 23);
1029 equal(strsep(&cp
, " ,"), "", 24);
1030 equal(strsep(&cp
, " ,"), "c", 25); /* Permute list too. */
1031 equal(strsep(&cp
, " ,"), "", 26);
1032 equal(strsep(&cp
, " ,"), "", 27);
1033 equal(strsep(&cp
, " ,"), "", 28);
1034 equal(strsep(&cp
, " ,"), "d", 29);
1035 equal(strsep(&cp
, " ,"), "", 30);
1036 check(strsep(&cp
, ", ") == NULL
, 31);
1037 check(strsep(&cp
, ", ") == NULL
, 32); /* Persistence. */
1038 cp
= strcpy(one
, ", ");
1039 equal(strsep(&cp
, ", "), "", 33);
1040 equal(strsep(&cp
, ", "), "", 34);
1041 equal(strsep(&cp
, ", "), "", 35);
1042 check(strsep(&cp
, ", ") == NULL
, 36); /* No tokens. */
1043 cp
= strcpy(one
, "");
1044 equal(strsep(&cp
, ", "), "", 37);
1045 check(strsep(&cp
, ", ") == NULL
, 38); /* Empty string. */
1046 cp
= strcpy(one
, "abc");
1047 equal(strsep(&cp
, ", "), "abc", 39); /* No delimiters. */
1048 check(strsep(&cp
, ", ") == NULL
, 40);
1049 cp
= strcpy(one
, "abc");
1050 equal(strsep(&cp
, ""), "abc", 41); /* Empty delimiter list. */
1051 check(strsep(&cp
, "") == NULL
, 42);
1052 (void) strcpy(one
, "abcdefgh");
1053 cp
= strcpy(one
, "a,b,c");
1054 equal(strsep(&cp
, ","), "a", 43); /* Basics again... */
1055 equal(strsep(&cp
, ","), "b", 44);
1056 equal(strsep(&cp
, ","), "c", 45);
1057 check(strsep(&cp
, ",") == NULL
, 46);
1058 equal(one
+6, "gh", 47); /* Stomped past end? */
1059 equal(one
, "a", 48); /* Stomped old tokens? */
1060 equal(one
+2, "b", 49);
1061 equal(one
+4, "c", 50);
1064 char text
[] = "This,is,a,test";
1065 char *list
= strdupa (text
);
1066 equal (strsep (&list
, ","), "This", 51);
1067 equal (strsep (&list
, ","), "is", 52);
1068 equal (strsep (&list
, ","), "a", 53);
1069 equal (strsep (&list
, ","), "test", 54);
1070 check (strsep (&list
, ",") == NULL
, 55);
1073 cp
= strcpy(one
, "a,b, c,, ,d,");
1074 equal(strsep(&cp
, ","), "a", 56); /* Different separators. */
1075 equal(strsep(&cp
, ","), "b", 57);
1076 equal(strsep(&cp
, ","), " c", 58); /* Permute list too. */
1077 equal(strsep(&cp
, ","), "", 59);
1078 equal(strsep(&cp
, ","), " ", 60);
1079 equal(strsep(&cp
, ","), "d", 61);
1080 equal(strsep(&cp
, ","), "", 62);
1081 check(strsep(&cp
, ",") == NULL
, 63);
1082 check(strsep(&cp
, ",") == NULL
, 64); /* Persistence. */
1084 cp
= strcpy(one
, "a,b, c,, ,d,");
1085 equal(strsep(&cp
, "xy,"), "a", 65); /* Different separators. */
1086 equal(strsep(&cp
, "x,y"), "b", 66);
1087 equal(strsep(&cp
, ",xy"), " c", 67); /* Permute list too. */
1088 equal(strsep(&cp
, "xy,"), "", 68);
1089 equal(strsep(&cp
, "x,y"), " ", 69);
1090 equal(strsep(&cp
, ",xy"), "d", 70);
1091 equal(strsep(&cp
, "xy,"), "", 71);
1092 check(strsep(&cp
, "x,y") == NULL
, 72);
1093 check(strsep(&cp
, ",xy") == NULL
, 73); /* Persistence. */
1095 cp
= strcpy(one
, "ABC");
1097 equal(strsep(&cp
, "C"), "AB", 74); /* Access beyond NUL. */
1098 ptr
= strsep(&cp
, ":");
1100 check(ptr
== one
+ 3, 76);
1101 check(cp
== NULL
, 77);
1103 cp
= strcpy(one
, "ABC");
1105 equal(strsep(&cp
, "CD"), "AB", 78); /* Access beyond NUL. */
1106 ptr
= strsep(&cp
, ":.");
1108 check(ptr
== one
+ 3, 80);
1110 cp
= strcpy(one
, "ABC"); /* No token in string. */
1111 equal(strsep(&cp
, ","), "ABC", 81);
1112 check(cp
== NULL
, 82);
1114 *one
= '\0'; /* Empty string. */
1116 ptr
= strsep(&cp
, ",");
1118 check(ptr
== one
, 84);
1119 check(cp
== NULL
, 85);
1121 *one
= '\0'; /* Empty string and no token. */
1123 ptr
= strsep(&cp
, "");
1125 check(ptr
== one
, 87);
1126 check(cp
== NULL
, 88);
1137 check(memcmp("a", "a", 1) == 0, cnt
++); /* Identity. */
1138 check(memcmp("abc", "abc", 3) == 0, cnt
++); /* Multicharacter. */
1139 check(memcmp("abcd", "abcf", 4) < 0, cnt
++); /* Honestly unequal. */
1140 check(memcmp("abcf", "abcd", 4) > 0, cnt
++);
1141 check(memcmp("alph", "cold", 4) < 0, cnt
++);
1142 check(memcmp("a\203", "a\003", 2) > 0, cnt
++);
1143 check(memcmp("a\003", "a\203", 2) < 0, cnt
++);
1144 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt
++);
1145 check(memcmp("abc\203", "abc\003", 4) > 0, cnt
++);
1146 check(memcmp("abc\003", "abc\203", 4) < 0, cnt
++);
1147 check(memcmp("abcf", "abcd", 3) == 0, cnt
++); /* Count limited. */
1148 check(memcmp("abc", "def", 0) == 0, cnt
++); /* Zero count. */
1149 /* Comparisons with shifting 4-byte boundaries. */
1150 for (int i
= 0; i
< 4; ++i
)
1154 strncpy(a
, "--------11112222", 16);
1155 strncpy(b
, "--------33334444", 16);
1156 check(memcmp(b
, a
, 16) > 0, cnt
++);
1157 check(memcmp(a
, b
, 16) < 0, cnt
++);
1165 check(memchr("abcd", 'z', 4) == NULL
, 1); /* Not found. */
1166 (void) strcpy(one
, "abcd");
1167 check(memchr(one
, 'c', 4) == one
+2, 2); /* Basic test. */
1168 check(memchr(one
, ~0xff|'c', 4) == one
+2, 2); /* ignore highorder bits. */
1169 check(memchr(one
, 'd', 4) == one
+3, 3); /* End of string. */
1170 check(memchr(one
, 'a', 4) == one
, 4); /* Beginning. */
1171 check(memchr(one
, '\0', 5) == one
+4, 5); /* Finding NUL. */
1172 (void) strcpy(one
, "ababa");
1173 check(memchr(one
, 'b', 5) == one
+1, 6); /* Finding first. */
1174 check(memchr(one
, 'b', 0) == NULL
, 7); /* Zero count. */
1175 check(memchr(one
, 'a', 1) == one
, 8); /* Singleton case. */
1176 (void) strcpy(one
, "a\203b");
1177 check(memchr(one
, 0203, 3) == one
+1, 9); /* Unsignedness. */
1179 /* now test all possible alignment and length combinations to catch
1180 bugs due to unrolled loops (assuming unrolling is limited to no
1181 more than 128 byte chunks: */
1183 char buf
[128 + sizeof(long)];
1184 long align
, len
, i
, pos
;
1186 for (align
= 0; align
< (long) sizeof(long); ++align
) {
1187 for (len
= 0; len
< (long) (sizeof(buf
) - align
); ++len
) {
1188 for (i
= 0; i
< len
; ++i
) {
1189 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
1191 for (pos
= 0; pos
< len
; ++pos
) {
1193 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
1195 check(memchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, 10);
1196 check(memchr(buf
+ align
, 'x', pos
) == NULL
, 11);
1197 buf
[align
+ pos
] = '-';
1209 check(memcpy(one
, "abc", 4) == one
, 1); /* Returned value. */
1210 equal(one
, "abc", 2); /* Did the copy go right? */
1212 (void) strcpy(one
, "abcdefgh");
1213 (void) memcpy(one
+1, "xyz", 2);
1214 equal(one
, "axydefgh", 3); /* Basic test. */
1216 (void) strcpy(one
, "abc");
1217 (void) memcpy(one
, "xyz", 0);
1218 equal(one
, "abc", 4); /* Zero-length copy. */
1220 (void) strcpy(one
, "hi there");
1221 (void) strcpy(two
, "foo");
1222 (void) memcpy(two
, one
, 9);
1223 equal(two
, "hi there", 5); /* Just paranoia. */
1224 equal(one
, "hi there", 6); /* Stomped on source? */
1226 for (i
= 0; i
< 16; i
++)
1228 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1230 check (memcpy (one
+ i
, "hi there", 9) == one
+ i
,
1231 7 + (i
* 6)); /* Unaligned destination. */
1232 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1233 equal (one
+ i
, "hi there", 9 + (i
* 6));
1234 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1235 check (memcpy (two
, one
+ i
, 9) == two
,
1236 11 + (i
* 6)); /* Unaligned source. */
1237 equal (two
, "hi there", 12 + (i
* 6));
1246 check(mempcpy(one
, "abc", 4) == one
+ 4, 1); /* Returned value. */
1247 equal(one
, "abc", 2); /* Did the copy go right? */
1249 (void) strcpy(one
, "abcdefgh");
1250 (void) mempcpy(one
+1, "xyz", 2);
1251 equal(one
, "axydefgh", 3); /* Basic test. */
1253 (void) strcpy(one
, "abc");
1254 (void) mempcpy(one
, "xyz", 0);
1255 equal(one
, "abc", 4); /* Zero-length copy. */
1257 (void) strcpy(one
, "hi there");
1258 (void) strcpy(two
, "foo");
1259 (void) mempcpy(two
, one
, 9);
1260 equal(two
, "hi there", 5); /* Just paranoia. */
1261 equal(one
, "hi there", 6); /* Stomped on source? */
1263 for (i
= 0; i
< 16; i
++)
1265 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1267 check (mempcpy (one
+ i
, "hi there", 9) == one
+ i
+ 9,
1268 7 + (i
* 6)); /* Unaligned destination. */
1269 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1270 equal (one
+ i
, "hi there", 9 + (i
* 6));
1271 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1272 check (mempcpy (two
, one
+ i
, 9) == two
+ 9,
1273 11 + (i
* 6)); /* Unaligned source. */
1274 equal (two
, "hi there", 12 + (i
* 6));
1282 check(memmove(one
, "abc", 4) == one
, 1); /* Returned value. */
1283 equal(one
, "abc", 2); /* Did the copy go right? */
1285 (void) strcpy(one
, "abcdefgh");
1286 (void) memmove(one
+1, "xyz", 2);
1287 equal(one
, "axydefgh", 3); /* Basic test. */
1289 (void) strcpy(one
, "abc");
1290 (void) memmove(one
, "xyz", 0);
1291 equal(one
, "abc", 4); /* Zero-length copy. */
1293 (void) strcpy(one
, "hi there");
1294 (void) strcpy(two
, "foo");
1295 (void) memmove(two
, one
, 9);
1296 equal(two
, "hi there", 5); /* Just paranoia. */
1297 equal(one
, "hi there", 6); /* Stomped on source? */
1299 (void) strcpy(one
, "abcdefgh");
1300 (void) memmove(one
+1, one
, 9);
1301 equal(one
, "aabcdefgh", 7); /* Overlap, right-to-left. */
1303 (void) strcpy(one
, "abcdefgh");
1304 (void) memmove(one
+1, one
+2, 7);
1305 equal(one
, "acdefgh", 8); /* Overlap, left-to-right. */
1307 (void) strcpy(one
, "abcdefgh");
1308 (void) memmove(one
, one
, 9);
1309 equal(one
, "abcdefgh", 9); /* 100% overlap. */
1315 /* First test like memcpy, then the search part The SVID, the only
1316 place where memccpy is mentioned, says overlap might fail, so we
1317 don't try it. Besides, it's hard to see the rationale for a
1318 non-left-to-right memccpy. */
1320 check(memccpy(one
, "abc", 'q', 4) == NULL
, 1); /* Returned value. */
1321 equal(one
, "abc", 2); /* Did the copy go right? */
1323 (void) strcpy(one
, "abcdefgh");
1324 (void) memccpy(one
+1, "xyz", 'q', 2);
1325 equal(one
, "axydefgh", 3); /* Basic test. */
1327 (void) strcpy(one
, "abc");
1328 (void) memccpy(one
, "xyz", 'q', 0);
1329 equal(one
, "abc", 4); /* Zero-length copy. */
1331 (void) strcpy(one
, "hi there");
1332 (void) strcpy(two
, "foo");
1333 (void) memccpy(two
, one
, 'q', 9);
1334 equal(two
, "hi there", 5); /* Just paranoia. */
1335 equal(one
, "hi there", 6); /* Stomped on source? */
1337 (void) strcpy(one
, "abcdefgh");
1338 (void) strcpy(two
, "horsefeathers");
1339 check(memccpy(two
, one
, 'f', 9) == two
+6, 7); /* Returned value. */
1340 equal(one
, "abcdefgh", 8); /* Source intact? */
1341 equal(two
, "abcdefeathers", 9); /* Copy correct? */
1343 (void) strcpy(one
, "abcd");
1344 (void) strcpy(two
, "bumblebee");
1345 check(memccpy(two
, one
, 'a', 4) == two
+1, 10); /* First char. */
1346 equal(two
, "aumblebee", 11);
1347 check(memccpy(two
, one
, 'd', 4) == two
+4, 12); /* Last char. */
1348 equal(two
, "abcdlebee", 13);
1349 (void) strcpy(one
, "xyz");
1350 check(memccpy(two
, one
, 'x', 1) == two
+1, 14); /* Singleton. */
1351 equal(two
, "xbcdlebee", 15);
1360 (void) strcpy(one
, "abcdefgh");
1361 check(memset(one
+1, 'x', 3) == one
+1, 1); /* Return value. */
1362 equal(one
, "axxxefgh", 2); /* Basic test. */
1364 DIAG_PUSH_NEEDS_COMMENT
;
1365 #if __GNUC_PREREQ (5, 0)
1366 /* GCC 5.0 warns about a zero-length memset because the arguments to memset
1367 may be in the wrong order. But we really want to test this. */
1368 DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args")
1370 (void) memset(one
+2, 'y', 0);
1371 equal(one
, "axxxefgh", 3); /* Zero-length set. */
1372 DIAG_POP_NEEDS_COMMENT
;
1374 (void) memset(one
+5, 0, 1);
1375 equal(one
, "axxxe", 4); /* Zero fill. */
1376 equal(one
+6, "gh", 5); /* And the leftover. */
1378 (void) memset(one
+2, 010045, 1);
1379 equal(one
, "ax\045xe", 6); /* Unsigned char convert. */
1381 /* Non-8bit fill character. */
1382 memset (one
, 0x101, sizeof (one
));
1383 for (i
= 0; i
< (int) sizeof (one
); ++i
)
1384 check (one
[i
] == '\01', 7);
1386 /* Test for more complex versions of memset, for all alignments and
1387 lengths up to 256. This test takes a little while, perhaps it should
1395 for (i
= 0; i
< 512; i
++)
1397 for (c
= 0; c
<= 'y'; c
+= 'y') /* check for memset(,0,) and
1399 for (j
= 0; j
< 256; j
++)
1400 for (i
= 0; i
< 256; i
++)
1402 memset (data
+ i
, c
, j
);
1403 for (k
= 0; k
< i
; k
++)
1406 for (k
= i
; k
< i
+j
; k
++)
1412 for (k
= i
+j
; k
< 512; k
++)
1418 check (0, 8 + i
+ j
* 256 + (c
!= 0) * 256 * 256);
1426 /* Much like memcpy. Berklix manual is silent about overlap, so
1429 (void) bcopy("abc", one
, 4);
1430 equal(one
, "abc", 1); /* Simple copy. */
1432 (void) strcpy(one
, "abcdefgh");
1433 (void) bcopy("xyz", one
+1, 2);
1434 equal(one
, "axydefgh", 2); /* Basic test. */
1436 (void) strcpy(one
, "abc");
1437 (void) bcopy("xyz", one
, 0);
1438 equal(one
, "abc", 3); /* Zero-length copy. */
1440 (void) strcpy(one
, "hi there");
1441 (void) strcpy(two
, "foo");
1442 (void) bcopy(one
, two
, 9);
1443 equal(two
, "hi there", 4); /* Just paranoia. */
1444 equal(one
, "hi there", 5); /* Stomped on source? */
1451 (void) strcpy(one
, "abcdef");
1453 equal(one
, "ab", 1); /* Basic test. */
1454 equal(one
+3, "", 2);
1455 equal(one
+4, "ef", 3);
1457 (void) strcpy(one
, "abcdef");
1459 equal(one
, "abcdef", 4); /* Zero-length copy. */
1467 p
= strndup("abcdef", 12);
1468 check(p
!= NULL
, 1);
1471 equal(p
, "abcdef", 2);
1472 q
= strndup(p
+ 1, 2);
1473 check(q
!= NULL
, 3);
1479 p
= strndup("abc def", 3);
1480 check(p
!= NULL
, 5);
1490 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1491 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1492 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1493 check(bcmp("abce", "abcd", 4) != 0, 4);
1494 check(bcmp("alph", "beta", 4) != 0, 5);
1495 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1496 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1500 test_strerror (void)
1503 check(strerror(EDOM
) != 0, 1);
1504 check(strerror(ERANGE
) != 0, 2);
1505 check(strerror(ENOENT
) != 0, 3);
1509 test_strcasecmp (void)
1512 /* Note that the locale is "C". */
1513 check(strcasecmp("a", "a") == 0, 1);
1514 check(strcasecmp("a", "A") == 0, 2);
1515 check(strcasecmp("A", "a") == 0, 3);
1516 check(strcasecmp("a", "b") < 0, 4);
1517 check(strcasecmp("c", "b") > 0, 5);
1518 check(strcasecmp("abc", "AbC") == 0, 6);
1519 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1520 check(strcasecmp("", "0123456789") < 0, 8);
1521 check(strcasecmp("AbC", "") > 0, 9);
1522 check(strcasecmp("AbC", "A") > 0, 10);
1523 check(strcasecmp("AbC", "Ab") > 0, 11);
1524 check(strcasecmp("AbC", "ab") > 0, 12);
1528 test_strncasecmp (void)
1531 /* Note that the locale is "C". */
1532 check(strncasecmp("a", "a", 5) == 0, 1);
1533 check(strncasecmp("a", "A", 5) == 0, 2);
1534 check(strncasecmp("A", "a", 5) == 0, 3);
1535 check(strncasecmp("a", "b", 5) < 0, 4);
1536 check(strncasecmp("c", "b", 5) > 0, 5);
1537 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1538 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1539 check(strncasecmp("", "0123456789", 10) < 0, 8);
1540 check(strncasecmp("AbC", "", 5) > 0, 9);
1541 check(strncasecmp("AbC", "A", 5) > 0, 10);
1542 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1543 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1544 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1545 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1546 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1547 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1548 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1549 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1550 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1551 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1559 /* Test strcmp first because we use it to test other things. */
1562 /* Test strcpy next because we need it to set up other tests. */
1565 /* A closely related function is stpcpy. */
1598 /* index - just like strchr. */
1607 /* rindex - just like strrchr. */
1610 /* strpbrk - somewhat like strchr. */
1613 /* strstr - somewhat like strchr. */
1622 /* strtok - the hard one. */
1637 /* memcpy - need not work for overlap. */
1640 /* memmove - must work on overlap. */
1658 /* bcmp - somewhat like memcmp. */
1664 /* strerror - VERY system-dependent. */
1667 /* strcasecmp. Without locale dependencies. */
1670 /* strncasecmp. Without locale dependencies. */
1671 test_strncasecmp ();
1675 status
= EXIT_SUCCESS
;
1680 status
= EXIT_FAILURE
;
1681 printf("%Zd errors.\n", errors
);