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