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