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