1272343Sngie/* $NetBSD: t_memchr.c,v 1.3 2012/04/06 07:53:10 jruoho Exp $ */
2272343Sngie
3272343Sngie/*
4272343Sngie * Written by J.T. Conklin <jtc@acorntoolworks.com>
5272343Sngie * Public domain.
6272343Sngie */
7272343Sngie
8272343Sngie#include <atf-c.h>
9272343Sngie#include <string.h>
10272343Sngie#include <unistd.h>
11272343Sngie#include <stdio.h>
12272343Sngie#include <stdlib.h>
13272343Sngie
14272343SngieATF_TC(memchr_basic);
15272343SngieATF_TC_HEAD(memchr_basic, tc)
16272343Sngie{
17272343Sngie        atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #1");
18272343Sngie}
19272343Sngie
20272343SngieATF_TC_BODY(memchr_basic, tc)
21272343Sngie{
22272343Sngie	/* try to trick the compiler */
23272343Sngie	void * (*f)(const void *, int, size_t) = memchr;
24272343Sngie
25272343Sngie	unsigned int a, t;
26272343Sngie	void *off, *off2;
27272343Sngie	char buf[32];
28272343Sngie
29272343Sngie	struct tab {
30272343Sngie		const char	*val;
31272343Sngie		size_t  	 len;
32272343Sngie		char		 match;
33272343Sngie		ssize_t		 off;
34272343Sngie	};
35272343Sngie
36272343Sngie	const struct tab tab[] = {
37272343Sngie		{ "",			0, 0, 0 },
38272343Sngie
39272343Sngie		{ "/",			0, 0, 0 },
40272343Sngie		{ "/",			1, 1, 0 },
41272343Sngie		{ "/a",			2, 1, 0 },
42272343Sngie		{ "/ab",		3, 1, 0 },
43272343Sngie		{ "/abc",		4, 1, 0 },
44272343Sngie		{ "/abcd",		5, 1, 0 },
45272343Sngie		{ "/abcde",		6, 1, 0 },
46272343Sngie		{ "/abcdef",		7, 1, 0 },
47272343Sngie		{ "/abcdefg",		8, 1, 0 },
48272343Sngie
49272343Sngie		{ "a/",			1, 0, 0 },
50272343Sngie		{ "a/",			2, 1, 1 },
51272343Sngie		{ "a/b",		3, 1, 1 },
52272343Sngie		{ "a/bc",		4, 1, 1 },
53272343Sngie		{ "a/bcd",		5, 1, 1 },
54272343Sngie		{ "a/bcde",		6, 1, 1 },
55272343Sngie		{ "a/bcdef",		7, 1, 1 },
56272343Sngie		{ "a/bcdefg",		8, 1, 1 },
57272343Sngie
58272343Sngie		{ "ab/",		2, 0, 0 },
59272343Sngie		{ "ab/",		3, 1, 2 },
60272343Sngie		{ "ab/c",		4, 1, 2 },
61272343Sngie		{ "ab/cd",		5, 1, 2 },
62272343Sngie		{ "ab/cde",		6, 1, 2 },
63272343Sngie		{ "ab/cdef",		7, 1, 2 },
64272343Sngie		{ "ab/cdefg",		8, 1, 2 },
65272343Sngie
66272343Sngie		{ "abc/",		3, 0, 0 },
67272343Sngie		{ "abc/",		4, 1, 3 },
68272343Sngie		{ "abc/d",		5, 1, 3 },
69272343Sngie		{ "abc/de",		6, 1, 3 },
70272343Sngie		{ "abc/def",		7, 1, 3 },
71272343Sngie		{ "abc/defg",		8, 1, 3 },
72272343Sngie
73272343Sngie		{ "abcd/",		4, 0, 0 },
74272343Sngie		{ "abcd/",		5, 1, 4 },
75272343Sngie		{ "abcd/e",		6, 1, 4 },
76272343Sngie		{ "abcd/ef",		7, 1, 4 },
77272343Sngie		{ "abcd/efg",		8, 1, 4 },
78272343Sngie
79272343Sngie		{ "abcde/",		5, 0, 0 },
80272343Sngie		{ "abcde/",		6, 1, 5 },
81272343Sngie		{ "abcde/f",		7, 1, 5 },
82272343Sngie		{ "abcde/fg",		8, 1, 5 },
83272343Sngie
84272343Sngie		{ "abcdef/",		6, 0, 0 },
85272343Sngie		{ "abcdef/",		7, 1, 6 },
86272343Sngie		{ "abcdef/g",		8, 1, 6 },
87272343Sngie
88272343Sngie		{ "abcdefg/",		7, 0, 0 },
89272343Sngie		{ "abcdefg/",		8, 1, 7 },
90272343Sngie
91272343Sngie		{ "\xff\xff\xff\xff" "efg/",	8, 1, 7 },
92272343Sngie		{ "a" "\xff\xff\xff\xff" "fg/",	8, 1, 7 },
93272343Sngie		{ "ab" "\xff\xff\xff\xff" "g/",	8, 1, 7 },
94272343Sngie		{ "abc" "\xff\xff\xff\xff" "/",	8, 1, 7 },
95272343Sngie	};
96272343Sngie
97272343Sngie	for (a = 1; a < 1 + sizeof(long); ++a) {
98272343Sngie		for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
99272343Sngie			buf[a-1] = '/';
100272343Sngie			strcpy(&buf[a], tab[t].val);
101272343Sngie
102272343Sngie			off = f(&buf[a], '/', tab[t].len);
103272343Sngie			if (tab[t].match == 0) {
104272343Sngie				if (off != 0) {
105272343Sngie					fprintf(stderr, "a = %d, t = %d\n",
106272343Sngie					    a, t);
107272343Sngie					atf_tc_fail("should not have found "
108272343Sngie					    " char past len");
109272343Sngie				}
110272343Sngie			} else if (tab[t].match == 1) {
111272343Sngie				if (tab[t].off != ((char*)off - &buf[a])) {
112272343Sngie					fprintf(stderr, "a = %d, t = %d\n",
113272343Sngie					    a, t);
114272343Sngie					atf_tc_fail("char not found at "
115272343Sngie					    "correct offset");
116272343Sngie				}
117272343Sngie	    		} else {
118272343Sngie				fprintf(stderr, "a = %d, t = %d\n", a, t);
119272343Sngie				atf_tc_fail("Corrupt test case data");
120272343Sngie			}
121272343Sngie
122272343Sngie			/* check zero extension of char arg */
123272343Sngie			off2 = f(&buf[a], 0xffffff00 | '/', tab[t].len);
124272343Sngie			if (off2 != off)
125272343Sngie				atf_tc_fail("zero extension of char arg "
126272343Sngie				    "failed");
127272343Sngie		}
128272343Sngie	}
129272343Sngie}
130272343Sngie
131272343SngieATF_TC(memchr_simple);
132272343SngieATF_TC_HEAD(memchr_simple, tc)
133272343Sngie{
134272343Sngie        atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #2");
135272343Sngie}
136272343Sngie
137272343SngieATF_TC_BODY(memchr_simple, tc)
138272343Sngie{
139272343Sngie	char buf[] = "abcdefg";
140272343Sngie	short i = 7;
141272343Sngie
142272343Sngie	ATF_CHECK(memchr(buf, 'a', 0) == NULL);
143272343Sngie	ATF_CHECK(memchr(buf, 'g', 0) == NULL);
144272343Sngie	ATF_CHECK(memchr(buf, 'x', 7) == NULL);
145272343Sngie
146272343Sngie	ATF_CHECK(memchr("\0", 'x', 0) == NULL);
147272343Sngie	ATF_CHECK(memchr("\0", 'x', 1) == NULL);
148272343Sngie
149272343Sngie	while (i <= 14) {
150272343Sngie
151272343Sngie		ATF_CHECK(memchr(buf, 'a', i) == buf + 0);
152272343Sngie		ATF_CHECK(memchr(buf, 'b', i) == buf + 1);
153272343Sngie		ATF_CHECK(memchr(buf, 'c', i) == buf + 2);
154272343Sngie		ATF_CHECK(memchr(buf, 'd', i) == buf + 3);
155272343Sngie		ATF_CHECK(memchr(buf, 'e', i) == buf + 4);
156272343Sngie		ATF_CHECK(memchr(buf, 'f', i) == buf + 5);
157272343Sngie		ATF_CHECK(memchr(buf, 'g', i) == buf + 6);
158272343Sngie
159272343Sngie		i *= 2;
160272343Sngie	}
161272343Sngie}
162272343Sngie
163272343SngieATF_TC(memrchr_simple);
164272343SngieATF_TC_HEAD(memrchr_simple, tc)
165272343Sngie{
166272343Sngie        atf_tc_set_md_var(tc, "descr", "Test memrchr(3) results");
167272343Sngie}
168272343Sngie
169272343SngieATF_TC_BODY(memrchr_simple, tc)
170272343Sngie{
171272343Sngie	char buf[] = "abcdabcd";
172272343Sngie
173272343Sngie	ATF_CHECK(memrchr(buf, 'a', 0) == NULL);
174272343Sngie	ATF_CHECK(memrchr(buf, 'g', 0) == NULL);
175272343Sngie	ATF_CHECK(memrchr(buf, 'x', 8) == NULL);
176272343Sngie
177272343Sngie	ATF_CHECK(memrchr("\0", 'x', 0) == NULL);
178272343Sngie	ATF_CHECK(memrchr("\0", 'x', 1) == NULL);
179272343Sngie
180272343Sngie	ATF_CHECK(memrchr(buf, 'a', 8) == buf + 4);
181272343Sngie	ATF_CHECK(memrchr(buf, 'b', 8) == buf + 5);
182272343Sngie	ATF_CHECK(memrchr(buf, 'c', 8) == buf + 6);
183272343Sngie	ATF_CHECK(memrchr(buf, 'd', 8) == buf + 7);
184272343Sngie}
185272343Sngie
186272343SngieATF_TP_ADD_TCS(tp)
187272343Sngie{
188272343Sngie
189272343Sngie	ATF_TP_ADD_TC(tp, memchr_basic);
190272343Sngie	ATF_TP_ADD_TC(tp, memchr_simple);
191272343Sngie	ATF_TP_ADD_TC(tp, memrchr_simple);
192272343Sngie
193272343Sngie	return atf_no_error();
194272343Sngie}
195