Warning: That file was not part of the compilation database. It may have many parsing errors.

1/* Tester for string functions.
2 Copyright (C) 1995-2019 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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/>. */
18
19#ifndef _GNU_SOURCE
20#define _GNU_SOURCE
21#endif
22
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
27#endif
28
29#include <errno.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <strings.h>
34#include <fcntl.h>
35#include <libc-diag.h>
36
37
38#define STREQ(a, b) (strcmp((a), (b)) == 0)
39
40const char *it = "<UNSET>"; /* Routine name for message routines. */
41size_t errors = 0;
42
43/* Complain if condition is not true. */
44static void
45check (int thing, int number)
46{
47 if (!thing)
48 {
49 printf ("%s flunked test %d\n", it, number);
50 ++errors;
51 }
52}
53
54/* Complain if first two args don't strcmp as equal. */
55static void
56equal (const char *a, const char *b, int number)
57{
58 check (a != NULL && b != NULL && STREQ (a, b), number);
59}
60
61char one[50];
62char two[50];
63char *cp;
64
65static void
66test_strcmp (void)
67{
68 it = "strcmp";
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);
78
79 {
80 char buf1[0x40], buf2[0x40];
81 int i, j;
82 for (i=0; i < 0x10; i++)
83 for (j = 0; j < 0x10; j++)
84 {
85 int k;
86 for (k = 0; k < 0x3f; k++)
87 {
88 buf1[k] = '0' ^ (k & 4);
89 buf2[k] = '4' ^ (k & 4);
90 }
91 buf1[i] = buf1[0x3f] = 0;
92 buf2[j] = buf2[0x3f] = 0;
93 for (k = 0; k < 0xf; k++)
94 {
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;
98 buf1[i+k+1] = 0;
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;
102 buf2[j+k+1] = 0;
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);
109 buf1[i] = 'A' + i;
110 }
111 }
112 }
113}
114
115#define SIMPLE_COPY(fn, n, str, ntest) \
116 do { \
117 int __n; \
118 char *cp; \
119 for (__n = 0; __n < (int) sizeof (one); ++__n) \
120 one[__n] = 'Z'; \
121 fn (one, str); \
122 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
123 check (*cp == '0' + (n % 10), ntest); \
124 check (*cp == '\0', ntest); \
125 } while (0)
126
127static void
128test_strcpy (void)
129{
130 int i;
131 it = "strcpy";
132 check (strcpy (one, "abcd") == one, 1); /* Returned value. */
133 equal (one, "abcd", 2); /* Basic test. */
134
135 (void) strcpy (one, "x");
136 equal (one, "x", 3); /* Writeover. */
137 equal (one+2, "cd", 4); /* Wrote too much? */
138
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? */
143
144 (void) strcpy (one, "");
145 equal (one, "", 7); /* Boundary condition. */
146
147 for (i = 0; i < 16; i++)
148 {
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));
153 }
154
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);
172
173 /* Simple test using implicitly coerced `void *' arguments. */
174 const void *src = "frobozz";
175 void *dst = one;
176 check (strcpy (dst, src) == dst, 1);
177 equal (dst, "frobozz", 2);
178}
179
180static void
181test_stpcpy (void)
182{
183 it = "stpcpy";
184 check ((stpcpy (one, "a") - one) == 1, 1);
185 equal (one, "a", 2);
186
187 check ((stpcpy (one, "ab") - one) == 2, 3);
188 equal (one, "ab", 4);
189
190 check ((stpcpy (one, "abc") - one) == 3, 5);
191 equal (one, "abc", 6);
192
193 check ((stpcpy (one, "abcd") - one) == 4, 7);
194 equal (one, "abcd", 8);
195
196 check ((stpcpy (one, "abcde") - one) == 5, 9);
197 equal (one, "abcde", 10);
198
199 check ((stpcpy (one, "abcdef") - one) == 6, 11);
200 equal (one, "abcdef", 12);
201
202 check ((stpcpy (one, "abcdefg") - one) == 7, 13);
203 equal (one, "abcdefg", 14);
204
205 check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
206 equal (one, "abcdefgh", 16);
207
208 check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
209 equal (one, "abcdefghi", 18);
210
211 check ((stpcpy (one, "x") - one) == 1, 19);
212 equal (one, "x", 20); /* Writeover. */
213 equal (one+2, "cdefghi", 21); /* Wrote too much? */
214
215 check ((stpcpy (one, "xx") - one) == 2, 22);
216 equal (one, "xx", 23); /* Writeover. */
217 equal (one+3, "defghi", 24); /* Wrote too much? */
218
219 check ((stpcpy (one, "xxx") - one) == 3, 25);
220 equal (one, "xxx", 26); /* Writeover. */
221 equal (one+4, "efghi", 27); /* Wrote too much? */
222
223 check ((stpcpy (one, "xxxx") - one) == 4, 28);
224 equal (one, "xxxx", 29); /* Writeover. */
225 equal (one+5, "fghi", 30); /* Wrote too much? */
226
227 check ((stpcpy (one, "xxxxx") - one) == 5, 31);
228 equal (one, "xxxxx", 32); /* Writeover. */
229 equal (one+6, "ghi", 33); /* Wrote too much? */
230
231 check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
232 equal (one, "xxxxxx", 35); /* Writeover. */
233 equal (one+7, "hi", 36); /* Wrote too much? */
234
235 check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
236 equal (one, "xxxxxxx", 38); /* Writeover. */
237 equal (one+8, "i", 39); /* Wrote too much? */
238
239 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
240 equal (one, "abc", 41);
241 equal (one + 4, "xxx", 42);
242
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);
260}
261
262static void
263test_stpncpy (void)
264{
265 it = "stpncpy";
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
270 tested here. */
271 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
272#endif
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);
282}
283
284static void
285test_strcat (void)
286{
287 it = "strcat";
288 (void) strcpy (one, "ijk");
289 check (strcat (one, "lmn") == one, 1); /* Returned value. */
290 equal (one, "ijklmn", 2); /* Basic test. */
291
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? */
296
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? */
302
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);
312
313 int ntest = 10;
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)
319 {
320 size_t olderrors = errors;
321
322 memset (buf1, 'b', sizeof (buf1));
323
324 memset (buf1 + n2, 'a', n3);
325 buf1[n2 + n3] = '\0';
326 strcpy (buf2 + n1, "123");
327
328 check (strcat (buf1 + n2, buf2 + n1) == buf1 + n2, ntest);
329 if (errors == olderrors)
330 for (size_t i = 0; i < sizeof (buf1); ++i)
331 {
332 if (i < n2)
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);
340 else
341 check (buf1[i] == 'b', ntest);
342
343 if (errors != olderrors)
344 {
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');
350 break;
351 }
352 }
353 }
354}
355
356static void
357test_strncat (void)
358{
359 /* First test it as strcat, with big counts, then test the count
360 mechanism. */
361 it = "strncat";
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=");
368#endif
369 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
370 DIAG_POP_NEEDS_COMMENT;
371 equal (one, "ijklmn", 2); /* Basic test. */
372
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=");
379#endif
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? */
384
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=");
393#endif
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? */
399
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=");
406#endif
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=");
416#endif
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=");
426#endif
427 (void) strncat (one, "cd", 99);
428 DIAG_POP_NEEDS_COMMENT;
429 equal (one, "cd", 9);
430
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
435 tested here. */
436 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
437#endif
438 (void) strncat (one, "cdef", 2);
439 DIAG_POP_NEEDS_COMMENT;
440 equal (one, "abcd", 10); /* Count-limited. */
441
442 (void) strncat (one, "gh", 0);
443 equal (one, "abcd", 11); /* Zero count. */
444
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=");
450#endif
451 (void) strncat (one, "gh", 2);
452 DIAG_POP_NEEDS_COMMENT;
453 equal (one, "abcdgh", 12); /* Count and length equal. */
454
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=");
460#endif
461 (void) strncat (one, "ij", (size_t)-1); /* set sign bit in count */
462 DIAG_POP_NEEDS_COMMENT;
463 equal (one, "abcdghij", 13);
464
465 int ntest = 14;
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)
472 {
473 size_t olderrors = errors;
474
475 memset (buf1, 'b', sizeof (buf1));
476
477 memset (buf1 + n2, 'a', n3);
478 buf1[n2 + n3] = '\0';
479 strcpy (buf2 + n1, "123");
480
481 DIAG_PUSH_NEEDS_COMMENT;
482#if __GNUC_PREREQ (7, 0)
483 /* GCC 7 warns about the size passed to strncat being
484 larger than the size of the buffer; this is
485 deliberately tested here; GCC 8 gives a -Warray-bounds
486 warning about this. */
487 DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
488 /* GCC 9 as of 2018-06-14 warns that the size passed is
489 large enough that, if it were the actual object size,
490 the objects would have to overlap. */
491 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wrestrict");
492#endif
493 DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
494 check (strncat (buf1 + n2, buf2 + n1, ~((size_t) 0) - n4)
495 == buf1 + n2, ntest);
496 DIAG_POP_NEEDS_COMMENT;
497 if (errors == olderrors)
498 for (size_t i = 0; i < sizeof (buf1); ++i)
499 {
500 if (i < n2)
501 check (buf1[i] == 'b', ntest);
502 else if (i < n2 + n3)
503 check (buf1[i] == 'a', ntest);
504 else if (i < n2 + n3 + 3)
505 check (buf1[i] == "123"[i - (n2 + n3)], ntest);
506 else if (i == n2 + n3 + 3)
507 check (buf1[i] == '\0', ntest);
508 else
509 check (buf1[i] == 'b', ntest);
510
511 if (errors != olderrors)
512 {
513 printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
514 n1, n2, n3, n4, buf1[0]);
515 for (size_t j = 1; j < sizeof (buf1); ++j)
516 printf (",%02hhx", buf1[j]);
517 putchar_unlocked ('\n');
518 break;
519 }
520 }
521 }
522}
523
524static void
525test_strncmp (void)
526{
527 /* First test as strcmp with big counts, then test count code. */
528 it = "strncmp";
529 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
530 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
531 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
532 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
533 check (strncmp ("abcd", "abc", 99) > 0, 5);
534 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
535 check (strncmp ("abce", "abcd", 99) > 0, 7);
536 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
537 check (strncmp ("a\203", "a\003", 2) > 0, 9);
538 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
539 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
540 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
541 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
542 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
543 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
544}
545
546static void
547test_strncpy (void)
548{
549 /* Testing is a bit different because of odd semantics. */
550 it = "strncpy";
551 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
552 equal (one, "abc", 2); /* Did the copy go right? */
553
554 (void) strcpy (one, "abcdefgh");
555 DIAG_PUSH_NEEDS_COMMENT;
556#if __GNUC_PREREQ (8, 0)
557 /* GCC 8 warns about strncpy truncating output; this is deliberately
558 tested here. */
559 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
560#endif
561 (void) strncpy (one, "xyz", 2);
562 DIAG_POP_NEEDS_COMMENT;
563 equal (one, "xycdefgh", 3); /* Copy cut by count. */
564
565 (void) strcpy (one, "abcdefgh");
566 DIAG_PUSH_NEEDS_COMMENT;
567#if __GNUC_PREREQ (8, 0)
568 /* GCC 8 warns about strncpy truncating output; this is deliberately
569 tested here. */
570 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
571#endif
572 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
573 DIAG_POP_NEEDS_COMMENT;
574 equal (one, "xyzdefgh", 4);
575
576 (void) strcpy (one, "abcdefgh");
577 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
578 equal (one, "xyz", 5);
579 equal (one+4, "efgh", 6); /* Wrote too much? */
580
581 (void) strcpy (one, "abcdefgh");
582 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
583 equal (one, "xyz", 7);
584 equal (one+4, "", 8);
585 equal (one+5, "fgh", 9);
586
587 (void) strcpy (one, "abc");
588 DIAG_PUSH_NEEDS_COMMENT;
589#if __GNUC_PREREQ (8, 0)
590 /* GCC 8 warns about strncpy truncating output; this is deliberately
591 tested here. */
592 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
593#endif
594 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
595 DIAG_POP_NEEDS_COMMENT;
596 equal (one, "abc", 10);
597
598 (void) strncpy (one, "", 2); /* Zero-length source. */
599 equal (one, "", 11);
600 equal (one+1, "", 12);
601 equal (one+2, "c", 13);
602
603 (void) strcpy (one, "hi there");
604 (void) strncpy (two, one, 9);
605 equal (two, "hi there", 14); /* Just paranoia. */
606 equal (one, "hi there", 15); /* Stomped on source? */
607}
608
609static void
610test_strlen (void)
611{
612 it = "strlen";
613 check (strlen ("") == 0, 1); /* Empty. */
614 check (strlen ("a") == 1, 2); /* Single char. */
615 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
616 {
617 char buf[4096];
618 int i;
619 char *p;
620 for (i=0; i < 0x100; i++)
621 {
622 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
623 strcpy (p, "OK");
624 strcpy (p+3, "BAD/WRONG");
625 check (strlen (p) == 2, 4+i);
626 }
627 }
628}
629
630static void
631test_strnlen (void)
632{
633 it = "strnlen";
634 check (strnlen ("", 10) == 0, 1); /* Empty. */
635 check (strnlen ("a", 10) == 1, 2); /* Single char. */
636 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
637 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
638 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
639 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
640 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
641 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
642 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
643
644 char buf[4096];
645 for (int i = 0; i < 0x100; ++i)
646 {
647 char *p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
648 strcpy (p, "OK");
649 strcpy (p + 3, "BAD/WRONG");
650 check (strnlen (p, 100) == 2, 10 + i);
651 }
652}
653
654static void
655test_strchr (void)
656{
657 it = "strchr";
658 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
659 (void) strcpy (one, "abcd");
660 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
661 check (strchr (one, 'd') == one+3, 3); /* End of string. */
662 check (strchr (one, 'a') == one, 4); /* Beginning. */
663 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
664 (void) strcpy (one, "ababa");
665 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
666 (void) strcpy (one, "");
667 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
668 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
669 {
670 char buf[4096];
671 int i;
672 char *p;
673 for (i=0; i < 0x100; i++)
674 {
675 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
676 strcpy (p, "OK");
677 strcpy (p+3, "BAD/WRONG");
678 check (strchr (p, '/') == NULL, 9+i);
679 }
680 }
681}
682
683static void
684test_strchrnul (void)
685{
686 const char *os;
687 it = "strchrnul";
688 cp = strchrnul ((os = "abcd"), 'z');
689 check (*cp == '\0', 1); /* Not found. */
690 check (cp == os + 4, 2);
691 (void) strcpy (one, "abcd");
692 check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */
693 check (strchrnul (one, 'd') == one+3, 4); /* End of string. */
694 check (strchrnul (one, 'a') == one, 5); /* Beginning. */
695 check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */
696 (void) strcpy (one, "ababa");
697 check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */
698 (void) strcpy (one, "");
699 check (strchrnul (one, 'b') == one, 8); /* Empty string. */
700 check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */
701 {
702 char buf[4096];
703 int i;
704 char *p;
705 for (i=0; i < 0x100; i++)
706 {
707 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
708 strcpy (p, "OK");
709 strcpy (p+3, "BAD/WRONG");
710 cp = strchrnul (p, '/');
711 check (*cp == '\0', 9+2*i);
712 check (cp == p+2, 10+2*i);
713 }
714 }
715}
716
717static void
718test_rawmemchr (void)
719{
720 it = "rawmemchr";
721 (void) strcpy (one, "abcd");
722 check (rawmemchr (one, 'c') == one+2, 1); /* Basic test. */
723 check (rawmemchr (one, 'd') == one+3, 2); /* End of string. */
724 check (rawmemchr (one, 'a') == one, 3); /* Beginning. */
725 check (rawmemchr (one, '\0') == one+4, 4); /* Finding NUL. */
726 (void) strcpy (one, "ababa");
727 check (rawmemchr (one, 'b') == one+1, 5); /* Finding first. */
728 (void) strcpy (one, "");
729 check (rawmemchr (one, '\0') == one, 6); /* NUL in empty string. */
730 {
731 char buf[4096];
732 int i;
733 char *p;
734 for (i=0; i < 0x100; i++)
735 {
736 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
737 strcpy (p, "OK");
738 strcpy (p+3, "BAD/WRONG");
739 check (rawmemchr (p, 'R') == p+8, 6+i);
740 }
741 }
742}
743
744static void
745test_index (void)
746{
747 it = "index";
748 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
749 (void) strcpy (one, "abcd");
750 check (index (one, 'c') == one+2, 2); /* Basic test. */
751 check (index (one, 'd') == one+3, 3); /* End of string. */
752 check (index (one, 'a') == one, 4); /* Beginning. */
753 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
754 (void) strcpy (one, "ababa");
755 check (index (one, 'b') == one+1, 6); /* Finding first. */
756 (void) strcpy (one, "");
757 check (index (one, 'b') == NULL, 7); /* Empty string. */
758 check (index (one, '\0') == one, 8); /* NUL in empty string. */
759}
760
761static void
762test_strrchr (void)
763{
764 it = "strrchr";
765 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
766 (void) strcpy (one, "abcd");
767 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
768 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
769 check (strrchr (one, 'a') == one, 4); /* Beginning. */
770 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
771 (void) strcpy (one, "ababa");
772 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
773 (void) strcpy (one, "");
774 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
775 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
776 {
777 char buf[4096];
778 int i;
779 char *p;
780 for (i=0; i < 0x100; i++)
781 {
782 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
783 strcpy (p, "OK");
784 strcpy (p+3, "BAD/WRONG");
785 check (strrchr (p, '/') == NULL, 9+i);
786 }
787 }
788}
789
790static void
791test_memrchr (void)
792{
793 size_t l;
794 it = "memrchr";
795 check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */
796 (void) strcpy (one, "abcd");
797 l = strlen (one) + 1;
798 check (memrchr (one, 'c', l) == one+2, 2); /* Basic test. */
799 check (memrchr (one, 'd', l) == one+3, 3); /* End of string. */
800 check (memrchr (one, 'a', l) == one, 4); /* Beginning. */
801 check (memrchr (one, '\0', l) == one+4, 5); /* Finding NUL. */
802 (void) strcpy (one, "ababa");
803 l = strlen (one) + 1;
804 check (memrchr (one, 'b', l) == one+3, 6); /* Finding last. */
805 (void) strcpy (one, "");
806 l = strlen (one) + 1;
807 check (memrchr (one, 'b', l) == NULL, 7); /* Empty string. */
808 check (memrchr (one, '\0', l) == one, 8); /* NUL in empty string. */
809
810 /* now test all possible alignment and length combinations to catch
811 bugs due to unrolled loops (assuming unrolling is limited to no
812 more than 128 byte chunks: */
813 {
814 char buf[128 + sizeof (long)];
815 long align, len, i, pos, n = 9;
816
817 for (align = 0; align < (long) sizeof (long); ++align) {
818 for (len = 0; len < (long) (sizeof (buf) - align); ++len) {
819 for (i = 0; i < len; ++i)
820 buf[align + i] = 'x'; /* don't depend on memset... */
821
822 for (pos = len - 1; pos >= 0; --pos) {
823#if 0
824 printf("align %d, len %d, pos %d\n", align, len, pos);
825#endif
826 check(memrchr(buf + align, 'x', len) == buf + align + pos, n++);
827 check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
828 n++);
829 buf[align + pos] = '-';
830 }
831 }
832 }
833 }
834}
835
836static void
837test_rindex (void)
838{
839 it = "rindex";
840 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
841 (void) strcpy (one, "abcd");
842 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
843 check (rindex (one, 'd') == one+3, 3); /* End of string. */
844 check (rindex (one, 'a') == one, 4); /* Beginning. */
845 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
846 (void) strcpy (one, "ababa");
847 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
848 (void) strcpy (one, "");
849 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
850 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
851}
852
853static void
854test_strpbrk (void)
855{
856 it = "strpbrk";
857 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
858 (void) strcpy(one, "abcd");
859 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
860 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
861 check(strpbrk(one, "a") == one, 4); /* Beginning. */
862 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
863 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
864 (void) strcpy(one, "abcabdea");
865 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
866 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
867 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
868 (void) strcpy(one, "");
869 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
870 (void) strcpy(one, "");
871 check(strpbrk(one, "bcd") == NULL, 11); /* Empty string. */
872 (void) strcpy(one, "");
873 check(strpbrk(one, "bcde") == NULL, 12); /* Empty string. */
874 check(strpbrk(one, "") == NULL, 13); /* Both strings empty. */
875 (void) strcpy(one, "abcabdea");
876 check(strpbrk(one, "befg") == one+1, 14); /* Finding first. */
877 check(strpbrk(one, "cbr") == one+1, 15); /* With multiple search. */
878 check(strpbrk(one, "db") == one+1, 16); /* Another variant. */
879 check(strpbrk(one, "efgh") == one+6, 17); /* And yet another. */
880}
881
882static void
883test_strstr (void)
884{
885 it = "strstr";
886 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
887 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
888 (void) strcpy(one, "abcd");
889 check(strstr(one, "c") == one+2, 3); /* Basic test. */
890 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
891 check(strstr(one, "d") == one+3, 5); /* End of string. */
892 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
893 check(strstr(one, "abc") == one, 7); /* Beginning. */
894 check(strstr(one, "abcd") == one, 8); /* Exact match. */
895 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
896 check(strstr(one, "de") == NULL, 10); /* Past end. */
897 check(strstr(one, "") == one, 11); /* Finding empty. */
898 (void) strcpy(one, "ababa");
899 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
900 (void) strcpy(one, "");
901 check(strstr(one, "b") == NULL, 13); /* Empty string. */
902 check(strstr(one, "") == one, 14); /* Empty in empty string. */
903 (void) strcpy(one, "bcbca");
904 check(strstr(one, "bca") == one+2, 15); /* False start. */
905 (void) strcpy(one, "bbbcabbca");
906 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
907}
908
909static void
910test_strspn (void)
911{
912 it = "strspn";
913 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
914 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
915 check(strspn("abc", "qx") == 0, 3); /* None. */
916 check(strspn("", "ab") == 0, 4); /* Null string. */
917 check(strspn("abc", "") == 0, 5); /* Null search list. */
918}
919
920static void
921test_strcspn (void)
922{
923 it = "strcspn";
924 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
925 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
926 check(strcspn("abc", "abc") == 0, 3); /* None. */
927 check(strcspn("", "ab") == 0, 4); /* Null string. */
928 check(strcspn("abc", "") == 3, 5); /* Null search list. */
929}
930
931static void
932test_strtok (void)
933{
934 it = "strtok";
935 (void) strcpy(one, "first, second, third");
936 equal(strtok(one, ", "), "first", 1); /* Basic test. */
937 equal(one, "first", 2);
938 equal(strtok((char *)NULL, ", "), "second", 3);
939 equal(strtok((char *)NULL, ", "), "third", 4);
940 check(strtok((char *)NULL, ", ") == NULL, 5);
941 (void) strcpy(one, ", first, ");
942 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
943 check(strtok((char *)NULL, ", ") == NULL, 7);
944 (void) strcpy(one, "1a, 1b; 2a, 2b");
945 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
946 equal(strtok((char *)NULL, "; "), "1b", 9);
947 equal(strtok((char *)NULL, ", "), "2a", 10);
948 (void) strcpy(two, "x-y");
949 equal(strtok(two, "-"), "x", 11); /* New string before done. */
950 equal(strtok((char *)NULL, "-"), "y", 12);
951 check(strtok((char *)NULL, "-") == NULL, 13);
952 (void) strcpy(one, "a,b, c,, ,d");
953 equal(strtok(one, ", "), "a", 14); /* Different separators. */
954 equal(strtok((char *)NULL, ", "), "b", 15);
955 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
956 equal(strtok((char *)NULL, " ,"), "d", 17);
957 check(strtok((char *)NULL, ", ") == NULL, 18);
958 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
959 (void) strcpy(one, ", ");
960 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
961 (void) strcpy(one, "");
962 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
963 (void) strcpy(one, "abc");
964 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
965 check(strtok((char *)NULL, ", ") == NULL, 23);
966 (void) strcpy(one, "abc");
967 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
968 check(strtok((char *)NULL, "") == NULL, 25);
969 (void) strcpy(one, "abcdefgh");
970 (void) strcpy(one, "a,b,c");
971 equal(strtok(one, ","), "a", 26); /* Basics again... */
972 equal(strtok((char *)NULL, ","), "b", 27);
973 equal(strtok((char *)NULL, ","), "c", 28);
974 check(strtok((char *)NULL, ",") == NULL, 29);
975 equal(one+6, "gh", 30); /* Stomped past end? */
976 equal(one, "a", 31); /* Stomped old tokens? */
977 equal(one+2, "b", 32);
978 equal(one+4, "c", 33);
979}
980
981static void
982test_strtok_r (void)
983{
984 it = "strtok_r";
985 (void) strcpy(one, "first, second, third");
986 cp = NULL; /* Always initialize cp to make sure it doesn't point to some old data. */
987 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
988 equal(one, "first", 2);
989 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
990 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
991 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
992 (void) strcpy(one, ", first, ");
993 cp = NULL;
994 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
995 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
996 (void) strcpy(one, "1a, 1b; 2a, 2b");
997 cp = NULL;
998 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
999 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
1000 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
1001 (void) strcpy(two, "x-y");
1002 cp = NULL;
1003 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
1004 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
1005 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
1006 (void) strcpy(one, "a,b, c,, ,d");
1007 cp = NULL;
1008 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
1009 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
1010 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
1011 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
1012 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
1013 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
1014 (void) strcpy(one, ", ");
1015 cp = NULL;
1016 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
1017 (void) strcpy(one, "");
1018 cp = NULL;
1019 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
1020 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22); /* Persistence. */
1021 (void) strcpy(one, "abc");
1022 cp = NULL;
1023 equal(strtok_r(one, ", ", &cp), "abc", 23); /* No delimiters. */
1024 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
1025 (void) strcpy(one, "abc");
1026 cp = NULL;
1027 equal(strtok_r(one, "", &cp), "abc", 25); /* Empty delimiter list. */
1028 check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
1029 (void) strcpy(one, "abcdefgh");
1030 (void) strcpy(one, "a,b,c");
1031 cp = NULL;
1032 equal(strtok_r(one, ",", &cp), "a", 27); /* Basics again... */
1033 equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
1034 equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
1035 check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
1036 equal(one+6, "gh", 31); /* Stomped past end? */
1037 equal(one, "a", 32); /* Stomped old tokens? */
1038 equal(one+2, "b", 33);
1039 equal(one+4, "c", 34);
1040 strcpy (one, ":::");
1041 cp = NULL;
1042 check (strtok_r (one, ":", &cp) == NULL, 35); /* Must store pointer in cp. */
1043 check (strtok_r (NULL, ":", &cp) == NULL, 36);
1044}
1045
1046static void
1047test_strsep (void)
1048{
1049 char *ptr;
1050 it = "strsep";
1051 cp = strcpy(one, "first, second, third");
1052 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
1053 equal(one, "first", 2);
1054 equal(strsep(&cp, ", "), "", 3);
1055 equal(strsep(&cp, ", "), "second", 4);
1056 equal(strsep(&cp, ", "), "", 5);
1057 equal(strsep(&cp, ", "), "third", 6);
1058 check(strsep(&cp, ", ") == NULL, 7);
1059 cp = strcpy(one, ", first, ");
1060 equal(strsep(&cp, ", "), "", 8);
1061 equal(strsep(&cp, ", "), "", 9);
1062 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
1063 equal(strsep(&cp, ", "), "", 11);
1064 equal(strsep(&cp, ", "), "", 12);
1065 check(strsep(&cp, ", ") == NULL, 13);
1066 cp = strcpy(one, "1a, 1b; 2a, 2b");
1067 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */
1068 equal(strsep(&cp, ", "), "", 15);
1069 equal(strsep(&cp, "; "), "1b", 16);
1070 equal(strsep(&cp, ", "), "", 17);
1071 equal(strsep(&cp, ", "), "2a", 18);
1072 cp = strcpy(two, "x-y");
1073 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */
1074 equal(strsep(&cp, "-"), "y", 20);
1075 check(strsep(&cp, "-") == NULL, 21);
1076 cp = strcpy(one, "a,b, c,, ,d ");
1077 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */
1078 equal(strsep(&cp, ", "), "b", 23);
1079 equal(strsep(&cp, " ,"), "", 24);
1080 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */
1081 equal(strsep(&cp, " ,"), "", 26);
1082 equal(strsep(&cp, " ,"), "", 27);
1083 equal(strsep(&cp, " ,"), "", 28);
1084 equal(strsep(&cp, " ,"), "d", 29);
1085 equal(strsep(&cp, " ,"), "", 30);
1086 check(strsep(&cp, ", ") == NULL, 31);
1087 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
1088 cp = strcpy(one, ", ");
1089 equal(strsep(&cp, ", "), "", 33);
1090 equal(strsep(&cp, ", "), "", 34);
1091 equal(strsep(&cp, ", "), "", 35);
1092 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
1093 cp = strcpy(one, "");
1094 equal(strsep(&cp, ", "), "", 37);
1095 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
1096 cp = strcpy(one, "abc");
1097 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */
1098 check(strsep(&cp, ", ") == NULL, 40);
1099 cp = strcpy(one, "abc");
1100 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */
1101 check(strsep(&cp, "") == NULL, 42);
1102 (void) strcpy(one, "abcdefgh");
1103 cp = strcpy(one, "a,b,c");
1104 equal(strsep(&cp, ","), "a", 43); /* Basics again... */
1105 equal(strsep(&cp, ","), "b", 44);
1106 equal(strsep(&cp, ","), "c", 45);
1107 check(strsep(&cp, ",") == NULL, 46);
1108 equal(one+6, "gh", 47); /* Stomped past end? */
1109 equal(one, "a", 48); /* Stomped old tokens? */
1110 equal(one+2, "b", 49);
1111 equal(one+4, "c", 50);
1112
1113 {
1114 char text[] = "This,is,a,test";
1115 char *list = strdupa (text);
1116 equal (strsep (&list, ","), "This", 51);
1117 equal (strsep (&list, ","), "is", 52);
1118 equal (strsep (&list, ","), "a", 53);
1119 equal (strsep (&list, ","), "test", 54);
1120 check (strsep (&list, ",") == NULL, 55);
1121 }
1122
1123 cp = strcpy(one, "a,b, c,, ,d,");
1124 equal(strsep(&cp, ","), "a", 56); /* Different separators. */
1125 equal(strsep(&cp, ","), "b", 57);
1126 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */
1127 equal(strsep(&cp, ","), "", 59);
1128 equal(strsep(&cp, ","), " ", 60);
1129 equal(strsep(&cp, ","), "d", 61);
1130 equal(strsep(&cp, ","), "", 62);
1131 check(strsep(&cp, ",") == NULL, 63);
1132 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */
1133
1134 cp = strcpy(one, "a,b, c,, ,d,");
1135 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */
1136 equal(strsep(&cp, "x,y"), "b", 66);
1137 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */
1138 equal(strsep(&cp, "xy,"), "", 68);
1139 equal(strsep(&cp, "x,y"), " ", 69);
1140 equal(strsep(&cp, ",xy"), "d", 70);
1141 equal(strsep(&cp, "xy,"), "", 71);
1142 check(strsep(&cp, "x,y") == NULL, 72);
1143 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
1144
1145 cp = strcpy(one, "ABC");
1146 one[4] = ':';
1147 equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */
1148 ptr = strsep(&cp, ":");
1149 equal(ptr, "", 75);
1150 check(ptr == one + 3, 76);
1151 check(cp == NULL, 77);
1152
1153 cp = strcpy(one, "ABC");
1154 one[4] = ':';
1155 equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */
1156 ptr = strsep(&cp, ":.");
1157 equal(ptr, "", 79);
1158 check(ptr == one + 3, 80);
1159
1160 cp = strcpy(one, "ABC"); /* No token in string. */
1161 equal(strsep(&cp, ","), "ABC", 81);
1162 check(cp == NULL, 82);
1163
1164 *one = '\0'; /* Empty string. */
1165 cp = one;
1166 ptr = strsep(&cp, ",");
1167 equal(ptr, "", 83);
1168 check(ptr == one, 84);
1169 check(cp == NULL, 85);
1170
1171 *one = '\0'; /* Empty string and no token. */
1172 cp = one;
1173 ptr = strsep(&cp, "");
1174 equal(ptr, "", 86);
1175 check(ptr == one , 87);
1176 check(cp == NULL, 88);
1177}
1178
1179static void
1180test_memcmp (void)
1181{
1182 int cnt = 1;
1183 char one[21];
1184 char two[21];
1185
1186 it = "memcmp";
1187 check(memcmp("a", "a", 1) == 0, cnt++); /* Identity. */
1188 check(memcmp("abc", "abc", 3) == 0, cnt++); /* Multicharacter. */
1189 check(memcmp("abcd", "abcf", 4) < 0, cnt++); /* Honestly unequal. */
1190 check(memcmp("abcf", "abcd", 4) > 0, cnt++);
1191 check(memcmp("alph", "cold", 4) < 0, cnt++);
1192 check(memcmp("a\203", "a\003", 2) > 0, cnt++);
1193 check(memcmp("a\003", "a\203", 2) < 0, cnt++);
1194 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt++);
1195 check(memcmp("abc\203", "abc\003", 4) > 0, cnt++);
1196 check(memcmp("abc\003", "abc\203", 4) < 0, cnt++);
1197 check(memcmp("abcf", "abcd", 3) == 0, cnt++); /* Count limited. */
1198 check(memcmp("abc", "def", 0) == 0, cnt++); /* Zero count. */
1199 /* Comparisons with shifting 4-byte boundaries. */
1200 for (int i = 0; i < 4; ++i)
1201 {
1202 char *a = one + i;
1203 char *b = two + i;
1204 memcpy(a, "--------11112222", 16);
1205 memcpy(b, "--------33334444", 16);
1206 check(memcmp(b, a, 16) > 0, cnt++);
1207 check(memcmp(a, b, 16) < 0, cnt++);
1208 }
1209}
1210
1211static void
1212test_memchr (void)
1213{
1214 it = "memchr";
1215 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
1216 (void) strcpy(one, "abcd");
1217 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
1218 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
1219 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
1220 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
1221 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
1222 (void) strcpy(one, "ababa");
1223 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
1224 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
1225 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
1226 (void) strcpy(one, "a\203b");
1227 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
1228
1229 /* now test all possible alignment and length combinations to catch
1230 bugs due to unrolled loops (assuming unrolling is limited to no
1231 more than 128 byte chunks: */
1232 {
1233 char buf[128 + sizeof (long)];
1234 long align, len, i, pos;
1235
1236 for (align = 0; align < (long) sizeof (long); ++align) {
1237 for (len = 0; len < (long) (sizeof (buf) - align); ++len) {
1238 for (i = 0; i < len; ++i) {
1239 buf[align + i] = 'x'; /* don't depend on memset... */
1240 }
1241 for (pos = 0; pos < len; ++pos) {
1242#if 0
1243 printf("align %d, len %d, pos %d\n", align, len, pos);
1244#endif
1245 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
1246 check(memchr(buf + align, 'x', pos) == NULL, 11);
1247 buf[align + pos] = '-';
1248 }
1249 }
1250 }
1251 }
1252}
1253
1254static void
1255test_memcpy (void)
1256{
1257 int i;
1258 it = "memcpy";
1259 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
1260 equal(one, "abc", 2); /* Did the copy go right? */
1261
1262 (void) strcpy(one, "abcdefgh");
1263 (void) memcpy(one+1, "xyz", 2);
1264 equal(one, "axydefgh", 3); /* Basic test. */
1265
1266 (void) strcpy(one, "abc");
1267 (void) memcpy(one, "xyz", 0);
1268 equal(one, "abc", 4); /* Zero-length copy. */
1269
1270 (void) strcpy(one, "hi there");
1271 (void) strcpy(two, "foo");
1272 (void) memcpy(two, one, 9);
1273 equal(two, "hi there", 5); /* Just paranoia. */
1274 equal(one, "hi there", 6); /* Stomped on source? */
1275
1276 for (i = 0; i < 16; i++)
1277 {
1278 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1279 strcpy (one, x);
1280 check (memcpy (one + i, "hi there", 9) == one + i,
1281 7 + (i * 6)); /* Unaligned destination. */
1282 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1283 equal (one + i, "hi there", 9 + (i * 6));
1284 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1285 check (memcpy (two, one + i, 9) == two,
1286 11 + (i * 6)); /* Unaligned source. */
1287 equal (two, "hi there", 12 + (i * 6));
1288 }
1289}
1290
1291static void
1292test_mempcpy (void)
1293{
1294 int i;
1295 it = "mempcpy";
1296 check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */
1297 equal(one, "abc", 2); /* Did the copy go right? */
1298
1299 (void) strcpy(one, "abcdefgh");
1300 (void) mempcpy(one+1, "xyz", 2);
1301 equal(one, "axydefgh", 3); /* Basic test. */
1302
1303 (void) strcpy(one, "abc");
1304 (void) mempcpy(one, "xyz", 0);
1305 equal(one, "abc", 4); /* Zero-length copy. */
1306
1307 (void) strcpy(one, "hi there");
1308 (void) strcpy(two, "foo");
1309 (void) mempcpy(two, one, 9);
1310 equal(two, "hi there", 5); /* Just paranoia. */
1311 equal(one, "hi there", 6); /* Stomped on source? */
1312
1313 for (i = 0; i < 16; i++)
1314 {
1315 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1316 strcpy (one, x);
1317 check (mempcpy (one + i, "hi there", 9) == one + i + 9,
1318 7 + (i * 6)); /* Unaligned destination. */
1319 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1320 equal (one + i, "hi there", 9 + (i * 6));
1321 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1322 check (mempcpy (two, one + i, 9) == two + 9,
1323 11 + (i * 6)); /* Unaligned source. */
1324 equal (two, "hi there", 12 + (i * 6));
1325 }
1326}
1327
1328static void
1329test_memmove (void)
1330{
1331 it = "memmove";
1332 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
1333 equal(one, "abc", 2); /* Did the copy go right? */
1334
1335 (void) strcpy(one, "abcdefgh");
1336 (void) memmove(one+1, "xyz", 2);
1337 equal(one, "axydefgh", 3); /* Basic test. */
1338
1339 (void) strcpy(one, "abc");
1340 (void) memmove(one, "xyz", 0);
1341 equal(one, "abc", 4); /* Zero-length copy. */
1342
1343 (void) strcpy(one, "hi there");
1344 (void) strcpy(two, "foo");
1345 (void) memmove(two, one, 9);
1346 equal(two, "hi there", 5); /* Just paranoia. */
1347 equal(one, "hi there", 6); /* Stomped on source? */
1348
1349 (void) strcpy(one, "abcdefgh");
1350 (void) memmove(one+1, one, 9);
1351 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
1352
1353 (void) strcpy(one, "abcdefgh");
1354 (void) memmove(one+1, one+2, 7);
1355 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
1356
1357 (void) strcpy(one, "abcdefgh");
1358 (void) memmove(one, one, 9);
1359 equal(one, "abcdefgh", 9); /* 100% overlap. */
1360}
1361
1362static void
1363test_memccpy (void)
1364{
1365 /* First test like memcpy, then the search part The SVID, the only
1366 place where memccpy is mentioned, says overlap might fail, so we
1367 don't try it. Besides, it's hard to see the rationale for a
1368 non-left-to-right memccpy. */
1369 it = "memccpy";
1370 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
1371 equal(one, "abc", 2); /* Did the copy go right? */
1372
1373 (void) strcpy(one, "abcdefgh");
1374 (void) memccpy(one+1, "xyz", 'q', 2);
1375 equal(one, "axydefgh", 3); /* Basic test. */
1376
1377 (void) strcpy(one, "abc");
1378 (void) memccpy(one, "xyz", 'q', 0);
1379 equal(one, "abc", 4); /* Zero-length copy. */
1380
1381 (void) strcpy(one, "hi there");
1382 (void) strcpy(two, "foo");
1383 (void) memccpy(two, one, 'q', 9);
1384 equal(two, "hi there", 5); /* Just paranoia. */
1385 equal(one, "hi there", 6); /* Stomped on source? */
1386
1387 (void) strcpy(one, "abcdefgh");
1388 (void) strcpy(two, "horsefeathers");
1389 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
1390 equal(one, "abcdefgh", 8); /* Source intact? */
1391 equal(two, "abcdefeathers", 9); /* Copy correct? */
1392
1393 (void) strcpy(one, "abcd");
1394 (void) strcpy(two, "bumblebee");
1395 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
1396 equal(two, "aumblebee", 11);
1397 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
1398 equal(two, "abcdlebee", 13);
1399 (void) strcpy(one, "xyz");
1400 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
1401 equal(two, "xbcdlebee", 15);
1402}
1403
1404static void
1405test_memset (void)
1406{
1407 int i;
1408
1409 it = "memset";
1410 (void) strcpy(one, "abcdefgh");
1411 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
1412 equal(one, "axxxefgh", 2); /* Basic test. */
1413
1414 DIAG_PUSH_NEEDS_COMMENT;
1415#if __GNUC_PREREQ (5, 0)
1416 /* GCC 5.0 warns about a zero-length memset because the arguments to memset
1417 may be in the wrong order. But we really want to test this. */
1418 DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args")
1419#endif
1420 (void) memset(one+2, 'y', 0);
1421 equal(one, "axxxefgh", 3); /* Zero-length set. */
1422 DIAG_POP_NEEDS_COMMENT;
1423
1424 (void) memset(one+5, 0, 1);
1425 equal(one, "axxxe", 4); /* Zero fill. */
1426 equal(one+6, "gh", 5); /* And the leftover. */
1427
1428 (void) memset(one+2, 010045, 1);
1429 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
1430
1431 /* Non-8bit fill character. */
1432 memset (one, 0x101, sizeof (one));
1433 for (i = 0; i < (int) sizeof (one); ++i)
1434 check (one[i] == '\01', 7);
1435
1436 /* Test for more complex versions of memset, for all alignments and
1437 lengths up to 256. This test takes a little while, perhaps it should
1438 be made weaker? */
1439 {
1440 char data[512];
1441 int j;
1442 int k;
1443 int c;
1444
1445 for (i = 0; i < 512; i++)
1446 data[i] = 'x';
1447 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
1448 memset(,'y',) */
1449 for (j = 0; j < 256; j++)
1450 for (i = 0; i < 256; i++)
1451 {
1452 memset (data + i, c, j);
1453 for (k = 0; k < i; k++)
1454 if (data[k] != 'x')
1455 goto fail;
1456 for (k = i; k < i+j; k++)
1457 {
1458 if (data[k] != c)
1459 goto fail;
1460 data[k] = 'x';
1461 }
1462 for (k = i+j; k < 512; k++)
1463 if (data[k] != 'x')
1464 goto fail;
1465 continue;
1466
1467 fail:
1468 check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
1469 }
1470 }
1471}
1472
1473static void
1474test_bcopy (void)
1475{
1476 /* Much like memcpy. Berklix manual is silent about overlap, so
1477 don't test it. */
1478 it = "bcopy";
1479 (void) bcopy("abc", one, 4);
1480 equal(one, "abc", 1); /* Simple copy. */
1481
1482 (void) strcpy(one, "abcdefgh");
1483 (void) bcopy("xyz", one+1, 2);
1484 equal(one, "axydefgh", 2); /* Basic test. */
1485
1486 (void) strcpy(one, "abc");
1487 (void) bcopy("xyz", one, 0);
1488 equal(one, "abc", 3); /* Zero-length copy. */
1489
1490 (void) strcpy(one, "hi there");
1491 (void) strcpy(two, "foo");
1492 (void) bcopy(one, two, 9);
1493 equal(two, "hi there", 4); /* Just paranoia. */
1494 equal(one, "hi there", 5); /* Stomped on source? */
1495}
1496
1497static void
1498test_bzero (void)
1499{
1500 it = "bzero";
1501 (void) strcpy(one, "abcdef");
1502 bzero(one+2, 2);
1503 equal(one, "ab", 1); /* Basic test. */
1504 equal(one+3, "", 2);
1505 equal(one+4, "ef", 3);
1506
1507 (void) strcpy(one, "abcdef");
1508 bzero(one+2, 0);
1509 equal(one, "abcdef", 4); /* Zero-length copy. */
1510}
1511
1512static void
1513test_strndup (void)
1514{
1515 char *p, *q;
1516 it = "strndup";
1517 p = strndup("abcdef", 12);
1518 check(p != NULL, 1);
1519 if (p != NULL)
1520 {
1521 equal(p, "abcdef", 2);
1522 q = strndup(p + 1, 2);
1523 check(q != NULL, 3);
1524 if (q != NULL)
1525 equal(q, "bc", 4);
1526 free (q);
1527 }
1528 free (p);
1529 p = strndup("abc def", 3);
1530 check(p != NULL, 5);
1531 if (p != NULL)
1532 equal(p, "abc", 6);
1533 free (p);
1534}
1535
1536static void
1537test_bcmp (void)
1538{
1539 it = "bcmp";
1540 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1541 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1542 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1543 check(bcmp("abce", "abcd", 4) != 0, 4);
1544 check(bcmp("alph", "beta", 4) != 0, 5);
1545 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1546 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1547}
1548
1549static void
1550test_strerror (void)
1551{
1552 it = "strerror";
1553 check(strerror(EDOM) != 0, 1);
1554 check(strerror(ERANGE) != 0, 2);
1555 check(strerror(ENOENT) != 0, 3);
1556}
1557
1558static void
1559test_strcasecmp (void)
1560{
1561 it = "strcasecmp";
1562 /* Note that the locale is "C". */
1563 check(strcasecmp("a", "a") == 0, 1);
1564 check(strcasecmp("a", "A") == 0, 2);
1565 check(strcasecmp("A", "a") == 0, 3);
1566 check(strcasecmp("a", "b") < 0, 4);
1567 check(strcasecmp("c", "b") > 0, 5);
1568 check(strcasecmp("abc", "AbC") == 0, 6);
1569 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1570 check(strcasecmp("", "0123456789") < 0, 8);
1571 check(strcasecmp("AbC", "") > 0, 9);
1572 check(strcasecmp("AbC", "A") > 0, 10);
1573 check(strcasecmp("AbC", "Ab") > 0, 11);
1574 check(strcasecmp("AbC", "ab") > 0, 12);
1575}
1576
1577static void
1578test_strncasecmp (void)
1579{
1580 it = "strncasecmp";
1581 /* Note that the locale is "C". */
1582 check(strncasecmp("a", "a", 5) == 0, 1);
1583 check(strncasecmp("a", "A", 5) == 0, 2);
1584 check(strncasecmp("A", "a", 5) == 0, 3);
1585 check(strncasecmp("a", "b", 5) < 0, 4);
1586 check(strncasecmp("c", "b", 5) > 0, 5);
1587 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1588 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1589 check(strncasecmp("", "0123456789", 10) < 0, 8);
1590 check(strncasecmp("AbC", "", 5) > 0, 9);
1591 check(strncasecmp("AbC", "A", 5) > 0, 10);
1592 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1593 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1594 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1595 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1596 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1597 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1598 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1599 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1600 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1601 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1602}
1603
1604int
1605main (void)
1606{
1607 int status;
1608
1609 /* Test strcmp first because we use it to test other things. */
1610 test_strcmp ();
1611
1612 /* Test strcpy next because we need it to set up other tests. */
1613 test_strcpy ();
1614
1615 /* A closely related function is stpcpy. */
1616 test_stpcpy ();
1617
1618 /* stpncpy. */
1619 test_stpncpy ();
1620
1621 /* strcat. */
1622 test_strcat ();
1623
1624 /* strncat. */
1625 test_strncat ();
1626
1627 /* strncmp. */
1628 test_strncmp ();
1629
1630 /* strncpy. */
1631 test_strncpy ();
1632
1633 /* strlen. */
1634 test_strlen ();
1635
1636 /* strnlen. */
1637 test_strnlen ();
1638
1639 /* strchr. */
1640 test_strchr ();
1641
1642 /* strchrnul. */
1643 test_strchrnul ();
1644
1645 /* rawmemchr. */
1646 test_rawmemchr ();
1647
1648 /* index - just like strchr. */
1649 test_index ();
1650
1651 /* strrchr. */
1652 test_strrchr ();
1653
1654 /* memrchr. */
1655 test_memrchr ();
1656
1657 /* rindex - just like strrchr. */
1658 test_rindex ();
1659
1660 /* strpbrk - somewhat like strchr. */
1661 test_strpbrk ();
1662
1663 /* strstr - somewhat like strchr. */
1664 test_strstr ();
1665
1666 /* strspn. */
1667 test_strspn ();
1668
1669 /* strcspn. */
1670 test_strcspn ();
1671
1672 /* strtok - the hard one. */
1673 test_strtok ();
1674
1675 /* strtok_r. */
1676 test_strtok_r ();
1677
1678 /* strsep. */
1679 test_strsep ();
1680
1681 /* memcmp. */
1682 test_memcmp ();
1683
1684 /* memchr. */
1685 test_memchr ();
1686
1687 /* memcpy - need not work for overlap. */
1688 test_memcpy ();
1689
1690 /* memmove - must work on overlap. */
1691 test_memmove ();
1692
1693 /* mempcpy */
1694 test_mempcpy ();
1695
1696 /* memccpy. */
1697 test_memccpy ();
1698
1699 /* memset. */
1700 test_memset ();
1701
1702 /* bcopy. */
1703 test_bcopy ();
1704
1705 /* bzero. */
1706 test_bzero ();
1707
1708 /* bcmp - somewhat like memcmp. */
1709 test_bcmp ();
1710
1711 /* strndup. */
1712 test_strndup ();
1713
1714 /* strerror - VERY system-dependent. */
1715 test_strerror ();
1716
1717 /* strcasecmp. Without locale dependencies. */
1718 test_strcasecmp ();
1719
1720 /* strncasecmp. Without locale dependencies. */
1721 test_strncasecmp ();
1722
1723 if (errors == 0)
1724 {
1725 status = EXIT_SUCCESS;
1726 puts("No errors.");
1727 }
1728 else
1729 {
1730 status = EXIT_FAILURE;
1731 printf("%Zd errors.\n", errors);
1732 }
1733
1734 return status;
1735}
1736

Warning: That file was not part of the compilation database. It may have many parsing errors.