xref: /openbmc/linux/scripts/kconfig/confdata.c (revision 87c2ce3b)
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 	}
378 	sym = sym_lookup("KERNELRELEASE", 0);
379 	sym_calc_value(sym);
380 	time(&now);
381 	env = getenv("KCONFIG_NOTIMESTAMP");
382 	if (env && *env)
383 		use_timestamp = 0;
384 
385 	fprintf(out, _("#\n"
386 		       "# Automatically generated make config: don't edit\n"
387 		       "# Linux kernel version: %s\n"
388 		       "%s%s"
389 		       "#\n"),
390 		     sym_get_string_value(sym),
391 		     use_timestamp ? "# " : "",
392 		     use_timestamp ? ctime(&now) : "");
393 	if (out_h)
394 		fprintf(out_h, "/*\n"
395 			       " * Automatically generated C config: don't edit\n"
396 			       " * Linux kernel version: %s\n"
397 			       "%s%s"
398 			       " */\n"
399 			       "#define AUTOCONF_INCLUDED\n",
400 			       sym_get_string_value(sym),
401 			       use_timestamp ? " * " : "",
402 			       use_timestamp ? ctime(&now) : "");
403 
404 	if (!sym_change_count)
405 		sym_clear_all_valid();
406 
407 	menu = rootmenu.list;
408 	while (menu) {
409 		sym = menu->sym;
410 		if (!sym) {
411 			if (!menu_is_visible(menu))
412 				goto next;
413 			str = menu_get_prompt(menu);
414 			fprintf(out, "\n"
415 				     "#\n"
416 				     "# %s\n"
417 				     "#\n", str);
418 			if (out_h)
419 				fprintf(out_h, "\n"
420 					       "/*\n"
421 					       " * %s\n"
422 					       " */\n", str);
423 		} else if (!(sym->flags & SYMBOL_CHOICE)) {
424 			sym_calc_value(sym);
425 			if (!(sym->flags & SYMBOL_WRITE))
426 				goto next;
427 			sym->flags &= ~SYMBOL_WRITE;
428 			type = sym->type;
429 			if (type == S_TRISTATE) {
430 				sym_calc_value(modules_sym);
431 				if (modules_sym->curr.tri == no)
432 					type = S_BOOLEAN;
433 			}
434 			switch (type) {
435 			case S_BOOLEAN:
436 			case S_TRISTATE:
437 				switch (sym_get_tristate_value(sym)) {
438 				case no:
439 					fprintf(out, "# CONFIG_%s is not set\n", sym->name);
440 					if (out_h)
441 						fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
442 					break;
443 				case mod:
444 					fprintf(out, "CONFIG_%s=m\n", sym->name);
445 					if (out_h)
446 						fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
447 					break;
448 				case yes:
449 					fprintf(out, "CONFIG_%s=y\n", sym->name);
450 					if (out_h)
451 						fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
452 					break;
453 				}
454 				break;
455 			case S_STRING:
456 				// fix me
457 				str = sym_get_string_value(sym);
458 				fprintf(out, "CONFIG_%s=\"", sym->name);
459 				if (out_h)
460 					fprintf(out_h, "#define CONFIG_%s \"", sym->name);
461 				do {
462 					l = strcspn(str, "\"\\");
463 					if (l) {
464 						fwrite(str, l, 1, out);
465 						if (out_h)
466 							fwrite(str, l, 1, out_h);
467 					}
468 					str += l;
469 					while (*str == '\\' || *str == '"') {
470 						fprintf(out, "\\%c", *str);
471 						if (out_h)
472 							fprintf(out_h, "\\%c", *str);
473 						str++;
474 					}
475 				} while (*str);
476 				fputs("\"\n", out);
477 				if (out_h)
478 					fputs("\"\n", out_h);
479 				break;
480 			case S_HEX:
481 				str = sym_get_string_value(sym);
482 				if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
483 					fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
484 					if (out_h)
485 						fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
486 					break;
487 				}
488 			case S_INT:
489 				str = sym_get_string_value(sym);
490 				fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
491 				if (out_h)
492 					fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
493 				break;
494 			}
495 		}
496 
497 	next:
498 		if (menu->list) {
499 			menu = menu->list;
500 			continue;
501 		}
502 		if (menu->next)
503 			menu = menu->next;
504 		else while ((menu = menu->parent)) {
505 			if (menu->next) {
506 				menu = menu->next;
507 				break;
508 			}
509 		}
510 	}
511 	fclose(out);
512 	if (out_h) {
513 		fclose(out_h);
514 		rename(".tmpconfig.h", "include/linux/autoconf.h");
515 		file_write_dep(NULL);
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