1 /* $NetBSD: t_memchr.c,v 1.3 2012/04/06 07:53:10 jruoho Exp $ */
2 
3 /*
4  * Written by J.T. Conklin <jtc@acorntoolworks.com>
5  * Public domain.
6  */
7 
8 #include <atf-c.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 
14 ATF_TC(memchr_basic);
ATF_TC_HEAD(memchr_basic,tc)15 ATF_TC_HEAD(memchr_basic, tc)
16 {
17         atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #1");
18 }
19 
ATF_TC_BODY(memchr_basic,tc)20 ATF_TC_BODY(memchr_basic, tc)
21 {
22           /* try to trick the compiler */
23           void * (*f)(const void *, int, size_t) = memchr;
24 
25           unsigned int a, t;
26           void *off, *off2;
27           char buf[32];
28 
29           struct tab {
30                     const char          *val;
31                     size_t     len;
32                     char                 match;
33                     ssize_t              off;
34           };
35 
36           const struct tab tab[] = {
37                     { "",                         0, 0, 0 },
38 
39                     { "/",                        0, 0, 0 },
40                     { "/",                        1, 1, 0 },
41                     { "/a",                       2, 1, 0 },
42                     { "/ab",            3, 1, 0 },
43                     { "/abc",           4, 1, 0 },
44                     { "/abcd",                    5, 1, 0 },
45                     { "/abcde",                   6, 1, 0 },
46                     { "/abcdef",                  7, 1, 0 },
47                     { "/abcdefg",                 8, 1, 0 },
48 
49                     { "a/",                       1, 0, 0 },
50                     { "a/",                       2, 1, 1 },
51                     { "a/b",            3, 1, 1 },
52                     { "a/bc",           4, 1, 1 },
53                     { "a/bcd",                    5, 1, 1 },
54                     { "a/bcde",                   6, 1, 1 },
55                     { "a/bcdef",                  7, 1, 1 },
56                     { "a/bcdefg",                 8, 1, 1 },
57 
58                     { "ab/",            2, 0, 0 },
59                     { "ab/",            3, 1, 2 },
60                     { "ab/c",           4, 1, 2 },
61                     { "ab/cd",                    5, 1, 2 },
62                     { "ab/cde",                   6, 1, 2 },
63                     { "ab/cdef",                  7, 1, 2 },
64                     { "ab/cdefg",                 8, 1, 2 },
65 
66                     { "abc/",           3, 0, 0 },
67                     { "abc/",           4, 1, 3 },
68                     { "abc/d",                    5, 1, 3 },
69                     { "abc/de",                   6, 1, 3 },
70                     { "abc/def",                  7, 1, 3 },
71                     { "abc/defg",                 8, 1, 3 },
72 
73                     { "abcd/",                    4, 0, 0 },
74                     { "abcd/",                    5, 1, 4 },
75                     { "abcd/e",                   6, 1, 4 },
76                     { "abcd/ef",                  7, 1, 4 },
77                     { "abcd/efg",                 8, 1, 4 },
78 
79                     { "abcde/",                   5, 0, 0 },
80                     { "abcde/",                   6, 1, 5 },
81                     { "abcde/f",                  7, 1, 5 },
82                     { "abcde/fg",                 8, 1, 5 },
83 
84                     { "abcdef/",                  6, 0, 0 },
85                     { "abcdef/",                  7, 1, 6 },
86                     { "abcdef/g",                 8, 1, 6 },
87 
88                     { "abcdefg/",                 7, 0, 0 },
89                     { "abcdefg/",                 8, 1, 7 },
90 
91                     { "\xff\xff\xff\xff" "efg/",  8, 1, 7 },
92                     { "a" "\xff\xff\xff\xff" "fg/",         8, 1, 7 },
93                     { "ab" "\xff\xff\xff\xff" "g/",         8, 1, 7 },
94                     { "abc" "\xff\xff\xff\xff" "/",         8, 1, 7 },
95           };
96 
97           for (a = 1; a < 1 + sizeof(long); ++a) {
98                     for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
99                               buf[a-1] = '/';
100                               strcpy(&buf[a], tab[t].val);
101 
102                               off = f(&buf[a], '/', tab[t].len);
103                               if (tab[t].match == 0) {
104                                         if (off != 0) {
105                                                   fprintf(stderr, "a = %d, t = %d\n",
106                                                       a, t);
107                                                   atf_tc_fail("should not have found "
108                                                       " char past len");
109                                         }
110                               } else if (tab[t].match == 1) {
111                                         if (tab[t].off != ((char*)off - &buf[a])) {
112                                                   fprintf(stderr, "a = %d, t = %d\n",
113                                                       a, t);
114                                                   atf_tc_fail("char not found at "
115                                                       "correct offset");
116                                         }
117                               } else {
118                                         fprintf(stderr, "a = %d, t = %d\n", a, t);
119                                         atf_tc_fail("Corrupt test case data");
120                               }
121 
122                               /* check zero extension of char arg */
123                               off2 = f(&buf[a], 0xffffff00 | '/', tab[t].len);
124                               if (off2 != off)
125                                         atf_tc_fail("zero extension of char arg "
126                                             "failed");
127                     }
128           }
129 }
130 
131 ATF_TC(memchr_simple);
ATF_TC_HEAD(memchr_simple,tc)132 ATF_TC_HEAD(memchr_simple, tc)
133 {
134         atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #2");
135 }
136 
ATF_TC_BODY(memchr_simple,tc)137 ATF_TC_BODY(memchr_simple, tc)
138 {
139           char buf[] = "abcdefg";
140           short i = 7;
141 
142           ATF_CHECK(memchr(buf, 'a', 0) == NULL);
143           ATF_CHECK(memchr(buf, 'g', 0) == NULL);
144           ATF_CHECK(memchr(buf, 'x', 7) == NULL);
145 
146           ATF_CHECK(memchr("\0", 'x', 0) == NULL);
147           ATF_CHECK(memchr("\0", 'x', 1) == NULL);
148 
149           while (i <= 14) {
150 
151                     ATF_CHECK(memchr(buf, 'a', i) == buf + 0);
152                     ATF_CHECK(memchr(buf, 'b', i) == buf + 1);
153                     ATF_CHECK(memchr(buf, 'c', i) == buf + 2);
154                     ATF_CHECK(memchr(buf, 'd', i) == buf + 3);
155                     ATF_CHECK(memchr(buf, 'e', i) == buf + 4);
156                     ATF_CHECK(memchr(buf, 'f', i) == buf + 5);
157                     ATF_CHECK(memchr(buf, 'g', i) == buf + 6);
158 
159                     i *= 2;
160           }
161 }
162 
163 ATF_TC(memrchr_simple);
ATF_TC_HEAD(memrchr_simple,tc)164 ATF_TC_HEAD(memrchr_simple, tc)
165 {
166         atf_tc_set_md_var(tc, "descr", "Test memrchr(3) results");
167 }
168 
ATF_TC_BODY(memrchr_simple,tc)169 ATF_TC_BODY(memrchr_simple, tc)
170 {
171           char buf[] = "abcdabcd";
172 
173           ATF_CHECK(memrchr(buf, 'a', 0) == NULL);
174           ATF_CHECK(memrchr(buf, 'g', 0) == NULL);
175           ATF_CHECK(memrchr(buf, 'x', 8) == NULL);
176 
177           ATF_CHECK(memrchr("\0", 'x', 0) == NULL);
178           ATF_CHECK(memrchr("\0", 'x', 1) == NULL);
179 
180           ATF_CHECK(memrchr(buf, 'a', 8) == buf + 4);
181           ATF_CHECK(memrchr(buf, 'b', 8) == buf + 5);
182           ATF_CHECK(memrchr(buf, 'c', 8) == buf + 6);
183           ATF_CHECK(memrchr(buf, 'd', 8) == buf + 7);
184 }
185 
ATF_TP_ADD_TCS(tp)186 ATF_TP_ADD_TCS(tp)
187 {
188 
189           ATF_TP_ADD_TC(tp, memchr_basic);
190           ATF_TP_ADD_TC(tp, memchr_simple);
191           ATF_TP_ADD_TC(tp, memrchr_simple);
192 
193           return atf_no_error();
194 }
195