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