Linux 6.9-rc1
[linux-2.6-microblaze.git] / scripts / kconfig / confdata.c
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 */
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 */
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 */
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  */
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' */
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
161 bool conf_errors(void)
162 {
163         if (conf_warnings)
164                 return getenv("KCONFIG_WERROR");
165         return false;
166 }
167
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
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;
188 void conf_set_message_callback(void (*fn)(const char *s))
189 {
190         conf_message_callback = fn;
191 }
192
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
208 const char *conf_get_configname(void)
209 {
210         char *name = getenv("KCONFIG_CONFIG");
211
212         return name ? name : ".config";
213 }
214
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
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
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
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 */
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
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
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) || (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(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 && !sym_is_choice(sym)) {
803                         sym_calc_value(sym);
804                         if (!(sym->flags & SYMBOL_WRITE))
805                                 goto next_menu;
806                         sym->flags &= ~SYMBOL_WRITE;
807                         /* If we cannot change the symbol - skip */
808                         if (!sym_is_changeable(sym))
809                                 goto next_menu;
810                         /* If symbol equals to default value - skip */
811                         if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
812                                 goto next_menu;
813
814                         /*
815                          * If symbol is a choice value and equals to the
816                          * default for a choice - skip.
817                          * But only if value is bool and equal to "y" and
818                          * choice is not "optional".
819                          * (If choice is "optional" then all values can be "n")
820                          */
821                         if (sym_is_choice_value(sym)) {
822                                 struct symbol *cs;
823                                 struct symbol *ds;
824
825                                 cs = prop_get_symbol(sym_get_choice_prop(sym));
826                                 ds = sym_choice_default(cs);
827                                 if (!sym_is_optional(cs) && sym == ds) {
828                                         if ((sym->type == S_BOOLEAN) &&
829                                             sym_get_tristate_value(sym) == yes)
830                                                 goto next_menu;
831                                 }
832                         }
833                         print_symbol_for_dotconfig(out, sym);
834                 }
835 next_menu:
836                 if (menu->list != NULL) {
837                         menu = menu->list;
838                 }
839                 else if (menu->next != NULL) {
840                         menu = menu->next;
841                 } else {
842                         while ((menu = menu->parent)) {
843                                 if (menu->next != NULL) {
844                                         menu = menu->next;
845                                         break;
846                                 }
847                         }
848                 }
849         }
850         fclose(out);
851         return 0;
852 }
853
854 int conf_write(const char *name)
855 {
856         FILE *out;
857         struct symbol *sym;
858         struct menu *menu;
859         const char *str;
860         char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
861         char *env;
862         bool need_newline = false;
863
864         if (!name)
865                 name = conf_get_configname();
866
867         if (!*name) {
868                 fprintf(stderr, "config name is empty\n");
869                 return -1;
870         }
871
872         if (is_dir(name)) {
873                 fprintf(stderr, "%s: Is a directory\n", name);
874                 return -1;
875         }
876
877         if (make_parent_dir(name))
878                 return -1;
879
880         env = getenv("KCONFIG_OVERWRITECONFIG");
881         if (env && *env) {
882                 *tmpname = 0;
883                 out = fopen(name, "w");
884         } else {
885                 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
886                          name, (int)getpid());
887                 out = fopen(tmpname, "w");
888         }
889         if (!out)
890                 return 1;
891
892         conf_write_heading(out, &comment_style_pound);
893
894         if (!conf_get_changed())
895                 sym_clear_all_valid();
896
897         menu = rootmenu.list;
898         while (menu) {
899                 sym = menu->sym;
900                 if (!sym) {
901                         if (!menu_is_visible(menu))
902                                 goto next;
903                         str = menu_get_prompt(menu);
904                         fprintf(out, "\n"
905                                      "#\n"
906                                      "# %s\n"
907                                      "#\n", str);
908                         need_newline = false;
909                 } else if (!(sym->flags & SYMBOL_CHOICE) &&
910                            !(sym->flags & SYMBOL_WRITTEN)) {
911                         sym_calc_value(sym);
912                         if (!(sym->flags & SYMBOL_WRITE))
913                                 goto next;
914                         if (need_newline) {
915                                 fprintf(out, "\n");
916                                 need_newline = false;
917                         }
918                         sym->flags |= SYMBOL_WRITTEN;
919                         print_symbol_for_dotconfig(out, sym);
920                 }
921
922 next:
923                 if (menu->list) {
924                         menu = menu->list;
925                         continue;
926                 }
927
928 end_check:
929                 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu &&
930                     menu->prompt->type == P_MENU) {
931                         fprintf(out, "# end of %s\n", menu_get_prompt(menu));
932                         need_newline = true;
933                 }
934
935                 if (menu->next) {
936                         menu = menu->next;
937                 } else {
938                         menu = menu->parent;
939                         if (menu)
940                                 goto end_check;
941                 }
942         }
943         fclose(out);
944
945         for_all_symbols(sym)
946                 sym->flags &= ~SYMBOL_WRITTEN;
947
948         if (*tmpname) {
949                 if (is_same(name, tmpname)) {
950                         conf_message("No change to %s", name);
951                         unlink(tmpname);
952                         conf_set_changed(false);
953                         return 0;
954                 }
955
956                 snprintf(oldname, sizeof(oldname), "%s.old", name);
957                 rename(name, oldname);
958                 if (rename(tmpname, name))
959                         return 1;
960         }
961
962         conf_message("configuration written to %s", name);
963
964         conf_set_changed(false);
965
966         return 0;
967 }
968
969 /* write a dependency file as used by kbuild to track dependencies */
970 static int conf_write_autoconf_cmd(const char *autoconf_name)
971 {
972         char name[PATH_MAX], tmp[PATH_MAX];
973         FILE *out;
974         int ret;
975
976         ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name);
977         if (ret >= sizeof(name)) /* check truncation */
978                 return -1;
979
980         if (make_parent_dir(name))
981                 return -1;
982
983         ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name);
984         if (ret >= sizeof(tmp)) /* check truncation */
985                 return -1;
986
987         out = fopen(tmp, "w");
988         if (!out) {
989                 perror("fopen");
990                 return -1;
991         }
992
993         fprintf(out, "autoconfig := %s\n", autoconf_name);
994
995         fputs(str_get(&autoconf_cmd), out);
996
997         fflush(out);
998         ret = ferror(out); /* error check for all fprintf() calls */
999         fclose(out);
1000         if (ret)
1001                 return -1;
1002
1003         if (rename(tmp, name)) {
1004                 perror("rename");
1005                 return -1;
1006         }
1007
1008         return 0;
1009 }
1010
1011 static int conf_touch_deps(void)
1012 {
1013         const char *name, *tmp;
1014         struct symbol *sym;
1015         int res;
1016
1017         name = conf_get_autoconfig_name();
1018         tmp = strrchr(name, '/');
1019         depfile_prefix_len = tmp ? tmp - name + 1 : 0;
1020         if (depfile_prefix_len + 1 > sizeof(depfile_path))
1021                 return -1;
1022
1023         strncpy(depfile_path, name, depfile_prefix_len);
1024         depfile_path[depfile_prefix_len] = 0;
1025
1026         conf_read_simple(name, S_DEF_AUTO);
1027         sym_calc_value(modules_sym);
1028
1029         for_all_symbols(sym) {
1030                 sym_calc_value(sym);
1031                 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
1032                         continue;
1033                 if (sym->flags & SYMBOL_WRITE) {
1034                         if (sym->flags & SYMBOL_DEF_AUTO) {
1035                                 /*
1036                                  * symbol has old and new value,
1037                                  * so compare them...
1038                                  */
1039                                 switch (sym->type) {
1040                                 case S_BOOLEAN:
1041                                 case S_TRISTATE:
1042                                         if (sym_get_tristate_value(sym) ==
1043                                             sym->def[S_DEF_AUTO].tri)
1044                                                 continue;
1045                                         break;
1046                                 case S_STRING:
1047                                 case S_HEX:
1048                                 case S_INT:
1049                                         if (!strcmp(sym_get_string_value(sym),
1050                                                     sym->def[S_DEF_AUTO].val))
1051                                                 continue;
1052                                         break;
1053                                 default:
1054                                         break;
1055                                 }
1056                         } else {
1057                                 /*
1058                                  * If there is no old value, only 'no' (unset)
1059                                  * is allowed as new value.
1060                                  */
1061                                 switch (sym->type) {
1062                                 case S_BOOLEAN:
1063                                 case S_TRISTATE:
1064                                         if (sym_get_tristate_value(sym) == no)
1065                                                 continue;
1066                                         break;
1067                                 default:
1068                                         break;
1069                                 }
1070                         }
1071                 } else if (!(sym->flags & SYMBOL_DEF_AUTO))
1072                         /* There is neither an old nor a new value. */
1073                         continue;
1074                 /* else
1075                  *      There is an old value, but no new value ('no' (unset)
1076                  *      isn't saved in auto.conf, so the old value is always
1077                  *      different from 'no').
1078                  */
1079
1080                 res = conf_touch_dep(sym->name);
1081                 if (res)
1082                         return res;
1083         }
1084
1085         return 0;
1086 }
1087
1088 static int __conf_write_autoconf(const char *filename,
1089                                  void (*print_symbol)(FILE *, struct symbol *),
1090                                  const struct comment_style *comment_style)
1091 {
1092         char tmp[PATH_MAX];
1093         FILE *file;
1094         struct symbol *sym;
1095         int ret;
1096
1097         if (make_parent_dir(filename))
1098                 return -1;
1099
1100         ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename);
1101         if (ret >= sizeof(tmp)) /* check truncation */
1102                 return -1;
1103
1104         file = fopen(tmp, "w");
1105         if (!file) {
1106                 perror("fopen");
1107                 return -1;
1108         }
1109
1110         conf_write_heading(file, comment_style);
1111
1112         for_all_symbols(sym)
1113                 if ((sym->flags & SYMBOL_WRITE) && sym->name)
1114                         print_symbol(file, sym);
1115
1116         fflush(file);
1117         /* check possible errors in conf_write_heading() and print_symbol() */
1118         ret = ferror(file);
1119         fclose(file);
1120         if (ret)
1121                 return -1;
1122
1123         if (rename(tmp, filename)) {
1124                 perror("rename");
1125                 return -1;
1126         }
1127
1128         return 0;
1129 }
1130
1131 int conf_write_autoconf(int overwrite)
1132 {
1133         struct symbol *sym;
1134         const char *autoconf_name = conf_get_autoconfig_name();
1135         int ret;
1136
1137         if (!overwrite && is_present(autoconf_name))
1138                 return 0;
1139
1140         ret = conf_write_autoconf_cmd(autoconf_name);
1141         if (ret)
1142                 return -1;
1143
1144         if (conf_touch_deps())
1145                 return 1;
1146
1147         for_all_symbols(sym)
1148                 sym_calc_value(sym);
1149
1150         ret = __conf_write_autoconf(conf_get_autoheader_name(),
1151                                     print_symbol_for_c,
1152                                     &comment_style_c);
1153         if (ret)
1154                 return ret;
1155
1156         ret = __conf_write_autoconf(conf_get_rustccfg_name(),
1157                                     print_symbol_for_rustccfg,
1158                                     NULL);
1159         if (ret)
1160                 return ret;
1161
1162         /*
1163          * Create include/config/auto.conf. This must be the last step because
1164          * Kbuild has a dependency on auto.conf and this marks the successful
1165          * completion of the previous steps.
1166          */
1167         ret = __conf_write_autoconf(conf_get_autoconfig_name(),
1168                                     print_symbol_for_autoconf,
1169                                     &comment_style_pound);
1170         if (ret)
1171                 return ret;
1172
1173         return 0;
1174 }
1175
1176 static bool conf_changed;
1177 static void (*conf_changed_callback)(void);
1178
1179 void conf_set_changed(bool val)
1180 {
1181         bool changed = conf_changed != val;
1182
1183         conf_changed = val;
1184
1185         if (conf_changed_callback && changed)
1186                 conf_changed_callback();
1187 }
1188
1189 bool conf_get_changed(void)
1190 {
1191         return conf_changed;
1192 }
1193
1194 void conf_set_changed_callback(void (*fn)(void))
1195 {
1196         conf_changed_callback = fn;
1197 }
1198
1199 void set_all_choice_values(struct symbol *csym)
1200 {
1201         struct property *prop;
1202         struct symbol *sym;
1203         struct expr *e;
1204
1205         prop = sym_get_choice_prop(csym);
1206
1207         /*
1208          * Set all non-assinged choice values to no
1209          */
1210         expr_list_for_each_sym(prop->expr, e, sym) {
1211                 if (!sym_has_value(sym))
1212                         sym->def[S_DEF_USER].tri = no;
1213         }
1214         csym->flags |= SYMBOL_DEF_USER;
1215         /* clear VALID to get value calculated */
1216         csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
1217 }