1/* $NetBSD: t_strrchr.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
14ATF_TC(strrchr_basic);
15ATF_TC_HEAD(strrchr_basic, tc)
16{
17        atf_tc_set_md_var(tc, "descr", "Test strrchr(3) results");
18}
19
20ATF_TC_BODY(strrchr_basic, tc)
21{
22	/* try to trick the compiler */
23	char * (*f)(const char *, int) = strrchr;
24
25	unsigned int a, t;
26	char *off, *off2;
27	char buf[32];
28
29	struct tab {
30		const char*	val;
31		char		match;
32		ssize_t		f_off;	/* offset of first match */
33		ssize_t		l_off;	/* offset of last match */
34	};
35
36	const struct tab tab[] = {
37		{ "",			0, 0, 0 },
38		{ "a",			0, 0, 0 },
39		{ "aa",			0, 0, 0 },
40		{ "abc",		0, 0, 0 },
41		{ "abcd",		0, 0, 0 },
42		{ "abcde",		0, 0, 0 },
43		{ "abcdef",		0, 0, 0 },
44		{ "abcdefg",		0, 0, 0 },
45		{ "abcdefgh",		0, 0, 0 },
46
47		{ "/",			1, 0, 0 },
48		{ "//",                 1, 0, 1 },
49		{ "/a",                 1, 0, 0 },
50		{ "/a/",                1, 0, 2 },
51		{ "/ab",                1, 0, 0 },
52		{ "/ab/",               1, 0, 3 },
53		{ "/abc",               1, 0, 0 },
54		{ "/abc/",              1, 0, 4 },
55		{ "/abcd",              1, 0, 0 },
56		{ "/abcd/",             1, 0, 5 },
57		{ "/abcde",             1, 0, 0 },
58		{ "/abcde/",            1, 0, 6 },
59		{ "/abcdef",            1, 0, 0 },
60		{ "/abcdef/",           1, 0, 7 },
61		{ "/abcdefg",           1, 0, 0 },
62		{ "/abcdefg/",          1, 0, 8 },
63		{ "/abcdefgh",          1, 0, 0 },
64		{ "/abcdefgh/",         1, 0, 9 },
65
66		{ "a/",                 1, 1, 1 },
67		{ "a//",                1, 1, 2 },
68		{ "a/a",                1, 1, 1 },
69		{ "a/a/",               1, 1, 3 },
70		{ "a/ab",               1, 1, 1 },
71		{ "a/ab/",              1, 1, 4 },
72		{ "a/abc",              1, 1, 1 },
73		{ "a/abc/",             1, 1, 5 },
74		{ "a/abcd",             1, 1, 1 },
75		{ "a/abcd/",            1, 1, 6 },
76		{ "a/abcde",            1, 1, 1 },
77		{ "a/abcde/",           1, 1, 7 },
78		{ "a/abcdef",           1, 1, 1 },
79		{ "a/abcdef/",          1, 1, 8 },
80		{ "a/abcdefg",          1, 1, 1 },
81		{ "a/abcdefg/",         1, 1, 9 },
82		{ "a/abcdefgh",         1, 1, 1 },
83		{ "a/abcdefgh/",        1, 1, 10 },
84
85		{ "ab/",                1, 2, 2 },
86		{ "ab//",               1, 2, 3 },
87		{ "ab/a",               1, 2, 2 },
88		{ "ab/a/",              1, 2, 4 },
89		{ "ab/ab",              1, 2, 2 },
90		{ "ab/ab/",             1, 2, 5 },
91		{ "ab/abc",             1, 2, 2 },
92		{ "ab/abc/",            1, 2, 6 },
93		{ "ab/abcd",            1, 2, 2 },
94		{ "ab/abcd/",           1, 2, 7 },
95		{ "ab/abcde",           1, 2, 2 },
96		{ "ab/abcde/",          1, 2, 8 },
97		{ "ab/abcdef",          1, 2, 2 },
98		{ "ab/abcdef/",         1, 2, 9 },
99		{ "ab/abcdefg",         1, 2, 2 },
100		{ "ab/abcdefg/",        1, 2, 10 },
101		{ "ab/abcdefgh",        1, 2, 2 },
102		{ "ab/abcdefgh/",       1, 2, 11 },
103
104		{ "abc/",               1, 3, 3 },
105		{ "abc//",              1, 3, 4 },
106		{ "abc/a",              1, 3, 3 },
107		{ "abc/a/",             1, 3, 5 },
108		{ "abc/ab",             1, 3, 3 },
109		{ "abc/ab/",            1, 3, 6 },
110		{ "abc/abc",            1, 3, 3 },
111		{ "abc/abc/",           1, 3, 7 },
112		{ "abc/abcd",           1, 3, 3 },
113		{ "abc/abcd/",          1, 3, 8 },
114		{ "abc/abcde",          1, 3, 3 },
115		{ "abc/abcde/",         1, 3, 9 },
116		{ "abc/abcdef",         1, 3, 3 },
117		{ "abc/abcdef/",        1, 3, 10 },
118		{ "abc/abcdefg",        1, 3, 3 },
119		{ "abc/abcdefg/",       1, 3, 11 },
120		{ "abc/abcdefgh",       1, 3, 3 },
121		{ "abc/abcdefgh/",      1, 3, 12 },
122
123		{ "abcd/",              1, 4, 4 },
124		{ "abcd//",             1, 4, 5 },
125		{ "abcd/a",             1, 4, 4 },
126		{ "abcd/a/",            1, 4, 6 },
127		{ "abcd/ab",            1, 4, 4 },
128		{ "abcd/ab/",           1, 4, 7 },
129		{ "abcd/abc",           1, 4, 4 },
130		{ "abcd/abc/",          1, 4, 8 },
131		{ "abcd/abcd",          1, 4, 4 },
132		{ "abcd/abcd/",         1, 4, 9 },
133		{ "abcd/abcde",         1, 4, 4 },
134		{ "abcd/abcde/",        1, 4, 10 },
135		{ "abcd/abcdef",        1, 4, 4 },
136		{ "abcd/abcdef/",       1, 4, 11 },
137		{ "abcd/abcdefg",       1, 4, 4 },
138		{ "abcd/abcdefg/",      1, 4, 12 },
139		{ "abcd/abcdefgh",      1, 4, 4 },
140		{ "abcd/abcdefgh/",     1, 4, 13 },
141
142		{ "abcde/",             1, 5, 5 },
143		{ "abcde//",            1, 5, 6 },
144		{ "abcde/a",            1, 5, 5 },
145		{ "abcde/a/",           1, 5, 7 },
146		{ "abcde/ab",           1, 5, 5 },
147		{ "abcde/ab/",          1, 5, 8 },
148		{ "abcde/abc",          1, 5, 5 },
149		{ "abcde/abc/",         1, 5, 9 },
150		{ "abcde/abcd",         1, 5, 5 },
151		{ "abcde/abcd/",        1, 5, 10 },
152		{ "abcde/abcde",        1, 5, 5 },
153		{ "abcde/abcde/",       1, 5, 11 },
154		{ "abcde/abcdef",       1, 5, 5 },
155		{ "abcde/abcdef/",      1, 5, 12 },
156		{ "abcde/abcdefg",      1, 5, 5 },
157		{ "abcde/abcdefg/",     1, 5, 13 },
158		{ "abcde/abcdefgh",     1, 5, 5 },
159		{ "abcde/abcdefgh/",    1, 5, 14 },
160
161		{ "abcdef/",            1, 6, 6 },
162		{ "abcdef//",           1, 6, 7 },
163		{ "abcdef/a",           1, 6, 6 },
164		{ "abcdef/a/",          1, 6, 8 },
165		{ "abcdef/ab",          1, 6, 6 },
166		{ "abcdef/ab/",         1, 6, 9 },
167		{ "abcdef/abc",         1, 6, 6 },
168		{ "abcdef/abc/",        1, 6, 10 },
169		{ "abcdef/abcd",        1, 6, 6 },
170		{ "abcdef/abcd/",       1, 6, 11 },
171		{ "abcdef/abcde",       1, 6, 6 },
172		{ "abcdef/abcde/",      1, 6, 12 },
173		{ "abcdef/abcdef",      1, 6, 6 },
174		{ "abcdef/abcdef/",     1, 6, 13 },
175		{ "abcdef/abcdefg",     1, 6, 6 },
176		{ "abcdef/abcdefg/",    1, 6, 14 },
177		{ "abcdef/abcdefgh",    1, 6, 6 },
178		{ "abcdef/abcdefgh/",   1, 6, 15 },
179
180		{ "abcdefg/",           1, 7, 7 },
181		{ "abcdefg//",          1, 7, 8 },
182		{ "abcdefg/a",          1, 7, 7 },
183		{ "abcdefg/a/",         1, 7, 9 },
184		{ "abcdefg/ab",         1, 7, 7 },
185		{ "abcdefg/ab/",        1, 7, 10 },
186		{ "abcdefg/abc",        1, 7, 7 },
187		{ "abcdefg/abc/",       1, 7, 11 },
188		{ "abcdefg/abcd",       1, 7, 7 },
189		{ "abcdefg/abcd/",      1, 7, 12 },
190		{ "abcdefg/abcde",      1, 7, 7 },
191		{ "abcdefg/abcde/",     1, 7, 13 },
192		{ "abcdefg/abcdef",     1, 7, 7 },
193		{ "abcdefg/abcdef/",    1, 7, 14 },
194		{ "abcdefg/abcdefg",    1, 7, 7 },
195		{ "abcdefg/abcdefg/",   1, 7, 15 },
196		{ "abcdefg/abcdefgh",   1, 7, 7 },
197		{ "abcdefg/abcdefgh/",  1, 7, 16 },
198
199		{ "abcdefgh/",          1, 8, 8 },
200		{ "abcdefgh//",         1, 8, 9 },
201		{ "abcdefgh/a",         1, 8, 8 },
202		{ "abcdefgh/a/",        1, 8, 10 },
203		{ "abcdefgh/ab",        1, 8, 8 },
204		{ "abcdefgh/ab/",       1, 8, 11 },
205		{ "abcdefgh/abc",       1, 8, 8 },
206		{ "abcdefgh/abc/",      1, 8, 12 },
207		{ "abcdefgh/abcd",      1, 8, 8 },
208		{ "abcdefgh/abcd/",     1, 8, 13 },
209		{ "abcdefgh/abcde",     1, 8, 8 },
210		{ "abcdefgh/abcde/",    1, 8, 14 },
211		{ "abcdefgh/abcdef",    1, 8, 8 },
212		{ "abcdefgh/abcdef/",   1, 8, 15 },
213		{ "abcdefgh/abcdefg",   1, 8, 8 },
214		{ "abcdefgh/abcdefg/",  1, 8, 16 },
215		{ "abcdefgh/abcdefgh",  1, 8, 8 },
216		{ "abcdefgh/abcdefgh/", 1, 8, 17 },
217	};
218
219	for (a = 0; a < sizeof(long); ++a) {
220		for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
221			strcpy(&buf[a], tab[t].val);
222
223			off = f(&buf[a], '/');
224			if (tab[t].match == 0) {
225				if (off != 0) {
226					fprintf(stderr, "a %d, t %d\n", a, t);
227					atf_tc_fail("strrchr should not have "
228					    "found the character");
229				}
230			} else if (tab[t].match == 1) {
231				 if (tab[t].l_off != (off - &buf[a])) {
232					fprintf(stderr, "a %d, t %d\n", a, t);
233					atf_tc_fail("strrchr returns wrong "
234					    "offset");
235				}
236			} else {
237				fprintf(stderr, "a %d, t %d\n", a, t);
238				atf_tc_fail("bad test case data");
239			}
240
241			/* check zero extension of char arg */
242			off2 = f(&buf[a], 0xffffff00 | '/');
243			if (off != off2) {
244				fprintf(stderr, "a %d, t %d\n", a, t);
245				atf_tc_fail("zero extension of char arg fails");
246			}
247		}
248	}
249}
250
251ATF_TP_ADD_TCS(tp)
252{
253
254	ATF_TP_ADD_TC(tp, strrchr_basic);
255
256	return atf_no_error();
257}
258