source: branches/libc-0.6/src/libctests/glibc/string/tester.c

Last change on this file was 2044, checked in by bird, 20 years ago

Porting to 64-bit FreeBSD...

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