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=");
489 DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
490 check (strncat (buf1
+ n2
, buf2
+ n1
, ~((size_t) 0) - n4
)
491 == buf1
+ n2
, ntest
);
492 DIAG_POP_NEEDS_COMMENT
;
493 if (errors
== olderrors
)
494 for (size_t i
= 0; i
< sizeof (buf1
); ++i
)
497 check (buf1
[i
] == 'b', ntest
);
498 else if (i
< n2
+ n3
)
499 check (buf1
[i
] == 'a', ntest
);
500 else if (i
< n2
+ n3
+ 3)
501 check (buf1
[i
] == "123"[i
- (n2
+ n3
)], ntest
);
502 else if (i
== n2
+ n3
+ 3)
503 check (buf1
[i
] == '\0', ntest
);
505 check (buf1
[i
] == 'b', ntest
);
507 if (errors
!= olderrors
)
509 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
510 n1
, n2
, n3
, n4
, buf1
[0]);
511 for (size_t j
= 1; j
< sizeof (buf1
); ++j
)
512 printf (",%02hhx", buf1
[j
]);
513 putchar_unlocked ('\n');
523 /* First test as strcmp with big counts, then test count code. */
525 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
526 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
527 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
528 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
529 check (strncmp ("abcd", "abc", 99) > 0, 5);
530 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
531 check (strncmp ("abce", "abcd", 99) > 0, 7);
532 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
533 check (strncmp ("a\203", "a\003", 2) > 0, 9);
534 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
535 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
536 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
537 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
538 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
539 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
545 /* Testing is a bit different because of odd semantics. */
547 check (strncpy (one
, "abc", 4) == one
, 1); /* Returned value. */
548 equal (one
, "abc", 2); /* Did the copy go right? */
550 (void) strcpy (one
, "abcdefgh");
551 DIAG_PUSH_NEEDS_COMMENT
;
552 #if __GNUC_PREREQ (8, 0)
553 /* GCC 8 warns about strncpy truncating output; this is deliberately
555 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
557 (void) strncpy (one
, "xyz", 2);
558 DIAG_POP_NEEDS_COMMENT
;
559 equal (one
, "xycdefgh", 3); /* Copy cut by count. */
561 (void) strcpy (one
, "abcdefgh");
562 DIAG_PUSH_NEEDS_COMMENT
;
563 #if __GNUC_PREREQ (8, 0)
564 /* GCC 8 warns about strncpy truncating output; this is deliberately
566 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
568 (void) strncpy (one
, "xyz", 3); /* Copy cut just before NUL. */
569 DIAG_POP_NEEDS_COMMENT
;
570 equal (one
, "xyzdefgh", 4);
572 (void) strcpy (one
, "abcdefgh");
573 (void) strncpy (one
, "xyz", 4); /* Copy just includes NUL. */
574 equal (one
, "xyz", 5);
575 equal (one
+4, "efgh", 6); /* Wrote too much? */
577 (void) strcpy (one
, "abcdefgh");
578 (void) strncpy (one
, "xyz", 5); /* Copy includes padding. */
579 equal (one
, "xyz", 7);
580 equal (one
+4, "", 8);
581 equal (one
+5, "fgh", 9);
583 (void) strcpy (one
, "abc");
584 DIAG_PUSH_NEEDS_COMMENT
;
585 #if __GNUC_PREREQ (8, 0)
586 /* GCC 8 warns about strncpy truncating output; this is deliberately
588 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
590 (void) strncpy (one
, "xyz", 0); /* Zero-length copy. */
591 DIAG_POP_NEEDS_COMMENT
;
592 equal (one
, "abc", 10);
594 (void) strncpy (one
, "", 2); /* Zero-length source. */
596 equal (one
+1, "", 12);
597 equal (one
+2, "c", 13);
599 (void) strcpy (one
, "hi there");
600 (void) strncpy (two
, one
, 9);
601 equal (two
, "hi there", 14); /* Just paranoia. */
602 equal (one
, "hi there", 15); /* Stomped on source? */
609 check (strlen ("") == 0, 1); /* Empty. */
610 check (strlen ("a") == 1, 2); /* Single char. */
611 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
616 for (i
=0; i
< 0x100; i
++)
618 p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
620 strcpy (p
+3, "BAD/WRONG");
621 check (strlen (p
) == 2, 4+i
);
630 check (strnlen ("", 10) == 0, 1); /* Empty. */
631 check (strnlen ("a", 10) == 1, 2); /* Single char. */
632 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
633 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
634 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
635 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
636 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
637 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
638 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
641 for (int i
= 0; i
< 0x100; ++i
)
643 char *p
= (char *) ((unsigned long int)(buf
+ 0xff) & ~0xff) + i
;
645 strcpy (p
+ 3, "BAD/WRONG");
646 check (strnlen (p
, 100) == 2, 10 + i
);
654 check (strchr ("abcd", 'z') == NULL
, 1); /* Not found. */
655 (void) strcpy (one
, "abcd");
656 check (strchr (one
, 'c') == one
+2, 2); /* Basic test. */
657 check (strchr (one
, 'd') == one
+3, 3); /* End of string. */
658 check (strchr (one
, 'a') == one
, 4); /* Beginning. */
659 check (strchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
660 (void) strcpy (one
, "ababa");
661 check (strchr (one
, 'b') == one
+1, 6); /* Finding first. */
662 (void) strcpy (one
, "");
663 check (strchr (one
, 'b') == NULL
, 7); /* Empty string. */
664 check (strchr (one
, '\0') == one
, 8); /* NUL in empty string. */
669 for (i
=0; i
< 0x100; i
++)
671 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
673 strcpy (p
+3, "BAD/WRONG");
674 check (strchr (p
, '/') == NULL
, 9+i
);
680 test_strchrnul (void)
684 cp
= strchrnul ((os
= "abcd"), 'z');
685 check (*cp
== '\0', 1); /* Not found. */
686 check (cp
== os
+ 4, 2);
687 (void) strcpy (one
, "abcd");
688 check (strchrnul (one
, 'c') == one
+2, 3); /* Basic test. */
689 check (strchrnul (one
, 'd') == one
+3, 4); /* End of string. */
690 check (strchrnul (one
, 'a') == one
, 5); /* Beginning. */
691 check (strchrnul (one
, '\0') == one
+4, 6); /* Finding NUL. */
692 (void) strcpy (one
, "ababa");
693 check (strchrnul (one
, 'b') == one
+1, 7); /* Finding first. */
694 (void) strcpy (one
, "");
695 check (strchrnul (one
, 'b') == one
, 8); /* Empty string. */
696 check (strchrnul (one
, '\0') == one
, 9); /* NUL in empty string. */
701 for (i
=0; i
< 0x100; i
++)
703 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
705 strcpy (p
+3, "BAD/WRONG");
706 cp
= strchrnul (p
, '/');
707 check (*cp
== '\0', 9+2*i
);
708 check (cp
== p
+2, 10+2*i
);
714 test_rawmemchr (void)
717 (void) strcpy (one
, "abcd");
718 check (rawmemchr (one
, 'c') == one
+2, 1); /* Basic test. */
719 check (rawmemchr (one
, 'd') == one
+3, 2); /* End of string. */
720 check (rawmemchr (one
, 'a') == one
, 3); /* Beginning. */
721 check (rawmemchr (one
, '\0') == one
+4, 4); /* Finding NUL. */
722 (void) strcpy (one
, "ababa");
723 check (rawmemchr (one
, 'b') == one
+1, 5); /* Finding first. */
724 (void) strcpy (one
, "");
725 check (rawmemchr (one
, '\0') == one
, 6); /* NUL in empty string. */
730 for (i
=0; i
< 0x100; i
++)
732 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
734 strcpy (p
+3, "BAD/WRONG");
735 check (rawmemchr (p
, 'R') == p
+8, 6+i
);
744 check (index ("abcd", 'z') == NULL
, 1); /* Not found. */
745 (void) strcpy (one
, "abcd");
746 check (index (one
, 'c') == one
+2, 2); /* Basic test. */
747 check (index (one
, 'd') == one
+3, 3); /* End of string. */
748 check (index (one
, 'a') == one
, 4); /* Beginning. */
749 check (index (one
, '\0') == one
+4, 5); /* Finding NUL. */
750 (void) strcpy (one
, "ababa");
751 check (index (one
, 'b') == one
+1, 6); /* Finding first. */
752 (void) strcpy (one
, "");
753 check (index (one
, 'b') == NULL
, 7); /* Empty string. */
754 check (index (one
, '\0') == one
, 8); /* NUL in empty string. */
761 check (strrchr ("abcd", 'z') == NULL
, 1); /* Not found. */
762 (void) strcpy (one
, "abcd");
763 check (strrchr (one
, 'c') == one
+2, 2); /* Basic test. */
764 check (strrchr (one
, 'd') == one
+3, 3); /* End of string. */
765 check (strrchr (one
, 'a') == one
, 4); /* Beginning. */
766 check (strrchr (one
, '\0') == one
+4, 5); /* Finding NUL. */
767 (void) strcpy (one
, "ababa");
768 check (strrchr (one
, 'b') == one
+3, 6); /* Finding last. */
769 (void) strcpy (one
, "");
770 check (strrchr (one
, 'b') == NULL
, 7); /* Empty string. */
771 check (strrchr (one
, '\0') == one
, 8); /* NUL in empty string. */
776 for (i
=0; i
< 0x100; i
++)
778 p
= (char *) ((unsigned long int) (buf
+ 0xff) & ~0xff) + i
;
780 strcpy (p
+3, "BAD/WRONG");
781 check (strrchr (p
, '/') == NULL
, 9+i
);
791 check (memrchr ("abcd", 'z', 5) == NULL
, 1); /* Not found. */
792 (void) strcpy (one
, "abcd");
793 l
= strlen (one
) + 1;
794 check (memrchr (one
, 'c', l
) == one
+2, 2); /* Basic test. */
795 check (memrchr (one
, 'd', l
) == one
+3, 3); /* End of string. */
796 check (memrchr (one
, 'a', l
) == one
, 4); /* Beginning. */
797 check (memrchr (one
, '\0', l
) == one
+4, 5); /* Finding NUL. */
798 (void) strcpy (one
, "ababa");
799 l
= strlen (one
) + 1;
800 check (memrchr (one
, 'b', l
) == one
+3, 6); /* Finding last. */
801 (void) strcpy (one
, "");
802 l
= strlen (one
) + 1;
803 check (memrchr (one
, 'b', l
) == NULL
, 7); /* Empty string. */
804 check (memrchr (one
, '\0', l
) == one
, 8); /* NUL in empty string. */
806 /* now test all possible alignment and length combinations to catch
807 bugs due to unrolled loops (assuming unrolling is limited to no
808 more than 128 byte chunks: */
810 char buf
[128 + sizeof(long)];
811 long align
, len
, i
, pos
, n
= 9;
813 for (align
= 0; align
< (long) sizeof(long); ++align
) {
814 for (len
= 0; len
< (long) (sizeof(buf
) - align
); ++len
) {
815 for (i
= 0; i
< len
; ++i
)
816 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
818 for (pos
= len
- 1; pos
>= 0; --pos
) {
820 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
822 check(memrchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, n
++);
823 check(memrchr(buf
+ align
+ pos
+ 1, 'x', len
- (pos
+ 1)) == NULL
,
825 buf
[align
+ pos
] = '-';
836 check (rindex ("abcd", 'z') == NULL
, 1); /* Not found. */
837 (void) strcpy (one
, "abcd");
838 check (rindex (one
, 'c') == one
+2, 2); /* Basic test. */
839 check (rindex (one
, 'd') == one
+3, 3); /* End of string. */
840 check (rindex (one
, 'a') == one
, 4); /* Beginning. */
841 check (rindex (one
, '\0') == one
+4, 5); /* Finding NUL. */
842 (void) strcpy (one
, "ababa");
843 check (rindex (one
, 'b') == one
+3, 6); /* Finding last. */
844 (void) strcpy (one
, "");
845 check (rindex (one
, 'b') == NULL
, 7); /* Empty string. */
846 check (rindex (one
, '\0') == one
, 8); /* NUL in empty string. */
853 check(strpbrk("abcd", "z") == NULL
, 1); /* Not found. */
854 (void) strcpy(one
, "abcd");
855 check(strpbrk(one
, "c") == one
+2, 2); /* Basic test. */
856 check(strpbrk(one
, "d") == one
+3, 3); /* End of string. */
857 check(strpbrk(one
, "a") == one
, 4); /* Beginning. */
858 check(strpbrk(one
, "") == NULL
, 5); /* Empty search list. */
859 check(strpbrk(one
, "cb") == one
+1, 6); /* Multiple search. */
860 (void) strcpy(one
, "abcabdea");
861 check(strpbrk(one
, "b") == one
+1, 7); /* Finding first. */
862 check(strpbrk(one
, "cb") == one
+1, 8); /* With multiple search. */
863 check(strpbrk(one
, "db") == one
+1, 9); /* Another variant. */
864 (void) strcpy(one
, "");
865 check(strpbrk(one
, "bc") == NULL
, 10); /* Empty string. */
866 (void) strcpy(one
, "");
867 check(strpbrk(one
, "bcd") == NULL
, 11); /* Empty string. */
868 (void) strcpy(one
, "");
869 check(strpbrk(one
, "bcde") == NULL
, 12); /* Empty string. */
870 check(strpbrk(one
, "") == NULL
, 13); /* Both strings empty. */
871 (void) strcpy(one
, "abcabdea");
872 check(strpbrk(one
, "befg") == one
+1, 14); /* Finding first. */
873 check(strpbrk(one
, "cbr") == one
+1, 15); /* With multiple search. */
874 check(strpbrk(one
, "db") == one
+1, 16); /* Another variant. */
875 check(strpbrk(one
, "efgh") == one
+6, 17); /* And yet another. */
882 check(strstr("abcd", "z") == NULL
, 1); /* Not found. */
883 check(strstr("abcd", "abx") == NULL
, 2); /* Dead end. */
884 (void) strcpy(one
, "abcd");
885 check(strstr(one
, "c") == one
+2, 3); /* Basic test. */
886 check(strstr(one
, "bc") == one
+1, 4); /* Multichar. */
887 check(strstr(one
, "d") == one
+3, 5); /* End of string. */
888 check(strstr(one
, "cd") == one
+2, 6); /* Tail of string. */
889 check(strstr(one
, "abc") == one
, 7); /* Beginning. */
890 check(strstr(one
, "abcd") == one
, 8); /* Exact match. */
891 check(strstr(one
, "abcde") == NULL
, 9); /* Too long. */
892 check(strstr(one
, "de") == NULL
, 10); /* Past end. */
893 check(strstr(one
, "") == one
, 11); /* Finding empty. */
894 (void) strcpy(one
, "ababa");
895 check(strstr(one
, "ba") == one
+1, 12); /* Finding first. */
896 (void) strcpy(one
, "");
897 check(strstr(one
, "b") == NULL
, 13); /* Empty string. */
898 check(strstr(one
, "") == one
, 14); /* Empty in empty string. */
899 (void) strcpy(one
, "bcbca");
900 check(strstr(one
, "bca") == one
+2, 15); /* False start. */
901 (void) strcpy(one
, "bbbcabbca");
902 check(strstr(one
, "bbca") == one
+1, 16); /* With overlap. */
909 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
910 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
911 check(strspn("abc", "qx") == 0, 3); /* None. */
912 check(strspn("", "ab") == 0, 4); /* Null string. */
913 check(strspn("abc", "") == 0, 5); /* Null search list. */
920 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
921 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
922 check(strcspn("abc", "abc") == 0, 3); /* None. */
923 check(strcspn("", "ab") == 0, 4); /* Null string. */
924 check(strcspn("abc", "") == 3, 5); /* Null search list. */
931 (void) strcpy(one
, "first, second, third");
932 equal(strtok(one
, ", "), "first", 1); /* Basic test. */
933 equal(one
, "first", 2);
934 equal(strtok((char *)NULL
, ", "), "second", 3);
935 equal(strtok((char *)NULL
, ", "), "third", 4);
936 check(strtok((char *)NULL
, ", ") == NULL
, 5);
937 (void) strcpy(one
, ", first, ");
938 equal(strtok(one
, ", "), "first", 6); /* Extra delims, 1 tok. */
939 check(strtok((char *)NULL
, ", ") == NULL
, 7);
940 (void) strcpy(one
, "1a, 1b; 2a, 2b");
941 equal(strtok(one
, ", "), "1a", 8); /* Changing delim lists. */
942 equal(strtok((char *)NULL
, "; "), "1b", 9);
943 equal(strtok((char *)NULL
, ", "), "2a", 10);
944 (void) strcpy(two
, "x-y");
945 equal(strtok(two
, "-"), "x", 11); /* New string before done. */
946 equal(strtok((char *)NULL
, "-"), "y", 12);
947 check(strtok((char *)NULL
, "-") == NULL
, 13);
948 (void) strcpy(one
, "a,b, c,, ,d");
949 equal(strtok(one
, ", "), "a", 14); /* Different separators. */
950 equal(strtok((char *)NULL
, ", "), "b", 15);
951 equal(strtok((char *)NULL
, " ,"), "c", 16); /* Permute list too. */
952 equal(strtok((char *)NULL
, " ,"), "d", 17);
953 check(strtok((char *)NULL
, ", ") == NULL
, 18);
954 check(strtok((char *)NULL
, ", ") == NULL
, 19); /* Persistence. */
955 (void) strcpy(one
, ", ");
956 check(strtok(one
, ", ") == NULL
, 20); /* No tokens. */
957 (void) strcpy(one
, "");
958 check(strtok(one
, ", ") == NULL
, 21); /* Empty string. */
959 (void) strcpy(one
, "abc");
960 equal(strtok(one
, ", "), "abc", 22); /* No delimiters. */
961 check(strtok((char *)NULL
, ", ") == NULL
, 23);
962 (void) strcpy(one
, "abc");
963 equal(strtok(one
, ""), "abc", 24); /* Empty delimiter list. */
964 check(strtok((char *)NULL
, "") == NULL
, 25);
965 (void) strcpy(one
, "abcdefgh");
966 (void) strcpy(one
, "a,b,c");
967 equal(strtok(one
, ","), "a", 26); /* Basics again... */
968 equal(strtok((char *)NULL
, ","), "b", 27);
969 equal(strtok((char *)NULL
, ","), "c", 28);
970 check(strtok((char *)NULL
, ",") == NULL
, 29);
971 equal(one
+6, "gh", 30); /* Stomped past end? */
972 equal(one
, "a", 31); /* Stomped old tokens? */
973 equal(one
+2, "b", 32);
974 equal(one
+4, "c", 33);
981 (void) strcpy(one
, "first, second, third");
982 cp
= NULL
; /* Always initialize cp to make sure it doesn't point to some old data. */
983 equal(strtok_r(one
, ", ", &cp
), "first", 1); /* Basic test. */
984 equal(one
, "first", 2);
985 equal(strtok_r((char *)NULL
, ", ", &cp
), "second", 3);
986 equal(strtok_r((char *)NULL
, ", ", &cp
), "third", 4);
987 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 5);
988 (void) strcpy(one
, ", first, ");
990 equal(strtok_r(one
, ", ", &cp
), "first", 6); /* Extra delims, 1 tok. */
991 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 7);
992 (void) strcpy(one
, "1a, 1b; 2a, 2b");
994 equal(strtok_r(one
, ", ", &cp
), "1a", 8); /* Changing delim lists. */
995 equal(strtok_r((char *)NULL
, "; ", &cp
), "1b", 9);
996 equal(strtok_r((char *)NULL
, ", ", &cp
), "2a", 10);
997 (void) strcpy(two
, "x-y");
999 equal(strtok_r(two
, "-", &cp
), "x", 11); /* New string before done. */
1000 equal(strtok_r((char *)NULL
, "-", &cp
), "y", 12);
1001 check(strtok_r((char *)NULL
, "-", &cp
) == NULL
, 13);
1002 (void) strcpy(one
, "a,b, c,, ,d");
1004 equal(strtok_r(one
, ", ", &cp
), "a", 14); /* Different separators. */
1005 equal(strtok_r((char *)NULL
, ", ", &cp
), "b", 15);
1006 equal(strtok_r((char *)NULL
, " ,", &cp
), "c", 16); /* Permute list too. */
1007 equal(strtok_r((char *)NULL
, " ,", &cp
), "d", 17);
1008 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 18);
1009 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 19); /* Persistence. */
1010 (void) strcpy(one
, ", ");
1012 check(strtok_r(one
, ", ", &cp
) == NULL
, 20); /* No tokens. */
1013 (void) strcpy(one
, "");
1015 check(strtok_r(one
, ", ", &cp
) == NULL
, 21); /* Empty string. */
1016 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 22); /* Persistence. */
1017 (void) strcpy(one
, "abc");
1019 equal(strtok_r(one
, ", ", &cp
), "abc", 23); /* No delimiters. */
1020 check(strtok_r((char *)NULL
, ", ", &cp
) == NULL
, 24);
1021 (void) strcpy(one
, "abc");
1023 equal(strtok_r(one
, "", &cp
), "abc", 25); /* Empty delimiter list. */
1024 check(strtok_r((char *)NULL
, "", &cp
) == NULL
, 26);
1025 (void) strcpy(one
, "abcdefgh");
1026 (void) strcpy(one
, "a,b,c");
1028 equal(strtok_r(one
, ",", &cp
), "a", 27); /* Basics again... */
1029 equal(strtok_r((char *)NULL
, ",", &cp
), "b", 28);
1030 equal(strtok_r((char *)NULL
, ",", &cp
), "c", 29);
1031 check(strtok_r((char *)NULL
, ",", &cp
) == NULL
, 30);
1032 equal(one
+6, "gh", 31); /* Stomped past end? */
1033 equal(one
, "a", 32); /* Stomped old tokens? */
1034 equal(one
+2, "b", 33);
1035 equal(one
+4, "c", 34);
1036 strcpy (one
, ":::");
1038 check (strtok_r (one
, ":", &cp
) == NULL
, 35); /* Must store pointer in cp. */
1039 check (strtok_r (NULL
, ":", &cp
) == NULL
, 36);
1047 cp
= strcpy(one
, "first, second, third");
1048 equal(strsep(&cp
, ", "), "first", 1); /* Basic test. */
1049 equal(one
, "first", 2);
1050 equal(strsep(&cp
, ", "), "", 3);
1051 equal(strsep(&cp
, ", "), "second", 4);
1052 equal(strsep(&cp
, ", "), "", 5);
1053 equal(strsep(&cp
, ", "), "third", 6);
1054 check(strsep(&cp
, ", ") == NULL
, 7);
1055 cp
= strcpy(one
, ", first, ");
1056 equal(strsep(&cp
, ", "), "", 8);
1057 equal(strsep(&cp
, ", "), "", 9);
1058 equal(strsep(&cp
, ", "), "first", 10); /* Extra delims, 1 tok. */
1059 equal(strsep(&cp
, ", "), "", 11);
1060 equal(strsep(&cp
, ", "), "", 12);
1061 check(strsep(&cp
, ", ") == NULL
, 13);
1062 cp
= strcpy(one
, "1a, 1b; 2a, 2b");
1063 equal(strsep(&cp
, ", "), "1a", 14); /* Changing delim lists. */
1064 equal(strsep(&cp
, ", "), "", 15);
1065 equal(strsep(&cp
, "; "), "1b", 16);
1066 equal(strsep(&cp
, ", "), "", 17);
1067 equal(strsep(&cp
, ", "), "2a", 18);
1068 cp
= strcpy(two
, "x-y");
1069 equal(strsep(&cp
, "-"), "x", 19); /* New string before done. */
1070 equal(strsep(&cp
, "-"), "y", 20);
1071 check(strsep(&cp
, "-") == NULL
, 21);
1072 cp
= strcpy(one
, "a,b, c,, ,d ");
1073 equal(strsep(&cp
, ", "), "a", 22); /* Different separators. */
1074 equal(strsep(&cp
, ", "), "b", 23);
1075 equal(strsep(&cp
, " ,"), "", 24);
1076 equal(strsep(&cp
, " ,"), "c", 25); /* Permute list too. */
1077 equal(strsep(&cp
, " ,"), "", 26);
1078 equal(strsep(&cp
, " ,"), "", 27);
1079 equal(strsep(&cp
, " ,"), "", 28);
1080 equal(strsep(&cp
, " ,"), "d", 29);
1081 equal(strsep(&cp
, " ,"), "", 30);
1082 check(strsep(&cp
, ", ") == NULL
, 31);
1083 check(strsep(&cp
, ", ") == NULL
, 32); /* Persistence. */
1084 cp
= strcpy(one
, ", ");
1085 equal(strsep(&cp
, ", "), "", 33);
1086 equal(strsep(&cp
, ", "), "", 34);
1087 equal(strsep(&cp
, ", "), "", 35);
1088 check(strsep(&cp
, ", ") == NULL
, 36); /* No tokens. */
1089 cp
= strcpy(one
, "");
1090 equal(strsep(&cp
, ", "), "", 37);
1091 check(strsep(&cp
, ", ") == NULL
, 38); /* Empty string. */
1092 cp
= strcpy(one
, "abc");
1093 equal(strsep(&cp
, ", "), "abc", 39); /* No delimiters. */
1094 check(strsep(&cp
, ", ") == NULL
, 40);
1095 cp
= strcpy(one
, "abc");
1096 equal(strsep(&cp
, ""), "abc", 41); /* Empty delimiter list. */
1097 check(strsep(&cp
, "") == NULL
, 42);
1098 (void) strcpy(one
, "abcdefgh");
1099 cp
= strcpy(one
, "a,b,c");
1100 equal(strsep(&cp
, ","), "a", 43); /* Basics again... */
1101 equal(strsep(&cp
, ","), "b", 44);
1102 equal(strsep(&cp
, ","), "c", 45);
1103 check(strsep(&cp
, ",") == NULL
, 46);
1104 equal(one
+6, "gh", 47); /* Stomped past end? */
1105 equal(one
, "a", 48); /* Stomped old tokens? */
1106 equal(one
+2, "b", 49);
1107 equal(one
+4, "c", 50);
1110 char text
[] = "This,is,a,test";
1111 char *list
= strdupa (text
);
1112 equal (strsep (&list
, ","), "This", 51);
1113 equal (strsep (&list
, ","), "is", 52);
1114 equal (strsep (&list
, ","), "a", 53);
1115 equal (strsep (&list
, ","), "test", 54);
1116 check (strsep (&list
, ",") == NULL
, 55);
1119 cp
= strcpy(one
, "a,b, c,, ,d,");
1120 equal(strsep(&cp
, ","), "a", 56); /* Different separators. */
1121 equal(strsep(&cp
, ","), "b", 57);
1122 equal(strsep(&cp
, ","), " c", 58); /* Permute list too. */
1123 equal(strsep(&cp
, ","), "", 59);
1124 equal(strsep(&cp
, ","), " ", 60);
1125 equal(strsep(&cp
, ","), "d", 61);
1126 equal(strsep(&cp
, ","), "", 62);
1127 check(strsep(&cp
, ",") == NULL
, 63);
1128 check(strsep(&cp
, ",") == NULL
, 64); /* Persistence. */
1130 cp
= strcpy(one
, "a,b, c,, ,d,");
1131 equal(strsep(&cp
, "xy,"), "a", 65); /* Different separators. */
1132 equal(strsep(&cp
, "x,y"), "b", 66);
1133 equal(strsep(&cp
, ",xy"), " c", 67); /* Permute list too. */
1134 equal(strsep(&cp
, "xy,"), "", 68);
1135 equal(strsep(&cp
, "x,y"), " ", 69);
1136 equal(strsep(&cp
, ",xy"), "d", 70);
1137 equal(strsep(&cp
, "xy,"), "", 71);
1138 check(strsep(&cp
, "x,y") == NULL
, 72);
1139 check(strsep(&cp
, ",xy") == NULL
, 73); /* Persistence. */
1141 cp
= strcpy(one
, "ABC");
1143 equal(strsep(&cp
, "C"), "AB", 74); /* Access beyond NUL. */
1144 ptr
= strsep(&cp
, ":");
1146 check(ptr
== one
+ 3, 76);
1147 check(cp
== NULL
, 77);
1149 cp
= strcpy(one
, "ABC");
1151 equal(strsep(&cp
, "CD"), "AB", 78); /* Access beyond NUL. */
1152 ptr
= strsep(&cp
, ":.");
1154 check(ptr
== one
+ 3, 80);
1156 cp
= strcpy(one
, "ABC"); /* No token in string. */
1157 equal(strsep(&cp
, ","), "ABC", 81);
1158 check(cp
== NULL
, 82);
1160 *one
= '\0'; /* Empty string. */
1162 ptr
= strsep(&cp
, ",");
1164 check(ptr
== one
, 84);
1165 check(cp
== NULL
, 85);
1167 *one
= '\0'; /* Empty string and no token. */
1169 ptr
= strsep(&cp
, "");
1171 check(ptr
== one
, 87);
1172 check(cp
== NULL
, 88);
1183 check(memcmp("a", "a", 1) == 0, cnt
++); /* Identity. */
1184 check(memcmp("abc", "abc", 3) == 0, cnt
++); /* Multicharacter. */
1185 check(memcmp("abcd", "abcf", 4) < 0, cnt
++); /* Honestly unequal. */
1186 check(memcmp("abcf", "abcd", 4) > 0, cnt
++);
1187 check(memcmp("alph", "cold", 4) < 0, cnt
++);
1188 check(memcmp("a\203", "a\003", 2) > 0, cnt
++);
1189 check(memcmp("a\003", "a\203", 2) < 0, cnt
++);
1190 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt
++);
1191 check(memcmp("abc\203", "abc\003", 4) > 0, cnt
++);
1192 check(memcmp("abc\003", "abc\203", 4) < 0, cnt
++);
1193 check(memcmp("abcf", "abcd", 3) == 0, cnt
++); /* Count limited. */
1194 check(memcmp("abc", "def", 0) == 0, cnt
++); /* Zero count. */
1195 /* Comparisons with shifting 4-byte boundaries. */
1196 for (int i
= 0; i
< 4; ++i
)
1200 memcpy(a
, "--------11112222", 16);
1201 memcpy(b
, "--------33334444", 16);
1202 check(memcmp(b
, a
, 16) > 0, cnt
++);
1203 check(memcmp(a
, b
, 16) < 0, cnt
++);
1211 check(memchr("abcd", 'z', 4) == NULL
, 1); /* Not found. */
1212 (void) strcpy(one
, "abcd");
1213 check(memchr(one
, 'c', 4) == one
+2, 2); /* Basic test. */
1214 check(memchr(one
, ~0xff|'c', 4) == one
+2, 2); /* ignore highorder bits. */
1215 check(memchr(one
, 'd', 4) == one
+3, 3); /* End of string. */
1216 check(memchr(one
, 'a', 4) == one
, 4); /* Beginning. */
1217 check(memchr(one
, '\0', 5) == one
+4, 5); /* Finding NUL. */
1218 (void) strcpy(one
, "ababa");
1219 check(memchr(one
, 'b', 5) == one
+1, 6); /* Finding first. */
1220 check(memchr(one
, 'b', 0) == NULL
, 7); /* Zero count. */
1221 check(memchr(one
, 'a', 1) == one
, 8); /* Singleton case. */
1222 (void) strcpy(one
, "a\203b");
1223 check(memchr(one
, 0203, 3) == one
+1, 9); /* Unsignedness. */
1225 /* now test all possible alignment and length combinations to catch
1226 bugs due to unrolled loops (assuming unrolling is limited to no
1227 more than 128 byte chunks: */
1229 char buf
[128 + sizeof(long)];
1230 long align
, len
, i
, pos
;
1232 for (align
= 0; align
< (long) sizeof(long); ++align
) {
1233 for (len
= 0; len
< (long) (sizeof(buf
) - align
); ++len
) {
1234 for (i
= 0; i
< len
; ++i
) {
1235 buf
[align
+ i
] = 'x'; /* don't depend on memset... */
1237 for (pos
= 0; pos
< len
; ++pos
) {
1239 printf("align %d, len %d, pos %d\n", align
, len
, pos
);
1241 check(memchr(buf
+ align
, 'x', len
) == buf
+ align
+ pos
, 10);
1242 check(memchr(buf
+ align
, 'x', pos
) == NULL
, 11);
1243 buf
[align
+ pos
] = '-';
1255 check(memcpy(one
, "abc", 4) == one
, 1); /* Returned value. */
1256 equal(one
, "abc", 2); /* Did the copy go right? */
1258 (void) strcpy(one
, "abcdefgh");
1259 (void) memcpy(one
+1, "xyz", 2);
1260 equal(one
, "axydefgh", 3); /* Basic test. */
1262 (void) strcpy(one
, "abc");
1263 (void) memcpy(one
, "xyz", 0);
1264 equal(one
, "abc", 4); /* Zero-length copy. */
1266 (void) strcpy(one
, "hi there");
1267 (void) strcpy(two
, "foo");
1268 (void) memcpy(two
, one
, 9);
1269 equal(two
, "hi there", 5); /* Just paranoia. */
1270 equal(one
, "hi there", 6); /* Stomped on source? */
1272 for (i
= 0; i
< 16; i
++)
1274 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1276 check (memcpy (one
+ i
, "hi there", 9) == one
+ i
,
1277 7 + (i
* 6)); /* Unaligned destination. */
1278 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1279 equal (one
+ i
, "hi there", 9 + (i
* 6));
1280 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1281 check (memcpy (two
, one
+ i
, 9) == two
,
1282 11 + (i
* 6)); /* Unaligned source. */
1283 equal (two
, "hi there", 12 + (i
* 6));
1292 check(mempcpy(one
, "abc", 4) == one
+ 4, 1); /* Returned value. */
1293 equal(one
, "abc", 2); /* Did the copy go right? */
1295 (void) strcpy(one
, "abcdefgh");
1296 (void) mempcpy(one
+1, "xyz", 2);
1297 equal(one
, "axydefgh", 3); /* Basic test. */
1299 (void) strcpy(one
, "abc");
1300 (void) mempcpy(one
, "xyz", 0);
1301 equal(one
, "abc", 4); /* Zero-length copy. */
1303 (void) strcpy(one
, "hi there");
1304 (void) strcpy(two
, "foo");
1305 (void) mempcpy(two
, one
, 9);
1306 equal(two
, "hi there", 5); /* Just paranoia. */
1307 equal(one
, "hi there", 6); /* Stomped on source? */
1309 for (i
= 0; i
< 16; i
++)
1311 const char *x
= "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1313 check (mempcpy (one
+ i
, "hi there", 9) == one
+ i
+ 9,
1314 7 + (i
* 6)); /* Unaligned destination. */
1315 check (memcmp (one
, x
, i
) == 0, 8 + (i
* 6)); /* Wrote under? */
1316 equal (one
+ i
, "hi there", 9 + (i
* 6));
1317 check (one
[i
+ 9] == 'x', 10 + (i
* 6)); /* Wrote over? */
1318 check (mempcpy (two
, one
+ i
, 9) == two
+ 9,
1319 11 + (i
* 6)); /* Unaligned source. */
1320 equal (two
, "hi there", 12 + (i
* 6));
1328 check(memmove(one
, "abc", 4) == one
, 1); /* Returned value. */
1329 equal(one
, "abc", 2); /* Did the copy go right? */
1331 (void) strcpy(one
, "abcdefgh");
1332 (void) memmove(one
+1, "xyz", 2);
1333 equal(one
, "axydefgh", 3); /* Basic test. */
1335 (void) strcpy(one
, "abc");
1336 (void) memmove(one
, "xyz", 0);
1337 equal(one
, "abc", 4); /* Zero-length copy. */
1339 (void) strcpy(one
, "hi there");
1340 (void) strcpy(two
, "foo");
1341 (void) memmove(two
, one
, 9);
1342 equal(two
, "hi there", 5); /* Just paranoia. */
1343 equal(one
, "hi there", 6); /* Stomped on source? */
1345 (void) strcpy(one
, "abcdefgh");
1346 (void) memmove(one
+1, one
, 9);
1347 equal(one
, "aabcdefgh", 7); /* Overlap, right-to-left. */
1349 (void) strcpy(one
, "abcdefgh");
1350 (void) memmove(one
+1, one
+2, 7);
1351 equal(one
, "acdefgh", 8); /* Overlap, left-to-right. */
1353 (void) strcpy(one
, "abcdefgh");
1354 (void) memmove(one
, one
, 9);
1355 equal(one
, "abcdefgh", 9); /* 100% overlap. */
1361 /* First test like memcpy, then the search part The SVID, the only
1362 place where memccpy is mentioned, says overlap might fail, so we
1363 don't try it. Besides, it's hard to see the rationale for a
1364 non-left-to-right memccpy. */
1366 check(memccpy(one
, "abc", 'q', 4) == NULL
, 1); /* Returned value. */
1367 equal(one
, "abc", 2); /* Did the copy go right? */
1369 (void) strcpy(one
, "abcdefgh");
1370 (void) memccpy(one
+1, "xyz", 'q', 2);
1371 equal(one
, "axydefgh", 3); /* Basic test. */
1373 (void) strcpy(one
, "abc");
1374 (void) memccpy(one
, "xyz", 'q', 0);
1375 equal(one
, "abc", 4); /* Zero-length copy. */
1377 (void) strcpy(one
, "hi there");
1378 (void) strcpy(two
, "foo");
1379 (void) memccpy(two
, one
, 'q', 9);
1380 equal(two
, "hi there", 5); /* Just paranoia. */
1381 equal(one
, "hi there", 6); /* Stomped on source? */
1383 (void) strcpy(one
, "abcdefgh");
1384 (void) strcpy(two
, "horsefeathers");
1385 check(memccpy(two
, one
, 'f', 9) == two
+6, 7); /* Returned value. */
1386 equal(one
, "abcdefgh", 8); /* Source intact? */
1387 equal(two
, "abcdefeathers", 9); /* Copy correct? */
1389 (void) strcpy(one
, "abcd");
1390 (void) strcpy(two
, "bumblebee");
1391 check(memccpy(two
, one
, 'a', 4) == two
+1, 10); /* First char. */
1392 equal(two
, "aumblebee", 11);
1393 check(memccpy(two
, one
, 'd', 4) == two
+4, 12); /* Last char. */
1394 equal(two
, "abcdlebee", 13);
1395 (void) strcpy(one
, "xyz");
1396 check(memccpy(two
, one
, 'x', 1) == two
+1, 14); /* Singleton. */
1397 equal(two
, "xbcdlebee", 15);
1406 (void) strcpy(one
, "abcdefgh");
1407 check(memset(one
+1, 'x', 3) == one
+1, 1); /* Return value. */
1408 equal(one
, "axxxefgh", 2); /* Basic test. */
1410 DIAG_PUSH_NEEDS_COMMENT
;
1411 #if __GNUC_PREREQ (5, 0)
1412 /* GCC 5.0 warns about a zero-length memset because the arguments to memset
1413 may be in the wrong order. But we really want to test this. */
1414 DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args")
1416 (void) memset(one
+2, 'y', 0);
1417 equal(one
, "axxxefgh", 3); /* Zero-length set. */
1418 DIAG_POP_NEEDS_COMMENT
;
1420 (void) memset(one
+5, 0, 1);
1421 equal(one
, "axxxe", 4); /* Zero fill. */
1422 equal(one
+6, "gh", 5); /* And the leftover. */
1424 (void) memset(one
+2, 010045, 1);
1425 equal(one
, "ax\045xe", 6); /* Unsigned char convert. */
1427 /* Non-8bit fill character. */
1428 memset (one
, 0x101, sizeof (one
));
1429 for (i
= 0; i
< (int) sizeof (one
); ++i
)
1430 check (one
[i
] == '\01', 7);
1432 /* Test for more complex versions of memset, for all alignments and
1433 lengths up to 256. This test takes a little while, perhaps it should
1441 for (i
= 0; i
< 512; i
++)
1443 for (c
= 0; c
<= 'y'; c
+= 'y') /* check for memset(,0,) and
1445 for (j
= 0; j
< 256; j
++)
1446 for (i
= 0; i
< 256; i
++)
1448 memset (data
+ i
, c
, j
);
1449 for (k
= 0; k
< i
; k
++)
1452 for (k
= i
; k
< i
+j
; k
++)
1458 for (k
= i
+j
; k
< 512; k
++)
1464 check (0, 8 + i
+ j
* 256 + (c
!= 0) * 256 * 256);
1472 /* Much like memcpy. Berklix manual is silent about overlap, so
1475 (void) bcopy("abc", one
, 4);
1476 equal(one
, "abc", 1); /* Simple copy. */
1478 (void) strcpy(one
, "abcdefgh");
1479 (void) bcopy("xyz", one
+1, 2);
1480 equal(one
, "axydefgh", 2); /* Basic test. */
1482 (void) strcpy(one
, "abc");
1483 (void) bcopy("xyz", one
, 0);
1484 equal(one
, "abc", 3); /* Zero-length copy. */
1486 (void) strcpy(one
, "hi there");
1487 (void) strcpy(two
, "foo");
1488 (void) bcopy(one
, two
, 9);
1489 equal(two
, "hi there", 4); /* Just paranoia. */
1490 equal(one
, "hi there", 5); /* Stomped on source? */
1497 (void) strcpy(one
, "abcdef");
1499 equal(one
, "ab", 1); /* Basic test. */
1500 equal(one
+3, "", 2);
1501 equal(one
+4, "ef", 3);
1503 (void) strcpy(one
, "abcdef");
1505 equal(one
, "abcdef", 4); /* Zero-length copy. */
1513 p
= strndup("abcdef", 12);
1514 check(p
!= NULL
, 1);
1517 equal(p
, "abcdef", 2);
1518 q
= strndup(p
+ 1, 2);
1519 check(q
!= NULL
, 3);
1525 p
= strndup("abc def", 3);
1526 check(p
!= NULL
, 5);
1536 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1537 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1538 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1539 check(bcmp("abce", "abcd", 4) != 0, 4);
1540 check(bcmp("alph", "beta", 4) != 0, 5);
1541 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1542 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1546 test_strerror (void)
1549 check(strerror(EDOM
) != 0, 1);
1550 check(strerror(ERANGE
) != 0, 2);
1551 check(strerror(ENOENT
) != 0, 3);
1555 test_strcasecmp (void)
1558 /* Note that the locale is "C". */
1559 check(strcasecmp("a", "a") == 0, 1);
1560 check(strcasecmp("a", "A") == 0, 2);
1561 check(strcasecmp("A", "a") == 0, 3);
1562 check(strcasecmp("a", "b") < 0, 4);
1563 check(strcasecmp("c", "b") > 0, 5);
1564 check(strcasecmp("abc", "AbC") == 0, 6);
1565 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1566 check(strcasecmp("", "0123456789") < 0, 8);
1567 check(strcasecmp("AbC", "") > 0, 9);
1568 check(strcasecmp("AbC", "A") > 0, 10);
1569 check(strcasecmp("AbC", "Ab") > 0, 11);
1570 check(strcasecmp("AbC", "ab") > 0, 12);
1574 test_strncasecmp (void)
1577 /* Note that the locale is "C". */
1578 check(strncasecmp("a", "a", 5) == 0, 1);
1579 check(strncasecmp("a", "A", 5) == 0, 2);
1580 check(strncasecmp("A", "a", 5) == 0, 3);
1581 check(strncasecmp("a", "b", 5) < 0, 4);
1582 check(strncasecmp("c", "b", 5) > 0, 5);
1583 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1584 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1585 check(strncasecmp("", "0123456789", 10) < 0, 8);
1586 check(strncasecmp("AbC", "", 5) > 0, 9);
1587 check(strncasecmp("AbC", "A", 5) > 0, 10);
1588 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1589 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1590 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1591 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1592 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1593 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1594 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1595 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1596 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1597 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1605 /* Test strcmp first because we use it to test other things. */
1608 /* Test strcpy next because we need it to set up other tests. */
1611 /* A closely related function is stpcpy. */
1644 /* index - just like strchr. */
1653 /* rindex - just like strrchr. */
1656 /* strpbrk - somewhat like strchr. */
1659 /* strstr - somewhat like strchr. */
1668 /* strtok - the hard one. */
1683 /* memcpy - need not work for overlap. */
1686 /* memmove - must work on overlap. */
1704 /* bcmp - somewhat like memcmp. */
1710 /* strerror - VERY system-dependent. */
1713 /* strcasecmp. Without locale dependencies. */
1716 /* strncasecmp. Without locale dependencies. */
1717 test_strncasecmp ();
1721 status
= EXIT_SUCCESS
;
1726 status
= EXIT_FAILURE
;
1727 printf("%Zd errors.\n", errors
);