Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
24struct gstr autoconf_cmd;
25
26/* return true if 'path' exists, false otherwise */
27static 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 */
35static 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 */
46static 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;
83close2:
84 close(fd2);
85close1:
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 */
96static 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
130static char depfile_path[PATH_MAX];
131static size_t depfile_prefix_len;
132
133/* touch depfile for symbol 'name' */
134static 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
152static void conf_warning(const char *fmt, ...)
153 __attribute__ ((format (printf, 1, 2)));
154
155static void conf_message(const char *fmt, ...)
156 __attribute__ ((format (printf, 1, 2)));
157
158static const char *conf_filename;
159static int conf_lineno, conf_warnings;
160
161bool conf_errors(void)
162{
163 if (conf_warnings)
164 return getenv("KCONFIG_WERROR");
165 return false;
166}
167
168static 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
179static void conf_default_message_callback(const char *s)
180{
181 printf("#\n# ");
182 printf("%s", s);
183 printf("\n#\n");
184}
185
186static void (*conf_message_callback)(const char *s) =
187 conf_default_message_callback;
188void conf_set_message_callback(void (*fn)(const char *s))
189{
190 conf_message_callback = fn;
191}
192
193static 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
208const char *conf_get_configname(void)
209{
210 char *name = getenv("KCONFIG_CONFIG");
211
212 return name ? name : ".config";
213}
214
215static 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
222static 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
229static 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
236static 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 */
300static 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
319int 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
378load:
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
489int 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 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
558struct comment_style {
559 const char *decoration;
560 const char *prefix;
561 const char *postfix;
562};
563
564static const struct comment_style comment_style_pound = {
565 .decoration = "#",
566 .prefix = "#",
567 .postfix = "#",
568};
569
570static const struct comment_style comment_style_c = {
571 .decoration = " *",
572 .prefix = "/*",
573 .postfix = " */",
574};
575
576static 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 */
592static 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
634enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };
635
636static 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
664static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
665{
666 __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
667}
668
669static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
670{
671 __print_symbol(fp, sym, OUTPUT_N_NONE, false);
672}
673
674void print_symbol_for_listconfig(struct symbol *sym)
675{
676 __print_symbol(stdout, sym, OUTPUT_N, true);
677}
678
679static 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
721static 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 */
784int 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 menu_for_each_entry(menu) {
797 struct menu *choice;
798
799 sym = menu->sym;
800 if (sym && !sym_is_choice(sym)) {
801 sym_calc_value(sym);
802 if (!(sym->flags & SYMBOL_WRITE))
803 continue;
804 sym->flags &= ~SYMBOL_WRITE;
805 /* If we cannot change the symbol - skip */
806 if (!sym_is_changeable(sym))
807 continue;
808 /* If symbol equals to default value - skip */
809 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
810 continue;
811
812 /*
813 * If symbol is a choice value and equals to the
814 * default for a choice - skip.
815 */
816 choice = sym_get_choice_menu(sym);
817 if (choice) {
818 struct symbol *ds;
819
820 ds = sym_choice_default(choice->sym);
821 if (sym == ds) {
822 if ((sym->type == S_BOOLEAN) &&
823 sym_get_tristate_value(sym) == yes)
824 continue;
825 }
826 }
827 print_symbol_for_dotconfig(out, sym);
828 }
829 }
830 fclose(out);
831 return 0;
832}
833
834int conf_write(const char *name)
835{
836 FILE *out;
837 struct symbol *sym;
838 struct menu *menu;
839 const char *str;
840 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
841 char *env;
842 bool need_newline = false;
843
844 if (!name)
845 name = conf_get_configname();
846
847 if (!*name) {
848 fprintf(stderr, "config name is empty\n");
849 return -1;
850 }
851
852 if (is_dir(name)) {
853 fprintf(stderr, "%s: Is a directory\n", name);
854 return -1;
855 }
856
857 if (make_parent_dir(name))
858 return -1;
859
860 env = getenv("KCONFIG_OVERWRITECONFIG");
861 if (env && *env) {
862 *tmpname = 0;
863 out = fopen(name, "w");
864 } else {
865 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
866 name, (int)getpid());
867 out = fopen(tmpname, "w");
868 }
869 if (!out)
870 return 1;
871
872 conf_write_heading(out, &comment_style_pound);
873
874 if (!conf_get_changed())
875 sym_clear_all_valid();
876
877 menu = rootmenu.list;
878 while (menu) {
879 sym = menu->sym;
880 if (!sym) {
881 if (!menu_is_visible(menu))
882 goto next;
883 str = menu_get_prompt(menu);
884 fprintf(out, "\n"
885 "#\n"
886 "# %s\n"
887 "#\n", str);
888 need_newline = false;
889 } else if (!sym_is_choice(sym) &&
890 !(sym->flags & SYMBOL_WRITTEN)) {
891 sym_calc_value(sym);
892 if (!(sym->flags & SYMBOL_WRITE))
893 goto next;
894 if (need_newline) {
895 fprintf(out, "\n");
896 need_newline = false;
897 }
898 sym->flags |= SYMBOL_WRITTEN;
899 print_symbol_for_dotconfig(out, sym);
900 }
901
902next:
903 if (menu->list) {
904 menu = menu->list;
905 continue;
906 }
907
908end_check:
909 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu &&
910 menu->prompt->type == P_MENU) {
911 fprintf(out, "# end of %s\n", menu_get_prompt(menu));
912 need_newline = true;
913 }
914
915 if (menu->next) {
916 menu = menu->next;
917 } else {
918 menu = menu->parent;
919 if (menu)
920 goto end_check;
921 }
922 }
923 fclose(out);
924
925 for_all_symbols(sym)
926 sym->flags &= ~SYMBOL_WRITTEN;
927
928 if (*tmpname) {
929 if (is_same(name, tmpname)) {
930 conf_message("No change to %s", name);
931 unlink(tmpname);
932 conf_set_changed(false);
933 return 0;
934 }
935
936 snprintf(oldname, sizeof(oldname), "%s.old", name);
937 rename(name, oldname);
938 if (rename(tmpname, name))
939 return 1;
940 }
941
942 conf_message("configuration written to %s", name);
943
944 conf_set_changed(false);
945
946 return 0;
947}
948
949/* write a dependency file as used by kbuild to track dependencies */
950static int conf_write_autoconf_cmd(const char *autoconf_name)
951{
952 char name[PATH_MAX], tmp[PATH_MAX];
953 FILE *out;
954 int ret;
955
956 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name);
957 if (ret >= sizeof(name)) /* check truncation */
958 return -1;
959
960 if (make_parent_dir(name))
961 return -1;
962
963 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name);
964 if (ret >= sizeof(tmp)) /* check truncation */
965 return -1;
966
967 out = fopen(tmp, "w");
968 if (!out) {
969 perror("fopen");
970 return -1;
971 }
972
973 fprintf(out, "autoconfig := %s\n", autoconf_name);
974
975 fputs(str_get(&autoconf_cmd), out);
976
977 fflush(out);
978 ret = ferror(out); /* error check for all fprintf() calls */
979 fclose(out);
980 if (ret)
981 return -1;
982
983 if (rename(tmp, name)) {
984 perror("rename");
985 return -1;
986 }
987
988 return 0;
989}
990
991static int conf_touch_deps(void)
992{
993 const char *name, *tmp;
994 struct symbol *sym;
995 int res;
996
997 name = conf_get_autoconfig_name();
998 tmp = strrchr(name, '/');
999 depfile_prefix_len = tmp ? tmp - name + 1 : 0;
1000 if (depfile_prefix_len + 1 > sizeof(depfile_path))
1001 return -1;
1002
1003 strncpy(depfile_path, name, depfile_prefix_len);
1004 depfile_path[depfile_prefix_len] = 0;
1005
1006 conf_read_simple(name, S_DEF_AUTO);
1007 sym_calc_value(modules_sym);
1008
1009 for_all_symbols(sym) {
1010 sym_calc_value(sym);
1011 if (sym_is_choice(sym))
1012 continue;
1013 if (sym->flags & SYMBOL_WRITE) {
1014 if (sym->flags & SYMBOL_DEF_AUTO) {
1015 /*
1016 * symbol has old and new value,
1017 * so compare them...
1018 */
1019 switch (sym->type) {
1020 case S_BOOLEAN:
1021 case S_TRISTATE:
1022 if (sym_get_tristate_value(sym) ==
1023 sym->def[S_DEF_AUTO].tri)
1024 continue;
1025 break;
1026 case S_STRING:
1027 case S_HEX:
1028 case S_INT:
1029 if (!strcmp(sym_get_string_value(sym),
1030 sym->def[S_DEF_AUTO].val))
1031 continue;
1032 break;
1033 default:
1034 break;
1035 }
1036 } else {
1037 /*
1038 * If there is no old value, only 'no' (unset)
1039 * is allowed as new value.
1040 */
1041 switch (sym->type) {
1042 case S_BOOLEAN:
1043 case S_TRISTATE:
1044 if (sym_get_tristate_value(sym) == no)
1045 continue;
1046 break;
1047 default:
1048 break;
1049 }
1050 }
1051 } else if (!(sym->flags & SYMBOL_DEF_AUTO))
1052 /* There is neither an old nor a new value. */
1053 continue;
1054 /* else
1055 * There is an old value, but no new value ('no' (unset)
1056 * isn't saved in auto.conf, so the old value is always
1057 * different from 'no').
1058 */
1059
1060 res = conf_touch_dep(sym->name);
1061 if (res)
1062 return res;
1063 }
1064
1065 return 0;
1066}
1067
1068static int __conf_write_autoconf(const char *filename,
1069 void (*print_symbol)(FILE *, struct symbol *),
1070 const struct comment_style *comment_style)
1071{
1072 char tmp[PATH_MAX];
1073 FILE *file;
1074 struct symbol *sym;
1075 int ret;
1076
1077 if (make_parent_dir(filename))
1078 return -1;
1079
1080 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename);
1081 if (ret >= sizeof(tmp)) /* check truncation */
1082 return -1;
1083
1084 file = fopen(tmp, "w");
1085 if (!file) {
1086 perror("fopen");
1087 return -1;
1088 }
1089
1090 conf_write_heading(file, comment_style);
1091
1092 for_all_symbols(sym)
1093 if ((sym->flags & SYMBOL_WRITE) && sym->name)
1094 print_symbol(file, sym);
1095
1096 fflush(file);
1097 /* check possible errors in conf_write_heading() and print_symbol() */
1098 ret = ferror(file);
1099 fclose(file);
1100 if (ret)
1101 return -1;
1102
1103 if (rename(tmp, filename)) {
1104 perror("rename");
1105 return -1;
1106 }
1107
1108 return 0;
1109}
1110
1111int conf_write_autoconf(int overwrite)
1112{
1113 struct symbol *sym;
1114 const char *autoconf_name = conf_get_autoconfig_name();
1115 int ret;
1116
1117 if (!overwrite && is_present(autoconf_name))
1118 return 0;
1119
1120 ret = conf_write_autoconf_cmd(autoconf_name);
1121 if (ret)
1122 return -1;
1123
1124 if (conf_touch_deps())
1125 return 1;
1126
1127 for_all_symbols(sym)
1128 sym_calc_value(sym);
1129
1130 ret = __conf_write_autoconf(conf_get_autoheader_name(),
1131 print_symbol_for_c,
1132 &comment_style_c);
1133 if (ret)
1134 return ret;
1135
1136 ret = __conf_write_autoconf(conf_get_rustccfg_name(),
1137 print_symbol_for_rustccfg,
1138 NULL);
1139 if (ret)
1140 return ret;
1141
1142 /*
1143 * Create include/config/auto.conf. This must be the last step because
1144 * Kbuild has a dependency on auto.conf and this marks the successful
1145 * completion of the previous steps.
1146 */
1147 ret = __conf_write_autoconf(conf_get_autoconfig_name(),
1148 print_symbol_for_autoconf,
1149 &comment_style_pound);
1150 if (ret)
1151 return ret;
1152
1153 return 0;
1154}
1155
1156static bool conf_changed;
1157static void (*conf_changed_callback)(void);
1158
1159void conf_set_changed(bool val)
1160{
1161 bool changed = conf_changed != val;
1162
1163 conf_changed = val;
1164
1165 if (conf_changed_callback && changed)
1166 conf_changed_callback();
1167}
1168
1169bool conf_get_changed(void)
1170{
1171 return conf_changed;
1172}
1173
1174void conf_set_changed_callback(void (*fn)(void))
1175{
1176 conf_changed_callback = fn;
1177}
1178
1179void set_all_choice_values(struct symbol *csym)
1180{
1181 struct property *prop;
1182 struct symbol *sym;
1183 struct expr *e;
1184
1185 prop = sym_get_choice_prop(csym);
1186
1187 /*
1188 * Set all non-assinged choice values to no
1189 */
1190 expr_list_for_each_sym(prop->expr, e, sym) {
1191 if (!sym_has_value(sym))
1192 sym->def[S_DEF_USER].tri = no;
1193 }
1194 csym->flags |= SYMBOL_DEF_USER;
1195 /* clear VALID to get value calculated */
1196 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
1197}