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