xref: /linux/scripts/kconfig/confdata.c (revision c181689b)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4  */
5 
6 #include <sys/mman.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <ctype.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <limits.h>
13 #include <stdarg.h>
14 #include <stdbool.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <time.h>
19 #include <unistd.h>
20 
21 #include "internal.h"
22 #include "lkc.h"
23 
24 struct gstr autoconf_cmd;
25 
26 /* return true if 'path' exists, false otherwise */
is_present(const char * path)27 static bool is_present(const char *path)
28 {
29 	struct stat st;
30 
31 	return !stat(path, &st);
32 }
33 
34 /* return true if 'path' exists and it is a directory, false otherwise */
is_dir(const char * path)35 static bool is_dir(const char *path)
36 {
37 	struct stat st;
38 
39 	if (stat(path, &st))
40 		return false;
41 
42 	return S_ISDIR(st.st_mode);
43 }
44 
45 /* return true if the given two files are the same, false otherwise */
is_same(const char * file1,const char * file2)46 static bool is_same(const char *file1, const char *file2)
47 {
48 	int fd1, fd2;
49 	struct stat st1, st2;
50 	void *map1, *map2;
51 	bool ret = false;
52 
53 	fd1 = open(file1, O_RDONLY);
54 	if (fd1 < 0)
55 		return ret;
56 
57 	fd2 = open(file2, O_RDONLY);
58 	if (fd2 < 0)
59 		goto close1;
60 
61 	ret = fstat(fd1, &st1);
62 	if (ret)
63 		goto close2;
64 	ret = fstat(fd2, &st2);
65 	if (ret)
66 		goto close2;
67 
68 	if (st1.st_size != st2.st_size)
69 		goto close2;
70 
71 	map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
72 	if (map1 == MAP_FAILED)
73 		goto close2;
74 
75 	map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
76 	if (map2 == MAP_FAILED)
77 		goto close2;
78 
79 	if (bcmp(map1, map2, st1.st_size))
80 		goto close2;
81 
82 	ret = true;
83 close2:
84 	close(fd2);
85 close1:
86 	close(fd1);
87 
88 	return ret;
89 }
90 
91 /*
92  * Create the parent directory of the given path.
93  *
94  * For example, if 'include/config/auto.conf' is given, create 'include/config'.
95  */
make_parent_dir(const char * path)96 static int make_parent_dir(const char *path)
97 {
98 	char tmp[PATH_MAX + 1];
99 	char *p;
100 
101 	strncpy(tmp, path, sizeof(tmp));
102 	tmp[sizeof(tmp) - 1] = 0;
103 
104 	/* Remove the base name. Just return if nothing is left */
105 	p = strrchr(tmp, '/');
106 	if (!p)
107 		return 0;
108 	*(p + 1) = 0;
109 
110 	/* Just in case it is an absolute path */
111 	p = tmp;
112 	while (*p == '/')
113 		p++;
114 
115 	while ((p = strchr(p, '/'))) {
116 		*p = 0;
117 
118 		/* skip if the directory exists */
119 		if (!is_dir(tmp) && mkdir(tmp, 0755))
120 			return -1;
121 
122 		*p = '/';
123 		while (*p == '/')
124 			p++;
125 	}
126 
127 	return 0;
128 }
129 
130 static char depfile_path[PATH_MAX];
131 static size_t depfile_prefix_len;
132 
133 /* touch depfile for symbol 'name' */
conf_touch_dep(const char * name)134 static int conf_touch_dep(const char *name)
135 {
136 	int fd;
137 
138 	/* check overflow: prefix + name + '\0' must fit in buffer. */
139 	if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path))
140 		return -1;
141 
142 	strcpy(depfile_path + depfile_prefix_len, name);
143 
144 	fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
145 	if (fd == -1)
146 		return -1;
147 	close(fd);
148 
149 	return 0;
150 }
151 
152 static void conf_warning(const char *fmt, ...)
153 	__attribute__ ((format (printf, 1, 2)));
154 
155 static void conf_message(const char *fmt, ...)
156 	__attribute__ ((format (printf, 1, 2)));
157 
158 static const char *conf_filename;
159 static int conf_lineno, conf_warnings;
160 
conf_errors(void)161 bool conf_errors(void)
162 {
163 	if (conf_warnings)
164 		return getenv("KCONFIG_WERROR");
165 	return false;
166 }
167 
conf_warning(const char * fmt,...)168 static void conf_warning(const char *fmt, ...)
169 {
170 	va_list ap;
171 	va_start(ap, fmt);
172 	fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
173 	vfprintf(stderr, fmt, ap);
174 	fprintf(stderr, "\n");
175 	va_end(ap);
176 	conf_warnings++;
177 }
178 
conf_default_message_callback(const char * s)179 static void conf_default_message_callback(const char *s)
180 {
181 	printf("#\n# ");
182 	printf("%s", s);
183 	printf("\n#\n");
184 }
185 
186 static void (*conf_message_callback)(const char *s) =
187 	conf_default_message_callback;
conf_set_message_callback(void (* fn)(const char * s))188 void conf_set_message_callback(void (*fn)(const char *s))
189 {
190 	conf_message_callback = fn;
191 }
192 
conf_message(const char * fmt,...)193 static void conf_message(const char *fmt, ...)
194 {
195 	va_list ap;
196 	char buf[4096];
197 
198 	if (!conf_message_callback)
199 		return;
200 
201 	va_start(ap, fmt);
202 
203 	vsnprintf(buf, sizeof(buf), fmt, ap);
204 	conf_message_callback(buf);
205 	va_end(ap);
206 }
207 
conf_get_configname(void)208 const char *conf_get_configname(void)
209 {
210 	char *name = getenv("KCONFIG_CONFIG");
211 
212 	return name ? name : ".config";
213 }
214 
conf_get_autoconfig_name(void)215 static const char *conf_get_autoconfig_name(void)
216 {
217 	char *name = getenv("KCONFIG_AUTOCONFIG");
218 
219 	return name ? name : "include/config/auto.conf";
220 }
221 
conf_get_autoheader_name(void)222 static const char *conf_get_autoheader_name(void)
223 {
224 	char *name = getenv("KCONFIG_AUTOHEADER");
225 
226 	return name ? name : "include/generated/autoconf.h";
227 }
228 
conf_get_rustccfg_name(void)229 static const char *conf_get_rustccfg_name(void)
230 {
231 	char *name = getenv("KCONFIG_RUSTCCFG");
232 
233 	return name ? name : "include/generated/rustc_cfg";
234 }
235 
conf_set_sym_val(struct symbol * sym,int def,int def_flags,char * p)236 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
237 {
238 	char *p2;
239 
240 	switch (sym->type) {
241 	case S_TRISTATE:
242 		if (p[0] == 'm') {
243 			sym->def[def].tri = mod;
244 			sym->flags |= def_flags;
245 			break;
246 		}
247 		/* fall through */
248 	case S_BOOLEAN:
249 		if (p[0] == 'y') {
250 			sym->def[def].tri = yes;
251 			sym->flags |= def_flags;
252 			break;
253 		}
254 		if (p[0] == 'n') {
255 			sym->def[def].tri = no;
256 			sym->flags |= def_flags;
257 			break;
258 		}
259 		if (def != S_DEF_AUTO)
260 			conf_warning("symbol value '%s' invalid for %s",
261 				     p, sym->name);
262 		return 1;
263 	case S_STRING:
264 		/* No escaping for S_DEF_AUTO (include/config/auto.conf) */
265 		if (def != S_DEF_AUTO) {
266 			if (*p++ != '"')
267 				break;
268 			for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
269 				if (*p2 == '"') {
270 					*p2 = 0;
271 					break;
272 				}
273 				memmove(p2, p2 + 1, strlen(p2));
274 			}
275 			if (!p2) {
276 				conf_warning("invalid string found");
277 				return 1;
278 			}
279 		}
280 		/* fall through */
281 	case S_INT:
282 	case S_HEX:
283 		if (sym_string_valid(sym, p)) {
284 			sym->def[def].val = xstrdup(p);
285 			sym->flags |= def_flags;
286 		} else {
287 			if (def != S_DEF_AUTO)
288 				conf_warning("symbol value '%s' invalid for %s",
289 					     p, sym->name);
290 			return 1;
291 		}
292 		break;
293 	default:
294 		;
295 	}
296 	return 0;
297 }
298 
299 /* like getline(), but the newline character is stripped away */
getline_stripped(char ** lineptr,size_t * n,FILE * stream)300 static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
301 {
302 	ssize_t len;
303 
304 	len = getline(lineptr, n, stream);
305 
306 	if (len > 0 && (*lineptr)[len - 1] == '\n') {
307 		len--;
308 		(*lineptr)[len] = '\0';
309 
310 		if (len > 0 && (*lineptr)[len - 1] == '\r') {
311 			len--;
312 			(*lineptr)[len] = '\0';
313 		}
314 	}
315 
316 	return len;
317 }
318 
conf_read_simple(const char * name,int def)319 int conf_read_simple(const char *name, int def)
320 {
321 	FILE *in = NULL;
322 	char   *line = NULL;
323 	size_t  line_asize = 0;
324 	char *p, *val;
325 	struct symbol *sym;
326 	int def_flags;
327 	const char *warn_unknown, *sym_name;
328 
329 	warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
330 	if (name) {
331 		in = zconf_fopen(name);
332 	} else {
333 		char *env;
334 
335 		name = conf_get_configname();
336 		in = zconf_fopen(name);
337 		if (in)
338 			goto load;
339 		conf_set_changed(true);
340 
341 		env = getenv("KCONFIG_DEFCONFIG_LIST");
342 		if (!env)
343 			return 1;
344 
345 		while (1) {
346 			bool is_last;
347 
348 			while (isspace(*env))
349 				env++;
350 
351 			if (!*env)
352 				break;
353 
354 			p = env;
355 			while (*p && !isspace(*p))
356 				p++;
357 
358 			is_last = (*p == '\0');
359 
360 			*p = '\0';
361 
362 			in = zconf_fopen(env);
363 			if (in) {
364 				conf_message("using defaults found in %s",
365 					     env);
366 				goto load;
367 			}
368 
369 			if (is_last)
370 				break;
371 
372 			env = p + 1;
373 		}
374 	}
375 	if (!in)
376 		return 1;
377 
378 load:
379 	conf_filename = name;
380 	conf_lineno = 0;
381 	conf_warnings = 0;
382 
383 	def_flags = SYMBOL_DEF << def;
384 	for_all_symbols(sym) {
385 		sym->flags |= SYMBOL_CHANGED;
386 		sym->flags &= ~(def_flags|SYMBOL_VALID);
387 		if (sym_is_choice(sym))
388 			sym->flags |= def_flags;
389 		switch (sym->type) {
390 		case S_INT:
391 		case S_HEX:
392 		case S_STRING:
393 			free(sym->def[def].val);
394 			/* fall through */
395 		default:
396 			sym->def[def].val = NULL;
397 			sym->def[def].tri = no;
398 		}
399 	}
400 
401 	while (getline_stripped(&line, &line_asize, in) != -1) {
402 		conf_lineno++;
403 
404 		if (!line[0]) /* blank line */
405 			continue;
406 
407 		if (line[0] == '#') {
408 			if (line[1] != ' ')
409 				continue;
410 			p = line + 2;
411 			if (memcmp(p, CONFIG_, strlen(CONFIG_)))
412 				continue;
413 			sym_name = p + strlen(CONFIG_);
414 			p = strchr(sym_name, ' ');
415 			if (!p)
416 				continue;
417 			*p++ = 0;
418 			if (strcmp(p, "is not set"))
419 				continue;
420 
421 			val = "n";
422 		} else {
423 			if (memcmp(line, CONFIG_, strlen(CONFIG_))) {
424 				conf_warning("unexpected data: %s", line);
425 				continue;
426 			}
427 
428 			sym_name = line + strlen(CONFIG_);
429 			p = strchr(sym_name, '=');
430 			if (!p) {
431 				conf_warning("unexpected data: %s", line);
432 				continue;
433 			}
434 			*p = 0;
435 			val = p + 1;
436 		}
437 
438 		sym = sym_find(sym_name);
439 		if (!sym) {
440 			if (def == S_DEF_AUTO) {
441 				/*
442 				 * Reading from include/config/auto.conf.
443 				 * If CONFIG_FOO previously existed in auto.conf
444 				 * but it is missing now, include/config/FOO
445 				 * must be touched.
446 				 */
447 				conf_touch_dep(sym_name);
448 			} else {
449 				if (warn_unknown)
450 					conf_warning("unknown symbol: %s", sym_name);
451 
452 				conf_set_changed(true);
453 			}
454 			continue;
455 		}
456 
457 		if (sym->flags & def_flags)
458 			conf_warning("override: reassigning to symbol %s", sym->name);
459 
460 		if (conf_set_sym_val(sym, def, def_flags, val))
461 			continue;
462 
463 		if (sym && sym_is_choice_value(sym)) {
464 			struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
465 			switch (sym->def[def].tri) {
466 			case no:
467 				break;
468 			case mod:
469 				if (cs->def[def].tri == yes) {
470 					conf_warning("%s creates inconsistent choice state", sym->name);
471 					cs->flags &= ~def_flags;
472 				}
473 				break;
474 			case yes:
475 				if (cs->def[def].tri != no)
476 					conf_warning("override: %s changes choice state", sym->name);
477 				cs->def[def].val = sym;
478 				break;
479 			}
480 			cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
481 		}
482 	}
483 	free(line);
484 	fclose(in);
485 
486 	return 0;
487 }
488 
conf_read(const char * name)489 int conf_read(const char *name)
490 {
491 	struct symbol *sym;
492 	int conf_unsaved = 0;
493 
494 	conf_set_changed(false);
495 
496 	if (conf_read_simple(name, S_DEF_USER)) {
497 		sym_calc_value(modules_sym);
498 		return 1;
499 	}
500 
501 	sym_calc_value(modules_sym);
502 
503 	for_all_symbols(sym) {
504 		sym_calc_value(sym);
505 		if (sym_is_choice(sym))
506 			continue;
507 		if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
508 			/* check that calculated value agrees with saved value */
509 			switch (sym->type) {
510 			case S_BOOLEAN:
511 			case S_TRISTATE:
512 				if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
513 					continue;
514 				break;
515 			default:
516 				if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
517 					continue;
518 				break;
519 			}
520 		} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
521 			/* no previous value and not saved */
522 			continue;
523 		conf_unsaved++;
524 		/* maybe print value in verbose mode... */
525 	}
526 
527 	for_all_symbols(sym) {
528 		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
529 			/* Reset values of generates values, so they'll appear
530 			 * as new, if they should become visible, but that
531 			 * doesn't quite work if the Kconfig and the saved
532 			 * configuration disagree.
533 			 */
534 			if (sym->visible == no && !conf_unsaved)
535 				sym->flags &= ~SYMBOL_DEF_USER;
536 		}
537 	}
538 
539 	if (conf_warnings || conf_unsaved)
540 		conf_set_changed(true);
541 
542 	return 0;
543 }
544 
545 struct comment_style {
546 	const char *decoration;
547 	const char *prefix;
548 	const char *postfix;
549 };
550 
551 static const struct comment_style comment_style_pound = {
552 	.decoration = "#",
553 	.prefix = "#",
554 	.postfix = "#",
555 };
556 
557 static const struct comment_style comment_style_c = {
558 	.decoration = " *",
559 	.prefix = "/*",
560 	.postfix = " */",
561 };
562 
conf_write_heading(FILE * fp,const struct comment_style * cs)563 static void conf_write_heading(FILE *fp, const struct comment_style *cs)
564 {
565 	if (!cs)
566 		return;
567 
568 	fprintf(fp, "%s\n", cs->prefix);
569 
570 	fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n",
571 		cs->decoration);
572 
573 	fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text);
574 
575 	fprintf(fp, "%s\n", cs->postfix);
576 }
577 
578 /* The returned pointer must be freed on the caller side */
escape_string_value(const char * in)579 static char *escape_string_value(const char *in)
580 {
581 	const char *p;
582 	char *out;
583 	size_t len;
584 
585 	len = strlen(in) + strlen("\"\"") + 1;
586 
587 	p = in;
588 	while (1) {
589 		p += strcspn(p, "\"\\");
590 
591 		if (p[0] == '\0')
592 			break;
593 
594 		len++;
595 		p++;
596 	}
597 
598 	out = xmalloc(len);
599 	out[0] = '\0';
600 
601 	strcat(out, "\"");
602 
603 	p = in;
604 	while (1) {
605 		len = strcspn(p, "\"\\");
606 		strncat(out, p, len);
607 		p += len;
608 
609 		if (p[0] == '\0')
610 			break;
611 
612 		strcat(out, "\\");
613 		strncat(out, p++, 1);
614 	}
615 
616 	strcat(out, "\"");
617 
618 	return out;
619 }
620 
621 enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };
622 
__print_symbol(FILE * fp,struct symbol * sym,enum output_n output_n,bool escape_string)623 static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
624 			   bool escape_string)
625 {
626 	const char *val;
627 	char *escaped = NULL;
628 
629 	if (sym->type == S_UNKNOWN)
630 		return;
631 
632 	val = sym_get_string_value(sym);
633 
634 	if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) &&
635 	    output_n != OUTPUT_N && *val == 'n') {
636 		if (output_n == OUTPUT_N_AS_UNSET)
637 			fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name);
638 		return;
639 	}
640 
641 	if (sym->type == S_STRING && escape_string) {
642 		escaped = escape_string_value(val);
643 		val = escaped;
644 	}
645 
646 	fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);
647 
648 	free(escaped);
649 }
650 
print_symbol_for_dotconfig(FILE * fp,struct symbol * sym)651 static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
652 {
653 	__print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
654 }
655 
print_symbol_for_autoconf(FILE * fp,struct symbol * sym)656 static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
657 {
658 	__print_symbol(fp, sym, OUTPUT_N_NONE, false);
659 }
660 
print_symbol_for_listconfig(struct symbol * sym)661 void print_symbol_for_listconfig(struct symbol *sym)
662 {
663 	__print_symbol(stdout, sym, OUTPUT_N, true);
664 }
665 
print_symbol_for_c(FILE * fp,struct symbol * sym)666 static void print_symbol_for_c(FILE *fp, struct symbol *sym)
667 {
668 	const char *val;
669 	const char *sym_suffix = "";
670 	const char *val_prefix = "";
671 	char *escaped = NULL;
672 
673 	if (sym->type == S_UNKNOWN)
674 		return;
675 
676 	val = sym_get_string_value(sym);
677 
678 	switch (sym->type) {
679 	case S_BOOLEAN:
680 	case S_TRISTATE:
681 		switch (*val) {
682 		case 'n':
683 			return;
684 		case 'm':
685 			sym_suffix = "_MODULE";
686 			/* fall through */
687 		default:
688 			val = "1";
689 		}
690 		break;
691 	case S_HEX:
692 		if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
693 			val_prefix = "0x";
694 		break;
695 	case S_STRING:
696 		escaped = escape_string_value(val);
697 		val = escaped;
698 	default:
699 		break;
700 	}
701 
702 	fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix,
703 		val_prefix, val);
704 
705 	free(escaped);
706 }
707 
print_symbol_for_rustccfg(FILE * fp,struct symbol * sym)708 static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
709 {
710 	const char *val;
711 	const char *val_prefix = "";
712 	char *val_prefixed = NULL;
713 	size_t val_prefixed_len;
714 	char *escaped = NULL;
715 
716 	if (sym->type == S_UNKNOWN)
717 		return;
718 
719 	val = sym_get_string_value(sym);
720 
721 	switch (sym->type) {
722 	case S_BOOLEAN:
723 	case S_TRISTATE:
724 		/*
725 		 * We do not care about disabled ones, i.e. no need for
726 		 * what otherwise are "comments" in other printers.
727 		 */
728 		if (*val == 'n')
729 			return;
730 
731 		/*
732 		 * To have similar functionality to the C macro `IS_ENABLED()`
733 		 * we provide an empty `--cfg CONFIG_X` here in both `y`
734 		 * and `m` cases.
735 		 *
736 		 * Then, the common `fprintf()` below will also give us
737 		 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
738 		 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
739 		 */
740 		fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
741 		break;
742 	case S_HEX:
743 		if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
744 			val_prefix = "0x";
745 		break;
746 	default:
747 		break;
748 	}
749 
750 	if (strlen(val_prefix) > 0) {
751 		val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
752 		val_prefixed = xmalloc(val_prefixed_len);
753 		snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
754 		val = val_prefixed;
755 	}
756 
757 	/* All values get escaped: the `--cfg` option only takes strings */
758 	escaped = escape_string_value(val);
759 	val = escaped;
760 
761 	fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);
762 
763 	free(escaped);
764 	free(val_prefixed);
765 }
766 
767 /*
768  * Write out a minimal config.
769  * All values that has default values are skipped as this is redundant.
770  */
conf_write_defconfig(const char * filename)771 int conf_write_defconfig(const char *filename)
772 {
773 	struct symbol *sym;
774 	struct menu *menu;
775 	FILE *out;
776 
777 	out = fopen(filename, "w");
778 	if (!out)
779 		return 1;
780 
781 	sym_clear_all_valid();
782 
783 	menu_for_each_entry(menu) {
784 		struct menu *choice;
785 
786 		sym = menu->sym;
787 		if (sym && !sym_is_choice(sym)) {
788 			sym_calc_value(sym);
789 			if (!(sym->flags & SYMBOL_WRITE))
790 				continue;
791 			sym->flags &= ~SYMBOL_WRITE;
792 			/* If we cannot change the symbol - skip */
793 			if (!sym_is_changeable(sym))
794 				continue;
795 			/* If symbol equals to default value - skip */
796 			if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
797 				continue;
798 
799 			/*
800 			 * If symbol is a choice value and equals to the
801 			 * default for a choice - skip.
802 			 */
803 			choice = sym_get_choice_menu(sym);
804 			if (choice) {
805 				struct symbol *ds;
806 
807 				ds = sym_choice_default(choice->sym);
808 				if (sym == ds) {
809 					if ((sym->type == S_BOOLEAN) &&
810 					    sym_get_tristate_value(sym) == yes)
811 						continue;
812 				}
813 			}
814 			print_symbol_for_dotconfig(out, sym);
815 		}
816 	}
817 	fclose(out);
818 	return 0;
819 }
820 
conf_write(const char * name)821 int conf_write(const char *name)
822 {
823 	FILE *out;
824 	struct symbol *sym;
825 	struct menu *menu;
826 	const char *str;
827 	char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
828 	char *env;
829 	bool need_newline = false;
830 
831 	if (!name)
832 		name = conf_get_configname();
833 
834 	if (!*name) {
835 		fprintf(stderr, "config name is empty\n");
836 		return -1;
837 	}
838 
839 	if (is_dir(name)) {
840 		fprintf(stderr, "%s: Is a directory\n", name);
841 		return -1;
842 	}
843 
844 	if (make_parent_dir(name))
845 		return -1;
846 
847 	env = getenv("KCONFIG_OVERWRITECONFIG");
848 	if (env && *env) {
849 		*tmpname = 0;
850 		out = fopen(name, "w");
851 	} else {
852 		snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
853 			 name, (int)getpid());
854 		out = fopen(tmpname, "w");
855 	}
856 	if (!out)
857 		return 1;
858 
859 	conf_write_heading(out, &comment_style_pound);
860 
861 	if (!conf_get_changed())
862 		sym_clear_all_valid();
863 
864 	menu = rootmenu.list;
865 	while (menu) {
866 		sym = menu->sym;
867 		if (!sym) {
868 			if (!menu_is_visible(menu))
869 				goto next;
870 			str = menu_get_prompt(menu);
871 			fprintf(out, "\n"
872 				     "#\n"
873 				     "# %s\n"
874 				     "#\n", str);
875 			need_newline = false;
876 		} else if (!sym_is_choice(sym) &&
877 			   !(sym->flags & SYMBOL_WRITTEN)) {
878 			sym_calc_value(sym);
879 			if (!(sym->flags & SYMBOL_WRITE))
880 				goto next;
881 			if (need_newline) {
882 				fprintf(out, "\n");
883 				need_newline = false;
884 			}
885 			sym->flags |= SYMBOL_WRITTEN;
886 			print_symbol_for_dotconfig(out, sym);
887 		}
888 
889 next:
890 		if (menu->list) {
891 			menu = menu->list;
892 			continue;
893 		}
894 
895 end_check:
896 		if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu &&
897 		    menu->prompt->type == P_MENU) {
898 			fprintf(out, "# end of %s\n", menu_get_prompt(menu));
899 			need_newline = true;
900 		}
901 
902 		if (menu->next) {
903 			menu = menu->next;
904 		} else {
905 			menu = menu->parent;
906 			if (menu)
907 				goto end_check;
908 		}
909 	}
910 	fclose(out);
911 
912 	for_all_symbols(sym)
913 		sym->flags &= ~SYMBOL_WRITTEN;
914 
915 	if (*tmpname) {
916 		if (is_same(name, tmpname)) {
917 			conf_message("No change to %s", name);
918 			unlink(tmpname);
919 			conf_set_changed(false);
920 			return 0;
921 		}
922 
923 		snprintf(oldname, sizeof(oldname), "%s.old", name);
924 		rename(name, oldname);
925 		if (rename(tmpname, name))
926 			return 1;
927 	}
928 
929 	conf_message("configuration written to %s", name);
930 
931 	conf_set_changed(false);
932 
933 	return 0;
934 }
935 
936 /* write a dependency file as used by kbuild to track dependencies */
conf_write_autoconf_cmd(const char * autoconf_name)937 static int conf_write_autoconf_cmd(const char *autoconf_name)
938 {
939 	char name[PATH_MAX], tmp[PATH_MAX];
940 	FILE *out;
941 	int ret;
942 
943 	ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name);
944 	if (ret >= sizeof(name)) /* check truncation */
945 		return -1;
946 
947 	if (make_parent_dir(name))
948 		return -1;
949 
950 	ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name);
951 	if (ret >= sizeof(tmp)) /* check truncation */
952 		return -1;
953 
954 	out = fopen(tmp, "w");
955 	if (!out) {
956 		perror("fopen");
957 		return -1;
958 	}
959 
960 	fprintf(out, "autoconfig := %s\n", autoconf_name);
961 
962 	fputs(str_get(&autoconf_cmd), out);
963 
964 	fflush(out);
965 	ret = ferror(out); /* error check for all fprintf() calls */
966 	fclose(out);
967 	if (ret)
968 		return -1;
969 
970 	if (rename(tmp, name)) {
971 		perror("rename");
972 		return -1;
973 	}
974 
975 	return 0;
976 }
977 
conf_touch_deps(void)978 static int conf_touch_deps(void)
979 {
980 	const char *name, *tmp;
981 	struct symbol *sym;
982 	int res;
983 
984 	name = conf_get_autoconfig_name();
985 	tmp = strrchr(name, '/');
986 	depfile_prefix_len = tmp ? tmp - name + 1 : 0;
987 	if (depfile_prefix_len + 1 > sizeof(depfile_path))
988 		return -1;
989 
990 	strncpy(depfile_path, name, depfile_prefix_len);
991 	depfile_path[depfile_prefix_len] = 0;
992 
993 	conf_read_simple(name, S_DEF_AUTO);
994 	sym_calc_value(modules_sym);
995 
996 	for_all_symbols(sym) {
997 		sym_calc_value(sym);
998 		if (sym_is_choice(sym))
999 			continue;
1000 		if (sym->flags & SYMBOL_WRITE) {
1001 			if (sym->flags & SYMBOL_DEF_AUTO) {
1002 				/*
1003 				 * symbol has old and new value,
1004 				 * so compare them...
1005 				 */
1006 				switch (sym->type) {
1007 				case S_BOOLEAN:
1008 				case S_TRISTATE:
1009 					if (sym_get_tristate_value(sym) ==
1010 					    sym->def[S_DEF_AUTO].tri)
1011 						continue;
1012 					break;
1013 				case S_STRING:
1014 				case S_HEX:
1015 				case S_INT:
1016 					if (!strcmp(sym_get_string_value(sym),
1017 						    sym->def[S_DEF_AUTO].val))
1018 						continue;
1019 					break;
1020 				default:
1021 					break;
1022 				}
1023 			} else {
1024 				/*
1025 				 * If there is no old value, only 'no' (unset)
1026 				 * is allowed as new value.
1027 				 */
1028 				switch (sym->type) {
1029 				case S_BOOLEAN:
1030 				case S_TRISTATE:
1031 					if (sym_get_tristate_value(sym) == no)
1032 						continue;
1033 					break;
1034 				default:
1035 					break;
1036 				}
1037 			}
1038 		} else if (!(sym->flags & SYMBOL_DEF_AUTO))
1039 			/* There is neither an old nor a new value. */
1040 			continue;
1041 		/* else
1042 		 *	There is an old value, but no new value ('no' (unset)
1043 		 *	isn't saved in auto.conf, so the old value is always
1044 		 *	different from 'no').
1045 		 */
1046 
1047 		res = conf_touch_dep(sym->name);
1048 		if (res)
1049 			return res;
1050 	}
1051 
1052 	return 0;
1053 }
1054 
__conf_write_autoconf(const char * filename,void (* print_symbol)(FILE *,struct symbol *),const struct comment_style * comment_style)1055 static int __conf_write_autoconf(const char *filename,
1056 				 void (*print_symbol)(FILE *, struct symbol *),
1057 				 const struct comment_style *comment_style)
1058 {
1059 	char tmp[PATH_MAX];
1060 	FILE *file;
1061 	struct symbol *sym;
1062 	int ret;
1063 
1064 	if (make_parent_dir(filename))
1065 		return -1;
1066 
1067 	ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename);
1068 	if (ret >= sizeof(tmp)) /* check truncation */
1069 		return -1;
1070 
1071 	file = fopen(tmp, "w");
1072 	if (!file) {
1073 		perror("fopen");
1074 		return -1;
1075 	}
1076 
1077 	conf_write_heading(file, comment_style);
1078 
1079 	for_all_symbols(sym)
1080 		if ((sym->flags & SYMBOL_WRITE) && sym->name)
1081 			print_symbol(file, sym);
1082 
1083 	fflush(file);
1084 	/* check possible errors in conf_write_heading() and print_symbol() */
1085 	ret = ferror(file);
1086 	fclose(file);
1087 	if (ret)
1088 		return -1;
1089 
1090 	if (rename(tmp, filename)) {
1091 		perror("rename");
1092 		return -1;
1093 	}
1094 
1095 	return 0;
1096 }
1097 
conf_write_autoconf(int overwrite)1098 int conf_write_autoconf(int overwrite)
1099 {
1100 	struct symbol *sym;
1101 	const char *autoconf_name = conf_get_autoconfig_name();
1102 	int ret;
1103 
1104 	if (!overwrite && is_present(autoconf_name))
1105 		return 0;
1106 
1107 	ret = conf_write_autoconf_cmd(autoconf_name);
1108 	if (ret)
1109 		return -1;
1110 
1111 	if (conf_touch_deps())
1112 		return 1;
1113 
1114 	for_all_symbols(sym)
1115 		sym_calc_value(sym);
1116 
1117 	ret = __conf_write_autoconf(conf_get_autoheader_name(),
1118 				    print_symbol_for_c,
1119 				    &comment_style_c);
1120 	if (ret)
1121 		return ret;
1122 
1123 	ret = __conf_write_autoconf(conf_get_rustccfg_name(),
1124 				    print_symbol_for_rustccfg,
1125 				    NULL);
1126 	if (ret)
1127 		return ret;
1128 
1129 	/*
1130 	 * Create include/config/auto.conf. This must be the last step because
1131 	 * Kbuild has a dependency on auto.conf and this marks the successful
1132 	 * completion of the previous steps.
1133 	 */
1134 	ret = __conf_write_autoconf(conf_get_autoconfig_name(),
1135 				    print_symbol_for_autoconf,
1136 				    &comment_style_pound);
1137 	if (ret)
1138 		return ret;
1139 
1140 	return 0;
1141 }
1142 
1143 static bool conf_changed;
1144 static void (*conf_changed_callback)(void);
1145 
conf_set_changed(bool val)1146 void conf_set_changed(bool val)
1147 {
1148 	bool changed = conf_changed != val;
1149 
1150 	conf_changed = val;
1151 
1152 	if (conf_changed_callback && changed)
1153 		conf_changed_callback();
1154 }
1155 
conf_get_changed(void)1156 bool conf_get_changed(void)
1157 {
1158 	return conf_changed;
1159 }
1160 
conf_set_changed_callback(void (* fn)(void))1161 void conf_set_changed_callback(void (*fn)(void))
1162 {
1163 	conf_changed_callback = fn;
1164 }
1165 
set_all_choice_values(struct symbol * csym)1166 void set_all_choice_values(struct symbol *csym)
1167 {
1168 	struct property *prop;
1169 	struct symbol *sym;
1170 	struct expr *e;
1171 
1172 	prop = sym_get_choice_prop(csym);
1173 
1174 	/*
1175 	 * Set all non-assinged choice values to no
1176 	 */
1177 	expr_list_for_each_sym(prop->expr, e, sym) {
1178 		if (!sym_has_value(sym))
1179 			sym->def[S_DEF_USER].tri = no;
1180 	}
1181 	csym->flags |= SYMBOL_DEF_USER;
1182 	/* clear VALID to get value calculated */
1183 	csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
1184 }
1185