Add optimized x86-64 implementation of strnlen.
[glibc.git] / string / tester.c
blob01da0465daa8b38fa9ad1f052e70e90f3ccfbb8f
1 /* Tester for string functions.
2 Copyright (C) 1995-2001, 2003, 2005, 2008, 2010 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #ifndef _GNU_SOURCE
21 #define _GNU_SOURCE
22 #endif
24 /* Make sure we don't test the optimized inline functions if we want to
25 test the real implementation. */
26 #if !defined DO_STRING_INLINES
27 #undef __USE_STRING_INLINES
28 #endif
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <strings.h>
35 #include <fcntl.h>
38 #define STREQ(a, b) (strcmp((a), (b)) == 0)
40 const char *it = "<UNSET>"; /* Routine name for message routines. */
41 size_t errors = 0;
43 /* Complain if condition is not true. */
44 static void
45 check (int thing, int number)
47 if (!thing)
49 printf("%s flunked test %d\n", it, number);
50 ++errors;
54 /* Complain if first two args don't strcmp as equal. */
55 static void
56 equal (const char *a, const char *b, int number)
58 check(a != NULL && b != NULL && STREQ (a, b), number);
61 char one[50];
62 char two[50];
63 char *cp;
65 static void
66 test_strcmp (void)
68 it = "strcmp";
69 check (strcmp ("", "") == 0, 1); /* Trivial case. */
70 check (strcmp ("a", "a") == 0, 2); /* Identity. */
71 check (strcmp ("abc", "abc") == 0, 3); /* Multicharacter. */
72 check (strcmp ("abc", "abcd") < 0, 4); /* Length mismatches. */
73 check (strcmp ("abcd", "abc") > 0, 5);
74 check (strcmp ("abcd", "abce") < 0, 6); /* Honest miscompares. */
75 check (strcmp ("abce", "abcd") > 0, 7);
76 check (strcmp ("a\203", "a") > 0, 8); /* Tricky if char signed. */
77 check (strcmp ("a\203", "a\003") > 0, 9);
80 char buf1[0x40], buf2[0x40];
81 int i, j;
82 for (i=0; i < 0x10; i++)
83 for (j = 0; j < 0x10; j++)
85 int k;
86 for (k = 0; k < 0x3f; k++)
88 buf1[k] = '0' ^ (k & 4);
89 buf2[k] = '4' ^ (k & 4);
91 buf1[i] = buf1[0x3f] = 0;
92 buf2[j] = buf2[0x3f] = 0;
93 for (k = 0; k < 0xf; k++)
95 int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
96 check (strcmp (buf1+i,buf2+j) == 0, cnum);
97 buf1[i+k] = 'A' + i + k;
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;
115 #define SIMPLE_COPY(fn, n, str, ntest) \
116 do { \
117 int __n; \
118 char *cp; \
119 for (__n = 0; __n < (int) sizeof (one); ++__n) \
120 one[__n] = 'Z'; \
121 fn (one, str); \
122 for (cp = one, __n = 0; __n < n; ++__n, ++cp) \
123 check (*cp == '0' + (n % 10), ntest); \
124 check (*cp == '\0', ntest); \
125 } while (0)
127 static void
128 test_strcpy (void)
130 int i;
131 it = "strcpy";
132 check (strcpy (one, "abcd") == one, 1); /* Returned value. */
133 equal (one, "abcd", 2); /* Basic test. */
135 (void) strcpy (one, "x");
136 equal (one, "x", 3); /* Writeover. */
137 equal (one+2, "cd", 4); /* Wrote too much? */
139 (void) strcpy (two, "hi there");
140 (void) strcpy (one, two);
141 equal (one, "hi there", 5); /* Basic test encore. */
142 equal (two, "hi there", 6); /* Stomped on source? */
144 (void) strcpy (one, "");
145 equal (one, "", 7); /* Boundary condition. */
147 for (i = 0; i < 16; i++)
149 (void) strcpy (one + i, "hi there"); /* Unaligned destination. */
150 equal (one + i, "hi there", 8 + (i * 2));
151 (void) strcpy (two, one + i); /* Unaligned source. */
152 equal (two, "hi there", 9 + (i * 2));
155 SIMPLE_COPY(strcpy, 0, "", 41);
156 SIMPLE_COPY(strcpy, 1, "1", 42);
157 SIMPLE_COPY(strcpy, 2, "22", 43);
158 SIMPLE_COPY(strcpy, 3, "333", 44);
159 SIMPLE_COPY(strcpy, 4, "4444", 45);
160 SIMPLE_COPY(strcpy, 5, "55555", 46);
161 SIMPLE_COPY(strcpy, 6, "666666", 47);
162 SIMPLE_COPY(strcpy, 7, "7777777", 48);
163 SIMPLE_COPY(strcpy, 8, "88888888", 49);
164 SIMPLE_COPY(strcpy, 9, "999999999", 50);
165 SIMPLE_COPY(strcpy, 10, "0000000000", 51);
166 SIMPLE_COPY(strcpy, 11, "11111111111", 52);
167 SIMPLE_COPY(strcpy, 12, "222222222222", 53);
168 SIMPLE_COPY(strcpy, 13, "3333333333333", 54);
169 SIMPLE_COPY(strcpy, 14, "44444444444444", 55);
170 SIMPLE_COPY(strcpy, 15, "555555555555555", 56);
171 SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);
173 /* Simple test using implicitly coerced `void *' arguments. */
174 const void *src = "frobozz";
175 void *dst = one;
176 check (strcpy (dst, src) == dst, 1);
177 equal (dst, "frobozz", 2);
180 static void
181 test_stpcpy (void)
183 it = "stpcpy";
184 check ((stpcpy (one, "a") - one) == 1, 1);
185 equal (one, "a", 2);
187 check ((stpcpy (one, "ab") - one) == 2, 3);
188 equal (one, "ab", 4);
190 check ((stpcpy (one, "abc") - one) == 3, 5);
191 equal (one, "abc", 6);
193 check ((stpcpy (one, "abcd") - one) == 4, 7);
194 equal (one, "abcd", 8);
196 check ((stpcpy (one, "abcde") - one) == 5, 9);
197 equal (one, "abcde", 10);
199 check ((stpcpy (one, "abcdef") - one) == 6, 11);
200 equal (one, "abcdef", 12);
202 check ((stpcpy (one, "abcdefg") - one) == 7, 13);
203 equal (one, "abcdefg", 14);
205 check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
206 equal (one, "abcdefgh", 16);
208 check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
209 equal (one, "abcdefghi", 18);
211 check ((stpcpy (one, "x") - one) == 1, 19);
212 equal (one, "x", 20); /* Writeover. */
213 equal (one+2, "cdefghi", 21); /* Wrote too much? */
215 check ((stpcpy (one, "xx") - one) == 2, 22);
216 equal (one, "xx", 23); /* Writeover. */
217 equal (one+3, "defghi", 24); /* Wrote too much? */
219 check ((stpcpy (one, "xxx") - one) == 3, 25);
220 equal (one, "xxx", 26); /* Writeover. */
221 equal (one+4, "efghi", 27); /* Wrote too much? */
223 check ((stpcpy (one, "xxxx") - one) == 4, 28);
224 equal (one, "xxxx", 29); /* Writeover. */
225 equal (one+5, "fghi", 30); /* Wrote too much? */
227 check ((stpcpy (one, "xxxxx") - one) == 5, 31);
228 equal (one, "xxxxx", 32); /* Writeover. */
229 equal (one+6, "ghi", 33); /* Wrote too much? */
231 check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
232 equal (one, "xxxxxx", 35); /* Writeover. */
233 equal (one+7, "hi", 36); /* Wrote too much? */
235 check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
236 equal (one, "xxxxxxx", 38); /* Writeover. */
237 equal (one+8, "i", 39); /* Wrote too much? */
239 check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
240 equal (one, "abc", 41);
241 equal (one + 4, "xxx", 42);
243 SIMPLE_COPY(stpcpy, 0, "", 43);
244 SIMPLE_COPY(stpcpy, 1, "1", 44);
245 SIMPLE_COPY(stpcpy, 2, "22", 45);
246 SIMPLE_COPY(stpcpy, 3, "333", 46);
247 SIMPLE_COPY(stpcpy, 4, "4444", 47);
248 SIMPLE_COPY(stpcpy, 5, "55555", 48);
249 SIMPLE_COPY(stpcpy, 6, "666666", 49);
250 SIMPLE_COPY(stpcpy, 7, "7777777", 50);
251 SIMPLE_COPY(stpcpy, 8, "88888888", 51);
252 SIMPLE_COPY(stpcpy, 9, "999999999", 52);
253 SIMPLE_COPY(stpcpy, 10, "0000000000", 53);
254 SIMPLE_COPY(stpcpy, 11, "11111111111", 54);
255 SIMPLE_COPY(stpcpy, 12, "222222222222", 55);
256 SIMPLE_COPY(stpcpy, 13, "3333333333333", 56);
257 SIMPLE_COPY(stpcpy, 14, "44444444444444", 57);
258 SIMPLE_COPY(stpcpy, 15, "555555555555555", 58);
259 SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59);
262 static void
263 test_stpncpy (void)
265 it = "stpncpy";
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);
277 static void
278 test_strcat (void)
280 it = "strcat";
281 (void) strcpy (one, "ijk");
282 check (strcat (one, "lmn") == one, 1); /* Returned value. */
283 equal (one, "ijklmn", 2); /* Basic test. */
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? */
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? */
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);
307 static void
308 test_strncat (void)
310 /* First test it as strcat, with big counts, then test the count
311 mechanism. */
312 it = "strncat";
313 (void) strcpy (one, "ijk");
314 check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
315 equal (one, "ijklmn", 2); /* Basic test. */
317 (void) strcpy (one, "x");
318 (void) strncat (one, "yz", 99);
319 equal (one, "xyz", 3); /* Writeover. */
320 equal (one+4, "mn", 4); /* Wrote too much? */
322 (void) strcpy (one, "gh");
323 (void) strcpy (two, "ef");
324 (void) strncat (one, two, 99);
325 equal (one, "ghef", 5); /* Basic test encore. */
326 equal (two, "ef", 6); /* Stomped on source? */
328 (void) strcpy (one, "");
329 (void) strncat (one, "", 99);
330 equal (one, "", 7); /* Boundary conditions. */
331 (void) strcpy (one, "ab");
332 (void) strncat (one, "", 99);
333 equal (one, "ab", 8);
334 (void) strcpy (one, "");
335 (void) strncat (one, "cd", 99);
336 equal (one, "cd", 9);
338 (void) strcpy (one, "ab");
339 (void) strncat (one, "cdef", 2);
340 equal (one, "abcd", 10); /* Count-limited. */
342 (void) strncat (one, "gh", 0);
343 equal (one, "abcd", 11); /* Zero count. */
345 (void) strncat (one, "gh", 2);
346 equal (one, "abcdgh", 12); /* Count and length equal. */
348 (void) strncat (one, "ij", (size_t)-1); /* set sign bit in count */
349 equal (one, "abcdghij", 13);
352 static void
353 test_strncmp (void)
355 /* First test as strcmp with big counts, then test count code. */
356 it = "strncmp";
357 check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
358 check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
359 check (strncmp ("abc", "abc", 99) == 0, 3); /* Multicharacter. */
360 check (strncmp ("abc", "abcd", 99) < 0, 4); /* Length unequal. */
361 check (strncmp ("abcd", "abc", 99) > 0, 5);
362 check (strncmp ("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
363 check (strncmp ("abce", "abcd", 99) > 0, 7);
364 check (strncmp ("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
365 check (strncmp ("a\203", "a\003", 2) > 0, 9);
366 check (strncmp ("abce", "abcd", 3) == 0, 10); /* Count limited. */
367 check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
368 check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
369 check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
370 check (strncmp ("abc", "", (size_t)-1) > 0, 14); /* set sign bit in count */
371 check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
374 static void
375 test_strncpy (void)
377 /* Testing is a bit different because of odd semantics. */
378 it = "strncpy";
379 check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
380 equal (one, "abc", 2); /* Did the copy go right? */
382 (void) strcpy (one, "abcdefgh");
383 (void) strncpy (one, "xyz", 2);
384 equal (one, "xycdefgh", 3); /* Copy cut by count. */
386 (void) strcpy (one, "abcdefgh");
387 (void) strncpy (one, "xyz", 3); /* Copy cut just before NUL. */
388 equal (one, "xyzdefgh", 4);
390 (void) strcpy (one, "abcdefgh");
391 (void) strncpy (one, "xyz", 4); /* Copy just includes NUL. */
392 equal (one, "xyz", 5);
393 equal (one+4, "efgh", 6); /* Wrote too much? */
395 (void) strcpy (one, "abcdefgh");
396 (void) strncpy (one, "xyz", 5); /* Copy includes padding. */
397 equal (one, "xyz", 7);
398 equal (one+4, "", 8);
399 equal (one+5, "fgh", 9);
401 (void) strcpy (one, "abc");
402 (void) strncpy (one, "xyz", 0); /* Zero-length copy. */
403 equal (one, "abc", 10);
405 (void) strncpy (one, "", 2); /* Zero-length source. */
406 equal (one, "", 11);
407 equal (one+1, "", 12);
408 equal (one+2, "c", 13);
410 (void) strcpy (one, "hi there");
411 (void) strncpy (two, one, 9);
412 equal (two, "hi there", 14); /* Just paranoia. */
413 equal (one, "hi there", 15); /* Stomped on source? */
416 static void
417 test_strlen (void)
419 it = "strlen";
420 check (strlen ("") == 0, 1); /* Empty. */
421 check (strlen ("a") == 1, 2); /* Single char. */
422 check (strlen ("abcd") == 4, 3); /* Multiple chars. */
424 char buf[4096];
425 int i;
426 char *p;
427 for (i=0; i < 0x100; i++)
429 p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
430 strcpy (p, "OK");
431 strcpy (p+3, "BAD/WRONG");
432 check (strlen (p) == 2, 4+i);
437 static void
438 test_strnlen (void)
440 it = "strnlen";
441 check (strnlen ("", 10) == 0, 1); /* Empty. */
442 check (strnlen ("a", 10) == 1, 2); /* Single char. */
443 check (strnlen ("abcd", 10) == 4, 3); /* Multiple chars. */
444 check (strnlen ("foo", (size_t) -1) == 3, 4); /* limits of n. */
445 check (strnlen ("abcd", 0) == 0, 5); /* Restricted. */
446 check (strnlen ("abcd", 1) == 1, 6); /* Restricted. */
447 check (strnlen ("abcd", 2) == 2, 7); /* Restricted. */
448 check (strnlen ("abcd", 3) == 3, 8); /* Restricted. */
449 check (strnlen ("abcd", 4) == 4, 9); /* Restricted. */
451 char buf[4096];
452 for (int i = 0; i < 0x100; ++i)
454 char *p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
455 strcpy (p, "OK");
456 strcpy (p + 3, "BAD/WRONG");
457 check (strnlen (p, 100) == 2, 10 + i);
461 static void
462 test_strchr (void)
464 it = "strchr";
465 check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
466 (void) strcpy (one, "abcd");
467 check (strchr (one, 'c') == one+2, 2); /* Basic test. */
468 check (strchr (one, 'd') == one+3, 3); /* End of string. */
469 check (strchr (one, 'a') == one, 4); /* Beginning. */
470 check (strchr (one, '\0') == one+4, 5); /* Finding NUL. */
471 (void) strcpy (one, "ababa");
472 check (strchr (one, 'b') == one+1, 6); /* Finding first. */
473 (void) strcpy (one, "");
474 check (strchr (one, 'b') == NULL, 7); /* Empty string. */
475 check (strchr (one, '\0') == one, 8); /* NUL in empty string. */
477 char buf[4096];
478 int i;
479 char *p;
480 for (i=0; i < 0x100; i++)
482 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
483 strcpy (p, "OK");
484 strcpy (p+3, "BAD/WRONG");
485 check (strchr (p, '/') == NULL, 9+i);
490 static void
491 test_strchrnul (void)
493 const char *os;
494 it = "strchrnul";
495 cp = strchrnul ((os = "abcd"), 'z');
496 check (*cp == '\0', 1); /* Not found. */
497 check (cp == os + 4, 2);
498 (void) strcpy (one, "abcd");
499 check (strchrnul (one, 'c') == one+2, 3); /* Basic test. */
500 check (strchrnul (one, 'd') == one+3, 4); /* End of string. */
501 check (strchrnul (one, 'a') == one, 5); /* Beginning. */
502 check (strchrnul (one, '\0') == one+4, 6); /* Finding NUL. */
503 (void) strcpy (one, "ababa");
504 check (strchrnul (one, 'b') == one+1, 7); /* Finding first. */
505 (void) strcpy (one, "");
506 check (strchrnul (one, 'b') == one, 8); /* Empty string. */
507 check (strchrnul (one, '\0') == one, 9); /* NUL in empty string. */
509 char buf[4096];
510 int i;
511 char *p;
512 for (i=0; i < 0x100; i++)
514 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
515 strcpy (p, "OK");
516 strcpy (p+3, "BAD/WRONG");
517 cp = strchrnul (p, '/');
518 check (*cp == '\0', 9+2*i);
519 check (cp == p+2, 10+2*i);
524 static void
525 test_rawmemchr (void)
527 it = "rawmemchr";
528 (void) strcpy (one, "abcd");
529 check (rawmemchr (one, 'c') == one+2, 1); /* Basic test. */
530 check (rawmemchr (one, 'd') == one+3, 2); /* End of string. */
531 check (rawmemchr (one, 'a') == one, 3); /* Beginning. */
532 check (rawmemchr (one, '\0') == one+4, 4); /* Finding NUL. */
533 (void) strcpy (one, "ababa");
534 check (rawmemchr (one, 'b') == one+1, 5); /* Finding first. */
535 (void) strcpy (one, "");
536 check (rawmemchr (one, '\0') == one, 6); /* NUL in empty string. */
538 char buf[4096];
539 int i;
540 char *p;
541 for (i=0; i < 0x100; i++)
543 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
544 strcpy (p, "OK");
545 strcpy (p+3, "BAD/WRONG");
546 check (rawmemchr (p, 'R') == p+8, 6+i);
551 static void
552 test_index (void)
554 it = "index";
555 check (index ("abcd", 'z') == NULL, 1); /* Not found. */
556 (void) strcpy (one, "abcd");
557 check (index (one, 'c') == one+2, 2); /* Basic test. */
558 check (index (one, 'd') == one+3, 3); /* End of string. */
559 check (index (one, 'a') == one, 4); /* Beginning. */
560 check (index (one, '\0') == one+4, 5); /* Finding NUL. */
561 (void) strcpy (one, "ababa");
562 check (index (one, 'b') == one+1, 6); /* Finding first. */
563 (void) strcpy (one, "");
564 check (index (one, 'b') == NULL, 7); /* Empty string. */
565 check (index (one, '\0') == one, 8); /* NUL in empty string. */
568 static void
569 test_strrchr (void)
571 it = "strrchr";
572 check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
573 (void) strcpy (one, "abcd");
574 check (strrchr (one, 'c') == one+2, 2); /* Basic test. */
575 check (strrchr (one, 'd') == one+3, 3); /* End of string. */
576 check (strrchr (one, 'a') == one, 4); /* Beginning. */
577 check (strrchr (one, '\0') == one+4, 5); /* Finding NUL. */
578 (void) strcpy (one, "ababa");
579 check (strrchr (one, 'b') == one+3, 6); /* Finding last. */
580 (void) strcpy (one, "");
581 check (strrchr (one, 'b') == NULL, 7); /* Empty string. */
582 check (strrchr (one, '\0') == one, 8); /* NUL in empty string. */
584 char buf[4096];
585 int i;
586 char *p;
587 for (i=0; i < 0x100; i++)
589 p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
590 strcpy (p, "OK");
591 strcpy (p+3, "BAD/WRONG");
592 check (strrchr (p, '/') == NULL, 9+i);
597 static void
598 test_memrchr (void)
600 size_t l;
601 it = "memrchr";
602 check (memrchr ("abcd", 'z', 5) == NULL, 1); /* Not found. */
603 (void) strcpy (one, "abcd");
604 l = strlen (one) + 1;
605 check (memrchr (one, 'c', l) == one+2, 2); /* Basic test. */
606 check (memrchr (one, 'd', l) == one+3, 3); /* End of string. */
607 check (memrchr (one, 'a', l) == one, 4); /* Beginning. */
608 check (memrchr (one, '\0', l) == one+4, 5); /* Finding NUL. */
609 (void) strcpy (one, "ababa");
610 l = strlen (one) + 1;
611 check (memrchr (one, 'b', l) == one+3, 6); /* Finding last. */
612 (void) strcpy (one, "");
613 l = strlen (one) + 1;
614 check (memrchr (one, 'b', l) == NULL, 7); /* Empty string. */
615 check (memrchr (one, '\0', l) == one, 8); /* NUL in empty string. */
617 /* now test all possible alignment and length combinations to catch
618 bugs due to unrolled loops (assuming unrolling is limited to no
619 more than 128 byte chunks: */
621 char buf[128 + sizeof(long)];
622 long align, len, i, pos;
624 for (align = 0; align < (long) sizeof(long); ++align) {
625 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
626 for (i = 0; i < len; ++i)
627 buf[align + i] = 'x'; /* don't depend on memset... */
629 for (pos = len - 1; pos >= 0; --pos) {
630 #if 0
631 printf("align %d, len %d, pos %d\n", align, len, pos);
632 #endif
633 check(memrchr(buf + align, 'x', len) == buf + align + pos, 9);
634 check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
635 10);
636 buf[align + pos] = '-';
643 static void
644 test_rindex (void)
646 it = "rindex";
647 check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
648 (void) strcpy (one, "abcd");
649 check (rindex (one, 'c') == one+2, 2); /* Basic test. */
650 check (rindex (one, 'd') == one+3, 3); /* End of string. */
651 check (rindex (one, 'a') == one, 4); /* Beginning. */
652 check (rindex (one, '\0') == one+4, 5); /* Finding NUL. */
653 (void) strcpy (one, "ababa");
654 check (rindex (one, 'b') == one+3, 6); /* Finding last. */
655 (void) strcpy (one, "");
656 check (rindex (one, 'b') == NULL, 7); /* Empty string. */
657 check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
660 static void
661 test_strpbrk (void)
663 it = "strpbrk";
664 check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
665 (void) strcpy(one, "abcd");
666 check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
667 check(strpbrk(one, "d") == one+3, 3); /* End of string. */
668 check(strpbrk(one, "a") == one, 4); /* Beginning. */
669 check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
670 check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
671 (void) strcpy(one, "abcabdea");
672 check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
673 check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
674 check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
675 (void) strcpy(one, "");
676 check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
677 (void) strcpy(one, "");
678 check(strpbrk(one, "bcd") == NULL, 11); /* Empty string. */
679 (void) strcpy(one, "");
680 check(strpbrk(one, "bcde") == NULL, 12); /* Empty string. */
681 check(strpbrk(one, "") == NULL, 13); /* Both strings empty. */
682 (void) strcpy(one, "abcabdea");
683 check(strpbrk(one, "befg") == one+1, 14); /* Finding first. */
684 check(strpbrk(one, "cbr") == one+1, 15); /* With multiple search. */
685 check(strpbrk(one, "db") == one+1, 16); /* Another variant. */
686 check(strpbrk(one, "efgh") == one+6, 17); /* And yet another. */
689 static void
690 test_strstr (void)
692 it = "strstr";
693 check(strstr("abcd", "z") == NULL, 1); /* Not found. */
694 check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
695 (void) strcpy(one, "abcd");
696 check(strstr(one, "c") == one+2, 3); /* Basic test. */
697 check(strstr(one, "bc") == one+1, 4); /* Multichar. */
698 check(strstr(one, "d") == one+3, 5); /* End of string. */
699 check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
700 check(strstr(one, "abc") == one, 7); /* Beginning. */
701 check(strstr(one, "abcd") == one, 8); /* Exact match. */
702 check(strstr(one, "abcde") == NULL, 9); /* Too long. */
703 check(strstr(one, "de") == NULL, 10); /* Past end. */
704 check(strstr(one, "") == one, 11); /* Finding empty. */
705 (void) strcpy(one, "ababa");
706 check(strstr(one, "ba") == one+1, 12); /* Finding first. */
707 (void) strcpy(one, "");
708 check(strstr(one, "b") == NULL, 13); /* Empty string. */
709 check(strstr(one, "") == one, 14); /* Empty in empty string. */
710 (void) strcpy(one, "bcbca");
711 check(strstr(one, "bca") == one+2, 15); /* False start. */
712 (void) strcpy(one, "bbbcabbca");
713 check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
716 static void
717 test_strspn (void)
719 it = "strspn";
720 check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
721 check(strspn("abcba", "ab") == 2, 2); /* Partial. */
722 check(strspn("abc", "qx") == 0, 3); /* None. */
723 check(strspn("", "ab") == 0, 4); /* Null string. */
724 check(strspn("abc", "") == 0, 5); /* Null search list. */
727 static void
728 test_strcspn (void)
730 it = "strcspn";
731 check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
732 check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
733 check(strcspn("abc", "abc") == 0, 3); /* None. */
734 check(strcspn("", "ab") == 0, 4); /* Null string. */
735 check(strcspn("abc", "") == 3, 5); /* Null search list. */
738 static void
739 test_strtok (void)
741 it = "strtok";
742 (void) strcpy(one, "first, second, third");
743 equal(strtok(one, ", "), "first", 1); /* Basic test. */
744 equal(one, "first", 2);
745 equal(strtok((char *)NULL, ", "), "second", 3);
746 equal(strtok((char *)NULL, ", "), "third", 4);
747 check(strtok((char *)NULL, ", ") == NULL, 5);
748 (void) strcpy(one, ", first, ");
749 equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
750 check(strtok((char *)NULL, ", ") == NULL, 7);
751 (void) strcpy(one, "1a, 1b; 2a, 2b");
752 equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
753 equal(strtok((char *)NULL, "; "), "1b", 9);
754 equal(strtok((char *)NULL, ", "), "2a", 10);
755 (void) strcpy(two, "x-y");
756 equal(strtok(two, "-"), "x", 11); /* New string before done. */
757 equal(strtok((char *)NULL, "-"), "y", 12);
758 check(strtok((char *)NULL, "-") == NULL, 13);
759 (void) strcpy(one, "a,b, c,, ,d");
760 equal(strtok(one, ", "), "a", 14); /* Different separators. */
761 equal(strtok((char *)NULL, ", "), "b", 15);
762 equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
763 equal(strtok((char *)NULL, " ,"), "d", 17);
764 check(strtok((char *)NULL, ", ") == NULL, 18);
765 check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
766 (void) strcpy(one, ", ");
767 check(strtok(one, ", ") == NULL, 20); /* No tokens. */
768 (void) strcpy(one, "");
769 check(strtok(one, ", ") == NULL, 21); /* Empty string. */
770 (void) strcpy(one, "abc");
771 equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
772 check(strtok((char *)NULL, ", ") == NULL, 23);
773 (void) strcpy(one, "abc");
774 equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
775 check(strtok((char *)NULL, "") == NULL, 25);
776 (void) strcpy(one, "abcdefgh");
777 (void) strcpy(one, "a,b,c");
778 equal(strtok(one, ","), "a", 26); /* Basics again... */
779 equal(strtok((char *)NULL, ","), "b", 27);
780 equal(strtok((char *)NULL, ","), "c", 28);
781 check(strtok((char *)NULL, ",") == NULL, 29);
782 equal(one+6, "gh", 30); /* Stomped past end? */
783 equal(one, "a", 31); /* Stomped old tokens? */
784 equal(one+2, "b", 32);
785 equal(one+4, "c", 33);
788 static void
789 test_strtok_r (void)
791 it = "strtok_r";
792 (void) strcpy(one, "first, second, third");
793 cp = NULL; /* Always initialize cp to make sure it doesn't point to some old data. */
794 equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
795 equal(one, "first", 2);
796 equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
797 equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
798 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
799 (void) strcpy(one, ", first, ");
800 cp = NULL;
801 equal(strtok_r(one, ", ", &cp), "first", 6); /* Extra delims, 1 tok. */
802 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
803 (void) strcpy(one, "1a, 1b; 2a, 2b");
804 cp = NULL;
805 equal(strtok_r(one, ", ", &cp), "1a", 8); /* Changing delim lists. */
806 equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
807 equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
808 (void) strcpy(two, "x-y");
809 cp = NULL;
810 equal(strtok_r(two, "-", &cp), "x", 11); /* New string before done. */
811 equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
812 check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
813 (void) strcpy(one, "a,b, c,, ,d");
814 cp = NULL;
815 equal(strtok_r(one, ", ", &cp), "a", 14); /* Different separators. */
816 equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
817 equal(strtok_r((char *)NULL, " ,", &cp), "c", 16); /* Permute list too. */
818 equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
819 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
820 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19); /* Persistence. */
821 (void) strcpy(one, ", ");
822 cp = NULL;
823 check(strtok_r(one, ", ", &cp) == NULL, 20); /* No tokens. */
824 (void) strcpy(one, "");
825 cp = NULL;
826 check(strtok_r(one, ", ", &cp) == NULL, 21); /* Empty string. */
827 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22); /* Persistence. */
828 (void) strcpy(one, "abc");
829 cp = NULL;
830 equal(strtok_r(one, ", ", &cp), "abc", 23); /* No delimiters. */
831 check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
832 (void) strcpy(one, "abc");
833 cp = NULL;
834 equal(strtok_r(one, "", &cp), "abc", 25); /* Empty delimiter list. */
835 check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
836 (void) strcpy(one, "abcdefgh");
837 (void) strcpy(one, "a,b,c");
838 cp = NULL;
839 equal(strtok_r(one, ",", &cp), "a", 27); /* Basics again... */
840 equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
841 equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
842 check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
843 equal(one+6, "gh", 31); /* Stomped past end? */
844 equal(one, "a", 32); /* Stomped old tokens? */
845 equal(one+2, "b", 33);
846 equal(one+4, "c", 34);
847 strcpy (one, ":::");
848 cp = NULL;
849 check (strtok_r (one, ":", &cp) == NULL, 35); /* Must store pointer in cp. */
850 check (strtok_r (NULL, ":", &cp) == NULL, 36);
853 static void
854 test_strsep (void)
856 char *ptr;
857 it = "strsep";
858 cp = strcpy(one, "first, second, third");
859 equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
860 equal(one, "first", 2);
861 equal(strsep(&cp, ", "), "", 3);
862 equal(strsep(&cp, ", "), "second", 4);
863 equal(strsep(&cp, ", "), "", 5);
864 equal(strsep(&cp, ", "), "third", 6);
865 check(strsep(&cp, ", ") == NULL, 7);
866 cp = strcpy(one, ", first, ");
867 equal(strsep(&cp, ", "), "", 8);
868 equal(strsep(&cp, ", "), "", 9);
869 equal(strsep(&cp, ", "), "first", 10); /* Extra delims, 1 tok. */
870 equal(strsep(&cp, ", "), "", 11);
871 equal(strsep(&cp, ", "), "", 12);
872 check(strsep(&cp, ", ") == NULL, 13);
873 cp = strcpy(one, "1a, 1b; 2a, 2b");
874 equal(strsep(&cp, ", "), "1a", 14); /* Changing delim lists. */
875 equal(strsep(&cp, ", "), "", 15);
876 equal(strsep(&cp, "; "), "1b", 16);
877 equal(strsep(&cp, ", "), "", 17);
878 equal(strsep(&cp, ", "), "2a", 18);
879 cp = strcpy(two, "x-y");
880 equal(strsep(&cp, "-"), "x", 19); /* New string before done. */
881 equal(strsep(&cp, "-"), "y", 20);
882 check(strsep(&cp, "-") == NULL, 21);
883 cp = strcpy(one, "a,b, c,, ,d ");
884 equal(strsep(&cp, ", "), "a", 22); /* Different separators. */
885 equal(strsep(&cp, ", "), "b", 23);
886 equal(strsep(&cp, " ,"), "", 24);
887 equal(strsep(&cp, " ,"), "c", 25); /* Permute list too. */
888 equal(strsep(&cp, " ,"), "", 26);
889 equal(strsep(&cp, " ,"), "", 27);
890 equal(strsep(&cp, " ,"), "", 28);
891 equal(strsep(&cp, " ,"), "d", 29);
892 equal(strsep(&cp, " ,"), "", 30);
893 check(strsep(&cp, ", ") == NULL, 31);
894 check(strsep(&cp, ", ") == NULL, 32); /* Persistence. */
895 cp = strcpy(one, ", ");
896 equal(strsep(&cp, ", "), "", 33);
897 equal(strsep(&cp, ", "), "", 34);
898 equal(strsep(&cp, ", "), "", 35);
899 check(strsep(&cp, ", ") == NULL, 36); /* No tokens. */
900 cp = strcpy(one, "");
901 equal(strsep(&cp, ", "), "", 37);
902 check(strsep(&cp, ", ") == NULL, 38); /* Empty string. */
903 cp = strcpy(one, "abc");
904 equal(strsep(&cp, ", "), "abc", 39); /* No delimiters. */
905 check(strsep(&cp, ", ") == NULL, 40);
906 cp = strcpy(one, "abc");
907 equal(strsep(&cp, ""), "abc", 41); /* Empty delimiter list. */
908 check(strsep(&cp, "") == NULL, 42);
909 (void) strcpy(one, "abcdefgh");
910 cp = strcpy(one, "a,b,c");
911 equal(strsep(&cp, ","), "a", 43); /* Basics again... */
912 equal(strsep(&cp, ","), "b", 44);
913 equal(strsep(&cp, ","), "c", 45);
914 check(strsep(&cp, ",") == NULL, 46);
915 equal(one+6, "gh", 47); /* Stomped past end? */
916 equal(one, "a", 48); /* Stomped old tokens? */
917 equal(one+2, "b", 49);
918 equal(one+4, "c", 50);
921 char text[] = "This,is,a,test";
922 char *list = strdupa (text);
923 equal (strsep (&list, ","), "This", 51);
924 equal (strsep (&list, ","), "is", 52);
925 equal (strsep (&list, ","), "a", 53);
926 equal (strsep (&list, ","), "test", 54);
927 check (strsep (&list, ",") == NULL, 55);
930 cp = strcpy(one, "a,b, c,, ,d,");
931 equal(strsep(&cp, ","), "a", 56); /* Different separators. */
932 equal(strsep(&cp, ","), "b", 57);
933 equal(strsep(&cp, ","), " c", 58); /* Permute list too. */
934 equal(strsep(&cp, ","), "", 59);
935 equal(strsep(&cp, ","), " ", 60);
936 equal(strsep(&cp, ","), "d", 61);
937 equal(strsep(&cp, ","), "", 62);
938 check(strsep(&cp, ",") == NULL, 63);
939 check(strsep(&cp, ",") == NULL, 64); /* Persistence. */
941 cp = strcpy(one, "a,b, c,, ,d,");
942 equal(strsep(&cp, "xy,"), "a", 65); /* Different separators. */
943 equal(strsep(&cp, "x,y"), "b", 66);
944 equal(strsep(&cp, ",xy"), " c", 67); /* Permute list too. */
945 equal(strsep(&cp, "xy,"), "", 68);
946 equal(strsep(&cp, "x,y"), " ", 69);
947 equal(strsep(&cp, ",xy"), "d", 70);
948 equal(strsep(&cp, "xy,"), "", 71);
949 check(strsep(&cp, "x,y") == NULL, 72);
950 check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
952 cp = strcpy(one, "ABC");
953 one[4] = ':';
954 equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */
955 ptr = strsep(&cp, ":");
956 equal(ptr, "", 75);
957 check(ptr == one + 3, 76);
958 check(cp == NULL, 77);
960 cp = strcpy(one, "ABC");
961 one[4] = ':';
962 equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */
963 ptr = strsep(&cp, ":.");
964 equal(ptr, "", 79);
965 check(ptr == one + 3, 80);
967 cp = strcpy(one, "ABC"); /* No token in string. */
968 equal(strsep(&cp, ","), "ABC", 81);
969 check(cp == NULL, 82);
971 *one = '\0'; /* Empty string. */
972 cp = one;
973 ptr = strsep(&cp, ",");
974 equal(ptr, "", 83);
975 check(ptr == one, 84);
976 check(cp == NULL, 85);
978 *one = '\0'; /* Empty string and no token. */
979 cp = one;
980 ptr = strsep(&cp, "");
981 equal(ptr, "", 86);
982 check(ptr == one , 87);
983 check(cp == NULL, 88);
986 static void
987 test_memcmp (void)
989 int cnt = 1;
990 char one[21];
991 char two[21];
993 it = "memcmp";
994 check(memcmp("a", "a", 1) == 0, cnt++); /* Identity. */
995 check(memcmp("abc", "abc", 3) == 0, cnt++); /* Multicharacter. */
996 check(memcmp("abcd", "abcf", 4) < 0, cnt++); /* Honestly unequal. */
997 check(memcmp("abcf", "abcd", 4) > 0, cnt++);
998 check(memcmp("alph", "cold", 4) < 0, cnt++);
999 check(memcmp("a\203", "a\003", 2) > 0, cnt++);
1000 check(memcmp("a\003", "a\203", 2) < 0, cnt++);
1001 check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt++);
1002 check(memcmp("abc\203", "abc\003", 4) > 0, cnt++);
1003 check(memcmp("abc\003", "abc\203", 4) < 0, cnt++);
1004 check(memcmp("abcf", "abcd", 3) == 0, cnt++); /* Count limited. */
1005 check(memcmp("abc", "def", 0) == 0, cnt++); /* Zero count. */
1006 /* Comparisons with shifting 4-byte boundaries. */
1007 for (int i = 0; i < 4; ++i)
1009 char *a = one + i;
1010 char *b = two + i;
1011 strncpy(a, "--------11112222", 16);
1012 strncpy(b, "--------33334444", 16);
1013 check(memcmp(b, a, 16) > 0, cnt++);
1014 check(memcmp(a, b, 16) < 0, cnt++);
1018 static void
1019 test_memchr (void)
1021 it = "memchr";
1022 check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
1023 (void) strcpy(one, "abcd");
1024 check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
1025 check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */
1026 check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
1027 check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
1028 check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
1029 (void) strcpy(one, "ababa");
1030 check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
1031 check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
1032 check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
1033 (void) strcpy(one, "a\203b");
1034 check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
1036 /* now test all possible alignment and length combinations to catch
1037 bugs due to unrolled loops (assuming unrolling is limited to no
1038 more than 128 byte chunks: */
1040 char buf[128 + sizeof(long)];
1041 long align, len, i, pos;
1043 for (align = 0; align < (long) sizeof(long); ++align) {
1044 for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
1045 for (i = 0; i < len; ++i) {
1046 buf[align + i] = 'x'; /* don't depend on memset... */
1048 for (pos = 0; pos < len; ++pos) {
1049 #if 0
1050 printf("align %d, len %d, pos %d\n", align, len, pos);
1051 #endif
1052 check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
1053 check(memchr(buf + align, 'x', pos) == NULL, 11);
1054 buf[align + pos] = '-';
1061 static void
1062 test_memcpy (void)
1064 int i;
1065 it = "memcpy";
1066 check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
1067 equal(one, "abc", 2); /* Did the copy go right? */
1069 (void) strcpy(one, "abcdefgh");
1070 (void) memcpy(one+1, "xyz", 2);
1071 equal(one, "axydefgh", 3); /* Basic test. */
1073 (void) strcpy(one, "abc");
1074 (void) memcpy(one, "xyz", 0);
1075 equal(one, "abc", 4); /* Zero-length copy. */
1077 (void) strcpy(one, "hi there");
1078 (void) strcpy(two, "foo");
1079 (void) memcpy(two, one, 9);
1080 equal(two, "hi there", 5); /* Just paranoia. */
1081 equal(one, "hi there", 6); /* Stomped on source? */
1083 for (i = 0; i < 16; i++)
1085 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1086 strcpy (one, x);
1087 check (memcpy (one + i, "hi there", 9) == one + i,
1088 7 + (i * 6)); /* Unaligned destination. */
1089 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1090 equal (one + i, "hi there", 9 + (i * 6));
1091 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1092 check (memcpy (two, one + i, 9) == two,
1093 11 + (i * 6)); /* Unaligned source. */
1094 equal (two, "hi there", 12 + (i * 6));
1098 static void
1099 test_mempcpy (void)
1101 int i;
1102 it = "mempcpy";
1103 check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */
1104 equal(one, "abc", 2); /* Did the copy go right? */
1106 (void) strcpy(one, "abcdefgh");
1107 (void) mempcpy(one+1, "xyz", 2);
1108 equal(one, "axydefgh", 3); /* Basic test. */
1110 (void) strcpy(one, "abc");
1111 (void) mempcpy(one, "xyz", 0);
1112 equal(one, "abc", 4); /* Zero-length copy. */
1114 (void) strcpy(one, "hi there");
1115 (void) strcpy(two, "foo");
1116 (void) mempcpy(two, one, 9);
1117 equal(two, "hi there", 5); /* Just paranoia. */
1118 equal(one, "hi there", 6); /* Stomped on source? */
1120 for (i = 0; i < 16; i++)
1122 const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
1123 strcpy (one, x);
1124 check (mempcpy (one + i, "hi there", 9) == one + i + 9,
1125 7 + (i * 6)); /* Unaligned destination. */
1126 check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */
1127 equal (one + i, "hi there", 9 + (i * 6));
1128 check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */
1129 check (mempcpy (two, one + i, 9) == two + 9,
1130 11 + (i * 6)); /* Unaligned source. */
1131 equal (two, "hi there", 12 + (i * 6));
1135 static void
1136 test_memmove (void)
1138 it = "memmove";
1139 check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
1140 equal(one, "abc", 2); /* Did the copy go right? */
1142 (void) strcpy(one, "abcdefgh");
1143 (void) memmove(one+1, "xyz", 2);
1144 equal(one, "axydefgh", 3); /* Basic test. */
1146 (void) strcpy(one, "abc");
1147 (void) memmove(one, "xyz", 0);
1148 equal(one, "abc", 4); /* Zero-length copy. */
1150 (void) strcpy(one, "hi there");
1151 (void) strcpy(two, "foo");
1152 (void) memmove(two, one, 9);
1153 equal(two, "hi there", 5); /* Just paranoia. */
1154 equal(one, "hi there", 6); /* Stomped on source? */
1156 (void) strcpy(one, "abcdefgh");
1157 (void) memmove(one+1, one, 9);
1158 equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
1160 (void) strcpy(one, "abcdefgh");
1161 (void) memmove(one+1, one+2, 7);
1162 equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
1164 (void) strcpy(one, "abcdefgh");
1165 (void) memmove(one, one, 9);
1166 equal(one, "abcdefgh", 9); /* 100% overlap. */
1169 static void
1170 test_memccpy (void)
1172 /* First test like memcpy, then the search part The SVID, the only
1173 place where memccpy is mentioned, says overlap might fail, so we
1174 don't try it. Besides, it's hard to see the rationale for a
1175 non-left-to-right memccpy. */
1176 it = "memccpy";
1177 check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
1178 equal(one, "abc", 2); /* Did the copy go right? */
1180 (void) strcpy(one, "abcdefgh");
1181 (void) memccpy(one+1, "xyz", 'q', 2);
1182 equal(one, "axydefgh", 3); /* Basic test. */
1184 (void) strcpy(one, "abc");
1185 (void) memccpy(one, "xyz", 'q', 0);
1186 equal(one, "abc", 4); /* Zero-length copy. */
1188 (void) strcpy(one, "hi there");
1189 (void) strcpy(two, "foo");
1190 (void) memccpy(two, one, 'q', 9);
1191 equal(two, "hi there", 5); /* Just paranoia. */
1192 equal(one, "hi there", 6); /* Stomped on source? */
1194 (void) strcpy(one, "abcdefgh");
1195 (void) strcpy(two, "horsefeathers");
1196 check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
1197 equal(one, "abcdefgh", 8); /* Source intact? */
1198 equal(two, "abcdefeathers", 9); /* Copy correct? */
1200 (void) strcpy(one, "abcd");
1201 (void) strcpy(two, "bumblebee");
1202 check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
1203 equal(two, "aumblebee", 11);
1204 check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
1205 equal(two, "abcdlebee", 13);
1206 (void) strcpy(one, "xyz");
1207 check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
1208 equal(two, "xbcdlebee", 15);
1211 static void
1212 test_memset (void)
1214 int i;
1216 it = "memset";
1217 (void) strcpy(one, "abcdefgh");
1218 check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
1219 equal(one, "axxxefgh", 2); /* Basic test. */
1221 (void) memset(one+2, 'y', 0);
1222 equal(one, "axxxefgh", 3); /* Zero-length set. */
1224 (void) memset(one+5, 0, 1);
1225 equal(one, "axxxe", 4); /* Zero fill. */
1226 equal(one+6, "gh", 5); /* And the leftover. */
1228 (void) memset(one+2, 010045, 1);
1229 equal(one, "ax\045xe", 6); /* Unsigned char convert. */
1231 /* Non-8bit fill character. */
1232 memset (one, 0x101, sizeof (one));
1233 for (i = 0; i < (int) sizeof (one); ++i)
1234 check (one[i] == '\01', 7);
1236 /* Test for more complex versions of memset, for all alignments and
1237 lengths up to 256. This test takes a little while, perhaps it should
1238 be made weaker? */
1240 char data[512];
1241 int j;
1242 int k;
1243 int c;
1245 for (i = 0; i < 512; i++)
1246 data[i] = 'x';
1247 for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and
1248 memset(,'y',) */
1249 for (j = 0; j < 256; j++)
1250 for (i = 0; i < 256; i++)
1252 memset (data + i, c, j);
1253 for (k = 0; k < i; k++)
1254 if (data[k] != 'x')
1255 goto fail;
1256 for (k = i; k < i+j; k++)
1258 if (data[k] != c)
1259 goto fail;
1260 data[k] = 'x';
1262 for (k = i+j; k < 512; k++)
1263 if (data[k] != 'x')
1264 goto fail;
1265 continue;
1267 fail:
1268 check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
1273 static void
1274 test_bcopy (void)
1276 /* Much like memcpy. Berklix manual is silent about overlap, so
1277 don't test it. */
1278 it = "bcopy";
1279 (void) bcopy("abc", one, 4);
1280 equal(one, "abc", 1); /* Simple copy. */
1282 (void) strcpy(one, "abcdefgh");
1283 (void) bcopy("xyz", one+1, 2);
1284 equal(one, "axydefgh", 2); /* Basic test. */
1286 (void) strcpy(one, "abc");
1287 (void) bcopy("xyz", one, 0);
1288 equal(one, "abc", 3); /* Zero-length copy. */
1290 (void) strcpy(one, "hi there");
1291 (void) strcpy(two, "foo");
1292 (void) bcopy(one, two, 9);
1293 equal(two, "hi there", 4); /* Just paranoia. */
1294 equal(one, "hi there", 5); /* Stomped on source? */
1297 static void
1298 test_bzero (void)
1300 it = "bzero";
1301 (void) strcpy(one, "abcdef");
1302 bzero(one+2, 2);
1303 equal(one, "ab", 1); /* Basic test. */
1304 equal(one+3, "", 2);
1305 equal(one+4, "ef", 3);
1307 (void) strcpy(one, "abcdef");
1308 bzero(one+2, 0);
1309 equal(one, "abcdef", 4); /* Zero-length copy. */
1312 static void
1313 test_strndup (void)
1315 char *p, *q;
1316 it = "strndup";
1317 p = strndup("abcdef", 12);
1318 check(p != NULL, 1);
1319 if (p != NULL)
1321 equal(p, "abcdef", 2);
1322 q = strndup(p + 1, 2);
1323 check(q != NULL, 3);
1324 if (q != NULL)
1325 equal(q, "bc", 4);
1326 free (q);
1328 free (p);
1329 p = strndup("abc def", 3);
1330 check(p != NULL, 5);
1331 if (p != NULL)
1332 equal(p, "abc", 6);
1333 free (p);
1336 static void
1337 test_bcmp (void)
1339 it = "bcmp";
1340 check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
1341 check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
1342 check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
1343 check(bcmp("abce", "abcd", 4) != 0, 4);
1344 check(bcmp("alph", "beta", 4) != 0, 5);
1345 check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
1346 check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
1349 static void
1350 test_strerror (void)
1352 it = "strerror";
1353 check(strerror(EDOM) != 0, 1);
1354 check(strerror(ERANGE) != 0, 2);
1355 check(strerror(ENOENT) != 0, 3);
1358 static void
1359 test_strcasecmp (void)
1361 it = "strcasecmp";
1362 /* Note that the locale is "C". */
1363 check(strcasecmp("a", "a") == 0, 1);
1364 check(strcasecmp("a", "A") == 0, 2);
1365 check(strcasecmp("A", "a") == 0, 3);
1366 check(strcasecmp("a", "b") < 0, 4);
1367 check(strcasecmp("c", "b") > 0, 5);
1368 check(strcasecmp("abc", "AbC") == 0, 6);
1369 check(strcasecmp("0123456789", "0123456789") == 0, 7);
1370 check(strcasecmp("", "0123456789") < 0, 8);
1371 check(strcasecmp("AbC", "") > 0, 9);
1372 check(strcasecmp("AbC", "A") > 0, 10);
1373 check(strcasecmp("AbC", "Ab") > 0, 11);
1374 check(strcasecmp("AbC", "ab") > 0, 12);
1377 static void
1378 test_strncasecmp (void)
1380 it = "strncasecmp";
1381 /* Note that the locale is "C". */
1382 check(strncasecmp("a", "a", 5) == 0, 1);
1383 check(strncasecmp("a", "A", 5) == 0, 2);
1384 check(strncasecmp("A", "a", 5) == 0, 3);
1385 check(strncasecmp("a", "b", 5) < 0, 4);
1386 check(strncasecmp("c", "b", 5) > 0, 5);
1387 check(strncasecmp("abc", "AbC", 5) == 0, 6);
1388 check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
1389 check(strncasecmp("", "0123456789", 10) < 0, 8);
1390 check(strncasecmp("AbC", "", 5) > 0, 9);
1391 check(strncasecmp("AbC", "A", 5) > 0, 10);
1392 check(strncasecmp("AbC", "Ab", 5) > 0, 11);
1393 check(strncasecmp("AbC", "ab", 5) > 0, 12);
1394 check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
1395 check(strncasecmp("AbC", "abc", 1) == 0, 14);
1396 check(strncasecmp("AbC", "abc", 2) == 0, 15);
1397 check(strncasecmp("AbC", "abc", 3) == 0, 16);
1398 check(strncasecmp("AbC", "abcd", 3) == 0, 17);
1399 check(strncasecmp("AbC", "abcd", 4) < 0, 18);
1400 check(strncasecmp("ADC", "abcd", 1) == 0, 19);
1401 check(strncasecmp("ADC", "abcd", 2) > 0, 20);
1405 main (void)
1407 int status;
1409 /* Test strcmp first because we use it to test other things. */
1410 test_strcmp ();
1412 /* Test strcpy next because we need it to set up other tests. */
1413 test_strcpy ();
1415 /* A closely related function is stpcpy. */
1416 test_stpcpy ();
1418 /* stpncpy. */
1419 test_stpncpy ();
1421 /* strcat. */
1422 test_strcat ();
1424 /* strncat. */
1425 test_strncat ();
1427 /* strncmp. */
1428 test_strncmp ();
1430 /* strncpy. */
1431 test_strncpy ();
1433 /* strlen. */
1434 test_strlen ();
1436 /* strnlen. */
1437 test_strnlen ();
1439 /* strchr. */
1440 test_strchr ();
1442 /* strchrnul. */
1443 test_strchrnul ();
1445 /* rawmemchr. */
1446 test_rawmemchr ();
1448 /* index - just like strchr. */
1449 test_index ();
1451 /* strrchr. */
1452 test_strrchr ();
1454 /* memrchr. */
1455 test_memrchr ();
1457 /* rindex - just like strrchr. */
1458 test_rindex ();
1460 /* strpbrk - somewhat like strchr. */
1461 test_strpbrk ();
1463 /* strstr - somewhat like strchr. */
1464 test_strstr ();
1466 /* strspn. */
1467 test_strspn ();
1469 /* strcspn. */
1470 test_strcspn ();
1472 /* strtok - the hard one. */
1473 test_strtok ();
1475 /* strtok_r. */
1476 test_strtok_r ();
1478 /* strsep. */
1479 test_strsep ();
1481 /* memcmp. */
1482 test_memcmp ();
1484 /* memchr. */
1485 test_memchr ();
1487 /* memcpy - need not work for overlap. */
1488 test_memcpy ();
1490 /* memmove - must work on overlap. */
1491 test_memmove ();
1493 /* mempcpy */
1494 test_mempcpy ();
1496 /* memccpy. */
1497 test_memccpy ();
1499 /* memset. */
1500 test_memset ();
1502 /* bcopy. */
1503 test_bcopy ();
1505 /* bzero. */
1506 test_bzero ();
1508 /* bcmp - somewhat like memcmp. */
1509 test_bcmp ();
1511 /* strndup. */
1512 test_strndup ();
1514 /* strerror - VERY system-dependent. */
1515 test_strerror ();
1517 /* strcasecmp. Without locale dependencies. */
1518 test_strcasecmp ();
1520 /* strncasecmp. Without locale dependencies. */
1521 test_strncasecmp ();
1523 if (errors == 0)
1525 status = EXIT_SUCCESS;
1526 puts("No errors.");
1528 else
1530 status = EXIT_FAILURE;
1531 printf("%Zd errors.\n", errors);
1534 return status;