xref: /aosp_15_r20/external/ltp/lib/tst_kconfig.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2018 Cyril Hrubis <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker  */
5*49cdfc7eSAndroid Build Coastguard Worker 
6*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
7*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
8*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
9*49cdfc7eSAndroid Build Coastguard Worker #include <ctype.h>
10*49cdfc7eSAndroid Build Coastguard Worker #include <sys/utsname.h>
11*49cdfc7eSAndroid Build Coastguard Worker 
12*49cdfc7eSAndroid Build Coastguard Worker #define TST_NO_DEFAULT_MAIN
13*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
14*49cdfc7eSAndroid Build Coastguard Worker #include "tst_private.h"
15*49cdfc7eSAndroid Build Coastguard Worker #include "tst_kconfig.h"
16*49cdfc7eSAndroid Build Coastguard Worker #include "tst_bool_expr.h"
17*49cdfc7eSAndroid Build Coastguard Worker #include "tst_safe_stdio.h"
18*49cdfc7eSAndroid Build Coastguard Worker 
kconfig_skip_check(void)19*49cdfc7eSAndroid Build Coastguard Worker static int kconfig_skip_check(void)
20*49cdfc7eSAndroid Build Coastguard Worker {
21*49cdfc7eSAndroid Build Coastguard Worker 	char *skipped = getenv("KCONFIG_SKIP_CHECK");
22*49cdfc7eSAndroid Build Coastguard Worker 
23*49cdfc7eSAndroid Build Coastguard Worker 	if (skipped) {
24*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TINFO, "Skipping kernel config check as requested");
25*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
26*49cdfc7eSAndroid Build Coastguard Worker 	}
27*49cdfc7eSAndroid Build Coastguard Worker 
28*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
29*49cdfc7eSAndroid Build Coastguard Worker }
30*49cdfc7eSAndroid Build Coastguard Worker 
kconfig_path(char * path_buf,size_t path_buf_len)31*49cdfc7eSAndroid Build Coastguard Worker static const char *kconfig_path(char *path_buf, size_t path_buf_len)
32*49cdfc7eSAndroid Build Coastguard Worker {
33*49cdfc7eSAndroid Build Coastguard Worker 	const char *path = getenv("KCONFIG_PATH");
34*49cdfc7eSAndroid Build Coastguard Worker 	struct utsname un;
35*49cdfc7eSAndroid Build Coastguard Worker 
36*49cdfc7eSAndroid Build Coastguard Worker 	if (path) {
37*49cdfc7eSAndroid Build Coastguard Worker 		if (!access(path, F_OK))
38*49cdfc7eSAndroid Build Coastguard Worker 			return path;
39*49cdfc7eSAndroid Build Coastguard Worker 
40*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TWARN, "KCONFIG_PATH='%s' does not exist", path);
41*49cdfc7eSAndroid Build Coastguard Worker 	}
42*49cdfc7eSAndroid Build Coastguard Worker 
43*49cdfc7eSAndroid Build Coastguard Worker 	if (!access("/proc/config.gz", F_OK))
44*49cdfc7eSAndroid Build Coastguard Worker 		return "/proc/config.gz";
45*49cdfc7eSAndroid Build Coastguard Worker 
46*49cdfc7eSAndroid Build Coastguard Worker 	uname(&un);
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker 	/* Common install module path */
49*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(path_buf, path_buf_len, "/lib/modules/%s/build/.config", un.release);
50*49cdfc7eSAndroid Build Coastguard Worker 
51*49cdfc7eSAndroid Build Coastguard Worker 	if (!access(path_buf, F_OK))
52*49cdfc7eSAndroid Build Coastguard Worker 		return path_buf;
53*49cdfc7eSAndroid Build Coastguard Worker 
54*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(path_buf, path_buf_len, "/lib/modules/%s/config", un.release);
55*49cdfc7eSAndroid Build Coastguard Worker 
56*49cdfc7eSAndroid Build Coastguard Worker 	if (!access(path_buf, F_OK))
57*49cdfc7eSAndroid Build Coastguard Worker 		return path_buf;
58*49cdfc7eSAndroid Build Coastguard Worker 
59*49cdfc7eSAndroid Build Coastguard Worker 	/* Debian and derivatives */
60*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(path_buf, path_buf_len, "/boot/config-%s", un.release);
61*49cdfc7eSAndroid Build Coastguard Worker 
62*49cdfc7eSAndroid Build Coastguard Worker 	if (!access(path_buf, F_OK))
63*49cdfc7eSAndroid Build Coastguard Worker 		return path_buf;
64*49cdfc7eSAndroid Build Coastguard Worker 
65*49cdfc7eSAndroid Build Coastguard Worker 	/* Clear Linux */
66*49cdfc7eSAndroid Build Coastguard Worker 	snprintf(path_buf, path_buf_len, "/lib/kernel/config-%s", un.release);
67*49cdfc7eSAndroid Build Coastguard Worker 
68*49cdfc7eSAndroid Build Coastguard Worker 	if (!access(path_buf, F_OK))
69*49cdfc7eSAndroid Build Coastguard Worker 		return path_buf;
70*49cdfc7eSAndroid Build Coastguard Worker 
71*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "Couldn't locate kernel config!");
72*49cdfc7eSAndroid Build Coastguard Worker 
73*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
74*49cdfc7eSAndroid Build Coastguard Worker }
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker static char is_gzip;
77*49cdfc7eSAndroid Build Coastguard Worker 
open_kconfig(void)78*49cdfc7eSAndroid Build Coastguard Worker static FILE *open_kconfig(void)
79*49cdfc7eSAndroid Build Coastguard Worker {
80*49cdfc7eSAndroid Build Coastguard Worker 	FILE *fp;
81*49cdfc7eSAndroid Build Coastguard Worker 	char buf[1064];
82*49cdfc7eSAndroid Build Coastguard Worker 	char path_buf[1024];
83*49cdfc7eSAndroid Build Coastguard Worker 	const char *path = kconfig_path(path_buf, sizeof(path_buf));
84*49cdfc7eSAndroid Build Coastguard Worker 
85*49cdfc7eSAndroid Build Coastguard Worker 	if (!path)
86*49cdfc7eSAndroid Build Coastguard Worker 		return NULL;
87*49cdfc7eSAndroid Build Coastguard Worker 
88*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "Parsing kernel config '%s'", path);
89*49cdfc7eSAndroid Build Coastguard Worker 
90*49cdfc7eSAndroid Build Coastguard Worker 	is_gzip = !!strstr(path, ".gz");
91*49cdfc7eSAndroid Build Coastguard Worker 
92*49cdfc7eSAndroid Build Coastguard Worker 	if (is_gzip) {
93*49cdfc7eSAndroid Build Coastguard Worker 		snprintf(buf, sizeof(buf), "zcat '%s'", path);
94*49cdfc7eSAndroid Build Coastguard Worker 		fp = popen(buf, "r");
95*49cdfc7eSAndroid Build Coastguard Worker 	} else {
96*49cdfc7eSAndroid Build Coastguard Worker 		fp = fopen(path, "r");
97*49cdfc7eSAndroid Build Coastguard Worker 	}
98*49cdfc7eSAndroid Build Coastguard Worker 
99*49cdfc7eSAndroid Build Coastguard Worker 	if (!fp)
100*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TERRNO, "Failed to open '%s'", path);
101*49cdfc7eSAndroid Build Coastguard Worker 
102*49cdfc7eSAndroid Build Coastguard Worker 	return fp;
103*49cdfc7eSAndroid Build Coastguard Worker }
104*49cdfc7eSAndroid Build Coastguard Worker 
close_kconfig(FILE * fp)105*49cdfc7eSAndroid Build Coastguard Worker static void close_kconfig(FILE *fp)
106*49cdfc7eSAndroid Build Coastguard Worker {
107*49cdfc7eSAndroid Build Coastguard Worker 	if (is_gzip)
108*49cdfc7eSAndroid Build Coastguard Worker 		pclose(fp);
109*49cdfc7eSAndroid Build Coastguard Worker 	else
110*49cdfc7eSAndroid Build Coastguard Worker 		fclose(fp);
111*49cdfc7eSAndroid Build Coastguard Worker }
112*49cdfc7eSAndroid Build Coastguard Worker 
kconfig_parse_line(const char * line,struct tst_kconfig_var * vars,unsigned int vars_len)113*49cdfc7eSAndroid Build Coastguard Worker static inline int kconfig_parse_line(const char *line,
114*49cdfc7eSAndroid Build Coastguard Worker                                      struct tst_kconfig_var *vars,
115*49cdfc7eSAndroid Build Coastguard Worker                                      unsigned int vars_len)
116*49cdfc7eSAndroid Build Coastguard Worker {
117*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i, var_len = 0;
118*49cdfc7eSAndroid Build Coastguard Worker 	const char *var;
119*49cdfc7eSAndroid Build Coastguard Worker 	int is_not_set = 0;
120*49cdfc7eSAndroid Build Coastguard Worker 
121*49cdfc7eSAndroid Build Coastguard Worker 	while (isspace(*line))
122*49cdfc7eSAndroid Build Coastguard Worker 		line++;
123*49cdfc7eSAndroid Build Coastguard Worker 
124*49cdfc7eSAndroid Build Coastguard Worker 	if (*line == '#') {
125*49cdfc7eSAndroid Build Coastguard Worker 		if (!strstr(line, "is not set"))
126*49cdfc7eSAndroid Build Coastguard Worker 			return 0;
127*49cdfc7eSAndroid Build Coastguard Worker 
128*49cdfc7eSAndroid Build Coastguard Worker 		is_not_set = 1;
129*49cdfc7eSAndroid Build Coastguard Worker 	}
130*49cdfc7eSAndroid Build Coastguard Worker 
131*49cdfc7eSAndroid Build Coastguard Worker 	var = strstr(line, "CONFIG_");
132*49cdfc7eSAndroid Build Coastguard Worker 
133*49cdfc7eSAndroid Build Coastguard Worker 	if (!var)
134*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
135*49cdfc7eSAndroid Build Coastguard Worker 
136*49cdfc7eSAndroid Build Coastguard Worker 	for (;;) {
137*49cdfc7eSAndroid Build Coastguard Worker 		switch (var[var_len]) {
138*49cdfc7eSAndroid Build Coastguard Worker 		case 'A' ... 'Z':
139*49cdfc7eSAndroid Build Coastguard Worker 		case '0' ... '9':
140*49cdfc7eSAndroid Build Coastguard Worker 		case '_':
141*49cdfc7eSAndroid Build Coastguard Worker 			var_len++;
142*49cdfc7eSAndroid Build Coastguard Worker 		break;
143*49cdfc7eSAndroid Build Coastguard Worker 		default:
144*49cdfc7eSAndroid Build Coastguard Worker 			goto out;
145*49cdfc7eSAndroid Build Coastguard Worker 		break;
146*49cdfc7eSAndroid Build Coastguard Worker 		}
147*49cdfc7eSAndroid Build Coastguard Worker 	}
148*49cdfc7eSAndroid Build Coastguard Worker 
149*49cdfc7eSAndroid Build Coastguard Worker out:
150*49cdfc7eSAndroid Build Coastguard Worker 
151*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < vars_len; i++) {
152*49cdfc7eSAndroid Build Coastguard Worker 		const char *val;
153*49cdfc7eSAndroid Build Coastguard Worker 		unsigned int val_len = 0;
154*49cdfc7eSAndroid Build Coastguard Worker 
155*49cdfc7eSAndroid Build Coastguard Worker 		if (vars[i].id_len != var_len)
156*49cdfc7eSAndroid Build Coastguard Worker 			continue;
157*49cdfc7eSAndroid Build Coastguard Worker 
158*49cdfc7eSAndroid Build Coastguard Worker 		if (strncmp(vars[i].id, var, var_len))
159*49cdfc7eSAndroid Build Coastguard Worker 			continue;
160*49cdfc7eSAndroid Build Coastguard Worker 
161*49cdfc7eSAndroid Build Coastguard Worker 		if (is_not_set) {
162*49cdfc7eSAndroid Build Coastguard Worker 			vars[i].choice = 'n';
163*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
164*49cdfc7eSAndroid Build Coastguard Worker 		}
165*49cdfc7eSAndroid Build Coastguard Worker 
166*49cdfc7eSAndroid Build Coastguard Worker 		val = var + var_len;
167*49cdfc7eSAndroid Build Coastguard Worker 
168*49cdfc7eSAndroid Build Coastguard Worker 		while (isspace(*val))
169*49cdfc7eSAndroid Build Coastguard Worker 			val++;
170*49cdfc7eSAndroid Build Coastguard Worker 
171*49cdfc7eSAndroid Build Coastguard Worker 		if (*val != '=')
172*49cdfc7eSAndroid Build Coastguard Worker 			return 0;
173*49cdfc7eSAndroid Build Coastguard Worker 
174*49cdfc7eSAndroid Build Coastguard Worker 		val++;
175*49cdfc7eSAndroid Build Coastguard Worker 
176*49cdfc7eSAndroid Build Coastguard Worker 		while (isspace(*val))
177*49cdfc7eSAndroid Build Coastguard Worker 			val++;
178*49cdfc7eSAndroid Build Coastguard Worker 
179*49cdfc7eSAndroid Build Coastguard Worker 		while (!isspace(val[val_len]))
180*49cdfc7eSAndroid Build Coastguard Worker 			val_len++;
181*49cdfc7eSAndroid Build Coastguard Worker 
182*49cdfc7eSAndroid Build Coastguard Worker 		if (val_len == 1) {
183*49cdfc7eSAndroid Build Coastguard Worker 			switch (val[0]) {
184*49cdfc7eSAndroid Build Coastguard Worker 			case 'y':
185*49cdfc7eSAndroid Build Coastguard Worker 				vars[i].choice = 'y';
186*49cdfc7eSAndroid Build Coastguard Worker 				return 1;
187*49cdfc7eSAndroid Build Coastguard Worker 			case 'm':
188*49cdfc7eSAndroid Build Coastguard Worker 				vars[i].choice = 'm';
189*49cdfc7eSAndroid Build Coastguard Worker 				return 1;
190*49cdfc7eSAndroid Build Coastguard Worker 			}
191*49cdfc7eSAndroid Build Coastguard Worker 		}
192*49cdfc7eSAndroid Build Coastguard Worker 
193*49cdfc7eSAndroid Build Coastguard Worker 		vars[i].choice = 'v';
194*49cdfc7eSAndroid Build Coastguard Worker 		vars[i].val = strndup(val, val_len);
195*49cdfc7eSAndroid Build Coastguard Worker 	}
196*49cdfc7eSAndroid Build Coastguard Worker 
197*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
198*49cdfc7eSAndroid Build Coastguard Worker }
199*49cdfc7eSAndroid Build Coastguard Worker 
tst_kconfig_read(struct tst_kconfig_var vars[],size_t vars_len)200*49cdfc7eSAndroid Build Coastguard Worker void tst_kconfig_read(struct tst_kconfig_var vars[], size_t vars_len)
201*49cdfc7eSAndroid Build Coastguard Worker {
202*49cdfc7eSAndroid Build Coastguard Worker 	char line[128];
203*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int vars_found = 0;
204*49cdfc7eSAndroid Build Coastguard Worker 
205*49cdfc7eSAndroid Build Coastguard Worker 	FILE *fp = open_kconfig();
206*49cdfc7eSAndroid Build Coastguard Worker 	if (!fp)
207*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Cannot parse kernel .config");
208*49cdfc7eSAndroid Build Coastguard Worker 
209*49cdfc7eSAndroid Build Coastguard Worker 	while (fgets(line, sizeof(line), fp)) {
210*49cdfc7eSAndroid Build Coastguard Worker 		if (kconfig_parse_line(line, vars, vars_len))
211*49cdfc7eSAndroid Build Coastguard Worker 			vars_found++;
212*49cdfc7eSAndroid Build Coastguard Worker 
213*49cdfc7eSAndroid Build Coastguard Worker 		if (vars_found == vars_len)
214*49cdfc7eSAndroid Build Coastguard Worker 			goto exit;
215*49cdfc7eSAndroid Build Coastguard Worker 	}
216*49cdfc7eSAndroid Build Coastguard Worker 
217*49cdfc7eSAndroid Build Coastguard Worker exit:
218*49cdfc7eSAndroid Build Coastguard Worker 	close_kconfig(fp);
219*49cdfc7eSAndroid Build Coastguard Worker }
220*49cdfc7eSAndroid Build Coastguard Worker 
array_len(const char * const kconfigs[])221*49cdfc7eSAndroid Build Coastguard Worker static size_t array_len(const char *const kconfigs[])
222*49cdfc7eSAndroid Build Coastguard Worker {
223*49cdfc7eSAndroid Build Coastguard Worker 	size_t i = 0;
224*49cdfc7eSAndroid Build Coastguard Worker 
225*49cdfc7eSAndroid Build Coastguard Worker 	while (kconfigs[++i]);
226*49cdfc7eSAndroid Build Coastguard Worker 
227*49cdfc7eSAndroid Build Coastguard Worker 	return i;
228*49cdfc7eSAndroid Build Coastguard Worker }
229*49cdfc7eSAndroid Build Coastguard Worker 
strnchr(const char * s,int c,unsigned int len)230*49cdfc7eSAndroid Build Coastguard Worker static const char *strnchr(const char *s, int c, unsigned int len)
231*49cdfc7eSAndroid Build Coastguard Worker {
232*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i;
233*49cdfc7eSAndroid Build Coastguard Worker 
234*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < len; i++) {
235*49cdfc7eSAndroid Build Coastguard Worker 		if (s[i] == c)
236*49cdfc7eSAndroid Build Coastguard Worker 			return s + i;
237*49cdfc7eSAndroid Build Coastguard Worker 	}
238*49cdfc7eSAndroid Build Coastguard Worker 
239*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
240*49cdfc7eSAndroid Build Coastguard Worker }
241*49cdfc7eSAndroid Build Coastguard Worker 
get_len(const char * kconfig,unsigned int len)242*49cdfc7eSAndroid Build Coastguard Worker static inline unsigned int get_len(const char* kconfig, unsigned int len)
243*49cdfc7eSAndroid Build Coastguard Worker {
244*49cdfc7eSAndroid Build Coastguard Worker 	const char *sep = strnchr(kconfig, '=', len);
245*49cdfc7eSAndroid Build Coastguard Worker 
246*49cdfc7eSAndroid Build Coastguard Worker 	if (!sep)
247*49cdfc7eSAndroid Build Coastguard Worker 		return len;
248*49cdfc7eSAndroid Build Coastguard Worker 
249*49cdfc7eSAndroid Build Coastguard Worker 	return sep - kconfig;
250*49cdfc7eSAndroid Build Coastguard Worker }
251*49cdfc7eSAndroid Build Coastguard Worker 
print_err(FILE * f,const struct tst_expr_tok * var,size_t spaces,const char * err)252*49cdfc7eSAndroid Build Coastguard Worker static void print_err(FILE *f, const struct tst_expr_tok *var,
253*49cdfc7eSAndroid Build Coastguard Worker                       size_t spaces, const char *err)
254*49cdfc7eSAndroid Build Coastguard Worker {
255*49cdfc7eSAndroid Build Coastguard Worker 	size_t i;
256*49cdfc7eSAndroid Build Coastguard Worker 
257*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < var->tok_len; i++)
258*49cdfc7eSAndroid Build Coastguard Worker 		fputc(var->tok[i], f);
259*49cdfc7eSAndroid Build Coastguard Worker 
260*49cdfc7eSAndroid Build Coastguard Worker 	fputc('\n', f);
261*49cdfc7eSAndroid Build Coastguard Worker 
262*49cdfc7eSAndroid Build Coastguard Worker 	while (spaces--)
263*49cdfc7eSAndroid Build Coastguard Worker 		fputc(' ', f);
264*49cdfc7eSAndroid Build Coastguard Worker 
265*49cdfc7eSAndroid Build Coastguard Worker 	fprintf(f, "^\n%s\n\n", err);
266*49cdfc7eSAndroid Build Coastguard Worker }
267*49cdfc7eSAndroid Build Coastguard Worker 
validate_var(const struct tst_expr_tok * var)268*49cdfc7eSAndroid Build Coastguard Worker static int validate_var(const struct tst_expr_tok *var)
269*49cdfc7eSAndroid Build Coastguard Worker {
270*49cdfc7eSAndroid Build Coastguard Worker 	size_t i = 7;
271*49cdfc7eSAndroid Build Coastguard Worker 
272*49cdfc7eSAndroid Build Coastguard Worker 	if (var->tok_len < 7 || strncmp(var->tok, "CONFIG_", 7)) {
273*49cdfc7eSAndroid Build Coastguard Worker 		print_err(stderr, var, 0, "Expected CONFIG_ prefix");
274*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
275*49cdfc7eSAndroid Build Coastguard Worker 	}
276*49cdfc7eSAndroid Build Coastguard Worker 
277*49cdfc7eSAndroid Build Coastguard Worker 	while (var->tok[i]) {
278*49cdfc7eSAndroid Build Coastguard Worker 		char c;
279*49cdfc7eSAndroid Build Coastguard Worker 
280*49cdfc7eSAndroid Build Coastguard Worker 		if (i >= var->tok_len)
281*49cdfc7eSAndroid Build Coastguard Worker 			return 0;
282*49cdfc7eSAndroid Build Coastguard Worker 
283*49cdfc7eSAndroid Build Coastguard Worker 		c = var->tok[i];
284*49cdfc7eSAndroid Build Coastguard Worker 
285*49cdfc7eSAndroid Build Coastguard Worker 		if ((c >= 'A' && c <= 'Z') || c == '_') {
286*49cdfc7eSAndroid Build Coastguard Worker 			i++;
287*49cdfc7eSAndroid Build Coastguard Worker 			continue;
288*49cdfc7eSAndroid Build Coastguard Worker 		}
289*49cdfc7eSAndroid Build Coastguard Worker 
290*49cdfc7eSAndroid Build Coastguard Worker 		if (c >= '0' && c <= '9') {
291*49cdfc7eSAndroid Build Coastguard Worker 			i++;
292*49cdfc7eSAndroid Build Coastguard Worker 			continue;
293*49cdfc7eSAndroid Build Coastguard Worker 		}
294*49cdfc7eSAndroid Build Coastguard Worker 
295*49cdfc7eSAndroid Build Coastguard Worker 		if (c == '=') {
296*49cdfc7eSAndroid Build Coastguard Worker 			i++;
297*49cdfc7eSAndroid Build Coastguard Worker 			break;
298*49cdfc7eSAndroid Build Coastguard Worker 		}
299*49cdfc7eSAndroid Build Coastguard Worker 
300*49cdfc7eSAndroid Build Coastguard Worker 		print_err(stderr, var, i, "Unexpected character in variable name");
301*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
302*49cdfc7eSAndroid Build Coastguard Worker 	}
303*49cdfc7eSAndroid Build Coastguard Worker 
304*49cdfc7eSAndroid Build Coastguard Worker 	if (i >= var->tok_len) {
305*49cdfc7eSAndroid Build Coastguard Worker 
306*49cdfc7eSAndroid Build Coastguard Worker 		if (var->tok[i-1] == '=') {
307*49cdfc7eSAndroid Build Coastguard Worker 			print_err(stderr, var, i, "Missing value");
308*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
309*49cdfc7eSAndroid Build Coastguard Worker 		}
310*49cdfc7eSAndroid Build Coastguard Worker 
311*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
312*49cdfc7eSAndroid Build Coastguard Worker 	}
313*49cdfc7eSAndroid Build Coastguard Worker 
314*49cdfc7eSAndroid Build Coastguard Worker 	if (var->tok[i] == '"') {
315*49cdfc7eSAndroid Build Coastguard Worker 		do {
316*49cdfc7eSAndroid Build Coastguard Worker 			i++;
317*49cdfc7eSAndroid Build Coastguard Worker 		} while (i < var->tok_len && var->tok[i] != '"');
318*49cdfc7eSAndroid Build Coastguard Worker 
319*49cdfc7eSAndroid Build Coastguard Worker 		if (i < var->tok_len - 1) {
320*49cdfc7eSAndroid Build Coastguard Worker 			print_err(stderr, var, i, "Garbage after a string");
321*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
322*49cdfc7eSAndroid Build Coastguard Worker 		}
323*49cdfc7eSAndroid Build Coastguard Worker 
324*49cdfc7eSAndroid Build Coastguard Worker 		if (var->tok[i] != '"') {
325*49cdfc7eSAndroid Build Coastguard Worker 			print_err(stderr, var, i, "Untermianted string");
326*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
327*49cdfc7eSAndroid Build Coastguard Worker 		}
328*49cdfc7eSAndroid Build Coastguard Worker 
329*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
330*49cdfc7eSAndroid Build Coastguard Worker 	}
331*49cdfc7eSAndroid Build Coastguard Worker 
332*49cdfc7eSAndroid Build Coastguard Worker 	do {
333*49cdfc7eSAndroid Build Coastguard Worker 		i++;
334*49cdfc7eSAndroid Build Coastguard Worker 	} while (i < var->tok_len && isalnum(var->tok[i]));
335*49cdfc7eSAndroid Build Coastguard Worker 
336*49cdfc7eSAndroid Build Coastguard Worker 	if (i < var->tok_len) {
337*49cdfc7eSAndroid Build Coastguard Worker 		print_err(stderr, var, i, "Invalid character in variable value");
338*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
339*49cdfc7eSAndroid Build Coastguard Worker 	}
340*49cdfc7eSAndroid Build Coastguard Worker 
341*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
342*49cdfc7eSAndroid Build Coastguard Worker }
343*49cdfc7eSAndroid Build Coastguard Worker 
validate_vars(struct tst_expr * const exprs[],unsigned int expr_cnt)344*49cdfc7eSAndroid Build Coastguard Worker static int validate_vars(struct tst_expr *const exprs[], unsigned int expr_cnt)
345*49cdfc7eSAndroid Build Coastguard Worker {
346*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i;
347*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_expr_tok *j;
348*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int ret = 0;
349*49cdfc7eSAndroid Build Coastguard Worker 
350*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < expr_cnt; i++) {
351*49cdfc7eSAndroid Build Coastguard Worker 		for (j = exprs[i]->rpn; j; j = j->next) {
352*49cdfc7eSAndroid Build Coastguard Worker 			if (j->op == TST_OP_VAR)
353*49cdfc7eSAndroid Build Coastguard Worker 				ret |= validate_var(j);
354*49cdfc7eSAndroid Build Coastguard Worker 		}
355*49cdfc7eSAndroid Build Coastguard Worker 	}
356*49cdfc7eSAndroid Build Coastguard Worker 
357*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
358*49cdfc7eSAndroid Build Coastguard Worker }
359*49cdfc7eSAndroid Build Coastguard Worker 
360*49cdfc7eSAndroid Build Coastguard Worker 
get_var_cnt(struct tst_expr * const exprs[],unsigned int expr_cnt)361*49cdfc7eSAndroid Build Coastguard Worker static inline unsigned int get_var_cnt(struct tst_expr *const exprs[],
362*49cdfc7eSAndroid Build Coastguard Worker                                        unsigned int expr_cnt)
363*49cdfc7eSAndroid Build Coastguard Worker {
364*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i;
365*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_expr_tok *j;
366*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int cnt = 0;
367*49cdfc7eSAndroid Build Coastguard Worker 
368*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < expr_cnt; i++) {
369*49cdfc7eSAndroid Build Coastguard Worker 		for (j = exprs[i]->rpn; j; j = j->next) {
370*49cdfc7eSAndroid Build Coastguard Worker 			if (j->op == TST_OP_VAR)
371*49cdfc7eSAndroid Build Coastguard Worker 				cnt++;
372*49cdfc7eSAndroid Build Coastguard Worker 		}
373*49cdfc7eSAndroid Build Coastguard Worker 	}
374*49cdfc7eSAndroid Build Coastguard Worker 
375*49cdfc7eSAndroid Build Coastguard Worker 	return cnt;
376*49cdfc7eSAndroid Build Coastguard Worker }
377*49cdfc7eSAndroid Build Coastguard Worker 
find_var(const struct tst_kconfig_var vars[],unsigned int var_cnt,const char * var)378*49cdfc7eSAndroid Build Coastguard Worker static const struct tst_kconfig_var *find_var(const struct tst_kconfig_var vars[],
379*49cdfc7eSAndroid Build Coastguard Worker                                         unsigned int var_cnt,
380*49cdfc7eSAndroid Build Coastguard Worker                                         const char *var)
381*49cdfc7eSAndroid Build Coastguard Worker {
382*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i;
383*49cdfc7eSAndroid Build Coastguard Worker 
384*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < var_cnt; i++) {
385*49cdfc7eSAndroid Build Coastguard Worker 		if (!strcmp(vars[i].id, var))
386*49cdfc7eSAndroid Build Coastguard Worker 			return &vars[i];
387*49cdfc7eSAndroid Build Coastguard Worker 	}
388*49cdfc7eSAndroid Build Coastguard Worker 
389*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
390*49cdfc7eSAndroid Build Coastguard Worker }
391*49cdfc7eSAndroid Build Coastguard Worker 
392*49cdfc7eSAndroid Build Coastguard Worker /*
393*49cdfc7eSAndroid Build Coastguard Worker  * Fill in the kconfig variables array from the expressions. Also makes sure
394*49cdfc7eSAndroid Build Coastguard Worker  * that each variable is copied to the array exaclty once.
395*49cdfc7eSAndroid Build Coastguard Worker  */
populate_vars(struct tst_expr * exprs[],unsigned int expr_cnt,struct tst_kconfig_var vars[])396*49cdfc7eSAndroid Build Coastguard Worker static inline unsigned int populate_vars(struct tst_expr *exprs[],
397*49cdfc7eSAndroid Build Coastguard Worker                                          unsigned int expr_cnt,
398*49cdfc7eSAndroid Build Coastguard Worker                                     struct tst_kconfig_var vars[])
399*49cdfc7eSAndroid Build Coastguard Worker {
400*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i;
401*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_expr_tok *j;
402*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int cnt = 0;
403*49cdfc7eSAndroid Build Coastguard Worker 
404*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < expr_cnt; i++) {
405*49cdfc7eSAndroid Build Coastguard Worker 		for (j = exprs[i]->rpn; j; j = j->next) {
406*49cdfc7eSAndroid Build Coastguard Worker 			const struct tst_kconfig_var *var;
407*49cdfc7eSAndroid Build Coastguard Worker 
408*49cdfc7eSAndroid Build Coastguard Worker 			if (j->op != TST_OP_VAR)
409*49cdfc7eSAndroid Build Coastguard Worker 				continue;
410*49cdfc7eSAndroid Build Coastguard Worker 
411*49cdfc7eSAndroid Build Coastguard Worker 			vars[cnt].id_len = get_len(j->tok, j->tok_len);
412*49cdfc7eSAndroid Build Coastguard Worker 
413*49cdfc7eSAndroid Build Coastguard Worker 			if (vars[cnt].id_len + 1 >= sizeof(vars[cnt].id))
414*49cdfc7eSAndroid Build Coastguard Worker 				tst_brk(TBROK, "kconfig var id too long!");
415*49cdfc7eSAndroid Build Coastguard Worker 
416*49cdfc7eSAndroid Build Coastguard Worker 			strncpy(vars[cnt].id, j->tok, vars[cnt].id_len);
417*49cdfc7eSAndroid Build Coastguard Worker 			vars[cnt].id[vars[cnt].id_len] = 0;
418*49cdfc7eSAndroid Build Coastguard Worker 			vars[cnt].choice = 0;
419*49cdfc7eSAndroid Build Coastguard Worker 			vars[cnt].val = NULL;
420*49cdfc7eSAndroid Build Coastguard Worker 
421*49cdfc7eSAndroid Build Coastguard Worker 			var = find_var(vars, cnt, vars[cnt].id);
422*49cdfc7eSAndroid Build Coastguard Worker 
423*49cdfc7eSAndroid Build Coastguard Worker 			if (var)
424*49cdfc7eSAndroid Build Coastguard Worker 				j->priv = var;
425*49cdfc7eSAndroid Build Coastguard Worker 			else
426*49cdfc7eSAndroid Build Coastguard Worker 				j->priv = &vars[cnt++];
427*49cdfc7eSAndroid Build Coastguard Worker 		}
428*49cdfc7eSAndroid Build Coastguard Worker 	}
429*49cdfc7eSAndroid Build Coastguard Worker 
430*49cdfc7eSAndroid Build Coastguard Worker 	return cnt;
431*49cdfc7eSAndroid Build Coastguard Worker }
432*49cdfc7eSAndroid Build Coastguard Worker 
map(struct tst_expr_tok * expr)433*49cdfc7eSAndroid Build Coastguard Worker static int map(struct tst_expr_tok *expr)
434*49cdfc7eSAndroid Build Coastguard Worker {
435*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_kconfig_var *var = expr->priv;
436*49cdfc7eSAndroid Build Coastguard Worker 
437*49cdfc7eSAndroid Build Coastguard Worker 	if (var->choice == 0)
438*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
439*49cdfc7eSAndroid Build Coastguard Worker 
440*49cdfc7eSAndroid Build Coastguard Worker 	const char *val = strnchr(expr->tok, '=', expr->tok_len);
441*49cdfc7eSAndroid Build Coastguard Worker 
442*49cdfc7eSAndroid Build Coastguard Worker 	/* CONFIG_FOO evaluates to true if y or m */
443*49cdfc7eSAndroid Build Coastguard Worker 	if (!val)
444*49cdfc7eSAndroid Build Coastguard Worker 		return var->choice == 'y' || var->choice == 'm';
445*49cdfc7eSAndroid Build Coastguard Worker 
446*49cdfc7eSAndroid Build Coastguard Worker 	val++;
447*49cdfc7eSAndroid Build Coastguard Worker 
448*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int len = expr->tok_len - (val - expr->tok);
449*49cdfc7eSAndroid Build Coastguard Worker 	char choice = 'v';
450*49cdfc7eSAndroid Build Coastguard Worker 
451*49cdfc7eSAndroid Build Coastguard Worker 	if (!strncmp(val, "n", len))
452*49cdfc7eSAndroid Build Coastguard Worker 		choice = 'n';
453*49cdfc7eSAndroid Build Coastguard Worker 
454*49cdfc7eSAndroid Build Coastguard Worker 	if (!strncmp(val, "y", len))
455*49cdfc7eSAndroid Build Coastguard Worker 		choice = 'y';
456*49cdfc7eSAndroid Build Coastguard Worker 
457*49cdfc7eSAndroid Build Coastguard Worker 	if (!strncmp(val, "m", len))
458*49cdfc7eSAndroid Build Coastguard Worker 		choice = 'm';
459*49cdfc7eSAndroid Build Coastguard Worker 
460*49cdfc7eSAndroid Build Coastguard Worker 	if (choice != 'v')
461*49cdfc7eSAndroid Build Coastguard Worker 		return var->choice == choice;
462*49cdfc7eSAndroid Build Coastguard Worker 
463*49cdfc7eSAndroid Build Coastguard Worker 	if (var->choice != 'v')
464*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
465*49cdfc7eSAndroid Build Coastguard Worker 
466*49cdfc7eSAndroid Build Coastguard Worker 	if (strlen(var->val) != len)
467*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
468*49cdfc7eSAndroid Build Coastguard Worker 
469*49cdfc7eSAndroid Build Coastguard Worker 	return !strncmp(val, var->val, len);
470*49cdfc7eSAndroid Build Coastguard Worker }
471*49cdfc7eSAndroid Build Coastguard Worker 
dump_vars(const struct tst_expr * expr)472*49cdfc7eSAndroid Build Coastguard Worker static void dump_vars(const struct tst_expr *expr)
473*49cdfc7eSAndroid Build Coastguard Worker {
474*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_expr_tok *i;
475*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_kconfig_var *var;
476*49cdfc7eSAndroid Build Coastguard Worker 
477*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "Variables:");
478*49cdfc7eSAndroid Build Coastguard Worker 
479*49cdfc7eSAndroid Build Coastguard Worker 	for (i = expr->rpn; i; i = i->next) {
480*49cdfc7eSAndroid Build Coastguard Worker 		if (i->op != TST_OP_VAR)
481*49cdfc7eSAndroid Build Coastguard Worker 			continue;
482*49cdfc7eSAndroid Build Coastguard Worker 
483*49cdfc7eSAndroid Build Coastguard Worker 		var = i->priv;
484*49cdfc7eSAndroid Build Coastguard Worker 
485*49cdfc7eSAndroid Build Coastguard Worker 		if (!var->choice) {
486*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO, " %s Undefined", var->id);
487*49cdfc7eSAndroid Build Coastguard Worker 			continue;
488*49cdfc7eSAndroid Build Coastguard Worker 		}
489*49cdfc7eSAndroid Build Coastguard Worker 
490*49cdfc7eSAndroid Build Coastguard Worker 		if (var->choice == 'v') {
491*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO, " %s=%s", var->id, var->val);
492*49cdfc7eSAndroid Build Coastguard Worker 			continue;
493*49cdfc7eSAndroid Build Coastguard Worker 		}
494*49cdfc7eSAndroid Build Coastguard Worker 
495*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TINFO, " %s=%c", var->id, var->choice);
496*49cdfc7eSAndroid Build Coastguard Worker 	}
497*49cdfc7eSAndroid Build Coastguard Worker }
498*49cdfc7eSAndroid Build Coastguard Worker 
tst_kconfig_check(const char * const kconfigs[])499*49cdfc7eSAndroid Build Coastguard Worker int tst_kconfig_check(const char *const kconfigs[])
500*49cdfc7eSAndroid Build Coastguard Worker {
501*49cdfc7eSAndroid Build Coastguard Worker 	size_t expr_cnt = array_len(kconfigs);
502*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_expr *exprs[expr_cnt];
503*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i, var_cnt;
504*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
505*49cdfc7eSAndroid Build Coastguard Worker 
506*49cdfc7eSAndroid Build Coastguard Worker 	if (kconfig_skip_check())
507*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
508*49cdfc7eSAndroid Build Coastguard Worker 
509*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < expr_cnt; i++) {
510*49cdfc7eSAndroid Build Coastguard Worker 		exprs[i] = tst_bool_expr_parse(kconfigs[i]);
511*49cdfc7eSAndroid Build Coastguard Worker 
512*49cdfc7eSAndroid Build Coastguard Worker 		if (!exprs[i])
513*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK, "Invalid kconfig expression!");
514*49cdfc7eSAndroid Build Coastguard Worker 	}
515*49cdfc7eSAndroid Build Coastguard Worker 
516*49cdfc7eSAndroid Build Coastguard Worker 	if (validate_vars(exprs, expr_cnt))
517*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Invalid kconfig variables!");
518*49cdfc7eSAndroid Build Coastguard Worker 
519*49cdfc7eSAndroid Build Coastguard Worker 	var_cnt = get_var_cnt(exprs, expr_cnt);
520*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_kconfig_var vars[var_cnt];
521*49cdfc7eSAndroid Build Coastguard Worker 
522*49cdfc7eSAndroid Build Coastguard Worker 	var_cnt = populate_vars(exprs, expr_cnt, vars);
523*49cdfc7eSAndroid Build Coastguard Worker 
524*49cdfc7eSAndroid Build Coastguard Worker 	tst_kconfig_read(vars, var_cnt);
525*49cdfc7eSAndroid Build Coastguard Worker 
526*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < expr_cnt; i++) {
527*49cdfc7eSAndroid Build Coastguard Worker 		int val = tst_bool_expr_eval(exprs[i], map);
528*49cdfc7eSAndroid Build Coastguard Worker 
529*49cdfc7eSAndroid Build Coastguard Worker 		if (val != 1) {
530*49cdfc7eSAndroid Build Coastguard Worker 			ret = 1;
531*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO, "Constraint '%s' not satisfied!", kconfigs[i]);
532*49cdfc7eSAndroid Build Coastguard Worker 			dump_vars(exprs[i]);
533*49cdfc7eSAndroid Build Coastguard Worker 		}
534*49cdfc7eSAndroid Build Coastguard Worker 
535*49cdfc7eSAndroid Build Coastguard Worker 		tst_bool_expr_free(exprs[i]);
536*49cdfc7eSAndroid Build Coastguard Worker 	}
537*49cdfc7eSAndroid Build Coastguard Worker 
538*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < var_cnt; i++) {
539*49cdfc7eSAndroid Build Coastguard Worker 		if (vars[i].choice == 'v')
540*49cdfc7eSAndroid Build Coastguard Worker 			free(vars[i].val);
541*49cdfc7eSAndroid Build Coastguard Worker 	}
542*49cdfc7eSAndroid Build Coastguard Worker 
543*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
544*49cdfc7eSAndroid Build Coastguard Worker }
545*49cdfc7eSAndroid Build Coastguard Worker 
tst_kconfig_get(const char * confname)546*49cdfc7eSAndroid Build Coastguard Worker char tst_kconfig_get(const char *confname)
547*49cdfc7eSAndroid Build Coastguard Worker {
548*49cdfc7eSAndroid Build Coastguard Worker 	struct tst_kconfig_var var;
549*49cdfc7eSAndroid Build Coastguard Worker 
550*49cdfc7eSAndroid Build Coastguard Worker 	if (kconfig_skip_check())
551*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
552*49cdfc7eSAndroid Build Coastguard Worker 
553*49cdfc7eSAndroid Build Coastguard Worker 	var.id_len = strlen(confname);
554*49cdfc7eSAndroid Build Coastguard Worker 
555*49cdfc7eSAndroid Build Coastguard Worker 	if (var.id_len >= sizeof(var.id))
556*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Kconfig var name \"%s\" too long", confname);
557*49cdfc7eSAndroid Build Coastguard Worker 
558*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(var.id, confname);
559*49cdfc7eSAndroid Build Coastguard Worker 	var.choice = 0;
560*49cdfc7eSAndroid Build Coastguard Worker 	var.val = NULL;
561*49cdfc7eSAndroid Build Coastguard Worker 
562*49cdfc7eSAndroid Build Coastguard Worker 	tst_kconfig_read(&var, 1);
563*49cdfc7eSAndroid Build Coastguard Worker 
564*49cdfc7eSAndroid Build Coastguard Worker 	if (var.choice == 'v')
565*49cdfc7eSAndroid Build Coastguard Worker 		free(var.val);
566*49cdfc7eSAndroid Build Coastguard Worker 
567*49cdfc7eSAndroid Build Coastguard Worker 	return var.choice;
568*49cdfc7eSAndroid Build Coastguard Worker }
569*49cdfc7eSAndroid Build Coastguard Worker 
tst_kcmdline_parse(struct tst_kcmdline_var params[],size_t params_len)570*49cdfc7eSAndroid Build Coastguard Worker void tst_kcmdline_parse(struct tst_kcmdline_var params[], size_t params_len)
571*49cdfc7eSAndroid Build Coastguard Worker {
572*49cdfc7eSAndroid Build Coastguard Worker 	char buf[128], line[512];
573*49cdfc7eSAndroid Build Coastguard Worker 	size_t b_pos = 0,l_pos =0, i;
574*49cdfc7eSAndroid Build Coastguard Worker 	int var_id = -1;
575*49cdfc7eSAndroid Build Coastguard Worker 
576*49cdfc7eSAndroid Build Coastguard Worker 	FILE *f = SAFE_FOPEN("/proc/cmdline", "r");
577*49cdfc7eSAndroid Build Coastguard Worker 
578*49cdfc7eSAndroid Build Coastguard Worker 	if (fgets(line, sizeof(line), f) == NULL) {
579*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_FCLOSE(f);
580*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Failed to read /proc/cmdline");
581*49cdfc7eSAndroid Build Coastguard Worker 	}
582*49cdfc7eSAndroid Build Coastguard Worker 
583*49cdfc7eSAndroid Build Coastguard Worker 	for (l_pos = 0; line[l_pos] != '\0'; l_pos++) {
584*49cdfc7eSAndroid Build Coastguard Worker 		char c = line[l_pos];
585*49cdfc7eSAndroid Build Coastguard Worker 
586*49cdfc7eSAndroid Build Coastguard Worker 		switch (c) {
587*49cdfc7eSAndroid Build Coastguard Worker 		case '=':
588*49cdfc7eSAndroid Build Coastguard Worker 			buf[b_pos] = '\0';
589*49cdfc7eSAndroid Build Coastguard Worker 			for (i = 0; i < params_len; i++) {
590*49cdfc7eSAndroid Build Coastguard Worker 				if (strcmp(buf, params[i].key) == 0) {
591*49cdfc7eSAndroid Build Coastguard Worker 					var_id = (int)i;
592*49cdfc7eSAndroid Build Coastguard Worker 					params[i].found = true;
593*49cdfc7eSAndroid Build Coastguard Worker 				}
594*49cdfc7eSAndroid Build Coastguard Worker 			}
595*49cdfc7eSAndroid Build Coastguard Worker 
596*49cdfc7eSAndroid Build Coastguard Worker 			b_pos = 0;
597*49cdfc7eSAndroid Build Coastguard Worker 		break;
598*49cdfc7eSAndroid Build Coastguard Worker 		case ' ':
599*49cdfc7eSAndroid Build Coastguard Worker 		case '\n':
600*49cdfc7eSAndroid Build Coastguard Worker 			buf[b_pos] = '\0';
601*49cdfc7eSAndroid Build Coastguard Worker 			if (var_id >= 0 && var_id < (int)params_len)
602*49cdfc7eSAndroid Build Coastguard Worker 				strcpy(params[var_id].value, buf);
603*49cdfc7eSAndroid Build Coastguard Worker 
604*49cdfc7eSAndroid Build Coastguard Worker 			var_id = -1;
605*49cdfc7eSAndroid Build Coastguard Worker 			b_pos = 0;
606*49cdfc7eSAndroid Build Coastguard Worker 		break;
607*49cdfc7eSAndroid Build Coastguard Worker 		default:
608*49cdfc7eSAndroid Build Coastguard Worker 			if (b_pos + 1 >= sizeof(buf)) {
609*49cdfc7eSAndroid Build Coastguard Worker 				tst_res(TWARN, "Buffer overflowed while parsing /proc/cmdline");
610*49cdfc7eSAndroid Build Coastguard Worker 				while (line[l_pos] != '\0' && line[l_pos] != ' ' && line[l_pos] != '\n')
611*49cdfc7eSAndroid Build Coastguard Worker 					l_pos++;
612*49cdfc7eSAndroid Build Coastguard Worker 
613*49cdfc7eSAndroid Build Coastguard Worker 				var_id = -1;
614*49cdfc7eSAndroid Build Coastguard Worker 				b_pos = 0;
615*49cdfc7eSAndroid Build Coastguard Worker 
616*49cdfc7eSAndroid Build Coastguard Worker 				if (line[l_pos] != '\0')
617*49cdfc7eSAndroid Build Coastguard Worker 					l_pos--;
618*49cdfc7eSAndroid Build Coastguard Worker 			} else {
619*49cdfc7eSAndroid Build Coastguard Worker 				buf[b_pos++] = c;
620*49cdfc7eSAndroid Build Coastguard Worker 			}
621*49cdfc7eSAndroid Build Coastguard Worker 		break;
622*49cdfc7eSAndroid Build Coastguard Worker 		}
623*49cdfc7eSAndroid Build Coastguard Worker 	}
624*49cdfc7eSAndroid Build Coastguard Worker 
625*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < params_len; i++) {
626*49cdfc7eSAndroid Build Coastguard Worker 		if (params[i].found)
627*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO, "%s is found in /proc/cmdline", params[i].key);
628*49cdfc7eSAndroid Build Coastguard Worker 		else
629*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TINFO, "%s is not found in /proc/cmdline", params[i].key);
630*49cdfc7eSAndroid Build Coastguard Worker 	}
631*49cdfc7eSAndroid Build Coastguard Worker 
632*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FCLOSE(f);
633*49cdfc7eSAndroid Build Coastguard Worker }
634