No empty .Rs/.Re
[netbsd-mini2440.git] / regress / lib / libc / string / memchr / memchr_test.c
blob18ece5dbff9340196bbc9d5d9c25003b245dd61a
1 /*
2 * Written by J.T. Conklin <jtc@acorntoolworks.com>
3 * Public domain.
4 */
6 /*
7 * str*() regression suite
9 * Trivial str*() implementations can be audited by hand. Optimized
10 * versions that unroll loops, use naturally-aligned memory acesses,
11 * and "magic" arithmetic sequences to detect zero-bytes, written in
12 * assembler are much harder to validate. This program attempts to
13 * catch the corner cases.
15 * BUGS:
16 * Misssing checks for strncpy, strncat, strncmp, etc.
18 * TODO:
19 * Use mmap/mprotect to ensure the functions don't access memory
20 * across page boundaries.
22 * Consider generating tables programmatically. It would reduce
23 * the size, but it's also one more thing to go wrong.
25 * Share tables between strlen, strcpy, and strcat?
26 * Share tables between strchr and strrchr?
29 #include <assert.h>
30 #include <string.h>
32 void check_memchr(void);
34 void
35 check_memchr(void)
37 /* try to trick the compiler */
38 void * (*f)(const void *, int, size_t) = memchr;
40 int a;
41 int t;
42 void * off;
43 char buf[32];
45 struct tab {
46 const char *val;
47 size_t len;
48 char match;
49 size_t off;
52 const struct tab tab[] = {
53 { "", 0, 0, 0 },
55 { "/", 0, 0, 0 },
56 { "/", 1, 1, 0 },
57 { "/a", 2, 1, 0 },
58 { "/ab", 3, 1, 0 },
59 { "/abc", 4, 1, 0 },
60 { "/abcd", 5, 1, 0 },
61 { "/abcde", 6, 1, 0 },
62 { "/abcdef", 7, 1, 0 },
63 { "/abcdefg", 8, 1, 0 },
65 { "a/", 1, 0, 0 },
66 { "a/", 2, 1, 1 },
67 { "a/b", 3, 1, 1 },
68 { "a/bc", 4, 1, 1 },
69 { "a/bcd", 5, 1, 1 },
70 { "a/bcde", 6, 1, 1 },
71 { "a/bcdef", 7, 1, 1 },
72 { "a/bcdefg", 8, 1, 1 },
74 { "ab/", 2, 0, 0 },
75 { "ab/", 3, 1, 2 },
76 { "ab/c", 4, 1, 2 },
77 { "ab/cd", 5, 1, 2 },
78 { "ab/cde", 6, 1, 2 },
79 { "ab/cdef", 7, 1, 2 },
80 { "ab/cdefg", 8, 1, 2 },
82 { "abc/", 3, 0, 0 },
83 { "abc/", 4, 1, 3 },
84 { "abc/d", 5, 1, 3 },
85 { "abc/de", 6, 1, 3 },
86 { "abc/def", 7, 1, 3 },
87 { "abc/defg", 8, 1, 3 },
89 { "abcd/", 4, 0, 0 },
90 { "abcd/", 5, 1, 4 },
91 { "abcd/e", 6, 1, 4 },
92 { "abcd/ef", 7, 1, 4 },
93 { "abcd/efg", 8, 1, 4 },
95 { "abcde/", 5, 0, 0 },
96 { "abcde/", 6, 1, 5 },
97 { "abcde/f", 7, 1, 5 },
98 { "abcde/fg", 8, 1, 5 },
100 { "abcdef/", 6, 0, 0 },
101 { "abcdef/", 7, 1, 6 },
102 { "abcdef/g", 8, 1, 6 },
104 { "abcdefg/", 7, 0, 0 },
105 { "abcdefg/", 8, 1, 7 },
107 { "\xff\xff\xff\xff" "efg/", 8, 1, 7 },
108 { "a" "\xff\xff\xff\xff" "fg/", 8, 1, 7 },
109 { "ab" "\xff\xff\xff\xff" "g/", 8, 1, 7 },
110 { "abc" "\xff\xff\xff\xff" "/", 8, 1, 7 },
113 for (a = 1; a < 1 + sizeof(long); ++a) {
114 for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
115 buf[a-1] = '/';
116 strcpy(&buf[a], tab[t].val);
118 off = f(&buf[a], '/', tab[t].len);
119 assert((tab[t].match == 0 && off == 0) ||
120 (tab[t].match == 1 && (tab[t].off == ((char*)off - &buf[a]))));
122 // check zero extension of char arg
123 off = f(&buf[a], 0xffffff00 | '/', tab[t].len);
124 assert((tab[t].match == 0 && off == 0) ||
125 (tab[t].match == 1 && (tab[t].off == ((char*)off - &buf[a]))));
131 main(void)
133 check_memchr();
134 return 0;