]> Git Repo - J-linux.git/blob - scripts/kconfig/confdata.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / scripts / kconfig / confdata.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2002 Roman Zippel <[email protected]>
4  */
5
6 #include <sys/mman.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <ctype.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <limits.h>
13 #include <stdarg.h>
14 #include <stdbool.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <time.h>
19 #include <unistd.h>
20
21 #include <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 (bcmp(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 const char *conf_get_configname(void)
210 {
211         char *name = getenv("KCONFIG_CONFIG");
212
213         return name ? name : ".config";
214 }
215
216 static const char *conf_get_autoconfig_name(void)
217 {
218         char *name = getenv("KCONFIG_AUTOCONFIG");
219
220         return name ? name : "include/config/auto.conf";
221 }
222
223 static const char *conf_get_autoheader_name(void)
224 {
225         char *name = getenv("KCONFIG_AUTOHEADER");
226
227         return name ? name : "include/generated/autoconf.h";
228 }
229
230 static const char *conf_get_rustccfg_name(void)
231 {
232         char *name = getenv("KCONFIG_RUSTCCFG");
233
234         return name ? name : "include/generated/rustc_cfg";
235 }
236
237 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
238 {
239         char *p2;
240
241         switch (sym->type) {
242         case S_TRISTATE:
243                 if (p[0] == 'm') {
244                         sym->def[def].tri = mod;
245                         sym->flags |= def_flags;
246                         break;
247                 }
248                 /* fall through */
249         case S_BOOLEAN:
250                 if (p[0] == 'y') {
251                         sym->def[def].tri = yes;
252                         sym->flags |= def_flags;
253                         break;
254                 }
255                 if (p[0] == 'n') {
256                         sym->def[def].tri = no;
257                         sym->flags |= def_flags;
258                         break;
259                 }
260                 if (def != S_DEF_AUTO)
261                         conf_warning("symbol value '%s' invalid for %s",
262                                      p, sym->name);
263                 return 1;
264         case S_STRING:
265                 /* No escaping for S_DEF_AUTO (include/config/auto.conf) */
266                 if (def != S_DEF_AUTO) {
267                         if (*p++ != '"')
268                                 break;
269                         for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
270                                 if (*p2 == '"') {
271                                         *p2 = 0;
272                                         break;
273                                 }
274                                 memmove(p2, p2 + 1, strlen(p2));
275                         }
276                         if (!p2) {
277                                 conf_warning("invalid string found");
278                                 return 1;
279                         }
280                 }
281                 /* fall through */
282         case S_INT:
283         case S_HEX:
284                 if (sym_string_valid(sym, p)) {
285                         sym->def[def].val = xstrdup(p);
286                         sym->flags |= def_flags;
287                 } else {
288                         if (def != S_DEF_AUTO)
289                                 conf_warning("symbol value '%s' invalid for %s",
290                                              p, sym->name);
291                         return 1;
292                 }
293                 break;
294         default:
295                 ;
296         }
297         return 0;
298 }
299
300 /* like getline(), but the newline character is stripped away */
301 static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
302 {
303         ssize_t len;
304
305         len = getline(lineptr, n, stream);
306
307         if (len > 0 && (*lineptr)[len - 1] == '\n') {
308                 len--;
309                 (*lineptr)[len] = '\0';
310
311                 if (len > 0 && (*lineptr)[len - 1] == '\r') {
312                         len--;
313                         (*lineptr)[len] = '\0';
314                 }
315         }
316
317         return len;
318 }
319
320 int conf_read_simple(const char *name, int def)
321 {
322         FILE *in = NULL;
323         char   *line = NULL;
324         size_t  line_asize = 0;
325         char *p, *val;
326         struct symbol *sym;
327         int def_flags;
328         const char *warn_unknown, *sym_name;
329
330         warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
331         if (name) {
332                 in = zconf_fopen(name);
333         } else {
334                 char *env;
335
336                 name = conf_get_configname();
337                 in = zconf_fopen(name);
338                 if (in)
339                         goto load;
340                 conf_set_changed(true);
341
342                 env = getenv("KCONFIG_DEFCONFIG_LIST");
343                 if (!env)
344                         return 1;
345
346                 while (1) {
347                         bool is_last;
348
349                         while (isspace(*env))
350                                 env++;
351
352                         if (!*env)
353                                 break;
354
355                         p = env;
356                         while (*p && !isspace(*p))
357                                 p++;
358
359                         is_last = (*p == '\0');
360
361                         *p = '\0';
362
363                         in = zconf_fopen(env);
364                         if (in) {
365                                 conf_message("using defaults found in %s",
366                                              env);
367                                 goto load;
368                         }
369
370                         if (is_last)
371                                 break;
372
373                         env = p + 1;
374                 }
375         }
376         if (!in)
377                 return 1;
378
379 load:
380         conf_filename = name;
381         conf_lineno = 0;
382         conf_warnings = 0;
383
384         def_flags = SYMBOL_DEF << def;
385         for_all_symbols(sym) {
386                 sym->flags &= ~(def_flags|SYMBOL_VALID);
387                 switch (sym->type) {
388                 case S_INT:
389                 case S_HEX:
390                 case S_STRING:
391                         free(sym->def[def].val);
392                         /* fall through */
393                 default:
394                         sym->def[def].val = NULL;
395                         sym->def[def].tri = no;
396                 }
397         }
398
399         expr_invalidate_all();
400
401         while (getline_stripped(&line, &line_asize, in) != -1) {
402                 struct menu *choice;
403
404                 conf_lineno++;
405
406                 if (!line[0]) /* blank line */
407                         continue;
408
409                 if (line[0] == '#') {
410                         if (line[1] != ' ')
411                                 continue;
412                         p = line + 2;
413                         if (memcmp(p, CONFIG_, strlen(CONFIG_)))
414                                 continue;
415                         sym_name = p + strlen(CONFIG_);
416                         p = strchr(sym_name, ' ');
417                         if (!p)
418                                 continue;
419                         *p++ = 0;
420                         if (strcmp(p, "is not set"))
421                                 continue;
422
423                         val = "n";
424                 } else {
425                         if (memcmp(line, CONFIG_, strlen(CONFIG_))) {
426                                 conf_warning("unexpected data: %s", line);
427                                 continue;
428                         }
429
430                         sym_name = line + strlen(CONFIG_);
431                         p = strchr(sym_name, '=');
432                         if (!p) {
433                                 conf_warning("unexpected data: %s", line);
434                                 continue;
435                         }
436                         *p = 0;
437                         val = p + 1;
438                 }
439
440                 sym = sym_find(sym_name);
441                 if (!sym) {
442                         if (def == S_DEF_AUTO) {
443                                 /*
444                                  * Reading from include/config/auto.conf.
445                                  * If CONFIG_FOO previously existed in auto.conf
446                                  * but it is missing now, include/config/FOO
447                                  * must be touched.
448                                  */
449                                 conf_touch_dep(sym_name);
450                         } else {
451                                 if (warn_unknown)
452                                         conf_warning("unknown symbol: %s", sym_name);
453
454                                 conf_set_changed(true);
455                         }
456                         continue;
457                 }
458
459                 if (sym->flags & def_flags)
460                         conf_warning("override: reassigning to symbol %s", sym->name);
461
462                 if (conf_set_sym_val(sym, def, def_flags, val))
463                         continue;
464
465                 /*
466                  * If this is a choice member, give it the highest priority.
467                  * If conflicting CONFIG options are given from an input file,
468                  * the last one wins.
469                  */
470                 choice = sym_get_choice_menu(sym);
471                 if (choice)
472                         list_move(&sym->choice_link, &choice->choice_members);
473         }
474         free(line);
475         fclose(in);
476
477         return 0;
478 }
479
480 int conf_read(const char *name)
481 {
482         struct symbol *sym;
483
484         conf_set_changed(false);
485
486         if (conf_read_simple(name, S_DEF_USER)) {
487                 sym_calc_value(modules_sym);
488                 return 1;
489         }
490
491         sym_calc_value(modules_sym);
492
493         for_all_symbols(sym) {
494                 sym_calc_value(sym);
495                 if (sym_is_choice(sym))
496                         continue;
497                 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
498                         /* check that calculated value agrees with saved value */
499                         switch (sym->type) {
500                         case S_BOOLEAN:
501                         case S_TRISTATE:
502                                 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
503                                         continue;
504                                 break;
505                         default:
506                                 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
507                                         continue;
508                                 break;
509                         }
510                 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
511                         /* no previous value and not saved */
512                         continue;
513                 conf_set_changed(true);
514                 /* maybe print value in verbose mode... */
515         }
516
517         if (conf_warnings)
518                 conf_set_changed(true);
519
520         return 0;
521 }
522
523 struct comment_style {
524         const char *decoration;
525         const char *prefix;
526         const char *postfix;
527 };
528
529 static const struct comment_style comment_style_pound = {
530         .decoration = "#",
531         .prefix = "#",
532         .postfix = "#",
533 };
534
535 static const struct comment_style comment_style_c = {
536         .decoration = " *",
537         .prefix = "/*",
538         .postfix = " */",
539 };
540
541 static void conf_write_heading(FILE *fp, const struct comment_style *cs)
542 {
543         if (!cs)
544                 return;
545
546         fprintf(fp, "%s\n", cs->prefix);
547
548         fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n",
549                 cs->decoration);
550
551         fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text);
552
553         fprintf(fp, "%s\n", cs->postfix);
554 }
555
556 /* The returned pointer must be freed on the caller side */
557 static char *escape_string_value(const char *in)
558 {
559         const char *p;
560         char *out;
561         size_t len;
562
563         len = strlen(in) + strlen("\"\"") + 1;
564
565         p = in;
566         while (1) {
567                 p += strcspn(p, "\"\\");
568
569                 if (p[0] == '\0')
570                         break;
571
572                 len++;
573                 p++;
574         }
575
576         out = xmalloc(len);
577         out[0] = '\0';
578
579         strcat(out, "\"");
580
581         p = in;
582         while (1) {
583                 len = strcspn(p, "\"\\");
584                 strncat(out, p, len);
585                 p += len;
586
587                 if (p[0] == '\0')
588                         break;
589
590                 strcat(out, "\\");
591                 strncat(out, p++, 1);
592         }
593
594         strcat(out, "\"");
595
596         return out;
597 }
598
599 enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };
600
601 static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
602                            bool escape_string)
603 {
604         const char *val;
605         char *escaped = NULL;
606
607         if (sym->type == S_UNKNOWN)
608                 return;
609
610         val = sym_get_string_value(sym);
611
612         if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) &&
613             output_n != OUTPUT_N && *val == 'n') {
614                 if (output_n == OUTPUT_N_AS_UNSET)
615                         fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name);
616                 return;
617         }
618
619         if (sym->type == S_STRING && escape_string) {
620                 escaped = escape_string_value(val);
621                 val = escaped;
622         }
623
624         fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);
625
626         free(escaped);
627 }
628
629 static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
630 {
631         __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
632 }
633
634 static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
635 {
636         __print_symbol(fp, sym, OUTPUT_N_NONE, false);
637 }
638
639 void print_symbol_for_listconfig(struct symbol *sym)
640 {
641         __print_symbol(stdout, sym, OUTPUT_N, true);
642 }
643
644 static void print_symbol_for_c(FILE *fp, struct symbol *sym)
645 {
646         const char *val;
647         const char *sym_suffix = "";
648         const char *val_prefix = "";
649         char *escaped = NULL;
650
651         if (sym->type == S_UNKNOWN)
652                 return;
653
654         val = sym_get_string_value(sym);
655
656         switch (sym->type) {
657         case S_BOOLEAN:
658         case S_TRISTATE:
659                 switch (*val) {
660                 case 'n':
661                         return;
662                 case 'm':
663                         sym_suffix = "_MODULE";
664                         /* fall through */
665                 default:
666                         val = "1";
667                 }
668                 break;
669         case S_HEX:
670                 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
671                         val_prefix = "0x";
672                 break;
673         case S_STRING:
674                 escaped = escape_string_value(val);
675                 val = escaped;
676         default:
677                 break;
678         }
679
680         fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix,
681                 val_prefix, val);
682
683         free(escaped);
684 }
685
686 static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
687 {
688         const char *val;
689         const char *val_prefix = "";
690         char *val_prefixed = NULL;
691         size_t val_prefixed_len;
692         char *escaped = NULL;
693
694         if (sym->type == S_UNKNOWN)
695                 return;
696
697         val = sym_get_string_value(sym);
698
699         switch (sym->type) {
700         case S_BOOLEAN:
701         case S_TRISTATE:
702                 /*
703                  * We do not care about disabled ones, i.e. no need for
704                  * what otherwise are "comments" in other printers.
705                  */
706                 if (*val == 'n')
707                         return;
708
709                 /*
710                  * To have similar functionality to the C macro `IS_ENABLED()`
711                  * we provide an empty `--cfg CONFIG_X` here in both `y`
712                  * and `m` cases.
713                  *
714                  * Then, the common `fprintf()` below will also give us
715                  * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
716                  * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
717                  */
718                 fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
719                 break;
720         case S_HEX:
721                 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
722                         val_prefix = "0x";
723                 break;
724         default:
725                 break;
726         }
727
728         if (strlen(val_prefix) > 0) {
729                 val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
730                 val_prefixed = xmalloc(val_prefixed_len);
731                 snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
732                 val = val_prefixed;
733         }
734
735         /* All values get escaped: the `--cfg` option only takes strings */
736         escaped = escape_string_value(val);
737         val = escaped;
738
739         fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);
740
741         free(escaped);
742         free(val_prefixed);
743 }
744
745 /*
746  * Write out a minimal config.
747  * All values that has default values are skipped as this is redundant.
748  */
749 int conf_write_defconfig(const char *filename)
750 {
751         struct symbol *sym;
752         struct menu *menu;
753         FILE *out;
754
755         out = fopen(filename, "w");
756         if (!out)
757                 return 1;
758
759         sym_clear_all_valid();
760
761         menu_for_each_entry(menu) {
762                 struct menu *choice;
763
764                 sym = menu->sym;
765
766                 if (!sym || sym_is_choice(sym))
767                         continue;
768
769                 sym_calc_value(sym);
770                 if (!(sym->flags & SYMBOL_WRITE))
771                         continue;
772                 sym->flags &= ~SYMBOL_WRITE;
773                 /* Skip unchangeable symbols */
774                 if (!sym_is_changeable(sym))
775                         continue;
776                 /* Skip symbols that are equal to the default */
777                 if (!strcmp(sym_get_string_value(sym), sym_get_string_default(sym)))
778                         continue;
779
780                 /* Skip choice values that are equal to the default */
781                 choice = sym_get_choice_menu(sym);
782                 if (choice) {
783                         struct symbol *ds;
784
785                         ds = sym_choice_default(choice);
786                         if (sym == ds && sym_get_tristate_value(sym) == yes)
787                                 continue;
788                 }
789                 print_symbol_for_dotconfig(out, sym);
790         }
791         fclose(out);
792         return 0;
793 }
794
795 int conf_write(const char *name)
796 {
797         FILE *out;
798         struct symbol *sym;
799         struct menu *menu;
800         const char *str;
801         char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
802         char *env;
803         bool need_newline = false;
804
805         if (!name)
806                 name = conf_get_configname();
807
808         if (!*name) {
809                 fprintf(stderr, "config name is empty\n");
810                 return -1;
811         }
812
813         if (is_dir(name)) {
814                 fprintf(stderr, "%s: Is a directory\n", name);
815                 return -1;
816         }
817
818         if (make_parent_dir(name))
819                 return -1;
820
821         env = getenv("KCONFIG_OVERWRITECONFIG");
822         if (env && *env) {
823                 *tmpname = 0;
824                 out = fopen(name, "w");
825         } else {
826                 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
827                          name, (int)getpid());
828                 out = fopen(tmpname, "w");
829         }
830         if (!out)
831                 return 1;
832
833         conf_write_heading(out, &comment_style_pound);
834
835         if (!conf_get_changed())
836                 sym_clear_all_valid();
837
838         menu = rootmenu.list;
839         while (menu) {
840                 sym = menu->sym;
841                 if (!sym) {
842                         if (!menu_is_visible(menu))
843                                 goto next;
844                         str = menu_get_prompt(menu);
845                         fprintf(out, "\n"
846                                      "#\n"
847                                      "# %s\n"
848                                      "#\n", str);
849                         need_newline = false;
850                 } else if (!sym_is_choice(sym) &&
851                            !(sym->flags & SYMBOL_WRITTEN)) {
852                         sym_calc_value(sym);
853                         if (!(sym->flags & SYMBOL_WRITE))
854                                 goto next;
855                         if (need_newline) {
856                                 fprintf(out, "\n");
857                                 need_newline = false;
858                         }
859                         sym->flags |= SYMBOL_WRITTEN;
860                         print_symbol_for_dotconfig(out, sym);
861                 }
862
863 next:
864                 if (menu->list) {
865                         menu = menu->list;
866                         continue;
867                 }
868
869 end_check:
870                 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu &&
871                     menu->prompt->type == P_MENU) {
872                         fprintf(out, "# end of %s\n", menu_get_prompt(menu));
873                         need_newline = true;
874                 }
875
876                 if (menu->next) {
877                         menu = menu->next;
878                 } else {
879                         menu = menu->parent;
880                         if (menu)
881                                 goto end_check;
882                 }
883         }
884         fclose(out);
885
886         for_all_symbols(sym)
887                 sym->flags &= ~SYMBOL_WRITTEN;
888
889         if (*tmpname) {
890                 if (is_same(name, tmpname)) {
891                         conf_message("No change to %s", name);
892                         unlink(tmpname);
893                         conf_set_changed(false);
894                         return 0;
895                 }
896
897                 snprintf(oldname, sizeof(oldname), "%s.old", name);
898                 rename(name, oldname);
899                 if (rename(tmpname, name))
900                         return 1;
901         }
902
903         conf_message("configuration written to %s", name);
904
905         conf_set_changed(false);
906
907         return 0;
908 }
909
910 /* write a dependency file as used by kbuild to track dependencies */
911 static int conf_write_autoconf_cmd(const char *autoconf_name)
912 {
913         char name[PATH_MAX], tmp[PATH_MAX];
914         FILE *out;
915         int ret;
916
917         ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name);
918         if (ret >= sizeof(name)) /* check truncation */
919                 return -1;
920
921         if (make_parent_dir(name))
922                 return -1;
923
924         ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name);
925         if (ret >= sizeof(tmp)) /* check truncation */
926                 return -1;
927
928         out = fopen(tmp, "w");
929         if (!out) {
930                 perror("fopen");
931                 return -1;
932         }
933
934         fprintf(out, "autoconfig := %s\n", autoconf_name);
935
936         fputs(str_get(&autoconf_cmd), out);
937
938         fflush(out);
939         ret = ferror(out); /* error check for all fprintf() calls */
940         fclose(out);
941         if (ret)
942                 return -1;
943
944         if (rename(tmp, name)) {
945                 perror("rename");
946                 return -1;
947         }
948
949         return 0;
950 }
951
952 static int conf_touch_deps(void)
953 {
954         const char *name, *tmp;
955         struct symbol *sym;
956         int res;
957
958         name = conf_get_autoconfig_name();
959         tmp = strrchr(name, '/');
960         depfile_prefix_len = tmp ? tmp - name + 1 : 0;
961         if (depfile_prefix_len + 1 > sizeof(depfile_path))
962                 return -1;
963
964         strncpy(depfile_path, name, depfile_prefix_len);
965         depfile_path[depfile_prefix_len] = 0;
966
967         conf_read_simple(name, S_DEF_AUTO);
968         sym_calc_value(modules_sym);
969
970         for_all_symbols(sym) {
971                 sym_calc_value(sym);
972                 if (sym_is_choice(sym))
973                         continue;
974                 if (sym->flags & SYMBOL_WRITE) {
975                         if (sym->flags & SYMBOL_DEF_AUTO) {
976                                 /*
977                                  * symbol has old and new value,
978                                  * so compare them...
979                                  */
980                                 switch (sym->type) {
981                                 case S_BOOLEAN:
982                                 case S_TRISTATE:
983                                         if (sym_get_tristate_value(sym) ==
984                                             sym->def[S_DEF_AUTO].tri)
985                                                 continue;
986                                         break;
987                                 case S_STRING:
988                                 case S_HEX:
989                                 case S_INT:
990                                         if (!strcmp(sym_get_string_value(sym),
991                                                     sym->def[S_DEF_AUTO].val))
992                                                 continue;
993                                         break;
994                                 default:
995                                         break;
996                                 }
997                         } else {
998                                 /*
999                                  * If there is no old value, only 'no' (unset)
1000                                  * is allowed as new value.
1001                                  */
1002                                 switch (sym->type) {
1003                                 case S_BOOLEAN:
1004                                 case S_TRISTATE:
1005                                         if (sym_get_tristate_value(sym) == no)
1006                                                 continue;
1007                                         break;
1008                                 default:
1009                                         break;
1010                                 }
1011                         }
1012                 } else if (!(sym->flags & SYMBOL_DEF_AUTO))
1013                         /* There is neither an old nor a new value. */
1014                         continue;
1015                 /* else
1016                  *      There is an old value, but no new value ('no' (unset)
1017                  *      isn't saved in auto.conf, so the old value is always
1018                  *      different from 'no').
1019                  */
1020
1021                 res = conf_touch_dep(sym->name);
1022                 if (res)
1023                         return res;
1024         }
1025
1026         return 0;
1027 }
1028
1029 static int __conf_write_autoconf(const char *filename,
1030                                  void (*print_symbol)(FILE *, struct symbol *),
1031                                  const struct comment_style *comment_style)
1032 {
1033         char tmp[PATH_MAX];
1034         FILE *file;
1035         struct symbol *sym;
1036         int ret;
1037
1038         if (make_parent_dir(filename))
1039                 return -1;
1040
1041         ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename);
1042         if (ret >= sizeof(tmp)) /* check truncation */
1043                 return -1;
1044
1045         file = fopen(tmp, "w");
1046         if (!file) {
1047                 perror("fopen");
1048                 return -1;
1049         }
1050
1051         conf_write_heading(file, comment_style);
1052
1053         for_all_symbols(sym)
1054                 if ((sym->flags & SYMBOL_WRITE) && sym->name)
1055                         print_symbol(file, sym);
1056
1057         fflush(file);
1058         /* check possible errors in conf_write_heading() and print_symbol() */
1059         ret = ferror(file);
1060         fclose(file);
1061         if (ret)
1062                 return -1;
1063
1064         if (rename(tmp, filename)) {
1065                 perror("rename");
1066                 return -1;
1067         }
1068
1069         return 0;
1070 }
1071
1072 int conf_write_autoconf(int overwrite)
1073 {
1074         struct symbol *sym;
1075         const char *autoconf_name = conf_get_autoconfig_name();
1076         int ret;
1077
1078         if (!overwrite && is_present(autoconf_name))
1079                 return 0;
1080
1081         ret = conf_write_autoconf_cmd(autoconf_name);
1082         if (ret)
1083                 return -1;
1084
1085         if (conf_touch_deps())
1086                 return 1;
1087
1088         for_all_symbols(sym)
1089                 sym_calc_value(sym);
1090
1091         ret = __conf_write_autoconf(conf_get_autoheader_name(),
1092                                     print_symbol_for_c,
1093                                     &comment_style_c);
1094         if (ret)
1095                 return ret;
1096
1097         ret = __conf_write_autoconf(conf_get_rustccfg_name(),
1098                                     print_symbol_for_rustccfg,
1099                                     NULL);
1100         if (ret)
1101                 return ret;
1102
1103         /*
1104          * Create include/config/auto.conf. This must be the last step because
1105          * Kbuild has a dependency on auto.conf and this marks the successful
1106          * completion of the previous steps.
1107          */
1108         ret = __conf_write_autoconf(conf_get_autoconfig_name(),
1109                                     print_symbol_for_autoconf,
1110                                     &comment_style_pound);
1111         if (ret)
1112                 return ret;
1113
1114         return 0;
1115 }
1116
1117 static bool conf_changed;
1118 static void (*conf_changed_callback)(bool);
1119
1120 void conf_set_changed(bool val)
1121 {
1122         if (conf_changed_callback && conf_changed != val)
1123                 conf_changed_callback(val);
1124
1125         conf_changed = val;
1126 }
1127
1128 bool conf_get_changed(void)
1129 {
1130         return conf_changed;
1131 }
1132
1133 void conf_set_changed_callback(void (*fn)(bool))
1134 {
1135         conf_changed_callback = fn;
1136 }
This page took 0.088823 seconds and 4 git commands to generate.