1 /* Tester for string functions.
2 Copyright (C) 1995-2018 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 DIAG_PUSH_NEEDS_COMMENT
;
268 #if __GNUC_PREREQ (8, 0)
269 /* GCC 8 warns about stpncpy truncating output; this is deliberately
271 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
273 check (stpncpy (one
, "abc", 2) == one
+ 2, 1);
274 check (stpncpy (one
, "abc", 3) == one
+ 3, 2);
275 DIAG_POP_NEEDS_COMMENT
;
276 check (stpncpy (one
, "abc", 4) == one
+ 3, 3);
277 check (one
[3] == '\0' && one
[4] == 'x', 4);
278 check (stpncpy (one
, "abcd", 5) == one
+ 4, 5);
279 check (one
[4] == '\0' && one
[5] == 'x', 6);
280 check (stpncpy (one
, "abcd", 6) == one
+ 4, 7);
281 check (one
[4] == '\0' && one
[5] == '\0' && one
[6] == 'x', 8);
288 (void) strcpy (one
, "ijk");
289 check (strcat (one
, "lmn") == one
, 1); /* Returned value. */
290 equal (one
, "ijklmn", 2); /* Basic test. */
292 (void) strcpy (one
, "x");
293 (void) strcat (one
, "yz");
294 equal (one
, "xyz", 3); /* Writeover. */
295 equal (one
+4, "mn", 4); /* Wrote too much? */
297 (void) strcpy (one
, "gh");
298 (void) strcpy (two
, "ef");
299 (void) strcat (one
, two
);
300 equal (one
, "ghef", 5); /* Basic test encore. */
301 equal (two
, "ef", 6); /* Stomped on source? */
303 (void) strcpy (one
, "");
304 (void) strcat (one
, "");
305 equal (one
, "", 7); /* Boundary conditions. */
306 (void) strcpy (one
, "ab");
307 (void) strcat (one
, "");
308 equal (one
, "ab", 8);
309 (void) strcpy (one
, "");
310 (void) strcat (one
, "cd");
311 equal (one
, "cd", 9);
314 char buf1
[80] __attribute__ ((aligned (16)));
315 char buf2
[32] __attribute__ ((aligned (16)));
316 for (size_t n1
= 0; n1
< 16; ++n1
)
317 for (size_t n2
= 0; n2
< 16; ++n2
)
318 for (size_t n3
= 0; n3
< 32; ++n3
)
320 size_t olderrors
= errors
;
322 memset (buf1
, 'b', sizeof (buf1
));
324 memset (buf1
+ n2
, 'a', n3
);
325 buf1
[n2
+ n3
] = '\0';
326 strcpy (buf2
+ n1
, "123");
328 check (strcat (buf1
+ n2
, buf2
+ n1
) == buf1
+ n2
, ntest
);
329 if (errors
== olderrors
)
330 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
333 check (buf1
[i
] == 'b', ntest
);
334 else if (i
< n2
+ n3
)
335 check (buf1
[i
] == 'a', ntest
);
336 else if (i
< n2
+ n3
+ 3)
337 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
338 else if (i
== n2
+ n3
+ 3)
339 check (buf1
[i
] == '\0', ntest
);
341 check (buf1
[i
] == 'b', ntest
);
343 if (errors
!= olderrors
)
345 printf ("n1=%zu, n2=%zu, n3=%zu, buf1=%02hhx",
346 n1
, n2
, n3
, buf1
[0]);
347 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
348 printf (",%02hhx", buf1
[j
]);
349 putchar_unlocked ('\n');
359 /* First test it as strcat, with big counts, then test the count
362 (void) strcpy (one
, "ijk");
363 DIAG_PUSH_NEEDS_COMMENT
;
364 #if __GNUC_PREREQ (7, 0)
365 /* GCC 7 warns about the size passed to strncat being larger than
366 the size of the buffer; this is deliberately tested here.. */
367 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
369 check (strncat (one
, "lmn", 99) == one
, 1); /* Returned value. */
370 DIAG_POP_NEEDS_COMMENT
;
371 equal (one
, "ijklmn", 2); /* Basic test. */
373 (void) strcpy (one
, "x");
374 DIAG_PUSH_NEEDS_COMMENT
;
375 #if __GNUC_PREREQ (7, 0)
376 /* GCC 7 warns about the size passed to strncat being larger than
377 the size of the buffer; this is deliberately tested here.. */
378 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
380 (void) strncat (one
, "yz", 99);
381 DIAG_POP_NEEDS_COMMENT
;
382 equal (one
, "xyz", 3); /* Writeover. */
383 equal (one
+4, "mn", 4); /* Wrote too much? */
385 (void) strcpy (one
, "gh");
386 (void) strcpy (two
, "ef");
387 DIAG_PUSH_NEEDS_COMMENT
;
388 #if __GNUC_PREREQ (7, 0)
389 /* GCC 7 warns about the size passed to strncat being larger than
390 the size of the buffer; this is deliberately tested here; GCC 8
391 gives a -Warray-bounds warning about this. */
392 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
394 DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
395 (void) strncat (one
, two
, 99);
396 DIAG_POP_NEEDS_COMMENT
;
397 equal (one
, "ghef", 5); /* Basic test encore. */
398 equal (two
, "ef", 6); /* Stomped on source? */
400 (void) strcpy (one
, "");
401 DIAG_PUSH_NEEDS_COMMENT
;
402 #if __GNUC_PREREQ (7, 0)
403 /* GCC 7 warns about the size passed to strncat being larger than
404 the size of the buffer; this is deliberately tested here.. */
405 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
407 (void) strncat (one
, "", 99);
408 DIAG_POP_NEEDS_COMMENT
;
409 equal (one
, "", 7); /* Boundary conditions. */
410 (void) strcpy (one
, "ab");
411 DIAG_PUSH_NEEDS_COMMENT
;
412 #if __GNUC_PREREQ (7, 0)
413 /* GCC 7 warns about the size passed to strncat being larger than
414 the size of the buffer; this is deliberately tested here.. */
415 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
417 (void) strncat (one
, "", 99);
418 DIAG_POP_NEEDS_COMMENT
;
419 equal (one
, "ab", 8);
420 (void) strcpy (one
, "");
421 DIAG_PUSH_NEEDS_COMMENT
;
422 #if __GNUC_PREREQ (7, 0)
423 /* GCC 7 warns about the size passed to strncat being larger than
424 the size of the buffer; this is deliberately tested here.. */
425 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
427 (void) strncat (one
, "cd", 99);
428 DIAG_POP_NEEDS_COMMENT
;
429 equal (one
, "cd", 9);
431 (void) strcpy (one
, "ab");
432 DIAG_PUSH_NEEDS_COMMENT
;
433 #if __GNUC_PREREQ (8, 0)
434 /* GCC 8 warns about strncat truncating output; this is deliberately
436 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
438 (void) strncat (one
, "cdef", 2);
439 DIAG_POP_NEEDS_COMMENT
;
440 equal (one
, "abcd", 10); /* Count-limited. */
442 (void) strncat (one
, "gh", 0);
443 equal (one
, "abcd", 11); /* Zero count. */
445 DIAG_PUSH_NEEDS_COMMENT
;
446 #if __GNUC_PREREQ (7, 0)
447 /* GCC 8 warns about strncat bound equal to source length; this is
448 deliberately tested here. */
449 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-overflow=");
451 (void) strncat (one
, "gh", 2);
452 DIAG_POP_NEEDS_COMMENT
;
453 equal (one
, "abcdgh", 12); /* Count and length equal. */
455 DIAG_PUSH_NEEDS_COMMENT
;
456 #if __GNUC_PREREQ (7, 0)
457 /* GCC 7 warns about the size passed to strncat being larger than
458 the size of the buffer; this is deliberately tested here.. */
459 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
461 (void) strncat (one
, "ij", (size_t)-1); /* set sign bit in count */
462 DIAG_POP_NEEDS_COMMENT
;
463 equal (one
, "abcdghij", 13);
466 char buf1
[80] __attribute__ ((aligned (16)));
467 char buf2
[32] __attribute__ ((aligned (16)));
468 for (size_t n1
= 0; n1
< 16; ++n1
)
469 for (size_t n2
= 0; n2
< 16; ++n2
)
470 for (size_t n3
= 0; n3
< 32; ++n3
)
471 for (size_t n4
= 0; n4
< 16; ++n4
)
473 size_t olderrors
= errors
;
475 memset (buf1
, 'b', sizeof (buf1
));
477 memset (buf1
+ n2
, 'a', n3
);
478 buf1
[n2
+ n3
] = '\0';
479 strcpy (buf2
+ n1
, "123");
481 DIAG_PUSH_NEEDS_COMMENT
;
482 #if __GNUC_PREREQ (7, 0)
483 /* GCC 7 warns about the size passed to strncat being
484 larger than the size of the buffer; this is
485 deliberately tested here; GCC 8 gives a -Warray-bounds
486 warning about this. */
487 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
488 /* GCC 9 as of 2018-06-14 warns that the size passed is
489 large enough that, if it were the actual object size,
490 the objects would have to overlap. */
491 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wrestrict");
493 DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
494 check (strncat (buf1
+ n2
, buf2
+ n1
, ~((size_t) 0) - n4
)
495 == buf1
+ n2
, ntest
);
496 DIAG_POP_NEEDS_COMMENT
;
497 if (errors
== olderrors
)
498 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
501 check (buf1
[i
] == 'b', ntest
);
502 else if (i
< n2
+ n3
)
503 check (buf1
[i
] == 'a', ntest
);
504 else if (i
< n2
+ n3
+ 3)
505 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
506 else if (i
== n2
+ n3
+ 3)
507 check (buf1
[i
] == '\0', ntest
);
509 check (buf1
[i
] == 'b', ntest
);
511 if (errors
!= olderrors
)
513 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
514 n1
, n2
, n3
, n4
, buf1
[0]);
515 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
516 printf (",%02hhx", buf1
[j
]);
517 putchar_unlocked ('\n');
527 /* First test as strcmp with big counts, then test count code. */
529 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
530 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
531 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
532 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
533 check (strncmp ("abcd", "abc", 99) > 0, 5);
534 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
535 check (strncmp ("abce", "abcd", 99) > 0, 7);
536 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
537 check (strncmp ("a\203", "a\003", 2) > 0, 9);
538 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
539 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
540 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
541 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
542 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
543 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
549 /* Testing is a bit different because of odd semantics. */
551 check (strncpy (one
, "abc", 4) == one
, 1); /* Returned value. */
552 equal (one
, "abc", 2); /* Did the copy go right? */
554 (void) strcpy (one
, "abcdefgh");
555 DIAG_PUSH_NEEDS_COMMENT
;
556 #if __GNUC_PREREQ (8, 0)
557 /* GCC 8 warns about strncpy truncating output; this is deliberately
559 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
561 (void) strncpy (one
, "xyz", 2);
562 DIAG_POP_NEEDS_COMMENT
;
563 equal (one
, "xycdefgh", 3); /* Copy cut by count. */
565 (void) strcpy (one
, "abcdefgh");
566 DIAG_PUSH_NEEDS_COMMENT
;
567 #if __GNUC_PREREQ (8, 0)
568 /* GCC 8 warns about strncpy truncating output; this is deliberately
570 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
572 (void) strncpy (one
, "xyz", 3); /* Copy cut just before NUL. */
573 DIAG_POP_NEEDS_COMMENT
;
574 equal (one
, "xyzdefgh", 4);
576 (void) strcpy (one
, "abcdefgh");
577 (void) strncpy (one
, "xyz", 4); /* Copy just includes NUL. */
578 equal (one
, "xyz", 5);
579 equal (one
+4, "efgh", 6); /* Wrote too much? */
581 (void) strcpy (one
, "abcdefgh");
582 (void) strncpy (one
, "xyz", 5); /* Copy includes padding. */
583 equal (one
, "xyz", 7);
584 equal (one
+4, "", 8);
585 equal (one
+5, "fgh", 9);
587 (void) strcpy (one
, "abc");
588 DIAG_PUSH_NEEDS_COMMENT
;
589 #if __GNUC_PREREQ (8, 0)
590 /* GCC 8 warns about strncpy truncating output; this is deliberately
592 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
594 (void) strncpy (one
, "xyz", 0); /* Zero-length copy. */
595 DIAG_POP_NEEDS_COMMENT
;
596 equal (one
, "abc", 10);
598 (void) strncpy (one
, "", 2); /* Zero-length source. */
600 equal (one
+1, "", 12);
601 equal (one
+2, "c", 13);
603 (void) strcpy (one
, "hi there");
604 (void) strncpy (two
, one
, 9);
605 equal (two
, "hi there", 14); /* Just paranoia. */
606 equal (one
, "hi there", 15); /* Stomped on source? */
613 check (strlen ("") == 0, 1); /* Empty. */
614 check (strlen ("a") == 1, 2); /* Single char. */
615 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
620 for (i
=0; i
< 0x100; i
++)
622 p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
624 strcpy (p
+3, "BAD/WRONG");
625 check (strlen (p
) == 2, 4+i
);
634 check (strnlen ("", 10) == 0, 1); /* Empty. */
635 check (strnlen ("a", 10) == 1, 2); /* Single char. */
636 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
637 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
638 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
639 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
640 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
641 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
642 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
645 for (int i
= 0; i
< 0x100; ++i
)
647 char *p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
649 strcpy (p
+ 3, "BAD/WRONG");
650 check (strnlen (p
, 100) == 2, 10 + i
);
658 check (strchr ("abcd", 'z') == NULL
, 1); /* Not found. */
659 (void) strcpy (one
, "abcd");
660 check (strchr (one
, 'c') == one
+2, 2); /* Basic test. */
661 check (strchr (one
, 'd') == one
+3, 3); /* End of string. */
662 check (strchr (one
, 'a') == one
, 4); /* Beginning. */
663 check (strchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
664 (void) strcpy (one
, "ababa");
665 check (strchr (one
, 'b') == one
+1, 6); /* Finding first. */
666 (void) strcpy (one
, "");
667 check (strchr (one
, 'b') == NULL
, 7); /* Empty string. */
668 check (strchr (one
, '\0') == one
, 8); /* NUL in empty string. */
673 for (i
=0; i
< 0x100; i
++)
675 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
677 strcpy (p
+3, "BAD/WRONG");
678 check (strchr (p
, '/') == NULL
, 9+i
);
684 test_strchrnul (void)
688 cp
= strchrnul ((os
= "abcd"), 'z');
689 check (*cp
== '\0', 1); /* Not found. */
690 check (cp
== os
+ 4, 2);
691 (void) strcpy (one
, "abcd");
692 check (strchrnul (one
, 'c') == one
+2, 3); /* Basic test. */
693 check (strchrnul (one
, 'd') == one
+3, 4); /* End of string. */
694 check (strchrnul (one
, 'a') == one
, 5); /* Beginning. */
695 check (strchrnul (one
, '\0') == one
+4, 6); /* Finding NUL. */
696 (void) strcpy (one
, "ababa");
697 check (strchrnul (one
, 'b') == one
+1, 7); /* Finding first. */
698 (void) strcpy (one
, "");
699 check (strchrnul (one
, 'b') == one
, 8); /* Empty string. */
700 check (strchrnul (one
, '\0') == one
, 9); /* NUL in empty string. */
705 for (i
=0; i
< 0x100; i
++)
707 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
709 strcpy (p
+3, "BAD/WRONG");
710 cp
= strchrnul (p
, '/');
711 check (*cp
== '\0', 9+2*i
);
712 check (cp
== p
+2, 10+2*i
);
718 test_rawmemchr (void)
721 (void) strcpy (one
, "abcd");
722 check (rawmemchr (one
, 'c') == one
+2, 1); /* Basic test. */
723 check (rawmemchr (one
, 'd') == one
+3, 2); /* End of string. */
724 check (rawmemchr (one
, 'a') == one
, 3); /* Beginning. */
725 check (rawmemchr (one
, '\0') == one
+4, 4); /* Finding NUL. */
726 (void) strcpy (one
, "ababa");
727 check (rawmemchr (one
, 'b') == one
+1, 5); /* Finding first. */
728 (void) strcpy (one
, "");
729 check (rawmemchr (one
, '\0') == one
, 6); /* NUL in empty string. */
734 for (i
=0; i
< 0x100; i
++)
736 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
738 strcpy (p
+3, "BAD/WRONG");
739 check (rawmemchr (p
, 'R') == p
+8, 6+i
);
748 check (index ("abcd", 'z') == NULL
, 1); /* Not found. */
749 (void) strcpy (one
, "abcd");
750 check (index (one
, 'c') == one
+2, 2); /* Basic test. */
751 check (index (one
, 'd') == one
+3, 3); /* End of string. */
752 check (index (one
, 'a') == one
, 4); /* Beginning. */
753 check (index (one
, '\0') == one
+4, 5); /* Finding NUL. */
754 (void) strcpy (one
, "ababa");
755 check (index (one
, 'b') == one
+1, 6); /* Finding first. */
756 (void) strcpy (one
, "");
757 check (index (one
, 'b') == NULL
, 7); /* Empty string. */
758 check (index (one
, '\0') == one
, 8); /* NUL in empty string. */
765 check (strrchr ("abcd", 'z') == NULL
, 1); /* Not found. */
766 (void) strcpy (one
, "abcd");
767 check (strrchr (one
, 'c') == one
+2, 2); /* Basic test. */
768 check (strrchr (one
, 'd') == one
+3, 3); /* End of string. */
769 check (strrchr (one
, 'a') == one
, 4); /* Beginning. */
770 check (strrchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
771 (void) strcpy (one
, "ababa");
772 check (strrchr (one
, 'b') == one
+3, 6); /* Finding last. */
773 (void) strcpy (one
, "");
774 check (strrchr (one
, 'b') == NULL
, 7); /* Empty string. */
775 check (strrchr (one
, '\0') == one
, 8); /* NUL in empty string. */
780 for (i
=0; i
< 0x100; i
++)
782 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
784 strcpy (p
+3, "BAD/WRONG");
785 check (strrchr (p
, '/') == NULL
, 9+i
);
795 check (memrchr ("abcd", 'z', 5) == NULL
, 1); /* Not found. */
796 (void) strcpy (one
, "abcd");
797 l
= strlen (one
) + 1;
798 check (memrchr (one
, 'c', l
) == one
+2, 2); /* Basic test. */
799 check (memrchr (one
, 'd', l
) == one
+3, 3); /* End of string. */
800 check (memrchr (one
, 'a', l
) == one
, 4); /* Beginning. */
801 check (memrchr (one
, '\0', l
) == one
+4, 5); /* Finding NUL. */
802 (void) strcpy (one
, "ababa");
803 l
= strlen (one
) + 1;
804 check (memrchr (one
, 'b', l
) == one
+3, 6); /* Finding last. */
805 (void) strcpy (one
, "");
806 l
= strlen (one
) + 1;
807 check (memrchr (one
, 'b', l
) == NULL
, 7); /* Empty string. */
808 check (memrchr (one
, '\0', l
) == one
, 8); /* NUL in empty string. */
810 /* now test all possible alignment and length combinations to catch
811 bugs due to unrolled loops (assuming unrolling is limited to no
812 more than 128 byte chunks: */
814 char buf
[128 + sizeof(long)];
815 long align
, len
, i
, pos
, n
= 9;
817 for (align
= 0; align
< (long) sizeof(long); ++align
) {
818 for (len
= 0; len
< (long) (sizeof(buf
) - align
); ++len
) {
819 for (i
= 0; i
< len
; ++i
)
820 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
822 for (pos
= len
- 1; pos
>= 0; --pos
) {
824 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
826 check(memrchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, n
++);
827 check(memrchr(buf
+ align
+ pos
+ 1, 'x', len
- (pos
+ 1)) == NULL
,
829 buf
[align
+ pos
] = '-';
840 check (rindex ("abcd", 'z') == NULL
, 1); /* Not found. */
841 (void) strcpy (one
, "abcd");
842 check (rindex (one
, 'c') == one
+2, 2); /* Basic test. */
843 check (rindex (one
, 'd') == one
+3, 3); /* End of string. */
844 check (rindex (one
, 'a') == one
, 4); /* Beginning. */
845 check (rindex (one
, '\0') == one
+4, 5); /* Finding NUL. */
846 (void) strcpy (one
, "ababa");
847 check (rindex (one
, 'b') == one
+3, 6); /* Finding last. */
848 (void) strcpy (one
, "");
849 check (rindex (one
, 'b') == NULL
, 7); /* Empty string. */
850 check (rindex (one
, '\0') == one
, 8); /* NUL in empty string. */
857 check(strpbrk("abcd", "z") == NULL
, 1); /* Not found. */
858 (void) strcpy(one
, "abcd");
859 check(strpbrk(one
, "c") == one
+2, 2); /* Basic test. */
860 check(strpbrk(one
, "d") == one
+3, 3); /* End of string. */
861 check(strpbrk(one
, "a") == one
, 4); /* Beginning. */
862 check(strpbrk(one
, "") == NULL
, 5); /* Empty search list. */
863 check(strpbrk(one
, "cb") == one
+1, 6); /* Multiple search. */
864 (void) strcpy(one
, "abcabdea");
865 check(strpbrk(one
, "b") == one
+1, 7); /* Finding first. */
866 check(strpbrk(one
, "cb") == one
+1, 8); /* With multiple search. */
867 check(strpbrk(one
, "db") == one
+1, 9); /* Another variant. */
868 (void) strcpy(one
, "");
869 check(strpbrk(one
, "bc") == NULL
, 10); /* Empty string. */
870 (void) strcpy(one
, "");
871 check(strpbrk(one
, "bcd") == NULL
, 11); /* Empty string. */
872 (void) strcpy(one
, "");
873 check(strpbrk(one
, "bcde") == NULL
, 12); /* Empty string. */
874 check(strpbrk(one
, "") == NULL
, 13); /* Both strings empty. */
875 (void) strcpy(one
, "abcabdea");
876 check(strpbrk(one
, "befg") == one
+1, 14); /* Finding first. */
877 check(strpbrk(one
, "cbr") == one
+1, 15); /* With multiple search. */
878 check(strpbrk(one
, "db") == one
+1, 16); /* Another variant. */
879 check(strpbrk(one
, "efgh") == one
+6, 17); /* And yet another. */
886 check(strstr("abcd", "z") == NULL
, 1); /* Not found. */
887 check(strstr("abcd", "abx") == NULL
, 2); /* Dead end. */
888 (void) strcpy(one
, "abcd");
889 check(strstr(one
, "c") == one
+2, 3); /* Basic test. */
890 check(strstr(one
, "bc") == one
+1, 4); /* Multichar. */
891 check(strstr(one
, "d") == one
+3, 5); /* End of string. */
892 check(strstr(one
, "cd") == one
+2, 6); /* Tail of string. */
893 check(strstr(one
, "abc") == one
, 7); /* Beginning. */
894 check(strstr(one
, "abcd") == one
, 8); /* Exact match. */
895 check(strstr(one
, "abcde") == NULL
, 9); /* Too long. */
896 check(strstr(one
, "de") == NULL
, 10); /* Past end. */
897 check(strstr(one
, "") == one
, 11); /* Finding empty. */
898 (void) strcpy(one
, "ababa");
899 check(strstr(one
, "ba") == one
+1, 12); /* Finding first. */
900 (void) strcpy(one
, "");
901 check(strstr(one
, "b") == NULL
, 13); /* Empty string. */
902 check(strstr(one
, "") == one
, 14); /* Empty in empty string. */
903 (void) strcpy(one
, "bcbca");
904 check(strstr(one
, "bca") == one
+2, 15); /* False start. */
905 (void) strcpy(one
, "bbbcabbca");
906 check(strstr(one
, "bbca") == one
+1, 16); /* With overlap. */
913 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
914 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
915 check(strspn("abc", "qx") == 0, 3); /* None. */
916 check(strspn("", "ab") == 0, 4); /* Null string. */
917 check(strspn("abc", "") == 0, 5); /* Null search list. */
924 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
925 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
926 check(strcspn("abc", "abc") == 0, 3); /* None. */
927 check(strcspn("", "ab") == 0, 4); /* Null string. */
928 check(strcspn("abc", "") == 3, 5); /* Null search list. */
935 (void) strcpy(one
, "first, second, third");
936 equal(strtok(one
, ", "), "first", 1); /* Basic test. */
937 equal(one
, "first", 2);
938 equal(strtok((char *)NULL
, ", "), "second", 3);
939 equal(strtok((char *)NULL
, ", "), "third", 4);
940 check(strtok((char *)NULL
, ", ") == NULL
, 5);
941 (void) strcpy(one
, ", first, ");
942 equal(strtok(one
, ", "), "first", 6); /* Extra delims, 1 tok. */
943 check(strtok((char *)NULL
, ", ") == NULL
, 7);
944 (void) strcpy(one
, "1a, 1b; 2a, 2b");
945 equal(strtok(one
, ", "), "1a", 8); /* Changing delim lists. */
946 equal(strtok((char *)NULL
, "; "), "1b", 9);
947 equal(strtok((char *)NULL
, ", "), "2a", 10);
948 (void) strcpy(two
, "x-y");
949 equal(strtok(two
, "-"), "x", 11); /* New string before done. */
950 equal(strtok((char *)NULL
, "-"), "y", 12);
951 check(strtok((char *)NULL
, "-") == NULL
, 13);
952 (void) strcpy(one
, "a,b, c,, ,d");
953 equal(strtok(one
, ", "), "a", 14); /* Different separators. */
954 equal(strtok((char *)NULL
, ", "), "b", 15);
955 equal(strtok((char *)NULL
, " ,"), "c", 16); /* Permute list too. */
956 equal(strtok((char *)NULL
, " ,"), "d", 17);
957 check(strtok((char *)NULL
, ", ") == NULL
, 18);
958 check(strtok((char *)NULL
, ", ") == NULL
, 19); /* Persistence. */
959 (void) strcpy(one
, ", ");
960 check(strtok(one
, ", ") == NULL
, 20); /* No tokens. */
961 (void) strcpy(one
, "");
962 check(strtok(one
, ", ") == NULL
, 21); /* Empty string. */
963 (void) strcpy(one
, "abc");
964 equal(strtok(one
, ", "), "abc", 22); /* No delimiters. */
965 check(strtok((char *)NULL
, ", ") == NULL
, 23);
966 (void) strcpy(one
, "abc");
967 equal(strtok(one
, ""), "abc", 24); /* Empty delimiter list. */
968 check(strtok((char *)NULL
, "") == NULL
, 25);
969 (void) strcpy(one
, "abcdefgh");
970 (void) strcpy(one
, "a,b,c");
971 equal(strtok(one
, ","), "a", 26); /* Basics again... */
972 equal(strtok((char *)NULL
, ","), "b", 27);
973 equal(strtok((char *)NULL
, ","), "c", 28);
974 check(strtok((char *)NULL
, ",") == NULL
, 29);
975 equal(one
+6, "gh", 30); /* Stomped past end? */
976 equal(one
, "a", 31); /* Stomped old tokens? */
977 equal(one
+2, "b", 32);
978 equal(one
+4, "c", 33);
985 (void) strcpy(one
, "first, second, third");
986 cp
= NULL
; /* Always initialize cp to make sure it doesn't point to some old data. */
987 equal(strtok_r(one
, ", ", &cp
), "first", 1); /* Basic test. */
988 equal(one
, "first", 2);
989 equal(strtok_r((char *)NULL
, ", ", &cp
), "second", 3);
990 equal(strtok_r((char *)NULL
, ", ", &cp
), "third", 4);
991 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 5);
992 (void) strcpy(one
, ", first, ");
994 equal(strtok_r(one
, ", ", &cp
), "first", 6); /* Extra delims, 1 tok. */
995 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 7);
996 (void) strcpy(one
, "1a, 1b; 2a, 2b");
998 equal(strtok_r(one
, ", ", &cp
), "1a", 8); /* Changing delim lists. */
999 equal(strtok_r((char *)NULL
, "; ", &cp
), "1b", 9);
1000 equal(strtok_r((char *)NULL
, ", ", &cp
), "2a", 10);
1001 (void) strcpy(two
, "x-y");
1003 equal(strtok_r(two
, "-", &cp
), "x", 11); /* New string before done. */
1004 equal(strtok_r((char *)NULL
, "-", &cp
), "y", 12);
1005 check(strtok_r((char *)NULL
, "-", &cp
) == NULL
, 13);
1006 (void) strcpy(one
, "a,b, c,, ,d");
1008 equal(strtok_r(one
, ", ", &cp
), "a", 14); /* Different separators. */
1009 equal(strtok_r((char *)NULL
, ", ", &cp
), "b", 15);
1010 equal(strtok_r((char *)NULL
, " ,", &cp
), "c", 16); /* Permute list too. */
1011 equal(strtok_r((char *)NULL
, " ,", &cp
), "d", 17);
1012 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 18);
1013 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 19); /* Persistence. */
1014 (void) strcpy(one
, ", ");
1016 check(strtok_r(one
, ", ", &cp
) == NULL
, 20); /* No tokens. */
1017 (void) strcpy(one
, "");
1019 check(strtok_r(one
, ", ", &cp
) == NULL
, 21); /* Empty string. */
1020 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 22); /* Persistence. */
1021 (void) strcpy(one
, "abc");
1023 equal(strtok_r(one
, ", ", &cp
), "abc", 23); /* No delimiters. */
1024 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 24);
1025 (void) strcpy(one
, "abc");
1027 equal(strtok_r(one
, "", &cp
), "abc", 25); /* Empty delimiter list. */
1028 check(strtok_r((char *)NULL
, "", &cp
) == NULL
, 26);
1029 (void) strcpy(one
, "abcdefgh");
1030 (void) strcpy(one
, "a,b,c");
1032 equal(strtok_r(one
, ",", &cp
), "a", 27); /* Basics again... */
1033 equal(strtok_r((char *)NULL
, ",", &cp
), "b", 28);
1034 equal(strtok_r((char *)NULL
, ",", &cp
), "c", 29);
1035 check(strtok_r((char *)NULL
, ",", &cp
) == NULL
, 30);
1036 equal(one
+6, "gh", 31); /* Stomped past end? */
1037 equal(one
, "a", 32); /* Stomped old tokens? */
1038 equal(one
+2, "b", 33);
1039 equal(one
+4, "c", 34);
1040 strcpy (one
, ":::");
1042 check (strtok_r (one
, ":", &cp
) == NULL
, 35); /* Must store pointer in cp. */
1043 check (strtok_r (NULL
, ":", &cp
) == NULL
, 36);
1051 cp
= strcpy(one
, "first, second, third");
1052 equal(strsep(&cp
, ", "), "first", 1); /* Basic test. */
1053 equal(one
, "first", 2);
1054 equal(strsep(&cp
, ", "), "", 3);
1055 equal(strsep(&cp
, ", "), "second", 4);
1056 equal(strsep(&cp
, ", "), "", 5);
1057 equal(strsep(&cp
, ", "), "third", 6);
1058 check(strsep(&cp
, ", ") == NULL
, 7);
1059 cp
= strcpy(one
, ", first, ");
1060 equal(strsep(&cp
, ", "), "", 8);
1061 equal(strsep(&cp
, ", "), "", 9);
1062 equal(strsep(&cp
, ", "), "first", 10); /* Extra delims, 1 tok. */
1063 equal(strsep(&cp
, ", "), "", 11);
1064 equal(strsep(&cp
, ", "), "", 12);
1065 check(strsep(&cp
, ", ") == NULL
, 13);
1066 cp
= strcpy(one
, "1a, 1b; 2a, 2b");
1067 equal(strsep(&cp
, ", "), "1a", 14); /* Changing delim lists. */
1068 equal(strsep(&cp
, ", "), "", 15);
1069 equal(strsep(&cp
, "; "), "1b", 16);
1070 equal(strsep(&cp
, ", "), "", 17);
1071 equal(strsep(&cp
, ", "), "2a", 18);
1072 cp
= strcpy(two
, "x-y");
1073 equal(strsep(&cp
, "-"), "x", 19); /* New string before done. */
1074 equal(strsep(&cp
, "-"), "y", 20);
1075 check(strsep(&cp
, "-") == NULL
, 21);
1076 cp
= strcpy(one
, "a,b, c,, ,d ");
1077 equal(strsep(&cp
, ", "), "a", 22); /* Different separators. */
1078 equal(strsep(&cp
, ", "), "b", 23);
1079 equal(strsep(&cp
, " ,"), "", 24);
1080 equal(strsep(&cp
, " ,"), "c", 25); /* Permute list too. */
1081 equal(strsep(&cp
, " ,"), "", 26);
1082 equal(strsep(&cp
, " ,"), "", 27);
1083 equal(strsep(&cp
, " ,"), "", 28);
1084 equal(strsep(&cp
, " ,"), "d", 29);
1085 equal(strsep(&cp
, " ,"), "", 30);
1086 check(strsep(&cp
, ", ") == NULL
, 31);
1087 check(strsep(&cp
, ", ") == NULL
, 32); /* Persistence. */
1088 cp
= strcpy(one
, ", ");
1089 equal(strsep(&cp
, ", "), "", 33);
1090 equal(strsep(&cp
, ", "), "", 34);
1091 equal(strsep(&cp
, ", "), "", 35);
1092 check(strsep(&cp
, ", ") == NULL
, 36); /* No tokens. */
1093 cp
= strcpy(one
, "");
1094 equal(strsep(&cp
, ", "), "", 37);
1095 check(strsep(&cp
, ", ") == NULL
, 38); /* Empty string. */
1096 cp
= strcpy(one
, "abc");
1097 equal(strsep(&cp
, ", "), "abc", 39); /* No delimiters. */
1098 check(strsep(&cp
, ", ") == NULL
, 40);
1099 cp
= strcpy(one
, "abc");
1100 equal(strsep(&cp
, ""), "abc", 41); /* Empty delimiter list. */
1101 check(strsep(&cp
, "") == NULL
, 42);
1102 (void) strcpy(one
, "abcdefgh");
1103 cp
= strcpy(one
, "a,b,c");
1104 equal(strsep(&cp
, ","), "a", 43); /* Basics again... */
1105 equal(strsep(&cp
, ","), "b", 44);
1106 equal(strsep(&cp
, ","), "c", 45);
1107 check(strsep(&cp
, ",") == NULL
, 46);
1108 equal(one
+6, "gh", 47); /* Stomped past end? */
1109 equal(one
, "a", 48); /* Stomped old tokens? */
1110 equal(one
+2, "b", 49);
1111 equal(one
+4, "c", 50);
1114 char text
[] = "This,is,a,test";
1115 char *list
= strdupa (text
);
1116 equal (strsep (&list
, ","), "This", 51);
1117 equal (strsep (&list
, ","), "is", 52);
1118 equal (strsep (&list
, ","), "a", 53);
1119 equal (strsep (&list
, ","), "test", 54);
1120 check (strsep (&list
, ",") == NULL
, 55);
1123 cp
= strcpy(one
, "a,b, c,, ,d,");
1124 equal(strsep(&cp
, ","), "a", 56); /* Different separators. */
1125 equal(strsep(&cp
, ","), "b", 57);
1126 equal(strsep(&cp
, ","), " c", 58); /* Permute list too. */
1127 equal(strsep(&cp
, ","), "", 59);
1128 equal(strsep(&cp
, ","), " ", 60);
1129 equal(strsep(&cp
, ","), "d", 61);
1130 equal(strsep(&cp
, ","), "", 62);
1131 check(strsep(&cp
, ",") == NULL
, 63);
1132 check(strsep(&cp
, ",") == NULL
, 64); /* Persistence. */
1134 cp
= strcpy(one
, "a,b, c,, ,d,");
1135 equal(strsep(&cp
, "xy,"), "a", 65); /* Different separators. */
1136 equal(strsep(&cp
, "x,y"), "b", 66);
1137 equal(strsep(&cp
, ",xy"), " c", 67); /* Permute list too. */
1138 equal(strsep(&cp
, "xy,"), "", 68);
1139 equal(strsep(&cp
, "x,y"), " ", 69);
1140 equal(strsep(&cp
, ",xy"), "d", 70);
1141 equal(strsep(&cp
, "xy,"), "", 71);
1142 check(strsep(&cp
, "x,y") == NULL
, 72);
1143 check(strsep(&cp
, ",xy") == NULL
, 73); /* Persistence. */
1145 cp
= strcpy(one
, "ABC");
1147 equal(strsep(&cp
, "C"), "AB", 74); /* Access beyond NUL. */
1148 ptr
= strsep(&cp
, ":");
1150 check(ptr
== one
+ 3, 76);
1151 check(cp
== NULL
, 77);
1153 cp
= strcpy(one
, "ABC");
1155 equal(strsep(&cp
, "CD"), "AB", 78); /* Access beyond NUL. */
1156 ptr
= strsep(&cp
, ":.");
1158 check(ptr
== one
+ 3, 80);
1160 cp
= strcpy(one
, "ABC"); /* No token in string. */
1161 equal(strsep(&cp
, ","), "ABC", 81);
1162 check(cp
== NULL
, 82);
1164 *one
= '\0'; /* Empty string. */
1166 ptr
= strsep(&cp
, ",");
1168 check(ptr
== one
, 84);
1169 check(cp
== NULL
, 85);
1171 *one
= '\0'; /* Empty string and no token. */
1173 ptr
= strsep(&cp
, "");
1175 check(ptr
== one
, 87);
1176 check(cp
== NULL
, 88);
1187 check(memcmp("a", "a", 1) == 0, cnt
++); /* Identity. */
1188 check(memcmp("abc", "abc", 3) == 0, cnt
++); /* Multicharacter. */
1189 check(memcmp("abcd", "abcf", 4) < 0, cnt
++); /* Honestly unequal. */
1190 check(memcmp("abcf", "abcd", 4) > 0, cnt
++);
1191 check(memcmp("alph", "cold", 4) < 0, cnt
++);
1192 check(memcmp("a\203", "a\003", 2) > 0, cnt
++);
1193 check(memcmp("a\003", "a\203", 2) < 0, cnt
++);
1194 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt
++);
1195 check(memcmp("abc\203", "abc\003", 4) > 0, cnt
++);
1196 check(memcmp("abc\003", "abc\203", 4) < 0, cnt
++);
1197 check(memcmp("abcf", "abcd", 3) == 0, cnt
++); /* Count limited. */
1198 check(memcmp("abc", "def", 0) == 0, cnt
++); /* Zero count. */
1199 /* Comparisons with shifting 4-byte boundaries. */
1200 for (int i
= 0; i
< 4; ++i
)
1204 memcpy(a
, "--------11112222", 16);
1205 memcpy(b
, "--------33334444", 16);
1206 check(memcmp(b
, a
, 16) > 0, cnt
++);
1207 check(memcmp(a
, b
, 16) < 0, cnt
++);
1215 check(memchr("abcd", 'z', 4) == NULL
, 1); /* Not found. */
1216 (void) strcpy(one
, "abcd");
1217 check(memchr(one
, 'c', 4) == one
+2, 2); /* Basic test. */
1218 check(memchr(one
, ~0xff|'c', 4) == one
+2, 2); /* ignore highorder bits. */
1219 check(memchr(one
, 'd', 4) == one
+3, 3); /* End of string. */
1220 check(memchr(one
, 'a', 4) == one
, 4); /* Beginning. */
1221 check(memchr(one
, '\0', 5) == one
+4, 5); /* Finding NUL. */
1222 (void) strcpy(one
, "ababa");
1223 check(memchr(one
, 'b', 5) == one
+1, 6); /* Finding first. */
1224 check(memchr(one
, 'b', 0) == NULL
, 7); /* Zero count. */
1225 check(memchr(one
, 'a', 1) == one
, 8); /* Singleton case. */
1226 (void) strcpy(one
, "a\203b");
1227 check(memchr(one
, 0203, 3) == one
+1, 9); /* Unsignedness. */
1229 /* now test all possible alignment and length combinations to catch
1230 bugs due to unrolled loops (assuming unrolling is limited to no
1231 more than 128 byte chunks: */
1233 char buf
[128 + sizeof(long)];
1234 long align
, len
, i
, pos
;
1236 for (align
= 0; align
< (long) sizeof(long); ++align
) {
1237 for (len
= 0; len
< (long) (sizeof(buf
) - align
); ++len
) {
1238 for (i
= 0; i
< len
; ++i
) {
1239 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
1241 for (pos
= 0; pos
< len
; ++pos
) {
1243 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
1245 check(memchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, 10);
1246 check(memchr(buf
+ align
, 'x', pos
) == NULL
, 11);
1247 buf
[align
+ pos
] = '-';
1259 check(memcpy(one
, "abc", 4) == one
, 1); /* Returned value. */
1260 equal(one
, "abc", 2); /* Did the copy go right? */
1262 (void) strcpy(one
, "abcdefgh");
1263 (void) memcpy(one
+1, "xyz", 2);
1264 equal(one
, "axydefgh", 3); /* Basic test. */
1266 (void) strcpy(one
, "abc");
1267 (void) memcpy(one
, "xyz", 0);
1268 equal(one
, "abc", 4); /* Zero-length copy. */
1270 (void) strcpy(one
, "hi there");
1271 (void) strcpy(two
, "foo");
1272 (void) memcpy(two
, one
, 9);
1273 equal(two
, "hi there", 5); /* Just paranoia. */
1274 equal(one
, "hi there", 6); /* Stomped on source? */
1276 for (i
= 0; i
< 16; i
++)
1278 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1280 check (memcpy (one
+ i
, "hi there", 9) == one
+ i
,
1281 7 + (i
* 6)); /* Unaligned destination. */
1282 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1283 equal (one
+ i
, "hi there", 9 + (i
* 6));
1284 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1285 check (memcpy (two
, one
+ i
, 9) == two
,
1286 11 + (i
* 6)); /* Unaligned source. */
1287 equal (two
, "hi there", 12 + (i
* 6));
1296 check(mempcpy(one
, "abc", 4) == one
+ 4, 1); /* Returned value. */
1297 equal(one
, "abc", 2); /* Did the copy go right? */
1299 (void) strcpy(one
, "abcdefgh");
1300 (void) mempcpy(one
+1, "xyz", 2);
1301 equal(one
, "axydefgh", 3); /* Basic test. */
1303 (void) strcpy(one
, "abc");
1304 (void) mempcpy(one
, "xyz", 0);
1305 equal(one
, "abc", 4); /* Zero-length copy. */
1307 (void) strcpy(one
, "hi there");
1308 (void) strcpy(two
, "foo");
1309 (void) mempcpy(two
, one
, 9);
1310 equal(two
, "hi there", 5); /* Just paranoia. */
1311 equal(one
, "hi there", 6); /* Stomped on source? */
1313 for (i
= 0; i
< 16; i
++)
1315 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1317 check (mempcpy (one
+ i
, "hi there", 9) == one
+ i
+ 9,
1318 7 + (i
* 6)); /* Unaligned destination. */
1319 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1320 equal (one
+ i
, "hi there", 9 + (i
* 6));
1321 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1322 check (mempcpy (two
, one
+ i
, 9) == two
+ 9,
1323 11 + (i
* 6)); /* Unaligned source. */
1324 equal (two
, "hi there", 12 + (i
* 6));
1332 check(memmove(one
, "abc", 4) == one
, 1); /* Returned value. */
1333 equal(one
, "abc", 2); /* Did the copy go right? */
1335 (void) strcpy(one
, "abcdefgh");
1336 (void) memmove(one
+1, "xyz", 2);
1337 equal(one
, "axydefgh", 3); /* Basic test. */
1339 (void) strcpy(one
, "abc");
1340 (void) memmove(one
, "xyz", 0);
1341 equal(one
, "abc", 4); /* Zero-length copy. */
1343 (void) strcpy(one
, "hi there");
1344 (void) strcpy(two
, "foo");
1345 (void) memmove(two
, one
, 9);
1346 equal(two
, "hi there", 5); /* Just paranoia. */
1347 equal(one
, "hi there", 6); /* Stomped on source? */
1349 (void) strcpy(one
, "abcdefgh");
1350 (void) memmove(one
+1, one
, 9);
1351 equal(one
, "aabcdefgh", 7); /* Overlap, right-to-left. */
1353 (void) strcpy(one
, "abcdefgh");
1354 (void) memmove(one
+1, one
+2, 7);
1355 equal(one
, "acdefgh", 8); /* Overlap, left-to-right. */
1357 (void) strcpy(one
, "abcdefgh");
1358 (void) memmove(one
, one
, 9);
1359 equal(one
, "abcdefgh", 9); /* 100% overlap. */
1365 /* First test like memcpy, then the search part The SVID, the only
1366 place where memccpy is mentioned, says overlap might fail, so we
1367 don't try it. Besides, it's hard to see the rationale for a
1368 non-left-to-right memccpy. */
1370 check(memccpy(one
, "abc", 'q', 4) == NULL
, 1); /* Returned value. */
1371 equal(one
, "abc", 2); /* Did the copy go right? */
1373 (void) strcpy(one
, "abcdefgh");
1374 (void) memccpy(one
+1, "xyz", 'q', 2);
1375 equal(one
, "axydefgh", 3); /* Basic test. */
1377 (void) strcpy(one
, "abc");
1378 (void) memccpy(one
, "xyz", 'q', 0);
1379 equal(one
, "abc", 4); /* Zero-length copy. */
1381 (void) strcpy(one
, "hi there");
1382 (void) strcpy(two
, "foo");
1383 (void) memccpy(two
, one
, 'q', 9);
1384 equal(two
, "hi there", 5); /* Just paranoia. */
1385 equal(one
, "hi there", 6); /* Stomped on source? */
1387 (void) strcpy(one
, "abcdefgh");
1388 (void) strcpy(two
, "horsefeathers");
1389 check(memccpy(two
, one
, 'f', 9) == two
+6, 7); /* Returned value. */
1390 equal(one
, "abcdefgh", 8); /* Source intact? */
1391 equal(two
, "abcdefeathers", 9); /* Copy correct? */
1393 (void) strcpy(one
, "abcd");
1394 (void) strcpy(two
, "bumblebee");
1395 check(memccpy(two
, one
, 'a', 4) == two
+1, 10); /* First char. */
1396 equal(two
, "aumblebee", 11);
1397 check(memccpy(two
, one
, 'd', 4) == two
+4, 12); /* Last char. */
1398 equal(two
, "abcdlebee", 13);
1399 (void) strcpy(one
, "xyz");
1400 check(memccpy(two
, one
, 'x', 1) == two
+1, 14); /* Singleton. */
1401 equal(two
, "xbcdlebee", 15);
1410 (void) strcpy(one
, "abcdefgh");
1411 check(memset(one
+1, 'x', 3) == one
+1, 1); /* Return value. */
1412 equal(one
, "axxxefgh", 2); /* Basic test. */
1414 DIAG_PUSH_NEEDS_COMMENT
;
1415 #if __GNUC_PREREQ (5, 0)
1416 /* GCC 5.0 warns about a zero-length memset because the arguments to memset
1417 may be in the wrong order. But we really want to test this. */
1418 DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args")
1420 (void) memset(one
+2, 'y', 0);
1421 equal(one
, "axxxefgh", 3); /* Zero-length set. */
1422 DIAG_POP_NEEDS_COMMENT
;
1424 (void) memset(one
+5, 0, 1);
1425 equal(one
, "axxxe", 4); /* Zero fill. */
1426 equal(one
+6, "gh", 5); /* And the leftover. */
1428 (void) memset(one
+2, 010045, 1);
1429 equal(one
, "ax\045xe", 6); /* Unsigned char convert. */
1431 /* Non-8bit fill character. */
1432 memset (one
, 0x101, sizeof (one
));
1433 for (i
= 0; i
< (int) sizeof (one
); ++i
)
1434 check (one
[i
] == '\01', 7);
1436 /* Test for more complex versions of memset, for all alignments and
1437 lengths up to 256. This test takes a little while, perhaps it should
1445 for (i
= 0; i
< 512; i
++)
1447 for (c
= 0; c
<= 'y'; c
+= 'y') /* check for memset(,0,) and
1449 for (j
= 0; j
< 256; j
++)
1450 for (i
= 0; i
< 256; i
++)
1452 memset (data
+ i
, c
, j
);
1453 for (k
= 0; k
< i
; k
++)
1456 for (k
= i
; k
< i
+j
; k
++)
1462 for (k
= i
+j
; k
< 512; k
++)
1468 check (0, 8 + i
+ j
* 256 + (c
!= 0) * 256 * 256);
1476 /* Much like memcpy. Berklix manual is silent about overlap, so
1479 (void) bcopy("abc", one
, 4);
1480 equal(one
, "abc", 1); /* Simple copy. */
1482 (void) strcpy(one
, "abcdefgh");
1483 (void) bcopy("xyz", one
+1, 2);
1484 equal(one
, "axydefgh", 2); /* Basic test. */
1486 (void) strcpy(one
, "abc");
1487 (void) bcopy("xyz", one
, 0);
1488 equal(one
, "abc", 3); /* Zero-length copy. */
1490 (void) strcpy(one
, "hi there");
1491 (void) strcpy(two
, "foo");
1492 (void) bcopy(one
, two
, 9);
1493 equal(two
, "hi there", 4); /* Just paranoia. */
1494 equal(one
, "hi there", 5); /* Stomped on source? */
1501 (void) strcpy(one
, "abcdef");
1503 equal(one
, "ab", 1); /* Basic test. */
1504 equal(one
+3, "", 2);
1505 equal(one
+4, "ef", 3);
1507 (void) strcpy(one
, "abcdef");
1509 equal(one
, "abcdef", 4); /* Zero-length copy. */
1517 p
= strndup("abcdef", 12);
1518 check(p
!= NULL
, 1);
1521 equal(p
, "abcdef", 2);
1522 q
= strndup(p
+ 1, 2);
1523 check(q
!= NULL
, 3);
1529 p
= strndup("abc def", 3);
1530 check(p
!= NULL
, 5);
1540 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1541 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1542 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1543 check(bcmp("abce", "abcd", 4) != 0, 4);
1544 check(bcmp("alph", "beta", 4) != 0, 5);
1545 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1546 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1550 test_strerror (void)
1553 check(strerror(EDOM
) != 0, 1);
1554 check(strerror(ERANGE
) != 0, 2);
1555 check(strerror(ENOENT
) != 0, 3);
1559 test_strcasecmp (void)
1562 /* Note that the locale is "C". */
1563 check(strcasecmp("a", "a") == 0, 1);
1564 check(strcasecmp("a", "A") == 0, 2);
1565 check(strcasecmp("A", "a") == 0, 3);
1566 check(strcasecmp("a", "b") < 0, 4);
1567 check(strcasecmp("c", "b") > 0, 5);
1568 check(strcasecmp("abc", "AbC") == 0, 6);
1569 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1570 check(strcasecmp("", "0123456789") < 0, 8);
1571 check(strcasecmp("AbC", "") > 0, 9);
1572 check(strcasecmp("AbC", "A") > 0, 10);
1573 check(strcasecmp("AbC", "Ab") > 0, 11);
1574 check(strcasecmp("AbC", "ab") > 0, 12);
1578 test_strncasecmp (void)
1581 /* Note that the locale is "C". */
1582 check(strncasecmp("a", "a", 5) == 0, 1);
1583 check(strncasecmp("a", "A", 5) == 0, 2);
1584 check(strncasecmp("A", "a", 5) == 0, 3);
1585 check(strncasecmp("a", "b", 5) < 0, 4);
1586 check(strncasecmp("c", "b", 5) > 0, 5);
1587 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1588 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1589 check(strncasecmp("", "0123456789", 10) < 0, 8);
1590 check(strncasecmp("AbC", "", 5) > 0, 9);
1591 check(strncasecmp("AbC", "A", 5) > 0, 10);
1592 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1593 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1594 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1595 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1596 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1597 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1598 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1599 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1600 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1601 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1609 /* Test strcmp first because we use it to test other things. */
1612 /* Test strcpy next because we need it to set up other tests. */
1615 /* A closely related function is stpcpy. */
1648 /* index - just like strchr. */
1657 /* rindex - just like strrchr. */
1660 /* strpbrk - somewhat like strchr. */
1663 /* strstr - somewhat like strchr. */
1672 /* strtok - the hard one. */
1687 /* memcpy - need not work for overlap. */
1690 /* memmove - must work on overlap. */
1708 /* bcmp - somewhat like memcmp. */
1714 /* strerror - VERY system-dependent. */
1717 /* strcasecmp. Without locale dependencies. */
1720 /* strncasecmp. Without locale dependencies. */
1721 test_strncasecmp ();
1725 status
= EXIT_SUCCESS
;
1730 status
= EXIT_FAILURE
;
1731 printf("%Zd errors.\n", errors
);