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