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 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.. */
391 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
393 (void) strncat (one
, two
, 99);
394 DIAG_POP_NEEDS_COMMENT
;
395 equal (one
, "ghef", 5); /* Basic test encore. */
396 equal (two
, "ef", 6); /* Stomped on source? */
398 (void) strcpy (one
, "");
399 DIAG_PUSH_NEEDS_COMMENT
;
400 #if __GNUC_PREREQ (7, 0)
401 /* GCC 7 warns about the size passed to strncat being larger than
402 the size of the buffer; this is deliberately tested here.. */
403 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
405 (void) strncat (one
, "", 99);
406 DIAG_POP_NEEDS_COMMENT
;
407 equal (one
, "", 7); /* Boundary conditions. */
408 (void) strcpy (one
, "ab");
409 DIAG_PUSH_NEEDS_COMMENT
;
410 #if __GNUC_PREREQ (7, 0)
411 /* GCC 7 warns about the size passed to strncat being larger than
412 the size of the buffer; this is deliberately tested here.. */
413 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
415 (void) strncat (one
, "", 99);
416 DIAG_POP_NEEDS_COMMENT
;
417 equal (one
, "ab", 8);
418 (void) strcpy (one
, "");
419 DIAG_PUSH_NEEDS_COMMENT
;
420 #if __GNUC_PREREQ (7, 0)
421 /* GCC 7 warns about the size passed to strncat being larger than
422 the size of the buffer; this is deliberately tested here.. */
423 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
425 (void) strncat (one
, "cd", 99);
426 DIAG_POP_NEEDS_COMMENT
;
427 equal (one
, "cd", 9);
429 (void) strcpy (one
, "ab");
430 DIAG_PUSH_NEEDS_COMMENT
;
431 #if __GNUC_PREREQ (8, 0)
432 /* GCC 8 warns about strncat truncating output; this is deliberately
434 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
436 (void) strncat (one
, "cdef", 2);
437 DIAG_POP_NEEDS_COMMENT
;
438 equal (one
, "abcd", 10); /* Count-limited. */
440 (void) strncat (one
, "gh", 0);
441 equal (one
, "abcd", 11); /* Zero count. */
443 DIAG_PUSH_NEEDS_COMMENT
;
444 #if __GNUC_PREREQ (7, 0)
445 /* GCC 8 warns about strncat bound equal to source length; this is
446 deliberately tested here. */
447 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-overflow=");
449 (void) strncat (one
, "gh", 2);
450 DIAG_POP_NEEDS_COMMENT
;
451 equal (one
, "abcdgh", 12); /* Count and length equal. */
453 DIAG_PUSH_NEEDS_COMMENT
;
454 #if __GNUC_PREREQ (7, 0)
455 /* GCC 7 warns about the size passed to strncat being larger than
456 the size of the buffer; this is deliberately tested here.. */
457 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
459 (void) strncat (one
, "ij", (size_t)-1); /* set sign bit in count */
460 DIAG_POP_NEEDS_COMMENT
;
461 equal (one
, "abcdghij", 13);
464 char buf1
[80] __attribute__ ((aligned (16)));
465 char buf2
[32] __attribute__ ((aligned (16)));
466 for (size_t n1
= 0; n1
< 16; ++n1
)
467 for (size_t n2
= 0; n2
< 16; ++n2
)
468 for (size_t n3
= 0; n3
< 32; ++n3
)
469 for (size_t n4
= 0; n4
< 16; ++n4
)
471 size_t olderrors
= errors
;
473 memset (buf1
, 'b', sizeof (buf1
));
475 memset (buf1
+ n2
, 'a', n3
);
476 buf1
[n2
+ n3
] = '\0';
477 strcpy (buf2
+ n1
, "123");
479 DIAG_PUSH_NEEDS_COMMENT
;
480 #if __GNUC_PREREQ (7, 0)
481 /* GCC 7 warns about the size passed to strncat being
482 larger than the size of the buffer; this is
483 deliberately tested here.. */
484 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
486 check (strncat (buf1
+ n2
, buf2
+ n1
, ~((size_t) 0) - n4
)
487 == buf1
+ n2
, ntest
);
488 DIAG_POP_NEEDS_COMMENT
;
489 if (errors
== olderrors
)
490 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
493 check (buf1
[i
] == 'b', ntest
);
494 else if (i
< n2
+ n3
)
495 check (buf1
[i
] == 'a', ntest
);
496 else if (i
< n2
+ n3
+ 3)
497 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
498 else if (i
== n2
+ n3
+ 3)
499 check (buf1
[i
] == '\0', ntest
);
501 check (buf1
[i
] == 'b', ntest
);
503 if (errors
!= olderrors
)
505 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
506 n1
, n2
, n3
, n4
, buf1
[0]);
507 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
508 printf (",%02hhx", buf1
[j
]);
509 putchar_unlocked ('\n');
519 /* First test as strcmp with big counts, then test count code. */
521 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
522 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
523 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
524 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
525 check (strncmp ("abcd", "abc", 99) > 0, 5);
526 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
527 check (strncmp ("abce", "abcd", 99) > 0, 7);
528 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
529 check (strncmp ("a\203", "a\003", 2) > 0, 9);
530 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
531 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
532 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
533 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
534 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
535 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
541 /* Testing is a bit different because of odd semantics. */
543 check (strncpy (one
, "abc", 4) == one
, 1); /* Returned value. */
544 equal (one
, "abc", 2); /* Did the copy go right? */
546 (void) strcpy (one
, "abcdefgh");
547 DIAG_PUSH_NEEDS_COMMENT
;
548 #if __GNUC_PREREQ (8, 0)
549 /* GCC 8 warns about strncpy truncating output; this is deliberately
551 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
553 (void) strncpy (one
, "xyz", 2);
554 DIAG_POP_NEEDS_COMMENT
;
555 equal (one
, "xycdefgh", 3); /* Copy cut by count. */
557 (void) strcpy (one
, "abcdefgh");
558 DIAG_PUSH_NEEDS_COMMENT
;
559 #if __GNUC_PREREQ (8, 0)
560 /* GCC 8 warns about strncpy truncating output; this is deliberately
562 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
564 (void) strncpy (one
, "xyz", 3); /* Copy cut just before NUL. */
565 DIAG_POP_NEEDS_COMMENT
;
566 equal (one
, "xyzdefgh", 4);
568 (void) strcpy (one
, "abcdefgh");
569 (void) strncpy (one
, "xyz", 4); /* Copy just includes NUL. */
570 equal (one
, "xyz", 5);
571 equal (one
+4, "efgh", 6); /* Wrote too much? */
573 (void) strcpy (one
, "abcdefgh");
574 (void) strncpy (one
, "xyz", 5); /* Copy includes padding. */
575 equal (one
, "xyz", 7);
576 equal (one
+4, "", 8);
577 equal (one
+5, "fgh", 9);
579 (void) strcpy (one
, "abc");
580 DIAG_PUSH_NEEDS_COMMENT
;
581 #if __GNUC_PREREQ (8, 0)
582 /* GCC 8 warns about strncpy truncating output; this is deliberately
584 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
586 (void) strncpy (one
, "xyz", 0); /* Zero-length copy. */
587 DIAG_POP_NEEDS_COMMENT
;
588 equal (one
, "abc", 10);
590 (void) strncpy (one
, "", 2); /* Zero-length source. */
592 equal (one
+1, "", 12);
593 equal (one
+2, "c", 13);
595 (void) strcpy (one
, "hi there");
596 (void) strncpy (two
, one
, 9);
597 equal (two
, "hi there", 14); /* Just paranoia. */
598 equal (one
, "hi there", 15); /* Stomped on source? */
605 check (strlen ("") == 0, 1); /* Empty. */
606 check (strlen ("a") == 1, 2); /* Single char. */
607 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
612 for (i
=0; i
< 0x100; i
++)
614 p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
616 strcpy (p
+3, "BAD/WRONG");
617 check (strlen (p
) == 2, 4+i
);
626 check (strnlen ("", 10) == 0, 1); /* Empty. */
627 check (strnlen ("a", 10) == 1, 2); /* Single char. */
628 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
629 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
630 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
631 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
632 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
633 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
634 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
637 for (int i
= 0; i
< 0x100; ++i
)
639 char *p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
641 strcpy (p
+ 3, "BAD/WRONG");
642 check (strnlen (p
, 100) == 2, 10 + i
);
650 check (strchr ("abcd", 'z') == NULL
, 1); /* Not found. */
651 (void) strcpy (one
, "abcd");
652 check (strchr (one
, 'c') == one
+2, 2); /* Basic test. */
653 check (strchr (one
, 'd') == one
+3, 3); /* End of string. */
654 check (strchr (one
, 'a') == one
, 4); /* Beginning. */
655 check (strchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
656 (void) strcpy (one
, "ababa");
657 check (strchr (one
, 'b') == one
+1, 6); /* Finding first. */
658 (void) strcpy (one
, "");
659 check (strchr (one
, 'b') == NULL
, 7); /* Empty string. */
660 check (strchr (one
, '\0') == one
, 8); /* NUL in empty string. */
665 for (i
=0; i
< 0x100; i
++)
667 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
669 strcpy (p
+3, "BAD/WRONG");
670 check (strchr (p
, '/') == NULL
, 9+i
);
676 test_strchrnul (void)
680 cp
= strchrnul ((os
= "abcd"), 'z');
681 check (*cp
== '\0', 1); /* Not found. */
682 check (cp
== os
+ 4, 2);
683 (void) strcpy (one
, "abcd");
684 check (strchrnul (one
, 'c') == one
+2, 3); /* Basic test. */
685 check (strchrnul (one
, 'd') == one
+3, 4); /* End of string. */
686 check (strchrnul (one
, 'a') == one
, 5); /* Beginning. */
687 check (strchrnul (one
, '\0') == one
+4, 6); /* Finding NUL. */
688 (void) strcpy (one
, "ababa");
689 check (strchrnul (one
, 'b') == one
+1, 7); /* Finding first. */
690 (void) strcpy (one
, "");
691 check (strchrnul (one
, 'b') == one
, 8); /* Empty string. */
692 check (strchrnul (one
, '\0') == one
, 9); /* NUL in empty string. */
697 for (i
=0; i
< 0x100; i
++)
699 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
701 strcpy (p
+3, "BAD/WRONG");
702 cp
= strchrnul (p
, '/');
703 check (*cp
== '\0', 9+2*i
);
704 check (cp
== p
+2, 10+2*i
);
710 test_rawmemchr (void)
713 (void) strcpy (one
, "abcd");
714 check (rawmemchr (one
, 'c') == one
+2, 1); /* Basic test. */
715 check (rawmemchr (one
, 'd') == one
+3, 2); /* End of string. */
716 check (rawmemchr (one
, 'a') == one
, 3); /* Beginning. */
717 check (rawmemchr (one
, '\0') == one
+4, 4); /* Finding NUL. */
718 (void) strcpy (one
, "ababa");
719 check (rawmemchr (one
, 'b') == one
+1, 5); /* Finding first. */
720 (void) strcpy (one
, "");
721 check (rawmemchr (one
, '\0') == one
, 6); /* NUL in empty string. */
726 for (i
=0; i
< 0x100; i
++)
728 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
730 strcpy (p
+3, "BAD/WRONG");
731 check (rawmemchr (p
, 'R') == p
+8, 6+i
);
740 check (index ("abcd", 'z') == NULL
, 1); /* Not found. */
741 (void) strcpy (one
, "abcd");
742 check (index (one
, 'c') == one
+2, 2); /* Basic test. */
743 check (index (one
, 'd') == one
+3, 3); /* End of string. */
744 check (index (one
, 'a') == one
, 4); /* Beginning. */
745 check (index (one
, '\0') == one
+4, 5); /* Finding NUL. */
746 (void) strcpy (one
, "ababa");
747 check (index (one
, 'b') == one
+1, 6); /* Finding first. */
748 (void) strcpy (one
, "");
749 check (index (one
, 'b') == NULL
, 7); /* Empty string. */
750 check (index (one
, '\0') == one
, 8); /* NUL in empty string. */
757 check (strrchr ("abcd", 'z') == NULL
, 1); /* Not found. */
758 (void) strcpy (one
, "abcd");
759 check (strrchr (one
, 'c') == one
+2, 2); /* Basic test. */
760 check (strrchr (one
, 'd') == one
+3, 3); /* End of string. */
761 check (strrchr (one
, 'a') == one
, 4); /* Beginning. */
762 check (strrchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
763 (void) strcpy (one
, "ababa");
764 check (strrchr (one
, 'b') == one
+3, 6); /* Finding last. */
765 (void) strcpy (one
, "");
766 check (strrchr (one
, 'b') == NULL
, 7); /* Empty string. */
767 check (strrchr (one
, '\0') == one
, 8); /* NUL in empty string. */
772 for (i
=0; i
< 0x100; i
++)
774 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
776 strcpy (p
+3, "BAD/WRONG");
777 check (strrchr (p
, '/') == NULL
, 9+i
);
787 check (memrchr ("abcd", 'z', 5) == NULL
, 1); /* Not found. */
788 (void) strcpy (one
, "abcd");
789 l
= strlen (one
) + 1;
790 check (memrchr (one
, 'c', l
) == one
+2, 2); /* Basic test. */
791 check (memrchr (one
, 'd', l
) == one
+3, 3); /* End of string. */
792 check (memrchr (one
, 'a', l
) == one
, 4); /* Beginning. */
793 check (memrchr (one
, '\0', l
) == one
+4, 5); /* Finding NUL. */
794 (void) strcpy (one
, "ababa");
795 l
= strlen (one
) + 1;
796 check (memrchr (one
, 'b', l
) == one
+3, 6); /* Finding last. */
797 (void) strcpy (one
, "");
798 l
= strlen (one
) + 1;
799 check (memrchr (one
, 'b', l
) == NULL
, 7); /* Empty string. */
800 check (memrchr (one
, '\0', l
) == one
, 8); /* NUL in empty string. */
802 /* now test all possible alignment and length combinations to catch
803 bugs due to unrolled loops (assuming unrolling is limited to no
804 more than 128 byte chunks: */
806 char buf
[128 + sizeof(long)];
807 long align
, len
, i
, pos
, n
= 9;
809 for (align
= 0; align
< (long) sizeof(long); ++align
) {
810 for (len
= 0; len
< (long) (sizeof(buf
) - align
); ++len
) {
811 for (i
= 0; i
< len
; ++i
)
812 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
814 for (pos
= len
- 1; pos
>= 0; --pos
) {
816 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
818 check(memrchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, n
++);
819 check(memrchr(buf
+ align
+ pos
+ 1, 'x', len
- (pos
+ 1)) == NULL
,
821 buf
[align
+ pos
] = '-';
832 check (rindex ("abcd", 'z') == NULL
, 1); /* Not found. */
833 (void) strcpy (one
, "abcd");
834 check (rindex (one
, 'c') == one
+2, 2); /* Basic test. */
835 check (rindex (one
, 'd') == one
+3, 3); /* End of string. */
836 check (rindex (one
, 'a') == one
, 4); /* Beginning. */
837 check (rindex (one
, '\0') == one
+4, 5); /* Finding NUL. */
838 (void) strcpy (one
, "ababa");
839 check (rindex (one
, 'b') == one
+3, 6); /* Finding last. */
840 (void) strcpy (one
, "");
841 check (rindex (one
, 'b') == NULL
, 7); /* Empty string. */
842 check (rindex (one
, '\0') == one
, 8); /* NUL in empty string. */
849 check(strpbrk("abcd", "z") == NULL
, 1); /* Not found. */
850 (void) strcpy(one
, "abcd");
851 check(strpbrk(one
, "c") == one
+2, 2); /* Basic test. */
852 check(strpbrk(one
, "d") == one
+3, 3); /* End of string. */
853 check(strpbrk(one
, "a") == one
, 4); /* Beginning. */
854 check(strpbrk(one
, "") == NULL
, 5); /* Empty search list. */
855 check(strpbrk(one
, "cb") == one
+1, 6); /* Multiple search. */
856 (void) strcpy(one
, "abcabdea");
857 check(strpbrk(one
, "b") == one
+1, 7); /* Finding first. */
858 check(strpbrk(one
, "cb") == one
+1, 8); /* With multiple search. */
859 check(strpbrk(one
, "db") == one
+1, 9); /* Another variant. */
860 (void) strcpy(one
, "");
861 check(strpbrk(one
, "bc") == NULL
, 10); /* Empty string. */
862 (void) strcpy(one
, "");
863 check(strpbrk(one
, "bcd") == NULL
, 11); /* Empty string. */
864 (void) strcpy(one
, "");
865 check(strpbrk(one
, "bcde") == NULL
, 12); /* Empty string. */
866 check(strpbrk(one
, "") == NULL
, 13); /* Both strings empty. */
867 (void) strcpy(one
, "abcabdea");
868 check(strpbrk(one
, "befg") == one
+1, 14); /* Finding first. */
869 check(strpbrk(one
, "cbr") == one
+1, 15); /* With multiple search. */
870 check(strpbrk(one
, "db") == one
+1, 16); /* Another variant. */
871 check(strpbrk(one
, "efgh") == one
+6, 17); /* And yet another. */
878 check(strstr("abcd", "z") == NULL
, 1); /* Not found. */
879 check(strstr("abcd", "abx") == NULL
, 2); /* Dead end. */
880 (void) strcpy(one
, "abcd");
881 check(strstr(one
, "c") == one
+2, 3); /* Basic test. */
882 check(strstr(one
, "bc") == one
+1, 4); /* Multichar. */
883 check(strstr(one
, "d") == one
+3, 5); /* End of string. */
884 check(strstr(one
, "cd") == one
+2, 6); /* Tail of string. */
885 check(strstr(one
, "abc") == one
, 7); /* Beginning. */
886 check(strstr(one
, "abcd") == one
, 8); /* Exact match. */
887 check(strstr(one
, "abcde") == NULL
, 9); /* Too long. */
888 check(strstr(one
, "de") == NULL
, 10); /* Past end. */
889 check(strstr(one
, "") == one
, 11); /* Finding empty. */
890 (void) strcpy(one
, "ababa");
891 check(strstr(one
, "ba") == one
+1, 12); /* Finding first. */
892 (void) strcpy(one
, "");
893 check(strstr(one
, "b") == NULL
, 13); /* Empty string. */
894 check(strstr(one
, "") == one
, 14); /* Empty in empty string. */
895 (void) strcpy(one
, "bcbca");
896 check(strstr(one
, "bca") == one
+2, 15); /* False start. */
897 (void) strcpy(one
, "bbbcabbca");
898 check(strstr(one
, "bbca") == one
+1, 16); /* With overlap. */
905 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
906 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
907 check(strspn("abc", "qx") == 0, 3); /* None. */
908 check(strspn("", "ab") == 0, 4); /* Null string. */
909 check(strspn("abc", "") == 0, 5); /* Null search list. */
916 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
917 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
918 check(strcspn("abc", "abc") == 0, 3); /* None. */
919 check(strcspn("", "ab") == 0, 4); /* Null string. */
920 check(strcspn("abc", "") == 3, 5); /* Null search list. */
927 (void) strcpy(one
, "first, second, third");
928 equal(strtok(one
, ", "), "first", 1); /* Basic test. */
929 equal(one
, "first", 2);
930 equal(strtok((char *)NULL
, ", "), "second", 3);
931 equal(strtok((char *)NULL
, ", "), "third", 4);
932 check(strtok((char *)NULL
, ", ") == NULL
, 5);
933 (void) strcpy(one
, ", first, ");
934 equal(strtok(one
, ", "), "first", 6); /* Extra delims, 1 tok. */
935 check(strtok((char *)NULL
, ", ") == NULL
, 7);
936 (void) strcpy(one
, "1a, 1b; 2a, 2b");
937 equal(strtok(one
, ", "), "1a", 8); /* Changing delim lists. */
938 equal(strtok((char *)NULL
, "; "), "1b", 9);
939 equal(strtok((char *)NULL
, ", "), "2a", 10);
940 (void) strcpy(two
, "x-y");
941 equal(strtok(two
, "-"), "x", 11); /* New string before done. */
942 equal(strtok((char *)NULL
, "-"), "y", 12);
943 check(strtok((char *)NULL
, "-") == NULL
, 13);
944 (void) strcpy(one
, "a,b, c,, ,d");
945 equal(strtok(one
, ", "), "a", 14); /* Different separators. */
946 equal(strtok((char *)NULL
, ", "), "b", 15);
947 equal(strtok((char *)NULL
, " ,"), "c", 16); /* Permute list too. */
948 equal(strtok((char *)NULL
, " ,"), "d", 17);
949 check(strtok((char *)NULL
, ", ") == NULL
, 18);
950 check(strtok((char *)NULL
, ", ") == NULL
, 19); /* Persistence. */
951 (void) strcpy(one
, ", ");
952 check(strtok(one
, ", ") == NULL
, 20); /* No tokens. */
953 (void) strcpy(one
, "");
954 check(strtok(one
, ", ") == NULL
, 21); /* Empty string. */
955 (void) strcpy(one
, "abc");
956 equal(strtok(one
, ", "), "abc", 22); /* No delimiters. */
957 check(strtok((char *)NULL
, ", ") == NULL
, 23);
958 (void) strcpy(one
, "abc");
959 equal(strtok(one
, ""), "abc", 24); /* Empty delimiter list. */
960 check(strtok((char *)NULL
, "") == NULL
, 25);
961 (void) strcpy(one
, "abcdefgh");
962 (void) strcpy(one
, "a,b,c");
963 equal(strtok(one
, ","), "a", 26); /* Basics again... */
964 equal(strtok((char *)NULL
, ","), "b", 27);
965 equal(strtok((char *)NULL
, ","), "c", 28);
966 check(strtok((char *)NULL
, ",") == NULL
, 29);
967 equal(one
+6, "gh", 30); /* Stomped past end? */
968 equal(one
, "a", 31); /* Stomped old tokens? */
969 equal(one
+2, "b", 32);
970 equal(one
+4, "c", 33);
977 (void) strcpy(one
, "first, second, third");
978 cp
= NULL
; /* Always initialize cp to make sure it doesn't point to some old data. */
979 equal(strtok_r(one
, ", ", &cp
), "first", 1); /* Basic test. */
980 equal(one
, "first", 2);
981 equal(strtok_r((char *)NULL
, ", ", &cp
), "second", 3);
982 equal(strtok_r((char *)NULL
, ", ", &cp
), "third", 4);
983 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 5);
984 (void) strcpy(one
, ", first, ");
986 equal(strtok_r(one
, ", ", &cp
), "first", 6); /* Extra delims, 1 tok. */
987 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 7);
988 (void) strcpy(one
, "1a, 1b; 2a, 2b");
990 equal(strtok_r(one
, ", ", &cp
), "1a", 8); /* Changing delim lists. */
991 equal(strtok_r((char *)NULL
, "; ", &cp
), "1b", 9);
992 equal(strtok_r((char *)NULL
, ", ", &cp
), "2a", 10);
993 (void) strcpy(two
, "x-y");
995 equal(strtok_r(two
, "-", &cp
), "x", 11); /* New string before done. */
996 equal(strtok_r((char *)NULL
, "-", &cp
), "y", 12);
997 check(strtok_r((char *)NULL
, "-", &cp
) == NULL
, 13);
998 (void) strcpy(one
, "a,b, c,, ,d");
1000 equal(strtok_r(one
, ", ", &cp
), "a", 14); /* Different separators. */
1001 equal(strtok_r((char *)NULL
, ", ", &cp
), "b", 15);
1002 equal(strtok_r((char *)NULL
, " ,", &cp
), "c", 16); /* Permute list too. */
1003 equal(strtok_r((char *)NULL
, " ,", &cp
), "d", 17);
1004 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 18);
1005 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 19); /* Persistence. */
1006 (void) strcpy(one
, ", ");
1008 check(strtok_r(one
, ", ", &cp
) == NULL
, 20); /* No tokens. */
1009 (void) strcpy(one
, "");
1011 check(strtok_r(one
, ", ", &cp
) == NULL
, 21); /* Empty string. */
1012 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 22); /* Persistence. */
1013 (void) strcpy(one
, "abc");
1015 equal(strtok_r(one
, ", ", &cp
), "abc", 23); /* No delimiters. */
1016 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 24);
1017 (void) strcpy(one
, "abc");
1019 equal(strtok_r(one
, "", &cp
), "abc", 25); /* Empty delimiter list. */
1020 check(strtok_r((char *)NULL
, "", &cp
) == NULL
, 26);
1021 (void) strcpy(one
, "abcdefgh");
1022 (void) strcpy(one
, "a,b,c");
1024 equal(strtok_r(one
, ",", &cp
), "a", 27); /* Basics again... */
1025 equal(strtok_r((char *)NULL
, ",", &cp
), "b", 28);
1026 equal(strtok_r((char *)NULL
, ",", &cp
), "c", 29);
1027 check(strtok_r((char *)NULL
, ",", &cp
) == NULL
, 30);
1028 equal(one
+6, "gh", 31); /* Stomped past end? */
1029 equal(one
, "a", 32); /* Stomped old tokens? */
1030 equal(one
+2, "b", 33);
1031 equal(one
+4, "c", 34);
1032 strcpy (one
, ":::");
1034 check (strtok_r (one
, ":", &cp
) == NULL
, 35); /* Must store pointer in cp. */
1035 check (strtok_r (NULL
, ":", &cp
) == NULL
, 36);
1043 cp
= strcpy(one
, "first, second, third");
1044 equal(strsep(&cp
, ", "), "first", 1); /* Basic test. */
1045 equal(one
, "first", 2);
1046 equal(strsep(&cp
, ", "), "", 3);
1047 equal(strsep(&cp
, ", "), "second", 4);
1048 equal(strsep(&cp
, ", "), "", 5);
1049 equal(strsep(&cp
, ", "), "third", 6);
1050 check(strsep(&cp
, ", ") == NULL
, 7);
1051 cp
= strcpy(one
, ", first, ");
1052 equal(strsep(&cp
, ", "), "", 8);
1053 equal(strsep(&cp
, ", "), "", 9);
1054 equal(strsep(&cp
, ", "), "first", 10); /* Extra delims, 1 tok. */
1055 equal(strsep(&cp
, ", "), "", 11);
1056 equal(strsep(&cp
, ", "), "", 12);
1057 check(strsep(&cp
, ", ") == NULL
, 13);
1058 cp
= strcpy(one
, "1a, 1b; 2a, 2b");
1059 equal(strsep(&cp
, ", "), "1a", 14); /* Changing delim lists. */
1060 equal(strsep(&cp
, ", "), "", 15);
1061 equal(strsep(&cp
, "; "), "1b", 16);
1062 equal(strsep(&cp
, ", "), "", 17);
1063 equal(strsep(&cp
, ", "), "2a", 18);
1064 cp
= strcpy(two
, "x-y");
1065 equal(strsep(&cp
, "-"), "x", 19); /* New string before done. */
1066 equal(strsep(&cp
, "-"), "y", 20);
1067 check(strsep(&cp
, "-") == NULL
, 21);
1068 cp
= strcpy(one
, "a,b, c,, ,d ");
1069 equal(strsep(&cp
, ", "), "a", 22); /* Different separators. */
1070 equal(strsep(&cp
, ", "), "b", 23);
1071 equal(strsep(&cp
, " ,"), "", 24);
1072 equal(strsep(&cp
, " ,"), "c", 25); /* Permute list too. */
1073 equal(strsep(&cp
, " ,"), "", 26);
1074 equal(strsep(&cp
, " ,"), "", 27);
1075 equal(strsep(&cp
, " ,"), "", 28);
1076 equal(strsep(&cp
, " ,"), "d", 29);
1077 equal(strsep(&cp
, " ,"), "", 30);
1078 check(strsep(&cp
, ", ") == NULL
, 31);
1079 check(strsep(&cp
, ", ") == NULL
, 32); /* Persistence. */
1080 cp
= strcpy(one
, ", ");
1081 equal(strsep(&cp
, ", "), "", 33);
1082 equal(strsep(&cp
, ", "), "", 34);
1083 equal(strsep(&cp
, ", "), "", 35);
1084 check(strsep(&cp
, ", ") == NULL
, 36); /* No tokens. */
1085 cp
= strcpy(one
, "");
1086 equal(strsep(&cp
, ", "), "", 37);
1087 check(strsep(&cp
, ", ") == NULL
, 38); /* Empty string. */
1088 cp
= strcpy(one
, "abc");
1089 equal(strsep(&cp
, ", "), "abc", 39); /* No delimiters. */
1090 check(strsep(&cp
, ", ") == NULL
, 40);
1091 cp
= strcpy(one
, "abc");
1092 equal(strsep(&cp
, ""), "abc", 41); /* Empty delimiter list. */
1093 check(strsep(&cp
, "") == NULL
, 42);
1094 (void) strcpy(one
, "abcdefgh");
1095 cp
= strcpy(one
, "a,b,c");
1096 equal(strsep(&cp
, ","), "a", 43); /* Basics again... */
1097 equal(strsep(&cp
, ","), "b", 44);
1098 equal(strsep(&cp
, ","), "c", 45);
1099 check(strsep(&cp
, ",") == NULL
, 46);
1100 equal(one
+6, "gh", 47); /* Stomped past end? */
1101 equal(one
, "a", 48); /* Stomped old tokens? */
1102 equal(one
+2, "b", 49);
1103 equal(one
+4, "c", 50);
1106 char text
[] = "This,is,a,test";
1107 char *list
= strdupa (text
);
1108 equal (strsep (&list
, ","), "This", 51);
1109 equal (strsep (&list
, ","), "is", 52);
1110 equal (strsep (&list
, ","), "a", 53);
1111 equal (strsep (&list
, ","), "test", 54);
1112 check (strsep (&list
, ",") == NULL
, 55);
1115 cp
= strcpy(one
, "a,b, c,, ,d,");
1116 equal(strsep(&cp
, ","), "a", 56); /* Different separators. */
1117 equal(strsep(&cp
, ","), "b", 57);
1118 equal(strsep(&cp
, ","), " c", 58); /* Permute list too. */
1119 equal(strsep(&cp
, ","), "", 59);
1120 equal(strsep(&cp
, ","), " ", 60);
1121 equal(strsep(&cp
, ","), "d", 61);
1122 equal(strsep(&cp
, ","), "", 62);
1123 check(strsep(&cp
, ",") == NULL
, 63);
1124 check(strsep(&cp
, ",") == NULL
, 64); /* Persistence. */
1126 cp
= strcpy(one
, "a,b, c,, ,d,");
1127 equal(strsep(&cp
, "xy,"), "a", 65); /* Different separators. */
1128 equal(strsep(&cp
, "x,y"), "b", 66);
1129 equal(strsep(&cp
, ",xy"), " c", 67); /* Permute list too. */
1130 equal(strsep(&cp
, "xy,"), "", 68);
1131 equal(strsep(&cp
, "x,y"), " ", 69);
1132 equal(strsep(&cp
, ",xy"), "d", 70);
1133 equal(strsep(&cp
, "xy,"), "", 71);
1134 check(strsep(&cp
, "x,y") == NULL
, 72);
1135 check(strsep(&cp
, ",xy") == NULL
, 73); /* Persistence. */
1137 cp
= strcpy(one
, "ABC");
1139 equal(strsep(&cp
, "C"), "AB", 74); /* Access beyond NUL. */
1140 ptr
= strsep(&cp
, ":");
1142 check(ptr
== one
+ 3, 76);
1143 check(cp
== NULL
, 77);
1145 cp
= strcpy(one
, "ABC");
1147 equal(strsep(&cp
, "CD"), "AB", 78); /* Access beyond NUL. */
1148 ptr
= strsep(&cp
, ":.");
1150 check(ptr
== one
+ 3, 80);
1152 cp
= strcpy(one
, "ABC"); /* No token in string. */
1153 equal(strsep(&cp
, ","), "ABC", 81);
1154 check(cp
== NULL
, 82);
1156 *one
= '\0'; /* Empty string. */
1158 ptr
= strsep(&cp
, ",");
1160 check(ptr
== one
, 84);
1161 check(cp
== NULL
, 85);
1163 *one
= '\0'; /* Empty string and no token. */
1165 ptr
= strsep(&cp
, "");
1167 check(ptr
== one
, 87);
1168 check(cp
== NULL
, 88);
1179 check(memcmp("a", "a", 1) == 0, cnt
++); /* Identity. */
1180 check(memcmp("abc", "abc", 3) == 0, cnt
++); /* Multicharacter. */
1181 check(memcmp("abcd", "abcf", 4) < 0, cnt
++); /* Honestly unequal. */
1182 check(memcmp("abcf", "abcd", 4) > 0, cnt
++);
1183 check(memcmp("alph", "cold", 4) < 0, cnt
++);
1184 check(memcmp("a\203", "a\003", 2) > 0, cnt
++);
1185 check(memcmp("a\003", "a\203", 2) < 0, cnt
++);
1186 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt
++);
1187 check(memcmp("abc\203", "abc\003", 4) > 0, cnt
++);
1188 check(memcmp("abc\003", "abc\203", 4) < 0, cnt
++);
1189 check(memcmp("abcf", "abcd", 3) == 0, cnt
++); /* Count limited. */
1190 check(memcmp("abc", "def", 0) == 0, cnt
++); /* Zero count. */
1191 /* Comparisons with shifting 4-byte boundaries. */
1192 for (int i
= 0; i
< 4; ++i
)
1196 memcpy(a
, "--------11112222", 16);
1197 memcpy(b
, "--------33334444", 16);
1198 check(memcmp(b
, a
, 16) > 0, cnt
++);
1199 check(memcmp(a
, b
, 16) < 0, cnt
++);
1207 check(memchr("abcd", 'z', 4) == NULL
, 1); /* Not found. */
1208 (void) strcpy(one
, "abcd");
1209 check(memchr(one
, 'c', 4) == one
+2, 2); /* Basic test. */
1210 check(memchr(one
, ~0xff|'c', 4) == one
+2, 2); /* ignore highorder bits. */
1211 check(memchr(one
, 'd', 4) == one
+3, 3); /* End of string. */
1212 check(memchr(one
, 'a', 4) == one
, 4); /* Beginning. */
1213 check(memchr(one
, '\0', 5) == one
+4, 5); /* Finding NUL. */
1214 (void) strcpy(one
, "ababa");
1215 check(memchr(one
, 'b', 5) == one
+1, 6); /* Finding first. */
1216 check(memchr(one
, 'b', 0) == NULL
, 7); /* Zero count. */
1217 check(memchr(one
, 'a', 1) == one
, 8); /* Singleton case. */
1218 (void) strcpy(one
, "a\203b");
1219 check(memchr(one
, 0203, 3) == one
+1, 9); /* Unsignedness. */
1221 /* now test all possible alignment and length combinations to catch
1222 bugs due to unrolled loops (assuming unrolling is limited to no
1223 more than 128 byte chunks: */
1225 char buf
[128 + sizeof(long)];
1226 long align
, len
, i
, pos
;
1228 for (align
= 0; align
< (long) sizeof(long); ++align
) {
1229 for (len
= 0; len
< (long) (sizeof(buf
) - align
); ++len
) {
1230 for (i
= 0; i
< len
; ++i
) {
1231 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
1233 for (pos
= 0; pos
< len
; ++pos
) {
1235 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
1237 check(memchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, 10);
1238 check(memchr(buf
+ align
, 'x', pos
) == NULL
, 11);
1239 buf
[align
+ pos
] = '-';
1251 check(memcpy(one
, "abc", 4) == one
, 1); /* Returned value. */
1252 equal(one
, "abc", 2); /* Did the copy go right? */
1254 (void) strcpy(one
, "abcdefgh");
1255 (void) memcpy(one
+1, "xyz", 2);
1256 equal(one
, "axydefgh", 3); /* Basic test. */
1258 (void) strcpy(one
, "abc");
1259 (void) memcpy(one
, "xyz", 0);
1260 equal(one
, "abc", 4); /* Zero-length copy. */
1262 (void) strcpy(one
, "hi there");
1263 (void) strcpy(two
, "foo");
1264 (void) memcpy(two
, one
, 9);
1265 equal(two
, "hi there", 5); /* Just paranoia. */
1266 equal(one
, "hi there", 6); /* Stomped on source? */
1268 for (i
= 0; i
< 16; i
++)
1270 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1272 check (memcpy (one
+ i
, "hi there", 9) == one
+ i
,
1273 7 + (i
* 6)); /* Unaligned destination. */
1274 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1275 equal (one
+ i
, "hi there", 9 + (i
* 6));
1276 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1277 check (memcpy (two
, one
+ i
, 9) == two
,
1278 11 + (i
* 6)); /* Unaligned source. */
1279 equal (two
, "hi there", 12 + (i
* 6));
1288 check(mempcpy(one
, "abc", 4) == one
+ 4, 1); /* Returned value. */
1289 equal(one
, "abc", 2); /* Did the copy go right? */
1291 (void) strcpy(one
, "abcdefgh");
1292 (void) mempcpy(one
+1, "xyz", 2);
1293 equal(one
, "axydefgh", 3); /* Basic test. */
1295 (void) strcpy(one
, "abc");
1296 (void) mempcpy(one
, "xyz", 0);
1297 equal(one
, "abc", 4); /* Zero-length copy. */
1299 (void) strcpy(one
, "hi there");
1300 (void) strcpy(two
, "foo");
1301 (void) mempcpy(two
, one
, 9);
1302 equal(two
, "hi there", 5); /* Just paranoia. */
1303 equal(one
, "hi there", 6); /* Stomped on source? */
1305 for (i
= 0; i
< 16; i
++)
1307 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1309 check (mempcpy (one
+ i
, "hi there", 9) == one
+ i
+ 9,
1310 7 + (i
* 6)); /* Unaligned destination. */
1311 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1312 equal (one
+ i
, "hi there", 9 + (i
* 6));
1313 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1314 check (mempcpy (two
, one
+ i
, 9) == two
+ 9,
1315 11 + (i
* 6)); /* Unaligned source. */
1316 equal (two
, "hi there", 12 + (i
* 6));
1324 check(memmove(one
, "abc", 4) == one
, 1); /* Returned value. */
1325 equal(one
, "abc", 2); /* Did the copy go right? */
1327 (void) strcpy(one
, "abcdefgh");
1328 (void) memmove(one
+1, "xyz", 2);
1329 equal(one
, "axydefgh", 3); /* Basic test. */
1331 (void) strcpy(one
, "abc");
1332 (void) memmove(one
, "xyz", 0);
1333 equal(one
, "abc", 4); /* Zero-length copy. */
1335 (void) strcpy(one
, "hi there");
1336 (void) strcpy(two
, "foo");
1337 (void) memmove(two
, one
, 9);
1338 equal(two
, "hi there", 5); /* Just paranoia. */
1339 equal(one
, "hi there", 6); /* Stomped on source? */
1341 (void) strcpy(one
, "abcdefgh");
1342 (void) memmove(one
+1, one
, 9);
1343 equal(one
, "aabcdefgh", 7); /* Overlap, right-to-left. */
1345 (void) strcpy(one
, "abcdefgh");
1346 (void) memmove(one
+1, one
+2, 7);
1347 equal(one
, "acdefgh", 8); /* Overlap, left-to-right. */
1349 (void) strcpy(one
, "abcdefgh");
1350 (void) memmove(one
, one
, 9);
1351 equal(one
, "abcdefgh", 9); /* 100% overlap. */
1357 /* First test like memcpy, then the search part The SVID, the only
1358 place where memccpy is mentioned, says overlap might fail, so we
1359 don't try it. Besides, it's hard to see the rationale for a
1360 non-left-to-right memccpy. */
1362 check(memccpy(one
, "abc", 'q', 4) == NULL
, 1); /* Returned value. */
1363 equal(one
, "abc", 2); /* Did the copy go right? */
1365 (void) strcpy(one
, "abcdefgh");
1366 (void) memccpy(one
+1, "xyz", 'q', 2);
1367 equal(one
, "axydefgh", 3); /* Basic test. */
1369 (void) strcpy(one
, "abc");
1370 (void) memccpy(one
, "xyz", 'q', 0);
1371 equal(one
, "abc", 4); /* Zero-length copy. */
1373 (void) strcpy(one
, "hi there");
1374 (void) strcpy(two
, "foo");
1375 (void) memccpy(two
, one
, 'q', 9);
1376 equal(two
, "hi there", 5); /* Just paranoia. */
1377 equal(one
, "hi there", 6); /* Stomped on source? */
1379 (void) strcpy(one
, "abcdefgh");
1380 (void) strcpy(two
, "horsefeathers");
1381 check(memccpy(two
, one
, 'f', 9) == two
+6, 7); /* Returned value. */
1382 equal(one
, "abcdefgh", 8); /* Source intact? */
1383 equal(two
, "abcdefeathers", 9); /* Copy correct? */
1385 (void) strcpy(one
, "abcd");
1386 (void) strcpy(two
, "bumblebee");
1387 check(memccpy(two
, one
, 'a', 4) == two
+1, 10); /* First char. */
1388 equal(two
, "aumblebee", 11);
1389 check(memccpy(two
, one
, 'd', 4) == two
+4, 12); /* Last char. */
1390 equal(two
, "abcdlebee", 13);
1391 (void) strcpy(one
, "xyz");
1392 check(memccpy(two
, one
, 'x', 1) == two
+1, 14); /* Singleton. */
1393 equal(two
, "xbcdlebee", 15);
1402 (void) strcpy(one
, "abcdefgh");
1403 check(memset(one
+1, 'x', 3) == one
+1, 1); /* Return value. */
1404 equal(one
, "axxxefgh", 2); /* Basic test. */
1406 DIAG_PUSH_NEEDS_COMMENT
;
1407 #if __GNUC_PREREQ (5, 0)
1408 /* GCC 5.0 warns about a zero-length memset because the arguments to memset
1409 may be in the wrong order. But we really want to test this. */
1410 DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args")
1412 (void) memset(one
+2, 'y', 0);
1413 equal(one
, "axxxefgh", 3); /* Zero-length set. */
1414 DIAG_POP_NEEDS_COMMENT
;
1416 (void) memset(one
+5, 0, 1);
1417 equal(one
, "axxxe", 4); /* Zero fill. */
1418 equal(one
+6, "gh", 5); /* And the leftover. */
1420 (void) memset(one
+2, 010045, 1);
1421 equal(one
, "ax\045xe", 6); /* Unsigned char convert. */
1423 /* Non-8bit fill character. */
1424 memset (one
, 0x101, sizeof (one
));
1425 for (i
= 0; i
< (int) sizeof (one
); ++i
)
1426 check (one
[i
] == '\01', 7);
1428 /* Test for more complex versions of memset, for all alignments and
1429 lengths up to 256. This test takes a little while, perhaps it should
1437 for (i
= 0; i
< 512; i
++)
1439 for (c
= 0; c
<= 'y'; c
+= 'y') /* check for memset(,0,) and
1441 for (j
= 0; j
< 256; j
++)
1442 for (i
= 0; i
< 256; i
++)
1444 memset (data
+ i
, c
, j
);
1445 for (k
= 0; k
< i
; k
++)
1448 for (k
= i
; k
< i
+j
; k
++)
1454 for (k
= i
+j
; k
< 512; k
++)
1460 check (0, 8 + i
+ j
* 256 + (c
!= 0) * 256 * 256);
1468 /* Much like memcpy. Berklix manual is silent about overlap, so
1471 (void) bcopy("abc", one
, 4);
1472 equal(one
, "abc", 1); /* Simple copy. */
1474 (void) strcpy(one
, "abcdefgh");
1475 (void) bcopy("xyz", one
+1, 2);
1476 equal(one
, "axydefgh", 2); /* Basic test. */
1478 (void) strcpy(one
, "abc");
1479 (void) bcopy("xyz", one
, 0);
1480 equal(one
, "abc", 3); /* Zero-length copy. */
1482 (void) strcpy(one
, "hi there");
1483 (void) strcpy(two
, "foo");
1484 (void) bcopy(one
, two
, 9);
1485 equal(two
, "hi there", 4); /* Just paranoia. */
1486 equal(one
, "hi there", 5); /* Stomped on source? */
1493 (void) strcpy(one
, "abcdef");
1495 equal(one
, "ab", 1); /* Basic test. */
1496 equal(one
+3, "", 2);
1497 equal(one
+4, "ef", 3);
1499 (void) strcpy(one
, "abcdef");
1501 equal(one
, "abcdef", 4); /* Zero-length copy. */
1509 p
= strndup("abcdef", 12);
1510 check(p
!= NULL
, 1);
1513 equal(p
, "abcdef", 2);
1514 q
= strndup(p
+ 1, 2);
1515 check(q
!= NULL
, 3);
1521 p
= strndup("abc def", 3);
1522 check(p
!= NULL
, 5);
1532 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1533 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1534 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1535 check(bcmp("abce", "abcd", 4) != 0, 4);
1536 check(bcmp("alph", "beta", 4) != 0, 5);
1537 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1538 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1542 test_strerror (void)
1545 check(strerror(EDOM
) != 0, 1);
1546 check(strerror(ERANGE
) != 0, 2);
1547 check(strerror(ENOENT
) != 0, 3);
1551 test_strcasecmp (void)
1554 /* Note that the locale is "C". */
1555 check(strcasecmp("a", "a") == 0, 1);
1556 check(strcasecmp("a", "A") == 0, 2);
1557 check(strcasecmp("A", "a") == 0, 3);
1558 check(strcasecmp("a", "b") < 0, 4);
1559 check(strcasecmp("c", "b") > 0, 5);
1560 check(strcasecmp("abc", "AbC") == 0, 6);
1561 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1562 check(strcasecmp("", "0123456789") < 0, 8);
1563 check(strcasecmp("AbC", "") > 0, 9);
1564 check(strcasecmp("AbC", "A") > 0, 10);
1565 check(strcasecmp("AbC", "Ab") > 0, 11);
1566 check(strcasecmp("AbC", "ab") > 0, 12);
1570 test_strncasecmp (void)
1573 /* Note that the locale is "C". */
1574 check(strncasecmp("a", "a", 5) == 0, 1);
1575 check(strncasecmp("a", "A", 5) == 0, 2);
1576 check(strncasecmp("A", "a", 5) == 0, 3);
1577 check(strncasecmp("a", "b", 5) < 0, 4);
1578 check(strncasecmp("c", "b", 5) > 0, 5);
1579 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1580 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1581 check(strncasecmp("", "0123456789", 10) < 0, 8);
1582 check(strncasecmp("AbC", "", 5) > 0, 9);
1583 check(strncasecmp("AbC", "A", 5) > 0, 10);
1584 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1585 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1586 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1587 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1588 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1589 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1590 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1591 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1592 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1593 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1601 /* Test strcmp first because we use it to test other things. */
1604 /* Test strcpy next because we need it to set up other tests. */
1607 /* A closely related function is stpcpy. */
1640 /* index - just like strchr. */
1649 /* rindex - just like strrchr. */
1652 /* strpbrk - somewhat like strchr. */
1655 /* strstr - somewhat like strchr. */
1664 /* strtok - the hard one. */
1679 /* memcpy - need not work for overlap. */
1682 /* memmove - must work on overlap. */
1700 /* bcmp - somewhat like memcmp. */
1706 /* strerror - VERY system-dependent. */
1709 /* strcasecmp. Without locale dependencies. */
1712 /* strncasecmp. Without locale dependencies. */
1713 test_strncasecmp ();
1717 status
= EXIT_SUCCESS
;
1722 status
= EXIT_FAILURE
;
1723 printf("%Zd errors.\n", errors
);