xref: /freebsd/contrib/netbsd-tests/lib/libc/string/t_strchr.c (revision 83e8b13f15e954a3783befd0a322935ac6a1bd7b)
157718be8SEnji Cooper /* $NetBSD: t_strchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */
257718be8SEnji Cooper 
357718be8SEnji Cooper /*
457718be8SEnji Cooper  * Written by J.T. Conklin <jtc@acorntoolworks.com>
557718be8SEnji Cooper  * Public domain.
657718be8SEnji Cooper  */
757718be8SEnji Cooper 
857718be8SEnji Cooper #include <atf-c.h>
957718be8SEnji Cooper #include <string.h>
1057718be8SEnji Cooper #include <unistd.h>
1157718be8SEnji Cooper #include <stdio.h>
1257718be8SEnji Cooper #include <stdlib.h>
1357718be8SEnji Cooper #include <dlfcn.h>
1457718be8SEnji Cooper 
1557718be8SEnji Cooper static char	*slow_strchr(char *, int);
1657718be8SEnji Cooper static void	 verify_strchr(char *, int, unsigned int, unsigned int);
1757718be8SEnji Cooper 
1857718be8SEnji Cooper char * (*volatile strchr_fn)(const char *, int);
1957718be8SEnji Cooper 
2057718be8SEnji Cooper static char *
2157718be8SEnji Cooper slow_strchr(char *buf, int ch)
2257718be8SEnji Cooper {
2357718be8SEnji Cooper 	unsigned char c = 1;
2457718be8SEnji Cooper 
2557718be8SEnji Cooper 	ch &= 0xff;
2657718be8SEnji Cooper 
2757718be8SEnji Cooper 	for (; c != 0; buf++) {
2857718be8SEnji Cooper 		c = *buf;
2957718be8SEnji Cooper 		if (c == ch)
3057718be8SEnji Cooper 			return buf;
3157718be8SEnji Cooper 	}
3257718be8SEnji Cooper 	return 0;
3357718be8SEnji Cooper }
3457718be8SEnji Cooper 
3557718be8SEnji Cooper static void
3657718be8SEnji Cooper verify_strchr(char *buf, int ch, unsigned int t, unsigned int a)
3757718be8SEnji Cooper {
3857718be8SEnji Cooper 	const char *off, *ok_off;
3957718be8SEnji Cooper 
4057718be8SEnji Cooper 	off = strchr_fn(buf, ch);
4157718be8SEnji Cooper 	ok_off = slow_strchr(buf, ch);
4257718be8SEnji Cooper 	if (off == ok_off)
4357718be8SEnji Cooper 		return;
4457718be8SEnji Cooper 
4557718be8SEnji Cooper 	fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, "
4657718be8SEnji Cooper 	    "alignment %d)\n",
4757718be8SEnji Cooper 	    buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a);
4857718be8SEnji Cooper 
4957718be8SEnji Cooper 	atf_tc_fail("Check stderr for details");
5057718be8SEnji Cooper }
5157718be8SEnji Cooper 
5257718be8SEnji Cooper ATF_TC(strchr_basic);
5357718be8SEnji Cooper ATF_TC_HEAD(strchr_basic, tc)
5457718be8SEnji Cooper {
5557718be8SEnji Cooper 
5657718be8SEnji Cooper         atf_tc_set_md_var(tc, "descr", "Test strchr(3) results");
5757718be8SEnji Cooper }
5857718be8SEnji Cooper 
5957718be8SEnji Cooper ATF_TC_BODY(strchr_basic, tc)
6057718be8SEnji Cooper {
61*83e8b13fSEnji Cooper #ifdef	__FreeBSD__
62*83e8b13fSEnji Cooper 	void *dl_handle;
63*83e8b13fSEnji Cooper #endif
6457718be8SEnji Cooper 	unsigned int t, a;
6557718be8SEnji Cooper 	char *off;
6657718be8SEnji Cooper 	char buf[32];
6757718be8SEnji Cooper 
6857718be8SEnji Cooper 	const char *tab[] = {
6957718be8SEnji Cooper 		"",
7057718be8SEnji Cooper 		"a",
7157718be8SEnji Cooper 		"aa",
7257718be8SEnji Cooper 		"abc",
7357718be8SEnji Cooper 		"abcd",
7457718be8SEnji Cooper 		"abcde",
7557718be8SEnji Cooper 		"abcdef",
7657718be8SEnji Cooper 		"abcdefg",
7757718be8SEnji Cooper 		"abcdefgh",
7857718be8SEnji Cooper 
7957718be8SEnji Cooper 		"/",
8057718be8SEnji Cooper 		"//",
8157718be8SEnji Cooper 		"/a",
8257718be8SEnji Cooper 		"/a/",
8357718be8SEnji Cooper 		"/ab",
8457718be8SEnji Cooper 		"/ab/",
8557718be8SEnji Cooper 		"/abc",
8657718be8SEnji Cooper 		"/abc/",
8757718be8SEnji Cooper 		"/abcd",
8857718be8SEnji Cooper 		"/abcd/",
8957718be8SEnji Cooper 		"/abcde",
9057718be8SEnji Cooper 		"/abcde/",
9157718be8SEnji Cooper 		"/abcdef",
9257718be8SEnji Cooper 		"/abcdef/",
9357718be8SEnji Cooper 		"/abcdefg",
9457718be8SEnji Cooper 		"/abcdefg/",
9557718be8SEnji Cooper 		"/abcdefgh",
9657718be8SEnji Cooper 		"/abcdefgh/",
9757718be8SEnji Cooper 
9857718be8SEnji Cooper 		"a/",
9957718be8SEnji Cooper 		"a//",
10057718be8SEnji Cooper 		"a/a",
10157718be8SEnji Cooper 		"a/a/",
10257718be8SEnji Cooper 		"a/ab",
10357718be8SEnji Cooper 		"a/ab/",
10457718be8SEnji Cooper 		"a/abc",
10557718be8SEnji Cooper 		"a/abc/",
10657718be8SEnji Cooper 		"a/abcd",
10757718be8SEnji Cooper 		"a/abcd/",
10857718be8SEnji Cooper 		"a/abcde",
10957718be8SEnji Cooper 		"a/abcde/",
11057718be8SEnji Cooper 		"a/abcdef",
11157718be8SEnji Cooper 		"a/abcdef/",
11257718be8SEnji Cooper 		"a/abcdefg",
11357718be8SEnji Cooper 		"a/abcdefg/",
11457718be8SEnji Cooper 		"a/abcdefgh",
11557718be8SEnji Cooper 		"a/abcdefgh/",
11657718be8SEnji Cooper 
11757718be8SEnji Cooper 		"ab/",
11857718be8SEnji Cooper 		"ab//",
11957718be8SEnji Cooper 		"ab/a",
12057718be8SEnji Cooper 		"ab/a/",
12157718be8SEnji Cooper 		"ab/ab",
12257718be8SEnji Cooper 		"ab/ab/",
12357718be8SEnji Cooper 		"ab/abc",
12457718be8SEnji Cooper 		"ab/abc/",
12557718be8SEnji Cooper 		"ab/abcd",
12657718be8SEnji Cooper 		"ab/abcd/",
12757718be8SEnji Cooper 		"ab/abcde",
12857718be8SEnji Cooper 		"ab/abcde/",
12957718be8SEnji Cooper 		"ab/abcdef",
13057718be8SEnji Cooper 		"ab/abcdef/",
13157718be8SEnji Cooper 		"ab/abcdefg",
13257718be8SEnji Cooper 		"ab/abcdefg/",
13357718be8SEnji Cooper 		"ab/abcdefgh",
13457718be8SEnji Cooper 		"ab/abcdefgh/",
13557718be8SEnji Cooper 
13657718be8SEnji Cooper 		"abc/",
13757718be8SEnji Cooper 		"abc//",
13857718be8SEnji Cooper 		"abc/a",
13957718be8SEnji Cooper 		"abc/a/",
14057718be8SEnji Cooper 		"abc/ab",
14157718be8SEnji Cooper 		"abc/ab/",
14257718be8SEnji Cooper 		"abc/abc",
14357718be8SEnji Cooper 		"abc/abc/",
14457718be8SEnji Cooper 		"abc/abcd",
14557718be8SEnji Cooper 		"abc/abcd/",
14657718be8SEnji Cooper 		"abc/abcde",
14757718be8SEnji Cooper 		"abc/abcde/",
14857718be8SEnji Cooper 		"abc/abcdef",
14957718be8SEnji Cooper 		"abc/abcdef/",
15057718be8SEnji Cooper 		"abc/abcdefg",
15157718be8SEnji Cooper 		"abc/abcdefg/",
15257718be8SEnji Cooper 		"abc/abcdefgh",
15357718be8SEnji Cooper 		"abc/abcdefgh/",
15457718be8SEnji Cooper 
15557718be8SEnji Cooper 		"abcd/",
15657718be8SEnji Cooper 		"abcd//",
15757718be8SEnji Cooper 		"abcd/a",
15857718be8SEnji Cooper 		"abcd/a/",
15957718be8SEnji Cooper 		"abcd/ab",
16057718be8SEnji Cooper 		"abcd/ab/",
16157718be8SEnji Cooper 		"abcd/abc",
16257718be8SEnji Cooper 		"abcd/abc/",
16357718be8SEnji Cooper 		"abcd/abcd",
16457718be8SEnji Cooper 		"abcd/abcd/",
16557718be8SEnji Cooper 		"abcd/abcde",
16657718be8SEnji Cooper 		"abcd/abcde/",
16757718be8SEnji Cooper 		"abcd/abcdef",
16857718be8SEnji Cooper 		"abcd/abcdef/",
16957718be8SEnji Cooper 		"abcd/abcdefg",
17057718be8SEnji Cooper 		"abcd/abcdefg/",
17157718be8SEnji Cooper 		"abcd/abcdefgh",
17257718be8SEnji Cooper 		"abcd/abcdefgh/",
17357718be8SEnji Cooper 
17457718be8SEnji Cooper 		"abcde/",
17557718be8SEnji Cooper 		"abcde//",
17657718be8SEnji Cooper 		"abcde/a",
17757718be8SEnji Cooper 		"abcde/a/",
17857718be8SEnji Cooper 		"abcde/ab",
17957718be8SEnji Cooper 		"abcde/ab/",
18057718be8SEnji Cooper 		"abcde/abc",
18157718be8SEnji Cooper 		"abcde/abc/",
18257718be8SEnji Cooper 		"abcde/abcd",
18357718be8SEnji Cooper 		"abcde/abcd/",
18457718be8SEnji Cooper 		"abcde/abcde",
18557718be8SEnji Cooper 		"abcde/abcde/",
18657718be8SEnji Cooper 		"abcde/abcdef",
18757718be8SEnji Cooper 		"abcde/abcdef/",
18857718be8SEnji Cooper 		"abcde/abcdefg",
18957718be8SEnji Cooper 		"abcde/abcdefg/",
19057718be8SEnji Cooper 		"abcde/abcdefgh",
19157718be8SEnji Cooper 		"abcde/abcdefgh/",
19257718be8SEnji Cooper 
19357718be8SEnji Cooper 		"abcdef/",
19457718be8SEnji Cooper 		"abcdef//",
19557718be8SEnji Cooper 		"abcdef/a",
19657718be8SEnji Cooper 		"abcdef/a/",
19757718be8SEnji Cooper 		"abcdef/ab",
19857718be8SEnji Cooper 		"abcdef/ab/",
19957718be8SEnji Cooper 		"abcdef/abc",
20057718be8SEnji Cooper 		"abcdef/abc/",
20157718be8SEnji Cooper 		"abcdef/abcd",
20257718be8SEnji Cooper 		"abcdef/abcd/",
20357718be8SEnji Cooper 		"abcdef/abcde",
20457718be8SEnji Cooper 		"abcdef/abcde/",
20557718be8SEnji Cooper 		"abcdef/abcdef",
20657718be8SEnji Cooper 		"abcdef/abcdef/",
20757718be8SEnji Cooper 		"abcdef/abcdefg",
20857718be8SEnji Cooper 		"abcdef/abcdefg/",
20957718be8SEnji Cooper 		"abcdef/abcdefgh",
21057718be8SEnji Cooper 		"abcdef/abcdefgh/",
21157718be8SEnji Cooper 
21257718be8SEnji Cooper 		"abcdefg/",
21357718be8SEnji Cooper 		"abcdefg//",
21457718be8SEnji Cooper 		"abcdefg/a",
21557718be8SEnji Cooper 		"abcdefg/a/",
21657718be8SEnji Cooper 		"abcdefg/ab",
21757718be8SEnji Cooper 		"abcdefg/ab/",
21857718be8SEnji Cooper 		"abcdefg/abc",
21957718be8SEnji Cooper 		"abcdefg/abc/",
22057718be8SEnji Cooper 		"abcdefg/abcd",
22157718be8SEnji Cooper 		"abcdefg/abcd/",
22257718be8SEnji Cooper 		"abcdefg/abcde",
22357718be8SEnji Cooper 		"abcdefg/abcde/",
22457718be8SEnji Cooper 		"abcdefg/abcdef",
22557718be8SEnji Cooper 		"abcdefg/abcdef/",
22657718be8SEnji Cooper 		"abcdefg/abcdefg",
22757718be8SEnji Cooper 		"abcdefg/abcdefg/",
22857718be8SEnji Cooper 		"abcdefg/abcdefgh",
22957718be8SEnji Cooper 		"abcdefg/abcdefgh/",
23057718be8SEnji Cooper 
23157718be8SEnji Cooper 		"abcdefgh/",
23257718be8SEnji Cooper 		"abcdefgh//",
23357718be8SEnji Cooper 		"abcdefgh/a",
23457718be8SEnji Cooper 		"abcdefgh/a/",
23557718be8SEnji Cooper 		"abcdefgh/ab",
23657718be8SEnji Cooper 		"abcdefgh/ab/",
23757718be8SEnji Cooper 		"abcdefgh/abc",
23857718be8SEnji Cooper 		"abcdefgh/abc/",
23957718be8SEnji Cooper 		"abcdefgh/abcd",
24057718be8SEnji Cooper 		"abcdefgh/abcd/",
24157718be8SEnji Cooper 		"abcdefgh/abcde",
24257718be8SEnji Cooper 		"abcdefgh/abcde/",
24357718be8SEnji Cooper 		"abcdefgh/abcdef",
24457718be8SEnji Cooper 		"abcdefgh/abcdef/",
24557718be8SEnji Cooper 		"abcdefgh/abcdefg",
24657718be8SEnji Cooper 		"abcdefgh/abcdefg/",
24757718be8SEnji Cooper 		"abcdefgh/abcdefgh",
24857718be8SEnji Cooper 		"abcdefgh/abcdefgh/",
24957718be8SEnji Cooper 	};
25057718be8SEnji Cooper 
251*83e8b13fSEnji Cooper #ifdef	__FreeBSD__
252*83e8b13fSEnji Cooper 	dl_handle = dlopen(NULL, RTLD_LAZY);
253*83e8b13fSEnji Cooper 	strchr_fn = dlsym(dl_handle, "test_strlen");
254*83e8b13fSEnji Cooper #else
25557718be8SEnji Cooper 	strchr_fn = dlsym(dlopen(0, RTLD_LAZY), "test_strchr");
256*83e8b13fSEnji Cooper #endif
25757718be8SEnji Cooper 	if (!strchr_fn)
25857718be8SEnji Cooper 		strchr_fn = strchr;
25957718be8SEnji Cooper 
26057718be8SEnji Cooper 	for (a = 3; a < 3 + sizeof(long); ++a) {
26157718be8SEnji Cooper 		/* Put char and a \0 before the buffer */
26257718be8SEnji Cooper 		buf[a-1] = '/';
26357718be8SEnji Cooper 		buf[a-2] = '0';
26457718be8SEnji Cooper 		buf[a-3] = 0xff;
26557718be8SEnji Cooper 		for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
26657718be8SEnji Cooper 			int len = strlen(tab[t]) + 1;
26757718be8SEnji Cooper 			memcpy(&buf[a], tab[t], len);
26857718be8SEnji Cooper 
26957718be8SEnji Cooper 			/* Put the char we are looking for after the \0 */
27057718be8SEnji Cooper 			buf[a + len] = '/';
27157718be8SEnji Cooper 
27257718be8SEnji Cooper 			/* Check search for NUL at end of string */
27357718be8SEnji Cooper 			verify_strchr(buf + a, 0, t, a);
27457718be8SEnji Cooper 
27557718be8SEnji Cooper 			/* Then for the '/' in the strings */
27657718be8SEnji Cooper 			verify_strchr(buf + a, '/', t, a);
27757718be8SEnji Cooper 
27857718be8SEnji Cooper 		   	/* check zero extension of char arg */
27957718be8SEnji Cooper 		   	verify_strchr(buf + a, 0xffffff00 | '/', t, a);
28057718be8SEnji Cooper 
28157718be8SEnji Cooper 		   	/* Replace all the '/' with 0xff */
28257718be8SEnji Cooper 		   	while ((off = slow_strchr(buf + a, '/')) != NULL)
28357718be8SEnji Cooper 				*off = 0xff;
28457718be8SEnji Cooper 
28557718be8SEnji Cooper 			buf[a + len] = 0xff;
28657718be8SEnji Cooper 
28757718be8SEnji Cooper 			/* Check we can search for 0xff as well as '/' */
28857718be8SEnji Cooper 			verify_strchr(buf + a, 0xff, t, a);
28957718be8SEnji Cooper 		}
29057718be8SEnji Cooper 	}
291*83e8b13fSEnji Cooper #ifdef	__FreeBSD__
292*83e8b13fSEnji Cooper 	(void)dlclose(dl_handle);
293*83e8b13fSEnji Cooper #endif
29457718be8SEnji Cooper }
29557718be8SEnji Cooper 
29657718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
29757718be8SEnji Cooper {
29857718be8SEnji Cooper 
29957718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, strchr_basic);
30057718be8SEnji Cooper 
30157718be8SEnji Cooper 	return atf_no_error();
30257718be8SEnji Cooper }
303