kconfig: remove 'optional' property support
[linux-2.6-block.git] / scripts / kconfig / confdata.c
CommitLineData
0c874100 1// SPDX-License-Identifier: GPL-2.0
1da177e4
LT
2/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
1da177e4
LT
4 */
5
67424f61 6#include <sys/mman.h>
1da177e4 7#include <sys/stat.h>
78cb0907 8#include <sys/types.h>
1da177e4 9#include <ctype.h>
94bedeca 10#include <errno.h>
2e3646e5 11#include <fcntl.h>
558e78e3 12#include <limits.h>
10a4b277 13#include <stdarg.h>
6ce45a91 14#include <stdbool.h>
1da177e4
LT
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <time.h>
19#include <unistd.h>
20
91b69454 21#include "internal.h"
1da177e4
LT
22#include "lkc.h"
23
526396b7
MY
24struct gstr autoconf_cmd;
25
0608182a
MY
26/* return true if 'path' exists, false otherwise */
27static bool is_present(const char *path)
28{
29 struct stat st;
30
31 return !stat(path, &st);
32}
33
34/* return true if 'path' exists and it is a directory, false otherwise */
35static bool is_dir(const char *path)
36{
37 struct stat st;
38
39 if (stat(path, &st))
a69b191f 40 return false;
0608182a
MY
41
42 return S_ISDIR(st.st_mode);
43}
44
67424f61
MY
45/* return true if the given two files are the same, false otherwise */
46static bool is_same(const char *file1, const char *file2)
47{
48 int fd1, fd2;
49 struct stat st1, st2;
50 void *map1, *map2;
51 bool ret = false;
52
53 fd1 = open(file1, O_RDONLY);
54 if (fd1 < 0)
55 return ret;
56
57 fd2 = open(file2, O_RDONLY);
58 if (fd2 < 0)
59 goto close1;
60
61 ret = fstat(fd1, &st1);
62 if (ret)
63 goto close2;
64 ret = fstat(fd2, &st2);
65 if (ret)
66 goto close2;
67
68 if (st1.st_size != st2.st_size)
69 goto close2;
70
71 map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
72 if (map1 == MAP_FAILED)
73 goto close2;
74
75 map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
76 if (map2 == MAP_FAILED)
77 goto close2;
78
79 if (bcmp(map1, map2, st1.st_size))
80 goto close2;
81
82 ret = true;
83close2:
84 close(fd2);
85close1:
86 close(fd1);
87
88 return ret;
89}
90
0608182a
MY
91/*
92 * Create the parent directory of the given path.
93 *
94 * For example, if 'include/config/auto.conf' is given, create 'include/config'.
95 */
96static int make_parent_dir(const char *path)
97{
98 char tmp[PATH_MAX + 1];
99 char *p;
100
101 strncpy(tmp, path, sizeof(tmp));
102 tmp[sizeof(tmp) - 1] = 0;
103
104 /* Remove the base name. Just return if nothing is left */
105 p = strrchr(tmp, '/');
106 if (!p)
107 return 0;
108 *(p + 1) = 0;
109
110 /* Just in case it is an absolute path */
111 p = tmp;
112 while (*p == '/')
113 p++;
114
115 while ((p = strchr(p, '/'))) {
116 *p = 0;
117
118 /* skip if the directory exists */
119 if (!is_dir(tmp) && mkdir(tmp, 0755))
120 return -1;
121
122 *p = '/';
123 while (*p == '/')
124 p++;
125 }
126
127 return 0;
128}
129
1508fec8
MY
130static char depfile_path[PATH_MAX];
131static size_t depfile_prefix_len;
132
133/* touch depfile for symbol 'name' */
134static int conf_touch_dep(const char *name)
135{
fee762d6 136 int fd;
1508fec8 137
0e0345b7
AD
138 /* check overflow: prefix + name + '\0' must fit in buffer. */
139 if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path))
1508fec8
MY
140 return -1;
141
fee762d6 142 strcpy(depfile_path + depfile_prefix_len, name);
1508fec8 143
1508fec8 144 fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
fee762d6
MY
145 if (fd == -1)
146 return -1;
1508fec8
MY
147 close(fd);
148
149 return 0;
150}
151
c1a0f5e3
RZ
152static void conf_warning(const char *fmt, ...)
153 __attribute__ ((format (printf, 1, 2)));
154
42368c37
MM
155static void conf_message(const char *fmt, ...)
156 __attribute__ ((format (printf, 1, 2)));
157
c1a0f5e3 158static const char *conf_filename;
84dd95d4 159static int conf_lineno, conf_warnings;
c1a0f5e3 160
15d3f766
SS
161bool conf_errors(void)
162{
163 if (conf_warnings)
164 return getenv("KCONFIG_WERROR");
165 return false;
166}
167
c1a0f5e3
RZ
168static void conf_warning(const char *fmt, ...)
169{
170 va_list ap;
171 va_start(ap, fmt);
172 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
173 vfprintf(stderr, fmt, ap);
174 fprintf(stderr, "\n");
175 va_end(ap);
176 conf_warnings++;
177}
178
5accd7f3 179static void conf_default_message_callback(const char *s)
42368c37
MM
180{
181 printf("#\n# ");
5accd7f3 182 printf("%s", s);
42368c37
MM
183 printf("\n#\n");
184}
185
5accd7f3 186static void (*conf_message_callback)(const char *s) =
42368c37 187 conf_default_message_callback;
5accd7f3 188void conf_set_message_callback(void (*fn)(const char *s))
42368c37
MM
189{
190 conf_message_callback = fn;
191}
192
193static void conf_message(const char *fmt, ...)
194{
195 va_list ap;
5accd7f3
MY
196 char buf[4096];
197
198 if (!conf_message_callback)
199 return;
42368c37
MM
200
201 va_start(ap, fmt);
5accd7f3
MY
202
203 vsnprintf(buf, sizeof(buf), fmt, ap);
204 conf_message_callback(buf);
b6a2ab2c 205 va_end(ap);
42368c37
MM
206}
207
14cdd3c4
RZ
208const char *conf_get_configname(void)
209{
210 char *name = getenv("KCONFIG_CONFIG");
211
212 return name ? name : ".config";
213}
214
9b9f5948 215static const char *conf_get_autoconfig_name(void)
12122f62
MH
216{
217 char *name = getenv("KCONFIG_AUTOCONFIG");
218
219 return name ? name : "include/config/auto.conf";
220}
221
8499f2dd
MY
222static const char *conf_get_autoheader_name(void)
223{
224 char *name = getenv("KCONFIG_AUTOHEADER");
225
226 return name ? name : "include/generated/autoconf.h";
227}
228
2f7ab126
MO
229static const char *conf_get_rustccfg_name(void)
230{
231 char *name = getenv("KCONFIG_RUSTCCFG");
232
233 return name ? name : "include/generated/rustc_cfg";
234}
235
9c900a9c
SR
236static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
237{
238 char *p2;
239
240 switch (sym->type) {
241 case S_TRISTATE:
242 if (p[0] == 'm') {
243 sym->def[def].tri = mod;
244 sym->flags |= def_flags;
245 break;
246 }
d8fc3200 247 /* fall through */
9c900a9c
SR
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 }
04b19b77
YM
259 if (def != S_DEF_AUTO)
260 conf_warning("symbol value '%s' invalid for %s",
261 p, sym->name);
75f1468b 262 return 1;
9c900a9c 263 case S_STRING:
129ab0d2
MY
264 /* No escaping for S_DEF_AUTO (include/config/auto.conf) */
265 if (def != S_DEF_AUTO) {
266 if (*p++ != '"')
9c900a9c 267 break;
129ab0d2
MY
268 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
269 if (*p2 == '"') {
270 *p2 = 0;
271 break;
272 }
273 memmove(p2, p2 + 1, strlen(p2));
9c900a9c 274 }
129ab0d2 275 if (!p2) {
04b19b77 276 conf_warning("invalid string found");
129ab0d2
MY
277 return 1;
278 }
9c900a9c 279 }
d8fc3200 280 /* fall through */
9c900a9c
SR
281 case S_INT:
282 case S_HEX:
9c900a9c 283 if (sym_string_valid(sym, p)) {
cd81fc82 284 sym->def[def].val = xstrdup(p);
9c900a9c
SR
285 sym->flags |= def_flags;
286 } else {
04b19b77
YM
287 if (def != S_DEF_AUTO)
288 conf_warning("symbol value '%s' invalid for %s",
289 p, sym->name);
9c900a9c
SR
290 return 1;
291 }
292 break;
293 default:
294 ;
295 }
296 return 0;
297}
298
9925d6b7
MY
299/* like getline(), but the newline character is stripped away */
300static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
301{
302 ssize_t len;
303
aa8427fb 304 len = getline(lineptr, n, stream);
9925d6b7
MY
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
669bfad9 319int conf_read_simple(const char *name, int def)
1da177e4
LT
320{
321 FILE *in = NULL;
1a7a8c6f
CS
322 char *line = NULL;
323 size_t line_asize = 0;
9925d6b7 324 char *p, *val;
1da177e4 325 struct symbol *sym;
91b69454 326 int def_flags;
15d3f766 327 const char *warn_unknown, *sym_name;
1da177e4 328
7cd34300 329 warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
1da177e4
LT
330 if (name) {
331 in = zconf_fopen(name);
332 } else {
b75b0a81 333 char *env;
face4374 334
14cdd3c4 335 name = conf_get_configname();
ddc97cac
RZ
336 in = zconf_fopen(name);
337 if (in)
338 goto load;
5ee54659 339 conf_set_changed(true);
b75b0a81
MY
340
341 env = getenv("KCONFIG_DEFCONFIG_LIST");
342 if (!env)
face4374
RZ
343 return 1;
344
b75b0a81
MY
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);
1da177e4 363 if (in) {
694c49a7 364 conf_message("using defaults found in %s",
b75b0a81 365 env);
ddc97cac 366 goto load;
1da177e4 367 }
b75b0a81
MY
368
369 if (is_last)
370 break;
371
372 env = p + 1;
1da177e4
LT
373 }
374 }
1da177e4
LT
375 if (!in)
376 return 1;
377
ddc97cac 378load:
c1a0f5e3
RZ
379 conf_filename = name;
380 conf_lineno = 0;
381 conf_warnings = 0;
c1a0f5e3 382
669bfad9 383 def_flags = SYMBOL_DEF << def;
91b69454 384 for_all_symbols(sym) {
669bfad9
RZ
385 sym->flags |= SYMBOL_CHANGED;
386 sym->flags &= ~(def_flags|SYMBOL_VALID);
490f1617
YM
387 if (sym_is_choice(sym))
388 sym->flags |= def_flags;
1da177e4
LT
389 switch (sym->type) {
390 case S_INT:
391 case S_HEX:
392 case S_STRING:
407868de 393 free(sym->def[def].val);
d8fc3200 394 /* fall through */
1da177e4 395 default:
669bfad9
RZ
396 sym->def[def].val = NULL;
397 sym->def[def].tri = no;
1da177e4
LT
398 }
399 }
400
9925d6b7 401 while (getline_stripped(&line, &line_asize, in) != -1) {
c1a0f5e3 402 conf_lineno++;
48ab6c9c
MY
403
404 if (!line[0]) /* blank line */
405 continue;
406
8baefd30 407 if (line[0] == '#') {
4d137ab0
MY
408 if (line[1] != ' ')
409 continue;
d854b4b2
MY
410 p = line + 2;
411 if (memcmp(p, CONFIG_, strlen(CONFIG_)))
1da177e4 412 continue;
d854b4b2
MY
413 sym_name = p + strlen(CONFIG_);
414 p = strchr(sym_name, ' ');
1da177e4
LT
415 if (!p)
416 continue;
417 *p++ = 0;
4aced3ec 418 if (strcmp(p, "is not set"))
1da177e4 419 continue;
92d4fe0a 420
d854b4b2 421 val = "n";
48ab6c9c
MY
422 } else {
423 if (memcmp(line, CONFIG_, strlen(CONFIG_))) {
424 conf_warning("unexpected data: %s", line);
425 continue;
426 }
427
d854b4b2
MY
428 sym_name = line + strlen(CONFIG_);
429 p = strchr(sym_name, '=');
48ab6c9c
MY
430 if (!p) {
431 conf_warning("unexpected data: %s", line);
1da177e4 432 continue;
48ab6c9c 433 }
9925d6b7
MY
434 *p = 0;
435 val = p + 1;
1da177e4 436 }
75889e9b 437
d854b4b2
MY
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
1da177e4
LT
463 if (sym && sym_is_choice_value(sym)) {
464 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
669bfad9 465 switch (sym->def[def].tri) {
1da177e4
LT
466 case no:
467 break;
468 case mod:
669bfad9 469 if (cs->def[def].tri == yes) {
c1a0f5e3 470 conf_warning("%s creates inconsistent choice state", sym->name);
490f1617 471 cs->flags &= ~def_flags;
c1a0f5e3 472 }
1da177e4
LT
473 break;
474 case yes:
d84876f9
JE
475 if (cs->def[def].tri != no)
476 conf_warning("override: %s changes choice state", sym->name);
477 cs->def[def].val = sym;
1da177e4
LT
478 break;
479 }
d6ee3576 480 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
1da177e4
LT
481 }
482 }
1a7a8c6f 483 free(line);
1da177e4 484 fclose(in);
7cd34300 485
90389160
RZ
486 return 0;
487}
488
489int conf_read(const char *name)
490{
5d09598d 491 struct symbol *sym;
84dd95d4 492 int conf_unsaved = 0;
90389160 493
5ee54659 494 conf_set_changed(false);
ddc97cac 495
6b87b70c
AV
496 if (conf_read_simple(name, S_DEF_USER)) {
497 sym_calc_value(modules_sym);
90389160 498 return 1;
6b87b70c
AV
499 }
500
501 sym_calc_value(modules_sym);
90389160 502
91b69454 503 for_all_symbols(sym) {
1da177e4 504 sym_calc_value(sym);
693359f7 505 if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
5d09598d 506 continue;
c1a0f5e3
RZ
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:
e3cd5136 512 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
5d09598d 513 continue;
e3cd5136 514 break;
c1a0f5e3 515 default:
0c1822e6 516 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
5d09598d 517 continue;
c1a0f5e3
RZ
518 break;
519 }
520 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
521 /* no previous value and not saved */
5d09598d 522 continue;
c1a0f5e3
RZ
523 conf_unsaved++;
524 /* maybe print value in verbose mode... */
d8982ba1
RZ
525 }
526
91b69454 527 for_all_symbols(sym) {
1da177e4 528 if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
d8982ba1
RZ
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)
669bfad9 535 sym->flags &= ~SYMBOL_DEF_USER;
1da177e4
LT
536 switch (sym->type) {
537 case S_STRING:
538 case S_INT:
539 case S_HEX:
d8982ba1
RZ
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;
ce1fc934 543 sym->flags &= ~SYMBOL_VALID;
d8982ba1
RZ
544 conf_unsaved++;
545 break;
1da177e4
LT
546 default:
547 break;
548 }
549 }
1da177e4
LT
550 }
551
5ee54659
MY
552 if (conf_warnings || conf_unsaved)
553 conf_set_changed(true);
1da177e4
LT
554
555 return 0;
556}
557
ca51b26b
MY
558struct comment_style {
559 const char *decoration;
560 const char *prefix;
561 const char *postfix;
562};
563
564static const struct comment_style comment_style_pound = {
565 .decoration = "#",
566 .prefix = "#",
567 .postfix = "#",
568};
569
570static const struct comment_style comment_style_c = {
571 .decoration = " *",
572 .prefix = "/*",
573 .postfix = " */",
574};
575
576static void conf_write_heading(FILE *fp, const struct comment_style *cs)
577{
2f7ab126
MO
578 if (!cs)
579 return;
580
ca51b26b
MY
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
80f7bc77
MY
591/* The returned pointer must be freed on the caller side */
592static char *escape_string_value(const char *in)
593{
594 const char *p;
595 char *out;
596 size_t len;
597
598 len = strlen(in) + strlen("\"\"") + 1;
599
600 p = in;
601 while (1) {
602 p += strcspn(p, "\"\\");
603
604 if (p[0] == '\0')
605 break;
606
607 len++;
608 p++;
609 }
610
611 out = xmalloc(len);
612 out[0] = '\0';
613
614 strcat(out, "\"");
615
616 p = in;
617 while (1) {
618 len = strcspn(p, "\"\\");
619 strncat(out, p, len);
620 p += len;
621
622 if (p[0] == '\0')
623 break;
624
625 strcat(out, "\\");
626 strncat(out, p++, 1);
627 }
628
629 strcat(out, "\"");
630
631 return out;
632}
633
6ce45a91 634enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE };
e54e692b 635
6ce45a91
MY
636static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n,
637 bool escape_string)
49192f26 638{
6ce45a91
MY
639 const char *val;
640 char *escaped = NULL;
e54e692b 641
6ce45a91
MY
642 if (sym->type == S_UNKNOWN)
643 return;
49192f26 644
6ce45a91 645 val = sym_get_string_value(sym);
eb4cf5a6 646
6ce45a91
MY
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;
eb4cf5a6 652 }
eb4cf5a6 653
6ce45a91 654 if (sym->type == S_STRING && escape_string) {
80f7bc77 655 escaped = escape_string_value(val);
6ce45a91 656 val = escaped;
e54e692b
AL
657 }
658
6ce45a91
MY
659 fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val);
660
661 free(escaped);
e54e692b
AL
662}
663
6ce45a91 664static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym)
e54e692b 665{
6ce45a91
MY
666 __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true);
667}
668
669static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym)
670{
129ab0d2 671 __print_symbol(fp, sym, OUTPUT_N_NONE, false);
6ce45a91 672}
e54e692b 673
51d792cb
MY
674void print_symbol_for_listconfig(struct symbol *sym)
675{
676 __print_symbol(stdout, sym, OUTPUT_N, true);
677}
678
6ce45a91 679static void print_symbol_for_c(FILE *fp, struct symbol *sym)
e54e692b 680{
229d0cfa 681 const char *val;
6ce45a91
MY
682 const char *sym_suffix = "";
683 const char *val_prefix = "";
229d0cfa 684 char *escaped = NULL;
e54e692b 685
229d0cfa
MY
686 if (sym->type == S_UNKNOWN)
687 return;
688
689 val = sym_get_string_value(sym);
690
6ce45a91
MY
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:
80f7bc77 709 escaped = escape_string_value(val);
229d0cfa 710 val = escaped;
6ce45a91
MY
711 default:
712 break;
49192f26 713 }
229d0cfa 714
6ce45a91
MY
715 fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix,
716 val_prefix, val);
229d0cfa
MY
717
718 free(escaped);
49192f26
SR
719}
720
2f7ab126
MO
721static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
722{
723 const char *val;
724 const char *val_prefix = "";
725 char *val_prefixed = NULL;
726 size_t val_prefixed_len;
727 char *escaped = NULL;
728
729 if (sym->type == S_UNKNOWN)
730 return;
731
732 val = sym_get_string_value(sym);
733
734 switch (sym->type) {
735 case S_BOOLEAN:
736 case S_TRISTATE:
737 /*
738 * We do not care about disabled ones, i.e. no need for
739 * what otherwise are "comments" in other printers.
740 */
741 if (*val == 'n')
742 return;
743
744 /*
745 * To have similar functionality to the C macro `IS_ENABLED()`
746 * we provide an empty `--cfg CONFIG_X` here in both `y`
747 * and `m` cases.
748 *
749 * Then, the common `fprintf()` below will also give us
750 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
751 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
752 */
753 fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
754 break;
755 case S_HEX:
756 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
757 val_prefix = "0x";
758 break;
759 default:
760 break;
761 }
762
763 if (strlen(val_prefix) > 0) {
764 val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
765 val_prefixed = xmalloc(val_prefixed_len);
766 snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
767 val = val_prefixed;
768 }
769
770 /* All values get escaped: the `--cfg` option only takes strings */
771 escaped = escape_string_value(val);
772 val = escaped;
773
774 fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);
775
776 free(escaped);
777 free(val_prefixed);
778}
779
7cf3d73b
SR
780/*
781 * Write out a minimal config.
782 * All values that has default values are skipped as this is redundant.
783 */
784int conf_write_defconfig(const char *filename)
785{
786 struct symbol *sym;
787 struct menu *menu;
788 FILE *out;
789
790 out = fopen(filename, "w");
791 if (!out)
792 return 1;
793
794 sym_clear_all_valid();
795
03c4ecaa 796 menu_for_each_entry(menu) {
7cf3d73b 797 sym = menu->sym;
b27a9138 798 if (sym && !sym_is_choice(sym)) {
7cf3d73b
SR
799 sym_calc_value(sym);
800 if (!(sym->flags & SYMBOL_WRITE))
03c4ecaa 801 continue;
7cf3d73b
SR
802 sym->flags &= ~SYMBOL_WRITE;
803 /* If we cannot change the symbol - skip */
baa23ec8 804 if (!sym_is_changeable(sym))
03c4ecaa 805 continue;
7cf3d73b
SR
806 /* If symbol equals to default value - skip */
807 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
03c4ecaa 808 continue;
7cf3d73b
SR
809
810 /*
811 * If symbol is a choice value and equals to the
812 * default for a choice - skip.
7cf3d73b
SR
813 */
814 if (sym_is_choice_value(sym)) {
815 struct symbol *cs;
816 struct symbol *ds;
817
818 cs = prop_get_symbol(sym_get_choice_prop(sym));
819 ds = sym_choice_default(cs);
6a121588 820 if (sym == ds) {
801690ca
SR
821 if ((sym->type == S_BOOLEAN) &&
822 sym_get_tristate_value(sym) == yes)
03c4ecaa 823 continue;
7cf3d73b
SR
824 }
825 }
6ce45a91 826 print_symbol_for_dotconfig(out, sym);
7cf3d73b 827 }
7cf3d73b
SR
828 }
829 fclose(out);
830 return 0;
831}
832
1da177e4
LT
833int conf_write(const char *name)
834{
c955ccaf 835 FILE *out;
1da177e4
LT
836 struct symbol *sym;
837 struct menu *menu;
1da177e4 838 const char *str;
ceb7f329 839 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
1da177e4 840 char *env;
aff11cd9 841 bool need_newline = false;
1da177e4 842
ceb7f329
MY
843 if (!name)
844 name = conf_get_configname();
845
846 if (!*name) {
847 fprintf(stderr, "config name is empty\n");
848 return -1;
849 }
850
851 if (is_dir(name)) {
852 fprintf(stderr, "%s: Is a directory\n", name);
853 return -1;
854 }
855
580c5b3e
MY
856 if (make_parent_dir(name))
857 return -1;
858
14cdd3c4 859 env = getenv("KCONFIG_OVERWRITECONFIG");
ceb7f329 860 if (env && *env) {
14cdd3c4 861 *tmpname = 0;
ceb7f329
MY
862 out = fopen(name, "w");
863 } else {
864 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
865 name, (int)getpid());
866 out = fopen(tmpname, "w");
14cdd3c4 867 }
1da177e4
LT
868 if (!out)
869 return 1;
14cdd3c4 870
ca51b26b 871 conf_write_heading(out, &comment_style_pound);
1da177e4 872
b3214293 873 if (!conf_get_changed())
1da177e4
LT
874 sym_clear_all_valid();
875
876 menu = rootmenu.list;
877 while (menu) {
878 sym = menu->sym;
879 if (!sym) {
880 if (!menu_is_visible(menu))
881 goto next;
882 str = menu_get_prompt(menu);
883 fprintf(out, "\n"
884 "#\n"
885 "# %s\n"
886 "#\n", str);
aff11cd9 887 need_newline = false;
1da251c6 888 } else if (!sym_is_choice(sym) &&
8e2442a5 889 !(sym->flags & SYMBOL_WRITTEN)) {
1da177e4
LT
890 sym_calc_value(sym);
891 if (!(sym->flags & SYMBOL_WRITE))
892 goto next;
aff11cd9
AP
893 if (need_newline) {
894 fprintf(out, "\n");
895 need_newline = false;
896 }
8e2442a5 897 sym->flags |= SYMBOL_WRITTEN;
6ce45a91 898 print_symbol_for_dotconfig(out, sym);
1da177e4
LT
899 }
900
49192f26 901next:
1da177e4
LT
902 if (menu->list) {
903 menu = menu->list;
904 continue;
905 }
a7d4f58e
MY
906
907end_check:
908 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu &&
909 menu->prompt->type == P_MENU) {
910 fprintf(out, "# end of %s\n", menu_get_prompt(menu));
911 need_newline = true;
912 }
913
914 if (menu->next) {
1da177e4 915 menu = menu->next;
a7d4f58e
MY
916 } else {
917 menu = menu->parent;
918 if (menu)
919 goto end_check;
1da177e4
LT
920 }
921 }
922 fclose(out);
14cdd3c4 923
91b69454 924 for_all_symbols(sym)
0c5b6c28
VB
925 sym->flags &= ~SYMBOL_WRITTEN;
926
14cdd3c4 927 if (*tmpname) {
67424f61
MY
928 if (is_same(name, tmpname)) {
929 conf_message("No change to %s", name);
930 unlink(tmpname);
5ee54659 931 conf_set_changed(false);
67424f61
MY
932 return 0;
933 }
934
ceb7f329
MY
935 snprintf(oldname, sizeof(oldname), "%s.old", name);
936 rename(name, oldname);
937 if (rename(tmpname, name))
14cdd3c4 938 return 1;
1da177e4 939 }
1da177e4 940
ceb7f329 941 conf_message("configuration written to %s", name);
ddc97cac 942
5ee54659 943 conf_set_changed(false);
1da177e4
LT
944
945 return 0;
946}
c955ccaf 947
a2ff4040 948/* write a dependency file as used by kbuild to track dependencies */
00d674cb 949static int conf_write_autoconf_cmd(const char *autoconf_name)
a2ff4040 950{
00d674cb 951 char name[PATH_MAX], tmp[PATH_MAX];
a2ff4040 952 FILE *out;
00d674cb 953 int ret;
a2ff4040 954
00d674cb
MY
955 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name);
956 if (ret >= sizeof(name)) /* check truncation */
957 return -1;
958
959 if (make_parent_dir(name))
960 return -1;
961
962 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name);
963 if (ret >= sizeof(tmp)) /* check truncation */
964 return -1;
965
966 out = fopen(tmp, "w");
967 if (!out) {
968 perror("fopen");
969 return -1;
a2ff4040 970 }
a2ff4040 971
56e634b0 972 fprintf(out, "autoconfig := %s\n", autoconf_name);
00d674cb 973
56e634b0 974 fputs(str_get(&autoconf_cmd), out);
00d674cb 975
868653f4 976 fflush(out);
d23a0c37 977 ret = ferror(out); /* error check for all fprintf() calls */
a2ff4040 978 fclose(out);
d23a0c37
MY
979 if (ret)
980 return -1;
79123b13 981
00d674cb
MY
982 if (rename(tmp, name)) {
983 perror("rename");
984 return -1;
985 }
986
a2ff4040
MY
987 return 0;
988}
989
0849d212 990static int conf_touch_deps(void)
2e3646e5 991{
1b9e740a 992 const char *name, *tmp;
2e3646e5 993 struct symbol *sym;
91b69454 994 int res;
1508fec8 995
12122f62 996 name = conf_get_autoconfig_name();
1b9e740a
JL
997 tmp = strrchr(name, '/');
998 depfile_prefix_len = tmp ? tmp - name + 1 : 0;
999 if (depfile_prefix_len + 1 > sizeof(depfile_path))
1000 return -1;
1001
1002 strncpy(depfile_path, name, depfile_prefix_len);
1003 depfile_path[depfile_prefix_len] = 0;
1004
2e3646e5 1005 conf_read_simple(name, S_DEF_AUTO);
6b87b70c 1006 sym_calc_value(modules_sym);
2e3646e5 1007
91b69454 1008 for_all_symbols(sym) {
2e3646e5 1009 sym_calc_value(sym);
693359f7 1010 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
2e3646e5
RZ
1011 continue;
1012 if (sym->flags & SYMBOL_WRITE) {
1013 if (sym->flags & SYMBOL_DEF_AUTO) {
1014 /*
1015 * symbol has old and new value,
1016 * so compare them...
1017 */
1018 switch (sym->type) {
1019 case S_BOOLEAN:
1020 case S_TRISTATE:
1021 if (sym_get_tristate_value(sym) ==
1022 sym->def[S_DEF_AUTO].tri)
1023 continue;
1024 break;
1025 case S_STRING:
1026 case S_HEX:
1027 case S_INT:
1028 if (!strcmp(sym_get_string_value(sym),
1029 sym->def[S_DEF_AUTO].val))
1030 continue;
1031 break;
1032 default:
1033 break;
1034 }
1035 } else {
1036 /*
1037 * If there is no old value, only 'no' (unset)
1038 * is allowed as new value.
1039 */
1040 switch (sym->type) {
1041 case S_BOOLEAN:
1042 case S_TRISTATE:
1043 if (sym_get_tristate_value(sym) == no)
1044 continue;
1045 break;
1046 default:
1047 break;
1048 }
1049 }
1050 } else if (!(sym->flags & SYMBOL_DEF_AUTO))
1051 /* There is neither an old nor a new value. */
1052 continue;
1053 /* else
1054 * There is an old value, but no new value ('no' (unset)
1055 * isn't saved in auto.conf, so the old value is always
1056 * different from 'no').
1057 */
1058
1508fec8
MY
1059 res = conf_touch_dep(sym->name);
1060 if (res)
1061 return res;
2e3646e5 1062 }
2e3646e5 1063
1508fec8 1064 return 0;
2e3646e5
RZ
1065}
1066
57ddd07c
MY
1067static int __conf_write_autoconf(const char *filename,
1068 void (*print_symbol)(FILE *, struct symbol *),
1069 const struct comment_style *comment_style)
1070{
1071 char tmp[PATH_MAX];
1072 FILE *file;
1073 struct symbol *sym;
91b69454 1074 int ret;
57ddd07c
MY
1075
1076 if (make_parent_dir(filename))
1077 return -1;
1078
1079 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename);
1080 if (ret >= sizeof(tmp)) /* check truncation */
1081 return -1;
1082
1083 file = fopen(tmp, "w");
1084 if (!file) {
1085 perror("fopen");
1086 return -1;
1087 }
1088
1089 conf_write_heading(file, comment_style);
1090
91b69454 1091 for_all_symbols(sym)
57ddd07c
MY
1092 if ((sym->flags & SYMBOL_WRITE) && sym->name)
1093 print_symbol(file, sym);
1094
868653f4 1095 fflush(file);
57ddd07c 1096 /* check possible errors in conf_write_heading() and print_symbol() */
d23a0c37 1097 ret = ferror(file);
57ddd07c 1098 fclose(file);
d23a0c37
MY
1099 if (ret)
1100 return -1;
57ddd07c
MY
1101
1102 if (rename(tmp, filename)) {
1103 perror("rename");
1104 return -1;
1105 }
1106
1107 return 0;
1108}
1109
00c864f8 1110int conf_write_autoconf(int overwrite)
c955ccaf
RZ
1111{
1112 struct symbol *sym;
00c864f8 1113 const char *autoconf_name = conf_get_autoconfig_name();
91b69454 1114 int ret;
c955ccaf 1115
00c864f8
MY
1116 if (!overwrite && is_present(autoconf_name))
1117 return 0;
1118
00d674cb
MY
1119 ret = conf_write_autoconf_cmd(autoconf_name);
1120 if (ret)
1121 return -1;
c955ccaf 1122
0849d212 1123 if (conf_touch_deps())
2e3646e5
RZ
1124 return 1;
1125
91b69454 1126 for_all_symbols(sym)
c955ccaf 1127 sym_calc_value(sym);
49192f26 1128
57ddd07c
MY
1129 ret = __conf_write_autoconf(conf_get_autoheader_name(),
1130 print_symbol_for_c,
1131 &comment_style_c);
1132 if (ret)
1133 return ret;
79123b13 1134
2f7ab126
MO
1135 ret = __conf_write_autoconf(conf_get_rustccfg_name(),
1136 print_symbol_for_rustccfg,
1137 NULL);
1138 if (ret)
1139 return ret;
1140
c955ccaf 1141 /*
57ddd07c
MY
1142 * Create include/config/auto.conf. This must be the last step because
1143 * Kbuild has a dependency on auto.conf and this marks the successful
1144 * completion of the previous steps.
c955ccaf 1145 */
57ddd07c
MY
1146 ret = __conf_write_autoconf(conf_get_autoconfig_name(),
1147 print_symbol_for_autoconf,
1148 &comment_style_pound);
1149 if (ret)
1150 return ret;
c955ccaf
RZ
1151
1152 return 0;
1153}
b3214293 1154
5ee54659 1155static bool conf_changed;
3b354c55 1156static void (*conf_changed_callback)(void);
bfc10001 1157
5ee54659 1158void conf_set_changed(bool val)
bfc10001 1159{
ee06a3ef 1160 bool changed = conf_changed != val;
bfc10001 1161
5ee54659 1162 conf_changed = val;
ee06a3ef
JV
1163
1164 if (conf_changed_callback && changed)
1165 conf_changed_callback();
bfc10001
KW
1166}
1167
b3214293
KW
1168bool conf_get_changed(void)
1169{
5ee54659 1170 return conf_changed;
b3214293 1171}
3b354c55
KW
1172
1173void conf_set_changed_callback(void (*fn)(void))
1174{
1175 conf_changed_callback = fn;
1176}
dc7862e5 1177
fbe98bb9 1178void set_all_choice_values(struct symbol *csym)
dc7862e5 1179{
dc7862e5 1180 struct property *prop;
a64b44ea 1181 struct symbol *sym;
dc7862e5 1182 struct expr *e;
a64b44ea
SR
1183
1184 prop = sym_get_choice_prop(csym);
1185
1186 /*
1187 * Set all non-assinged choice values to no
1188 */
1189 expr_list_for_each_sym(prop->expr, e, sym) {
1190 if (!sym_has_value(sym))
1191 sym->def[S_DEF_USER].tri = no;
1192 }
1193 csym->flags |= SYMBOL_DEF_USER;
1194 /* clear VALID to get value calculated */
fbe98bb9 1195 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
a64b44ea 1196}