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