t_strchr.c revision 311611
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
15static char	*slow_strchr(char *, int);
16static void	 verify_strchr(char *, int, unsigned int, unsigned int);
17
18char * (*volatile strchr_fn)(const char *, int);
19
20static char *
21slow_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
35static void
36verify_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
52ATF_TC(strchr_basic);
53ATF_TC_HEAD(strchr_basic, tc)
54{
55
56        atf_tc_set_md_var(tc, "descr", "Test strchr(3) results");
57}
58
59ATF_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
296ATF_TP_ADD_TCS(tp)
297{
298
299	ATF_TP_ADD_TC(tp, strchr_basic);
300
301	return atf_no_error();
302}
303