xref: /freebsd/contrib/netbsd-tests/lib/libc/string/t_strchr.c (revision 20a4ce8bf215487ce53d30ccae3bb6c86babb5a2)
1 /* $NetBSD: t_strchr.c,v 1.1 2011/07/07 08:59:33 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 #include <dlfcn.h>
14 
15 static char	*slow_strchr(char *, int);
16 static void	 verify_strchr(char *, int, unsigned int, unsigned int);
17 
18 char * (*volatile strchr_fn)(const char *, int);
19 
20 static char *
21 slow_strchr(char *buf, int ch)
22 {
23 	unsigned char c = 1;
24 
25 	ch &= 0xff;
26 
27 	for (; c != 0; buf++) {
28 		c = *buf;
29 		if (c == ch)
30 			return buf;
31 	}
32 	return 0;
33 }
34 
35 static void
36 verify_strchr(char *buf, int ch, unsigned int t, unsigned int a)
37 {
38 	const char *off, *ok_off;
39 
40 	off = strchr_fn(buf, ch);
41 	ok_off = slow_strchr(buf, ch);
42 	if (off == ok_off)
43 		return;
44 
45 	fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, "
46 	    "alignment %d)\n",
47 	    buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a);
48 
49 	atf_tc_fail("Check stderr for details");
50 }
51 
52 ATF_TC(strchr_basic);
53 ATF_TC_HEAD(strchr_basic, tc)
54 {
55 
56         atf_tc_set_md_var(tc, "descr", "Test strchr(3) results");
57 }
58 
59 ATF_TC_BODY(strchr_basic, tc)
60 {
61 #ifdef	__FreeBSD__
62 	void *dl_handle;
63 #endif
64 	unsigned int t, a;
65 	char *off;
66 	char buf[32];
67 
68 	const char *tab[] = {
69 		"",
70 		"a",
71 		"aa",
72 		"abc",
73 		"abcd",
74 		"abcde",
75 		"abcdef",
76 		"abcdefg",
77 		"abcdefgh",
78 
79 		"/",
80 		"//",
81 		"/a",
82 		"/a/",
83 		"/ab",
84 		"/ab/",
85 		"/abc",
86 		"/abc/",
87 		"/abcd",
88 		"/abcd/",
89 		"/abcde",
90 		"/abcde/",
91 		"/abcdef",
92 		"/abcdef/",
93 		"/abcdefg",
94 		"/abcdefg/",
95 		"/abcdefgh",
96 		"/abcdefgh/",
97 
98 		"a/",
99 		"a//",
100 		"a/a",
101 		"a/a/",
102 		"a/ab",
103 		"a/ab/",
104 		"a/abc",
105 		"a/abc/",
106 		"a/abcd",
107 		"a/abcd/",
108 		"a/abcde",
109 		"a/abcde/",
110 		"a/abcdef",
111 		"a/abcdef/",
112 		"a/abcdefg",
113 		"a/abcdefg/",
114 		"a/abcdefgh",
115 		"a/abcdefgh/",
116 
117 		"ab/",
118 		"ab//",
119 		"ab/a",
120 		"ab/a/",
121 		"ab/ab",
122 		"ab/ab/",
123 		"ab/abc",
124 		"ab/abc/",
125 		"ab/abcd",
126 		"ab/abcd/",
127 		"ab/abcde",
128 		"ab/abcde/",
129 		"ab/abcdef",
130 		"ab/abcdef/",
131 		"ab/abcdefg",
132 		"ab/abcdefg/",
133 		"ab/abcdefgh",
134 		"ab/abcdefgh/",
135 
136 		"abc/",
137 		"abc//",
138 		"abc/a",
139 		"abc/a/",
140 		"abc/ab",
141 		"abc/ab/",
142 		"abc/abc",
143 		"abc/abc/",
144 		"abc/abcd",
145 		"abc/abcd/",
146 		"abc/abcde",
147 		"abc/abcde/",
148 		"abc/abcdef",
149 		"abc/abcdef/",
150 		"abc/abcdefg",
151 		"abc/abcdefg/",
152 		"abc/abcdefgh",
153 		"abc/abcdefgh/",
154 
155 		"abcd/",
156 		"abcd//",
157 		"abcd/a",
158 		"abcd/a/",
159 		"abcd/ab",
160 		"abcd/ab/",
161 		"abcd/abc",
162 		"abcd/abc/",
163 		"abcd/abcd",
164 		"abcd/abcd/",
165 		"abcd/abcde",
166 		"abcd/abcde/",
167 		"abcd/abcdef",
168 		"abcd/abcdef/",
169 		"abcd/abcdefg",
170 		"abcd/abcdefg/",
171 		"abcd/abcdefgh",
172 		"abcd/abcdefgh/",
173 
174 		"abcde/",
175 		"abcde//",
176 		"abcde/a",
177 		"abcde/a/",
178 		"abcde/ab",
179 		"abcde/ab/",
180 		"abcde/abc",
181 		"abcde/abc/",
182 		"abcde/abcd",
183 		"abcde/abcd/",
184 		"abcde/abcde",
185 		"abcde/abcde/",
186 		"abcde/abcdef",
187 		"abcde/abcdef/",
188 		"abcde/abcdefg",
189 		"abcde/abcdefg/",
190 		"abcde/abcdefgh",
191 		"abcde/abcdefgh/",
192 
193 		"abcdef/",
194 		"abcdef//",
195 		"abcdef/a",
196 		"abcdef/a/",
197 		"abcdef/ab",
198 		"abcdef/ab/",
199 		"abcdef/abc",
200 		"abcdef/abc/",
201 		"abcdef/abcd",
202 		"abcdef/abcd/",
203 		"abcdef/abcde",
204 		"abcdef/abcde/",
205 		"abcdef/abcdef",
206 		"abcdef/abcdef/",
207 		"abcdef/abcdefg",
208 		"abcdef/abcdefg/",
209 		"abcdef/abcdefgh",
210 		"abcdef/abcdefgh/",
211 
212 		"abcdefg/",
213 		"abcdefg//",
214 		"abcdefg/a",
215 		"abcdefg/a/",
216 		"abcdefg/ab",
217 		"abcdefg/ab/",
218 		"abcdefg/abc",
219 		"abcdefg/abc/",
220 		"abcdefg/abcd",
221 		"abcdefg/abcd/",
222 		"abcdefg/abcde",
223 		"abcdefg/abcde/",
224 		"abcdefg/abcdef",
225 		"abcdefg/abcdef/",
226 		"abcdefg/abcdefg",
227 		"abcdefg/abcdefg/",
228 		"abcdefg/abcdefgh",
229 		"abcdefg/abcdefgh/",
230 
231 		"abcdefgh/",
232 		"abcdefgh//",
233 		"abcdefgh/a",
234 		"abcdefgh/a/",
235 		"abcdefgh/ab",
236 		"abcdefgh/ab/",
237 		"abcdefgh/abc",
238 		"abcdefgh/abc/",
239 		"abcdefgh/abcd",
240 		"abcdefgh/abcd/",
241 		"abcdefgh/abcde",
242 		"abcdefgh/abcde/",
243 		"abcdefgh/abcdef",
244 		"abcdefgh/abcdef/",
245 		"abcdefgh/abcdefg",
246 		"abcdefgh/abcdefg/",
247 		"abcdefgh/abcdefgh",
248 		"abcdefgh/abcdefgh/",
249 	};
250 
251 #ifdef	__FreeBSD__
252 	dl_handle = dlopen(NULL, RTLD_LAZY);
253 	strchr_fn = dlsym(dl_handle, "test_strlen");
254 #else
255 	strchr_fn = dlsym(dlopen(0, RTLD_LAZY), "test_strchr");
256 #endif
257 	if (!strchr_fn)
258 		strchr_fn = strchr;
259 
260 	for (a = 3; a < 3 + sizeof(long); ++a) {
261 		/* Put char and a \0 before the buffer */
262 		buf[a-1] = '/';
263 		buf[a-2] = '0';
264 		buf[a-3] = 0xff;
265 		for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
266 			int len = strlen(tab[t]) + 1;
267 			memcpy(&buf[a], tab[t], len);
268 
269 			/* Put the char we are looking for after the \0 */
270 			buf[a + len] = '/';
271 
272 			/* Check search for NUL at end of string */
273 			verify_strchr(buf + a, 0, t, a);
274 
275 			/* Then for the '/' in the strings */
276 			verify_strchr(buf + a, '/', t, a);
277 
278 		   	/* check zero extension of char arg */
279 		   	verify_strchr(buf + a, 0xffffff00 | '/', t, a);
280 
281 		   	/* Replace all the '/' with 0xff */
282 		   	while ((off = slow_strchr(buf + a, '/')) != NULL)
283 				*off = 0xff;
284 
285 			buf[a + len] = 0xff;
286 
287 			/* Check we can search for 0xff as well as '/' */
288 			verify_strchr(buf + a, 0xff, t, a);
289 		}
290 	}
291 #ifdef	__FreeBSD__
292 	(void)dlclose(dl_handle);
293 #endif
294 }
295 
296 ATF_TP_ADD_TCS(tp)
297 {
298 
299 	ATF_TP_ADD_TC(tp, strchr_basic);
300 
301 	return atf_no_error();
302 }
303