aboutsummaryrefslogtreecommitdiff
blob: c4de4db9d10c6d869632c1302a1e6319a0779b22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "tests.h"

const char *color_normal = "\033[0m";
const char *color_green  = "\033[32;01m";
const char *color_yellow = "\033[33;01m";
const char *color_red    = "\033[31;01m";

#ifndef CONFIG
# define CONFIG 1
#endif

int at_get_fd(const char *str_dirfd)
{
	if (!strcmp(str_dirfd, "AT_FDCWD"))
		return AT_FDCWD;
	else
		return atoi(str_dirfd);
}

int at_get_flags(const char *str_flags)
{
	if (!strcmp(str_flags, "AT_SYMLINK_NOFOLLOW"))
		return AT_SYMLINK_NOFOLLOW;
	else {
		int flags = 0;
		sscanf(str_flags, "%i", &flags);
		return flags;
	}
}

int f_get_flags(const char *str_flags)
{
	const char *delim = "|";
	char *tok = strtok(strdup(str_flags), delim);
	struct {
		const char *name;
		int val;
	} const flags[] = {
		PAIR(O_APPEND)
		PAIR(O_CREAT)
		PAIR(O_EXCL)
		PAIR(O_NOCTTY)
		PAIR(O_NOFOLLOW)
		PAIR(O_RDONLY)
		PAIR(O_RDWR)
		PAIR(O_TRUNC)
		PAIR(O_WRONLY)
	};
	int i, ret = 0;
	while (tok) {
		for (i = 0; i < ARRAY_SIZE(flags); ++i)
			if (!strcmp(tok, flags[i].name)) {
				ret |= flags[i].val;
				break;
			}
		if (i == ARRAY_SIZE(flags)) {
			int a;
			sscanf(tok, "%i", &a);
			ret |= a;
		}
		tok = strtok(NULL, delim);
	}
	return ret;
}

mode_t sscanf_mode_t(const char *str_mode)
{
	/* some systems (like Linux) have a 32bit mode_t.  Others
	 * (like FreeBSD) have a 16bit mode_t.  We can't straight
	 * sscanf() into it otherwise we might smash the stack.
	 */
	int mode;
	sscanf(str_mode, "%i", &mode);
	return (mode_t)mode;
}

dev_t sscanf_dev_t(const char *str_dev)
{
	/* Similar issue with dev_t as mode_t.  Can't assume that
	 * sizeof(dev_t) == sizeof(int).  Often dev_t is 64bit.
	 */
	int dev;
	sscanf(str_dev, "%i", &dev);
	return (dev_t)dev;
}

int main(int argc, char *argv[])
{
#if CONFIG
	int i, test_ret;

	if ((argc - 1) % (ARG_CNT + 1) || argc == 1) {
		printf(
			"usage: " SFUNC " <tests>\n"
			"test: < <ret> " ARG_USE " >\n"
		);
		exit(1);
	}

	if (getenv("NOCOLOR"))
		color_normal = color_green = color_yellow = color_red = "";

	test_ret = 0;
	i = 1;
	while (i < argc) {
		char *s;

		s = argv[i++];
		long want_ret = atoi(s);

		int want_errno = 0;
		s = strchr(s, ',');
		if (s++) {
			want_errno = lookup_errno(s);
			if (!want_errno)
				err("unable to lookup errno '%s'", s);
		}

		process_args();

		errno = 0;
		long actual_ret = (long)FUNC(FUNC_IMP);
		int actual_errno = errno;

		bool passed_ret = want_ret == actual_ret;
		bool passed_errno = !want_errno || want_errno == actual_errno;
		bool passed = passed_ret && passed_errno;
#define COLOR(b) (b ? color_green : color_red)

		printf(
			"%s%s%s: " SFUNC "(" FUNC_STR ") = "
			"%s%li (wanted %li)%s; "
			"%serrno = %i [%s] (wanted %i [%s])%s\n",
			COLOR(passed), passed ? "PASS" : "FAIL", color_normal,
			FUNC_IMP,
			(passed ? "" : COLOR(passed_ret)),
			actual_ret, want_ret, color_normal,
			(!passed && want_errno) ? COLOR(passed_errno) : "",
			actual_errno, strerror(actual_errno),
			want_errno, strerror(want_errno), color_normal);

		if (!passed) ++test_ret;
	}

	return test_ret;
#else
	puts("not implemented");
	return 77;
#endif
}