xref: /openbmc/linux/scripts/kconfig/confdata.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds /*
2*1da177e4SLinus Torvalds  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3*1da177e4SLinus Torvalds  * Released under the terms of the GNU GPL v2.0.
4*1da177e4SLinus Torvalds  */
5*1da177e4SLinus Torvalds 
6*1da177e4SLinus Torvalds #include <sys/stat.h>
7*1da177e4SLinus Torvalds #include <ctype.h>
8*1da177e4SLinus Torvalds #include <stdio.h>
9*1da177e4SLinus Torvalds #include <stdlib.h>
10*1da177e4SLinus Torvalds #include <string.h>
11*1da177e4SLinus Torvalds #include <time.h>
12*1da177e4SLinus Torvalds #include <unistd.h>
13*1da177e4SLinus Torvalds 
14*1da177e4SLinus Torvalds #define LKC_DIRECT_LINK
15*1da177e4SLinus Torvalds #include "lkc.h"
16*1da177e4SLinus Torvalds 
17*1da177e4SLinus Torvalds const char conf_def_filename[] = ".config";
18*1da177e4SLinus Torvalds 
19*1da177e4SLinus Torvalds const char conf_defname[] = "arch/$ARCH/defconfig";
20*1da177e4SLinus Torvalds 
21*1da177e4SLinus Torvalds const char *conf_confnames[] = {
22*1da177e4SLinus Torvalds 	".config",
23*1da177e4SLinus Torvalds 	"/lib/modules/$UNAME_RELEASE/.config",
24*1da177e4SLinus Torvalds 	"/etc/kernel-config",
25*1da177e4SLinus Torvalds 	"/boot/config-$UNAME_RELEASE",
26*1da177e4SLinus Torvalds 	conf_defname,
27*1da177e4SLinus Torvalds 	NULL,
28*1da177e4SLinus Torvalds };
29*1da177e4SLinus Torvalds 
30*1da177e4SLinus Torvalds static char *conf_expand_value(const signed char *in)
31*1da177e4SLinus Torvalds {
32*1da177e4SLinus Torvalds 	struct symbol *sym;
33*1da177e4SLinus Torvalds 	const signed char *src;
34*1da177e4SLinus Torvalds 	static char res_value[SYMBOL_MAXLENGTH];
35*1da177e4SLinus Torvalds 	char *dst, name[SYMBOL_MAXLENGTH];
36*1da177e4SLinus Torvalds 
37*1da177e4SLinus Torvalds 	res_value[0] = 0;
38*1da177e4SLinus Torvalds 	dst = name;
39*1da177e4SLinus Torvalds 	while ((src = strchr(in, '$'))) {
40*1da177e4SLinus Torvalds 		strncat(res_value, in, src - in);
41*1da177e4SLinus Torvalds 		src++;
42*1da177e4SLinus Torvalds 		dst = name;
43*1da177e4SLinus Torvalds 		while (isalnum(*src) || *src == '_')
44*1da177e4SLinus Torvalds 			*dst++ = *src++;
45*1da177e4SLinus Torvalds 		*dst = 0;
46*1da177e4SLinus Torvalds 		sym = sym_lookup(name, 0);
47*1da177e4SLinus Torvalds 		sym_calc_value(sym);
48*1da177e4SLinus Torvalds 		strcat(res_value, sym_get_string_value(sym));
49*1da177e4SLinus Torvalds 		in = src;
50*1da177e4SLinus Torvalds 	}
51*1da177e4SLinus Torvalds 	strcat(res_value, in);
52*1da177e4SLinus Torvalds 
53*1da177e4SLinus Torvalds 	return res_value;
54*1da177e4SLinus Torvalds }
55*1da177e4SLinus Torvalds 
56*1da177e4SLinus Torvalds char *conf_get_default_confname(void)
57*1da177e4SLinus Torvalds {
58*1da177e4SLinus Torvalds 	struct stat buf;
59*1da177e4SLinus Torvalds 	static char fullname[PATH_MAX+1];
60*1da177e4SLinus Torvalds 	char *env, *name;
61*1da177e4SLinus Torvalds 
62*1da177e4SLinus Torvalds 	name = conf_expand_value(conf_defname);
63*1da177e4SLinus Torvalds 	env = getenv(SRCTREE);
64*1da177e4SLinus Torvalds 	if (env) {
65*1da177e4SLinus Torvalds 		sprintf(fullname, "%s/%s", env, name);
66*1da177e4SLinus Torvalds 		if (!stat(fullname, &buf))
67*1da177e4SLinus Torvalds 			return fullname;
68*1da177e4SLinus Torvalds 	}
69*1da177e4SLinus Torvalds 	return name;
70*1da177e4SLinus Torvalds }
71*1da177e4SLinus Torvalds 
72*1da177e4SLinus Torvalds int conf_read(const char *name)
73*1da177e4SLinus Torvalds {
74*1da177e4SLinus Torvalds 	FILE *in = NULL;
75*1da177e4SLinus Torvalds 	char line[1024];
76*1da177e4SLinus Torvalds 	char *p, *p2;
77*1da177e4SLinus Torvalds 	int lineno = 0;
78*1da177e4SLinus Torvalds 	struct symbol *sym;
79*1da177e4SLinus Torvalds 	struct property *prop;
80*1da177e4SLinus Torvalds 	struct expr *e;
81*1da177e4SLinus Torvalds 	int i;
82*1da177e4SLinus Torvalds 
83*1da177e4SLinus Torvalds 	if (name) {
84*1da177e4SLinus Torvalds 		in = zconf_fopen(name);
85*1da177e4SLinus Torvalds 	} else {
86*1da177e4SLinus Torvalds 		const char **names = conf_confnames;
87*1da177e4SLinus Torvalds 		while ((name = *names++)) {
88*1da177e4SLinus Torvalds 			name = conf_expand_value(name);
89*1da177e4SLinus Torvalds 			in = zconf_fopen(name);
90*1da177e4SLinus Torvalds 			if (in) {
91*1da177e4SLinus Torvalds 				printf("#\n"
92*1da177e4SLinus Torvalds 				       "# using defaults found in %s\n"
93*1da177e4SLinus Torvalds 				       "#\n", name);
94*1da177e4SLinus Torvalds 				break;
95*1da177e4SLinus Torvalds 			}
96*1da177e4SLinus Torvalds 		}
97*1da177e4SLinus Torvalds 	}
98*1da177e4SLinus Torvalds 
99*1da177e4SLinus Torvalds 	if (!in)
100*1da177e4SLinus Torvalds 		return 1;
101*1da177e4SLinus Torvalds 
102*1da177e4SLinus Torvalds 	for_all_symbols(i, sym) {
103*1da177e4SLinus Torvalds 		sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
104*1da177e4SLinus Torvalds 		sym->flags &= ~SYMBOL_VALID;
105*1da177e4SLinus Torvalds 		switch (sym->type) {
106*1da177e4SLinus Torvalds 		case S_INT:
107*1da177e4SLinus Torvalds 		case S_HEX:
108*1da177e4SLinus Torvalds 		case S_STRING:
109*1da177e4SLinus Torvalds 			if (sym->user.val)
110*1da177e4SLinus Torvalds 				free(sym->user.val);
111*1da177e4SLinus Torvalds 		default:
112*1da177e4SLinus Torvalds 			sym->user.val = NULL;
113*1da177e4SLinus Torvalds 			sym->user.tri = no;
114*1da177e4SLinus Torvalds 		}
115*1da177e4SLinus Torvalds 	}
116*1da177e4SLinus Torvalds 
117*1da177e4SLinus Torvalds 	while (fgets(line, sizeof(line), in)) {
118*1da177e4SLinus Torvalds 		lineno++;
119*1da177e4SLinus Torvalds 		sym = NULL;
120*1da177e4SLinus Torvalds 		switch (line[0]) {
121*1da177e4SLinus Torvalds 		case '#':
122*1da177e4SLinus Torvalds 			if (memcmp(line + 2, "CONFIG_", 7))
123*1da177e4SLinus Torvalds 				continue;
124*1da177e4SLinus Torvalds 			p = strchr(line + 9, ' ');
125*1da177e4SLinus Torvalds 			if (!p)
126*1da177e4SLinus Torvalds 				continue;
127*1da177e4SLinus Torvalds 			*p++ = 0;
128*1da177e4SLinus Torvalds 			if (strncmp(p, "is not set", 10))
129*1da177e4SLinus Torvalds 				continue;
130*1da177e4SLinus Torvalds 			sym = sym_find(line + 9);
131*1da177e4SLinus Torvalds 			if (!sym) {
132*1da177e4SLinus Torvalds 				fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9);
133*1da177e4SLinus Torvalds 				break;
134*1da177e4SLinus Torvalds 			}
135*1da177e4SLinus Torvalds 			switch (sym->type) {
136*1da177e4SLinus Torvalds 			case S_BOOLEAN:
137*1da177e4SLinus Torvalds 			case S_TRISTATE:
138*1da177e4SLinus Torvalds 				sym->user.tri = no;
139*1da177e4SLinus Torvalds 				sym->flags &= ~SYMBOL_NEW;
140*1da177e4SLinus Torvalds 				break;
141*1da177e4SLinus Torvalds 			default:
142*1da177e4SLinus Torvalds 				;
143*1da177e4SLinus Torvalds 			}
144*1da177e4SLinus Torvalds 			break;
145*1da177e4SLinus Torvalds 		case 'C':
146*1da177e4SLinus Torvalds 			if (memcmp(line, "CONFIG_", 7))
147*1da177e4SLinus Torvalds 				continue;
148*1da177e4SLinus Torvalds 			p = strchr(line + 7, '=');
149*1da177e4SLinus Torvalds 			if (!p)
150*1da177e4SLinus Torvalds 				continue;
151*1da177e4SLinus Torvalds 			*p++ = 0;
152*1da177e4SLinus Torvalds 			p2 = strchr(p, '\n');
153*1da177e4SLinus Torvalds 			if (p2)
154*1da177e4SLinus Torvalds 				*p2 = 0;
155*1da177e4SLinus Torvalds 			sym = sym_find(line + 7);
156*1da177e4SLinus Torvalds 			if (!sym) {
157*1da177e4SLinus Torvalds 				fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
158*1da177e4SLinus Torvalds 				break;
159*1da177e4SLinus Torvalds 			}
160*1da177e4SLinus Torvalds 			switch (sym->type) {
161*1da177e4SLinus Torvalds 			case S_TRISTATE:
162*1da177e4SLinus Torvalds 				if (p[0] == 'm') {
163*1da177e4SLinus Torvalds 					sym->user.tri = mod;
164*1da177e4SLinus Torvalds 					sym->flags &= ~SYMBOL_NEW;
165*1da177e4SLinus Torvalds 					break;
166*1da177e4SLinus Torvalds 				}
167*1da177e4SLinus Torvalds 			case S_BOOLEAN:
168*1da177e4SLinus Torvalds 				if (p[0] == 'y') {
169*1da177e4SLinus Torvalds 					sym->user.tri = yes;
170*1da177e4SLinus Torvalds 					sym->flags &= ~SYMBOL_NEW;
171*1da177e4SLinus Torvalds 					break;
172*1da177e4SLinus Torvalds 				}
173*1da177e4SLinus Torvalds 				if (p[0] == 'n') {
174*1da177e4SLinus Torvalds 					sym->user.tri = no;
175*1da177e4SLinus Torvalds 					sym->flags &= ~SYMBOL_NEW;
176*1da177e4SLinus Torvalds 					break;
177*1da177e4SLinus Torvalds 				}
178*1da177e4SLinus Torvalds 				break;
179*1da177e4SLinus Torvalds 			case S_STRING:
180*1da177e4SLinus Torvalds 				if (*p++ != '"')
181*1da177e4SLinus Torvalds 					break;
182*1da177e4SLinus Torvalds 				for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
183*1da177e4SLinus Torvalds 					if (*p2 == '"') {
184*1da177e4SLinus Torvalds 						*p2 = 0;
185*1da177e4SLinus Torvalds 						break;
186*1da177e4SLinus Torvalds 					}
187*1da177e4SLinus Torvalds 					memmove(p2, p2 + 1, strlen(p2));
188*1da177e4SLinus Torvalds 				}
189*1da177e4SLinus Torvalds 				if (!p2) {
190*1da177e4SLinus Torvalds 					fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
191*1da177e4SLinus Torvalds 					exit(1);
192*1da177e4SLinus Torvalds 				}
193*1da177e4SLinus Torvalds 			case S_INT:
194*1da177e4SLinus Torvalds 			case S_HEX:
195*1da177e4SLinus Torvalds 				if (sym_string_valid(sym, p)) {
196*1da177e4SLinus Torvalds 					sym->user.val = strdup(p);
197*1da177e4SLinus Torvalds 					sym->flags &= ~SYMBOL_NEW;
198*1da177e4SLinus Torvalds 				} else {
199*1da177e4SLinus Torvalds 					fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
200*1da177e4SLinus Torvalds 					exit(1);
201*1da177e4SLinus Torvalds 				}
202*1da177e4SLinus Torvalds 				break;
203*1da177e4SLinus Torvalds 			default:
204*1da177e4SLinus Torvalds 				;
205*1da177e4SLinus Torvalds 			}
206*1da177e4SLinus Torvalds 			break;
207*1da177e4SLinus Torvalds 		case '\n':
208*1da177e4SLinus Torvalds 			break;
209*1da177e4SLinus Torvalds 		default:
210*1da177e4SLinus Torvalds 			continue;
211*1da177e4SLinus Torvalds 		}
212*1da177e4SLinus Torvalds 		if (sym && sym_is_choice_value(sym)) {
213*1da177e4SLinus Torvalds 			struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
214*1da177e4SLinus Torvalds 			switch (sym->user.tri) {
215*1da177e4SLinus Torvalds 			case no:
216*1da177e4SLinus Torvalds 				break;
217*1da177e4SLinus Torvalds 			case mod:
218*1da177e4SLinus Torvalds 				if (cs->user.tri == yes)
219*1da177e4SLinus Torvalds 					/* warn? */;
220*1da177e4SLinus Torvalds 				break;
221*1da177e4SLinus Torvalds 			case yes:
222*1da177e4SLinus Torvalds 				if (cs->user.tri != no)
223*1da177e4SLinus Torvalds 					/* warn? */;
224*1da177e4SLinus Torvalds 				cs->user.val = sym;
225*1da177e4SLinus Torvalds 				break;
226*1da177e4SLinus Torvalds 			}
227*1da177e4SLinus Torvalds 			cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
228*1da177e4SLinus Torvalds 			cs->flags &= ~SYMBOL_NEW;
229*1da177e4SLinus Torvalds 		}
230*1da177e4SLinus Torvalds 	}
231*1da177e4SLinus Torvalds 	fclose(in);
232*1da177e4SLinus Torvalds 
233*1da177e4SLinus Torvalds 	if (modules_sym)
234*1da177e4SLinus Torvalds 		sym_calc_value(modules_sym);
235*1da177e4SLinus Torvalds 	for_all_symbols(i, sym) {
236*1da177e4SLinus Torvalds 		sym_calc_value(sym);
237*1da177e4SLinus Torvalds 		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
238*1da177e4SLinus Torvalds 			if (sym->visible == no)
239*1da177e4SLinus Torvalds 				sym->flags |= SYMBOL_NEW;
240*1da177e4SLinus Torvalds 			switch (sym->type) {
241*1da177e4SLinus Torvalds 			case S_STRING:
242*1da177e4SLinus Torvalds 			case S_INT:
243*1da177e4SLinus Torvalds 			case S_HEX:
244*1da177e4SLinus Torvalds 				if (!sym_string_within_range(sym, sym->user.val))
245*1da177e4SLinus Torvalds 					sym->flags |= SYMBOL_NEW;
246*1da177e4SLinus Torvalds 			default:
247*1da177e4SLinus Torvalds 				break;
248*1da177e4SLinus Torvalds 			}
249*1da177e4SLinus Torvalds 		}
250*1da177e4SLinus Torvalds 		if (!sym_is_choice(sym))
251*1da177e4SLinus Torvalds 			continue;
252*1da177e4SLinus Torvalds 		prop = sym_get_choice_prop(sym);
253*1da177e4SLinus Torvalds 		for (e = prop->expr; e; e = e->left.expr)
254*1da177e4SLinus Torvalds 			if (e->right.sym->visible != no)
255*1da177e4SLinus Torvalds 				sym->flags |= e->right.sym->flags & SYMBOL_NEW;
256*1da177e4SLinus Torvalds 	}
257*1da177e4SLinus Torvalds 
258*1da177e4SLinus Torvalds 	sym_change_count = 1;
259*1da177e4SLinus Torvalds 
260*1da177e4SLinus Torvalds 	return 0;
261*1da177e4SLinus Torvalds }
262*1da177e4SLinus Torvalds 
263*1da177e4SLinus Torvalds int conf_write(const char *name)
264*1da177e4SLinus Torvalds {
265*1da177e4SLinus Torvalds 	FILE *out, *out_h;
266*1da177e4SLinus Torvalds 	struct symbol *sym;
267*1da177e4SLinus Torvalds 	struct menu *menu;
268*1da177e4SLinus Torvalds 	const char *basename;
269*1da177e4SLinus Torvalds 	char dirname[128], tmpname[128], newname[128];
270*1da177e4SLinus Torvalds 	int type, l;
271*1da177e4SLinus Torvalds 	const char *str;
272*1da177e4SLinus Torvalds 	time_t now;
273*1da177e4SLinus Torvalds 	int use_timestamp = 1;
274*1da177e4SLinus Torvalds 	char *env;
275*1da177e4SLinus Torvalds 
276*1da177e4SLinus Torvalds 	dirname[0] = 0;
277*1da177e4SLinus Torvalds 	if (name && name[0]) {
278*1da177e4SLinus Torvalds 		struct stat st;
279*1da177e4SLinus Torvalds 		char *slash;
280*1da177e4SLinus Torvalds 
281*1da177e4SLinus Torvalds 		if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
282*1da177e4SLinus Torvalds 			strcpy(dirname, name);
283*1da177e4SLinus Torvalds 			strcat(dirname, "/");
284*1da177e4SLinus Torvalds 			basename = conf_def_filename;
285*1da177e4SLinus Torvalds 		} else if ((slash = strrchr(name, '/'))) {
286*1da177e4SLinus Torvalds 			int size = slash - name + 1;
287*1da177e4SLinus Torvalds 			memcpy(dirname, name, size);
288*1da177e4SLinus Torvalds 			dirname[size] = 0;
289*1da177e4SLinus Torvalds 			if (slash[1])
290*1da177e4SLinus Torvalds 				basename = slash + 1;
291*1da177e4SLinus Torvalds 			else
292*1da177e4SLinus Torvalds 				basename = conf_def_filename;
293*1da177e4SLinus Torvalds 		} else
294*1da177e4SLinus Torvalds 			basename = name;
295*1da177e4SLinus Torvalds 	} else
296*1da177e4SLinus Torvalds 		basename = conf_def_filename;
297*1da177e4SLinus Torvalds 
298*1da177e4SLinus Torvalds 	sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
299*1da177e4SLinus Torvalds 	out = fopen(newname, "w");
300*1da177e4SLinus Torvalds 	if (!out)
301*1da177e4SLinus Torvalds 		return 1;
302*1da177e4SLinus Torvalds 	out_h = NULL;
303*1da177e4SLinus Torvalds 	if (!name) {
304*1da177e4SLinus Torvalds 		out_h = fopen(".tmpconfig.h", "w");
305*1da177e4SLinus Torvalds 		if (!out_h)
306*1da177e4SLinus Torvalds 			return 1;
307*1da177e4SLinus Torvalds 	}
308*1da177e4SLinus Torvalds 	sym = sym_lookup("KERNELRELEASE", 0);
309*1da177e4SLinus Torvalds 	sym_calc_value(sym);
310*1da177e4SLinus Torvalds 	time(&now);
311*1da177e4SLinus Torvalds 	env = getenv("KCONFIG_NOTIMESTAMP");
312*1da177e4SLinus Torvalds 	if (env && *env)
313*1da177e4SLinus Torvalds 		use_timestamp = 0;
314*1da177e4SLinus Torvalds 
315*1da177e4SLinus Torvalds 	fprintf(out, "#\n"
316*1da177e4SLinus Torvalds 		     "# Automatically generated make config: don't edit\n"
317*1da177e4SLinus Torvalds 		     "# Linux kernel version: %s\n"
318*1da177e4SLinus Torvalds 		     "%s%s"
319*1da177e4SLinus Torvalds 		     "#\n",
320*1da177e4SLinus Torvalds 		     sym_get_string_value(sym),
321*1da177e4SLinus Torvalds 		     use_timestamp ? "# " : "",
322*1da177e4SLinus Torvalds 		     use_timestamp ? ctime(&now) : "");
323*1da177e4SLinus Torvalds 	if (out_h)
324*1da177e4SLinus Torvalds 		fprintf(out_h, "/*\n"
325*1da177e4SLinus Torvalds 			       " * Automatically generated C config: don't edit\n"
326*1da177e4SLinus Torvalds 			       " * Linux kernel version: %s\n"
327*1da177e4SLinus Torvalds 			       "%s%s"
328*1da177e4SLinus Torvalds 			       " */\n"
329*1da177e4SLinus Torvalds 			       "#define AUTOCONF_INCLUDED\n",
330*1da177e4SLinus Torvalds 			       sym_get_string_value(sym),
331*1da177e4SLinus Torvalds 			       use_timestamp ? " * " : "",
332*1da177e4SLinus Torvalds 			       use_timestamp ? ctime(&now) : "");
333*1da177e4SLinus Torvalds 
334*1da177e4SLinus Torvalds 	if (!sym_change_count)
335*1da177e4SLinus Torvalds 		sym_clear_all_valid();
336*1da177e4SLinus Torvalds 
337*1da177e4SLinus Torvalds 	menu = rootmenu.list;
338*1da177e4SLinus Torvalds 	while (menu) {
339*1da177e4SLinus Torvalds 		sym = menu->sym;
340*1da177e4SLinus Torvalds 		if (!sym) {
341*1da177e4SLinus Torvalds 			if (!menu_is_visible(menu))
342*1da177e4SLinus Torvalds 				goto next;
343*1da177e4SLinus Torvalds 			str = menu_get_prompt(menu);
344*1da177e4SLinus Torvalds 			fprintf(out, "\n"
345*1da177e4SLinus Torvalds 				     "#\n"
346*1da177e4SLinus Torvalds 				     "# %s\n"
347*1da177e4SLinus Torvalds 				     "#\n", str);
348*1da177e4SLinus Torvalds 			if (out_h)
349*1da177e4SLinus Torvalds 				fprintf(out_h, "\n"
350*1da177e4SLinus Torvalds 					       "/*\n"
351*1da177e4SLinus Torvalds 					       " * %s\n"
352*1da177e4SLinus Torvalds 					       " */\n", str);
353*1da177e4SLinus Torvalds 		} else if (!(sym->flags & SYMBOL_CHOICE)) {
354*1da177e4SLinus Torvalds 			sym_calc_value(sym);
355*1da177e4SLinus Torvalds 			if (!(sym->flags & SYMBOL_WRITE))
356*1da177e4SLinus Torvalds 				goto next;
357*1da177e4SLinus Torvalds 			sym->flags &= ~SYMBOL_WRITE;
358*1da177e4SLinus Torvalds 			type = sym->type;
359*1da177e4SLinus Torvalds 			if (type == S_TRISTATE) {
360*1da177e4SLinus Torvalds 				sym_calc_value(modules_sym);
361*1da177e4SLinus Torvalds 				if (modules_sym->curr.tri == no)
362*1da177e4SLinus Torvalds 					type = S_BOOLEAN;
363*1da177e4SLinus Torvalds 			}
364*1da177e4SLinus Torvalds 			switch (type) {
365*1da177e4SLinus Torvalds 			case S_BOOLEAN:
366*1da177e4SLinus Torvalds 			case S_TRISTATE:
367*1da177e4SLinus Torvalds 				switch (sym_get_tristate_value(sym)) {
368*1da177e4SLinus Torvalds 				case no:
369*1da177e4SLinus Torvalds 					fprintf(out, "# CONFIG_%s is not set\n", sym->name);
370*1da177e4SLinus Torvalds 					if (out_h)
371*1da177e4SLinus Torvalds 						fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
372*1da177e4SLinus Torvalds 					break;
373*1da177e4SLinus Torvalds 				case mod:
374*1da177e4SLinus Torvalds 					fprintf(out, "CONFIG_%s=m\n", sym->name);
375*1da177e4SLinus Torvalds 					if (out_h)
376*1da177e4SLinus Torvalds 						fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
377*1da177e4SLinus Torvalds 					break;
378*1da177e4SLinus Torvalds 				case yes:
379*1da177e4SLinus Torvalds 					fprintf(out, "CONFIG_%s=y\n", sym->name);
380*1da177e4SLinus Torvalds 					if (out_h)
381*1da177e4SLinus Torvalds 						fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
382*1da177e4SLinus Torvalds 					break;
383*1da177e4SLinus Torvalds 				}
384*1da177e4SLinus Torvalds 				break;
385*1da177e4SLinus Torvalds 			case S_STRING:
386*1da177e4SLinus Torvalds 				// fix me
387*1da177e4SLinus Torvalds 				str = sym_get_string_value(sym);
388*1da177e4SLinus Torvalds 				fprintf(out, "CONFIG_%s=\"", sym->name);
389*1da177e4SLinus Torvalds 				if (out_h)
390*1da177e4SLinus Torvalds 					fprintf(out_h, "#define CONFIG_%s \"", sym->name);
391*1da177e4SLinus Torvalds 				do {
392*1da177e4SLinus Torvalds 					l = strcspn(str, "\"\\");
393*1da177e4SLinus Torvalds 					if (l) {
394*1da177e4SLinus Torvalds 						fwrite(str, l, 1, out);
395*1da177e4SLinus Torvalds 						if (out_h)
396*1da177e4SLinus Torvalds 							fwrite(str, l, 1, out_h);
397*1da177e4SLinus Torvalds 					}
398*1da177e4SLinus Torvalds 					str += l;
399*1da177e4SLinus Torvalds 					while (*str == '\\' || *str == '"') {
400*1da177e4SLinus Torvalds 						fprintf(out, "\\%c", *str);
401*1da177e4SLinus Torvalds 						if (out_h)
402*1da177e4SLinus Torvalds 							fprintf(out_h, "\\%c", *str);
403*1da177e4SLinus Torvalds 						str++;
404*1da177e4SLinus Torvalds 					}
405*1da177e4SLinus Torvalds 				} while (*str);
406*1da177e4SLinus Torvalds 				fputs("\"\n", out);
407*1da177e4SLinus Torvalds 				if (out_h)
408*1da177e4SLinus Torvalds 					fputs("\"\n", out_h);
409*1da177e4SLinus Torvalds 				break;
410*1da177e4SLinus Torvalds 			case S_HEX:
411*1da177e4SLinus Torvalds 				str = sym_get_string_value(sym);
412*1da177e4SLinus Torvalds 				if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
413*1da177e4SLinus Torvalds 					fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
414*1da177e4SLinus Torvalds 					if (out_h)
415*1da177e4SLinus Torvalds 						fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
416*1da177e4SLinus Torvalds 					break;
417*1da177e4SLinus Torvalds 				}
418*1da177e4SLinus Torvalds 			case S_INT:
419*1da177e4SLinus Torvalds 				str = sym_get_string_value(sym);
420*1da177e4SLinus Torvalds 				fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
421*1da177e4SLinus Torvalds 				if (out_h)
422*1da177e4SLinus Torvalds 					fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
423*1da177e4SLinus Torvalds 				break;
424*1da177e4SLinus Torvalds 			}
425*1da177e4SLinus Torvalds 		}
426*1da177e4SLinus Torvalds 
427*1da177e4SLinus Torvalds 	next:
428*1da177e4SLinus Torvalds 		if (menu->list) {
429*1da177e4SLinus Torvalds 			menu = menu->list;
430*1da177e4SLinus Torvalds 			continue;
431*1da177e4SLinus Torvalds 		}
432*1da177e4SLinus Torvalds 		if (menu->next)
433*1da177e4SLinus Torvalds 			menu = menu->next;
434*1da177e4SLinus Torvalds 		else while ((menu = menu->parent)) {
435*1da177e4SLinus Torvalds 			if (menu->next) {
436*1da177e4SLinus Torvalds 				menu = menu->next;
437*1da177e4SLinus Torvalds 				break;
438*1da177e4SLinus Torvalds 			}
439*1da177e4SLinus Torvalds 		}
440*1da177e4SLinus Torvalds 	}
441*1da177e4SLinus Torvalds 	fclose(out);
442*1da177e4SLinus Torvalds 	if (out_h) {
443*1da177e4SLinus Torvalds 		fclose(out_h);
444*1da177e4SLinus Torvalds 		rename(".tmpconfig.h", "include/linux/autoconf.h");
445*1da177e4SLinus Torvalds 		file_write_dep(NULL);
446*1da177e4SLinus Torvalds 	}
447*1da177e4SLinus Torvalds 	if (!name || basename != conf_def_filename) {
448*1da177e4SLinus Torvalds 		if (!name)
449*1da177e4SLinus Torvalds 			name = conf_def_filename;
450*1da177e4SLinus Torvalds 		sprintf(tmpname, "%s.old", name);
451*1da177e4SLinus Torvalds 		rename(name, tmpname);
452*1da177e4SLinus Torvalds 	}
453*1da177e4SLinus Torvalds 	sprintf(tmpname, "%s%s", dirname, basename);
454*1da177e4SLinus Torvalds 	if (rename(newname, tmpname))
455*1da177e4SLinus Torvalds 		return 1;
456*1da177e4SLinus Torvalds 
457*1da177e4SLinus Torvalds 	sym_change_count = 0;
458*1da177e4SLinus Torvalds 
459*1da177e4SLinus Torvalds 	return 0;
460*1da177e4SLinus Torvalds }
461