blob: a39a716f79a2b25f247c5e2d9fd75c0d0b162fcb [file] [log] [blame]
Patrick Georgi0588d192009-08-12 15:00:51 +00001/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <sys/stat.h>
7#include <ctype.h>
Patrick Georgid5208402014-04-11 20:24:06 +02008#include <errno.h>
Patrick Georgi0588d192009-08-12 15:00:51 +00009#include <fcntl.h>
Patrick Georgid5208402014-04-11 20:24:06 +020010#include <stdarg.h>
Patrick Georgi0588d192009-08-12 15:00:51 +000011#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <time.h>
15#include <unistd.h>
16
Patrick Georgi0588d192009-08-12 15:00:51 +000017#include "lkc.h"
18
19static void conf_warning(const char *fmt, ...)
20 __attribute__ ((format (printf, 1, 2)));
21
Patrick Georgid5208402014-04-11 20:24:06 +020022static void conf_message(const char *fmt, ...)
23 __attribute__ ((format (printf, 1, 2)));
24
Patrick Georgi0588d192009-08-12 15:00:51 +000025static const char *conf_filename;
26static int conf_lineno, conf_warnings, conf_unsaved;
27
28const char conf_defname[] = "arch/$ARCH/defconfig";
29
30static void conf_warning(const char *fmt, ...)
31{
32 va_list ap;
33 va_start(ap, fmt);
34 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
35 vfprintf(stderr, fmt, ap);
36 fprintf(stderr, "\n");
37 va_end(ap);
38 conf_warnings++;
39}
40
Patrick Georgid5208402014-04-11 20:24:06 +020041static void conf_default_message_callback(const char *fmt, va_list ap)
42{
43 printf("#\n# ");
44 vprintf(fmt, ap);
45 printf("\n#\n");
46}
47
48static void (*conf_message_callback) (const char *fmt, va_list ap) =
49 conf_default_message_callback;
50void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap))
51{
52 conf_message_callback = fn;
53}
54
55static void conf_message(const char *fmt, ...)
56{
57 va_list ap;
58
59 va_start(ap, fmt);
60 if (conf_message_callback)
61 conf_message_callback(fmt, ap);
Stefan Reinauercce66622015-04-06 01:14:21 +020062 va_end(ap);
Patrick Georgid5208402014-04-11 20:24:06 +020063}
64
Patrick Georgi0588d192009-08-12 15:00:51 +000065const char *conf_get_configname(void)
66{
67 char *name = getenv("KCONFIG_CONFIG");
68
69 return name ? name : ".config";
70}
71
Patrick Georgid5208402014-04-11 20:24:06 +020072const char *conf_get_autoconfig_name(void)
73{
74 char *name = getenv("KCONFIG_AUTOCONFIG");
75
76 return name ? name : "include/config/auto.conf";
77}
78
Patrick Georgi0588d192009-08-12 15:00:51 +000079static char *conf_expand_value(const char *in)
80{
81 struct symbol *sym;
82 const char *src;
83 static char res_value[SYMBOL_MAXLENGTH];
84 char *dst, name[SYMBOL_MAXLENGTH];
85
86 res_value[0] = 0;
87 dst = name;
88 while ((src = strchr(in, '$'))) {
89 strncat(res_value, in, src - in);
90 src++;
91 dst = name;
92 while (isalnum(*src) || *src == '_')
93 *dst++ = *src++;
94 *dst = 0;
95 sym = sym_lookup(name, 0);
96 sym_calc_value(sym);
97 strcat(res_value, sym_get_string_value(sym));
98 in = src;
99 }
100 strcat(res_value, in);
101
102 return res_value;
103}
104
105char *conf_get_default_confname(void)
106{
107 struct stat buf;
108 static char fullname[PATH_MAX+1];
109 char *env, *name;
110
111 name = conf_expand_value(conf_defname);
112 env = getenv(SRCTREE);
113 if (env) {
114 sprintf(fullname, "%s/%s", env, name);
115 if (!stat(fullname, &buf))
116 return fullname;
117 }
118 return name;
119}
120
121static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
122{
123 char *p2;
124
125 switch (sym->type) {
126 case S_TRISTATE:
127 if (p[0] == 'm') {
128 sym->def[def].tri = mod;
129 sym->flags |= def_flags;
130 break;
131 }
Patrick Georgid5208402014-04-11 20:24:06 +0200132 /* fall through */
Patrick Georgi0588d192009-08-12 15:00:51 +0000133 case S_BOOLEAN:
134 if (p[0] == 'y') {
135 sym->def[def].tri = yes;
136 sym->flags |= def_flags;
137 break;
138 }
139 if (p[0] == 'n') {
140 sym->def[def].tri = no;
141 sym->flags |= def_flags;
142 break;
143 }
Patrick Georgid5208402014-04-11 20:24:06 +0200144 if (def != S_DEF_AUTO)
145 conf_warning("symbol value '%s' invalid for %s",
146 p, sym->name);
147 return 1;
Patrick Georgi0588d192009-08-12 15:00:51 +0000148 case S_OTHER:
149 if (*p != '"') {
150 for (p2 = p; *p2 && !isspace(*p2); p2++)
151 ;
152 sym->type = S_STRING;
153 goto done;
154 }
Patrick Georgid5208402014-04-11 20:24:06 +0200155 /* fall through */
Patrick Georgi0588d192009-08-12 15:00:51 +0000156 case S_STRING:
157 if (*p++ != '"')
158 break;
159 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
160 if (*p2 == '"') {
161 *p2 = 0;
162 break;
163 }
164 memmove(p2, p2 + 1, strlen(p2));
165 }
166 if (!p2) {
Patrick Georgid5208402014-04-11 20:24:06 +0200167 if (def != S_DEF_AUTO)
168 conf_warning("invalid string found");
Patrick Georgi0588d192009-08-12 15:00:51 +0000169 return 1;
170 }
Patrick Georgid5208402014-04-11 20:24:06 +0200171 /* fall through */
Patrick Georgi0588d192009-08-12 15:00:51 +0000172 case S_INT:
173 case S_HEX:
174 done:
175 if (sym_string_valid(sym, p)) {
176 sym->def[def].val = strdup(p);
177 sym->flags |= def_flags;
178 } else {
Patrick Georgid5208402014-04-11 20:24:06 +0200179 if (def != S_DEF_AUTO)
180 conf_warning("symbol value '%s' invalid for %s",
181 p, sym->name);
Patrick Georgi0588d192009-08-12 15:00:51 +0000182 return 1;
183 }
184 break;
185 default:
186 ;
187 }
188 return 0;
189}
190
Patrick Georgid5208402014-04-11 20:24:06 +0200191#define LINE_GROWTH 16
192static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
193{
194 char *nline;
195 size_t new_size = slen + 1;
196 if (new_size > *n) {
197 new_size += LINE_GROWTH - 1;
198 new_size *= 2;
199 nline = realloc(*lineptr, new_size);
200 if (!nline)
201 return -1;
202
203 *lineptr = nline;
204 *n = new_size;
205 }
206
207 (*lineptr)[slen] = c;
208
209 return 0;
210}
211
212static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
213{
214 char *line = *lineptr;
215 size_t slen = 0;
216
217 for (;;) {
218 int c = getc(stream);
219
220 switch (c) {
221 case '\n':
222 if (add_byte(c, &line, slen, n) < 0)
223 goto e_out;
224 slen++;
225 /* fall through */
226 case EOF:
227 if (add_byte('\0', &line, slen, n) < 0)
228 goto e_out;
229 *lineptr = line;
230 if (slen == 0)
231 return -1;
232 return slen;
233 default:
234 if (add_byte(c, &line, slen, n) < 0)
235 goto e_out;
236 slen++;
237 }
238 }
239
240e_out:
241 line[slen-1] = '\0';
242 *lineptr = line;
243 return -1;
244}
245
Patrick Georgi0588d192009-08-12 15:00:51 +0000246int conf_read_simple(const char *name, int def)
247{
248 FILE *in = NULL;
Patrick Georgid5208402014-04-11 20:24:06 +0200249 char *line = NULL;
250 size_t line_asize = 0;
Patrick Georgi0588d192009-08-12 15:00:51 +0000251 char *p, *p2;
252 struct symbol *sym;
253 int i, def_flags;
254
255 if (name) {
256 in = zconf_fopen(name);
257 } else {
258 struct property *prop;
259
260 name = conf_get_configname();
261 in = zconf_fopen(name);
262 if (in)
263 goto load;
264 sym_add_change_count(1);
Patrick Georgid5208402014-04-11 20:24:06 +0200265 if (!sym_defconfig_list) {
266 if (modules_sym)
267 sym_calc_value(modules_sym);
Patrick Georgi0588d192009-08-12 15:00:51 +0000268 return 1;
Patrick Georgid5208402014-04-11 20:24:06 +0200269 }
Patrick Georgi0588d192009-08-12 15:00:51 +0000270
271 for_all_defaults(sym_defconfig_list, prop) {
272 if (expr_calc_value(prop->visible.expr) == no ||
273 prop->expr->type != E_SYMBOL)
274 continue;
275 name = conf_expand_value(prop->expr->left.sym->name);
276 in = zconf_fopen(name);
277 if (in) {
Patrick Georgid5208402014-04-11 20:24:06 +0200278 conf_message(_("using defaults found in %s"),
279 name);
Patrick Georgi0588d192009-08-12 15:00:51 +0000280 goto load;
281 }
282 }
283 }
284 if (!in)
285 return 1;
286
287load:
288 conf_filename = name;
289 conf_lineno = 0;
290 conf_warnings = 0;
291 conf_unsaved = 0;
292
293 def_flags = SYMBOL_DEF << def;
294 for_all_symbols(i, sym) {
295 sym->flags |= SYMBOL_CHANGED;
296 sym->flags &= ~(def_flags|SYMBOL_VALID);
297 if (sym_is_choice(sym))
298 sym->flags |= def_flags;
299 switch (sym->type) {
300 case S_INT:
301 case S_HEX:
302 case S_STRING:
303 if (sym->def[def].val)
304 free(sym->def[def].val);
Patrick Georgid5208402014-04-11 20:24:06 +0200305 /* fall through */
Patrick Georgi0588d192009-08-12 15:00:51 +0000306 default:
307 sym->def[def].val = NULL;
308 sym->def[def].tri = no;
309 }
310 }
311
Patrick Georgid5208402014-04-11 20:24:06 +0200312 while (compat_getline(&line, &line_asize, in) != -1) {
Patrick Georgi0588d192009-08-12 15:00:51 +0000313 conf_lineno++;
314 sym = NULL;
Patrick Georgid5208402014-04-11 20:24:06 +0200315 if (line[0] == '#') {
316 if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
Patrick Georgi0588d192009-08-12 15:00:51 +0000317 continue;
Patrick Georgid5208402014-04-11 20:24:06 +0200318 p = strchr(line + 2 + strlen(CONFIG_), ' ');
Patrick Georgi0588d192009-08-12 15:00:51 +0000319 if (!p)
320 continue;
321 *p++ = 0;
322 if (strncmp(p, "is not set", 10))
323 continue;
324 if (def == S_DEF_USER) {
Patrick Georgid5208402014-04-11 20:24:06 +0200325 sym = sym_find(line + 2 + strlen(CONFIG_));
Patrick Georgi0588d192009-08-12 15:00:51 +0000326 if (!sym) {
Patrick Georgid5208402014-04-11 20:24:06 +0200327 sym_add_change_count(1);
328 goto setsym;
Patrick Georgi0588d192009-08-12 15:00:51 +0000329 }
330 } else {
Patrick Georgid5208402014-04-11 20:24:06 +0200331 sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
Patrick Georgi0588d192009-08-12 15:00:51 +0000332 if (sym->type == S_UNKNOWN)
333 sym->type = S_BOOLEAN;
334 }
335 if (sym->flags & def_flags) {
336 conf_warning("override: reassigning to symbol %s", sym->name);
337 }
338 switch (sym->type) {
339 case S_BOOLEAN:
340 case S_TRISTATE:
341 sym->def[def].tri = no;
342 sym->flags |= def_flags;
343 break;
344 default:
345 ;
346 }
Patrick Georgid5208402014-04-11 20:24:06 +0200347 } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
348 p = strchr(line + strlen(CONFIG_), '=');
Patrick Georgi0588d192009-08-12 15:00:51 +0000349 if (!p)
350 continue;
351 *p++ = 0;
352 p2 = strchr(p, '\n');
353 if (p2) {
354 *p2-- = 0;
355 if (*p2 == '\r')
356 *p2 = 0;
357 }
358 if (def == S_DEF_USER) {
Patrick Georgid5208402014-04-11 20:24:06 +0200359 sym = sym_find(line + strlen(CONFIG_));
Patrick Georgi0588d192009-08-12 15:00:51 +0000360 if (!sym) {
Stefan Reinauerf5342032015-07-17 17:26:48 -0700361 conf_warning("trying to assign non-existent symbol %s", line + strlen(CONFIG_));
Patrick Georgid5208402014-04-11 20:24:06 +0200362 sym_add_change_count(1);
363 goto setsym;
Patrick Georgi0588d192009-08-12 15:00:51 +0000364 }
365 } else {
Patrick Georgid5208402014-04-11 20:24:06 +0200366 sym = sym_lookup(line + strlen(CONFIG_), 0);
Patrick Georgi0588d192009-08-12 15:00:51 +0000367 if (sym->type == S_UNKNOWN)
368 sym->type = S_OTHER;
369 }
370 if (sym->flags & def_flags) {
371 conf_warning("override: reassigning to symbol %s", sym->name);
372 }
373 if (conf_set_sym_val(sym, def, def_flags, p))
374 continue;
Patrick Georgid5208402014-04-11 20:24:06 +0200375 } else {
376 if (line[0] != '\r' && line[0] != '\n')
377 conf_warning("unexpected data");
Patrick Georgi0588d192009-08-12 15:00:51 +0000378 continue;
379 }
Patrick Georgid5208402014-04-11 20:24:06 +0200380setsym:
Patrick Georgi0588d192009-08-12 15:00:51 +0000381 if (sym && sym_is_choice_value(sym)) {
382 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
383 switch (sym->def[def].tri) {
384 case no:
385 break;
386 case mod:
387 if (cs->def[def].tri == yes) {
388 conf_warning("%s creates inconsistent choice state", sym->name);
389 cs->flags &= ~def_flags;
390 }
391 break;
392 case yes:
393 if (cs->def[def].tri != no)
394 conf_warning("override: %s changes choice state", sym->name);
395 cs->def[def].val = sym;
396 break;
397 }
398 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
399 }
400 }
Patrick Georgid5208402014-04-11 20:24:06 +0200401 free(line);
Patrick Georgi0588d192009-08-12 15:00:51 +0000402 fclose(in);
403
404 if (modules_sym)
405 sym_calc_value(modules_sym);
Stefan Reinauerf5342032015-07-17 17:26:48 -0700406
Stefan Reinauer57a31312015-08-20 11:19:34 -0700407 kconfig_warnings += conf_warnings;
Stefan Reinauerf5342032015-07-17 17:26:48 -0700408
Patrick Georgi0588d192009-08-12 15:00:51 +0000409 return 0;
410}
411
412int conf_read(const char *name)
413{
Patrick Georgid5208402014-04-11 20:24:06 +0200414 struct symbol *sym;
415 int i;
Patrick Georgi0588d192009-08-12 15:00:51 +0000416
417 sym_set_change_count(0);
418
419 if (conf_read_simple(name, S_DEF_USER))
420 return 1;
421
422 for_all_symbols(i, sym) {
423 sym_calc_value(sym);
424 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
Patrick Georgid5208402014-04-11 20:24:06 +0200425 continue;
Patrick Georgi0588d192009-08-12 15:00:51 +0000426 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
427 /* check that calculated value agrees with saved value */
428 switch (sym->type) {
429 case S_BOOLEAN:
430 case S_TRISTATE:
431 if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
432 break;
433 if (!sym_is_choice(sym))
Patrick Georgid5208402014-04-11 20:24:06 +0200434 continue;
435 /* fall through */
Patrick Georgi0588d192009-08-12 15:00:51 +0000436 default:
437 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
Patrick Georgid5208402014-04-11 20:24:06 +0200438 continue;
Patrick Georgi0588d192009-08-12 15:00:51 +0000439 break;
440 }
441 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
442 /* no previous value and not saved */
Patrick Georgid5208402014-04-11 20:24:06 +0200443 continue;
Patrick Georgi0588d192009-08-12 15:00:51 +0000444 conf_unsaved++;
445 /* maybe print value in verbose mode... */
Patrick Georgi0588d192009-08-12 15:00:51 +0000446 }
447
448 for_all_symbols(i, sym) {
449 if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
450 /* Reset values of generates values, so they'll appear
451 * as new, if they should become visible, but that
452 * doesn't quite work if the Kconfig and the saved
453 * configuration disagree.
454 */
455 if (sym->visible == no && !conf_unsaved)
456 sym->flags &= ~SYMBOL_DEF_USER;
457 switch (sym->type) {
458 case S_STRING:
459 case S_INT:
460 case S_HEX:
461 /* Reset a string value if it's out of range */
462 if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
463 break;
464 sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
465 conf_unsaved++;
466 break;
467 default:
468 break;
469 }
470 }
471 }
472
473 sym_add_change_count(conf_warnings || conf_unsaved);
474
475 return 0;
476}
477
Patrick Georgid5208402014-04-11 20:24:06 +0200478/*
479 * Kconfig configuration printer
480 *
481 * This printer is used when generating the resulting configuration after
482 * kconfig invocation and `defconfig' files. Unset symbol might be omitted by
483 * passing a non-NULL argument to the printer.
484 *
485 */
486static void
487kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
488{
489
490 switch (sym->type) {
491 case S_BOOLEAN:
492 case S_TRISTATE:
493 if (*value == 'n') {
494 bool skip_unset = (arg != NULL);
495
496 if (!skip_unset)
497 fprintf(fp, "# %s%s is not set\n",
498 CONFIG_, sym->name);
499 return;
500 }
501 break;
502 default:
503 break;
504 }
505
506 fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value);
507}
508
509static void
510kconfig_print_comment(FILE *fp, const char *value, void *arg)
511{
512 const char *p = value;
513 size_t l;
514
515 for (;;) {
516 l = strcspn(p, "\n");
517 fprintf(fp, "#");
518 if (l) {
519 fprintf(fp, " ");
520 xfwrite(p, l, 1, fp);
521 p += l;
522 }
523 fprintf(fp, "\n");
524 if (*p++ == '\0')
525 break;
526 }
527}
528
529static struct conf_printer kconfig_printer_cb =
530{
531 .print_symbol = kconfig_print_symbol,
532 .print_comment = kconfig_print_comment,
533};
534
535/*
536 * Header printer
537 *
538 * This printer is used when generating the `include/generated/autoconf.h' file.
539 */
540static void
541header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
542{
543
544 switch (sym->type) {
545 case S_BOOLEAN:
546 case S_TRISTATE: {
547 const char *suffix = "";
548
549 switch (*value) {
550 case 'n':
551 if (getenv("KCONFIG_NEGATIVES")) {
552 fprintf(fp, "#define %s%s%s 0\n",
553 CONFIG_, sym->name, suffix);
554 }
555 break;
556 case 'm':
557 suffix = "_MODULE";
558 /* fall through */
559 default:
560 fprintf(fp, "#define %s%s%s 1\n",
561 CONFIG_, sym->name, suffix);
562 }
563 break;
564 }
565 case S_HEX: {
566 const char *prefix = "";
567
568 if (!value || (value[0] == '\0')) {
569 value = "0";
570 } else
571 if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X'))
572 prefix = "0x";
573 fprintf(fp, "#define %s%s %s%s\n",
574 CONFIG_, sym->name, prefix, value);
575 break;
576 }
577 case S_INT:
578 if (!value || (value[0] == '\0')) {
579 value = "0";
580 }
581 /* fall through */
582 case S_STRING:
583 fprintf(fp, "#define %s%s %s\n",
584 CONFIG_, sym->name, value);
585 break;
586 default:
587 break;
588 }
589
590}
591
592static void
593header_print_comment(FILE *fp, const char *value, void *arg)
594{
595 const char *p = value;
596 size_t l;
597
598 fprintf(fp, "/*\n");
599 for (;;) {
600 l = strcspn(p, "\n");
601 fprintf(fp, " *");
602 if (l) {
603 fprintf(fp, " ");
604 xfwrite(p, l, 1, fp);
605 p += l;
606 }
607 fprintf(fp, "\n");
608 if (*p++ == '\0')
609 break;
610 }
611 fprintf(fp, " */\n");
612}
613
614static struct conf_printer header_printer_cb =
615{
616 .print_symbol = header_print_symbol,
617 .print_comment = header_print_comment,
618};
619
620/*
621 * Tristate printer
622 *
623 * This printer is used when generating the `include/config/tristate.conf' file.
624 */
625static void
626tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
627{
628
629 if (sym->type == S_TRISTATE && (*value != 'n' || arg == NULL))
630 fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value));
631}
632
633static struct conf_printer tristate_printer_cb =
634{
635 .print_symbol = tristate_print_symbol,
636 .print_comment = kconfig_print_comment,
637};
638
639static void conf_write_symbol(FILE *fp, struct symbol *sym,
640 struct conf_printer *printer, void *printer_arg)
641{
642 const char *str;
643
644 switch (sym->type) {
645 case S_OTHER:
646 case S_UNKNOWN:
647 break;
648 case S_STRING:
649 str = sym_get_string_value(sym);
650 str = sym_escape_string_value(str);
651 printer->print_symbol(fp, sym, str, printer_arg);
652 free((void *)str);
653 break;
654 default:
655 str = sym_get_string_value(sym);
656 printer->print_symbol(fp, sym, str, printer_arg);
657 }
658}
659
660static void
661conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg)
662{
663 char buf[256];
664
665 snprintf(buf, sizeof(buf),
666 "\n"
667 "Automatically generated file; DO NOT EDIT.\n"
668 "%s\n",
669 rootmenu.prompt->text);
670
671 printer->print_comment(fp, buf, printer_arg);
672}
673
674/*
675 * Write out a minimal config.
676 * All values that has default values are skipped as this is redundant.
677 */
678int conf_write_defconfig(const char *filename)
679{
680 struct symbol *sym;
681 struct menu *menu;
682 FILE *out;
683
684 out = fopen(filename, "w");
685 if (!out)
686 return 1;
687
688 sym_clear_all_valid();
689
690 /* Traverse all menus to find all relevant symbols */
691 menu = rootmenu.list;
692
693 while (menu != NULL)
694 {
695 sym = menu->sym;
696 if (sym == NULL) {
697 if (!menu_is_visible(menu))
698 goto next_menu;
699 } else if (!sym_is_choice(sym)) {
700 sym_calc_value(sym);
701 if (!(sym->flags & SYMBOL_WRITE))
702 goto next_menu;
703 sym->flags &= ~SYMBOL_WRITE;
704 /* If we cannot change the symbol - skip */
705 if (!sym_is_changable(sym))
706 goto next_menu;
707 /* If symbol equals to default value - skip */
708 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
709 goto next_menu;
710
711 /*
712 * If symbol is a choice value and equals to the
713 * default for a choice - skip.
714 * But only if value is bool and equal to "y" and
715 * choice is not "optional".
716 * (If choice is "optional" then all values can be "n")
717 */
718 if (sym_is_choice_value(sym)) {
719 struct symbol *cs;
720 struct symbol *ds;
721
722 cs = prop_get_symbol(sym_get_choice_prop(sym));
723 ds = sym_choice_default(cs);
724 if (!sym_is_optional(cs) && sym == ds) {
725 if ((sym->type == S_BOOLEAN) &&
726 sym_get_tristate_value(sym) == yes)
727 goto next_menu;
728 }
729 }
730 conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
731 }
732next_menu:
733 if (menu->list != NULL) {
734 menu = menu->list;
735 }
736 else if (menu->next != NULL) {
737 menu = menu->next;
738 } else {
739 while ((menu = menu->parent)) {
740 if (menu->next != NULL) {
741 menu = menu->next;
742 break;
743 }
744 }
745 }
746 }
747 fclose(out);
748 return 0;
749}
750
Patrick Georgi0588d192009-08-12 15:00:51 +0000751int conf_write(const char *name)
752{
753 FILE *out;
754 struct symbol *sym;
755 struct menu *menu;
756 const char *basename;
Patrick Georgi0588d192009-08-12 15:00:51 +0000757 const char *str;
Patrick Georgid5208402014-04-11 20:24:06 +0200758 char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
Patrick Georgi0588d192009-08-12 15:00:51 +0000759 char *env;
760
761 dirname[0] = 0;
762 if (name && name[0]) {
763 struct stat st;
764 char *slash;
765
766 if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
767 strcpy(dirname, name);
768 strcat(dirname, "/");
769 basename = conf_get_configname();
770 } else if ((slash = strrchr(name, '/'))) {
771 int size = slash - name + 1;
772 memcpy(dirname, name, size);
773 dirname[size] = 0;
774 if (slash[1])
775 basename = slash + 1;
776 else
777 basename = conf_get_configname();
778 } else
779 basename = name;
780 } else
781 basename = conf_get_configname();
782
783 sprintf(newname, "%s%s", dirname, basename);
784 env = getenv("KCONFIG_OVERWRITECONFIG");
785 if (!env || !*env) {
786 sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
787 out = fopen(tmpname, "w");
788 } else {
789 *tmpname = 0;
790 out = fopen(newname, "w");
791 }
792 if (!out)
793 return 1;
794
Patrick Georgid5208402014-04-11 20:24:06 +0200795 conf_write_heading(out, &kconfig_printer_cb, NULL);
Patrick Georgi0588d192009-08-12 15:00:51 +0000796
797 if (!conf_get_changed())
798 sym_clear_all_valid();
799
800 menu = rootmenu.list;
801 while (menu) {
802 sym = menu->sym;
803 if (!sym) {
804 if (!menu_is_visible(menu))
805 goto next;
806 str = menu_get_prompt(menu);
807 fprintf(out, "\n"
808 "#\n"
809 "# %s\n"
810 "#\n", str);
811 } else if (!(sym->flags & SYMBOL_CHOICE)) {
812 sym_calc_value(sym);
813 if (!(sym->flags & SYMBOL_WRITE))
814 goto next;
815 sym->flags &= ~SYMBOL_WRITE;
Patrick Georgid5208402014-04-11 20:24:06 +0200816
817 conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
Patrick Georgi0588d192009-08-12 15:00:51 +0000818 }
819
Patrick Georgid5208402014-04-11 20:24:06 +0200820next:
Patrick Georgi0588d192009-08-12 15:00:51 +0000821 if (menu->list) {
822 menu = menu->list;
823 continue;
824 }
825 if (menu->next)
826 menu = menu->next;
827 else while ((menu = menu->parent)) {
828 if (menu->next) {
829 menu = menu->next;
830 break;
831 }
832 }
833 }
834 fclose(out);
835
836 if (*tmpname) {
837 strcat(dirname, basename);
838 strcat(dirname, ".old");
839 rename(newname, dirname);
840 if (rename(tmpname, newname))
841 return 1;
842 }
843
Patrick Georgid5208402014-04-11 20:24:06 +0200844 conf_message(_("configuration written to %s"), newname);
Patrick Georgi0588d192009-08-12 15:00:51 +0000845
846 sym_set_change_count(0);
847
848 return 0;
849}
850
Patrick Georgid5208402014-04-11 20:24:06 +0200851static int conf_split_config(void)
Patrick Georgi0588d192009-08-12 15:00:51 +0000852{
Patrick Georgid5208402014-04-11 20:24:06 +0200853 const char *name;
854 char path[PATH_MAX+1];
855 char pwd[PATH_MAX+1];
Patrick Georgi0588d192009-08-12 15:00:51 +0000856 char *s, *d, c;
857 struct symbol *sym;
858 struct stat sb;
859 int res, i, fd;
860
Patrick Georgid5208402014-04-11 20:24:06 +0200861 name = conf_get_autoconfig_name();
Patrick Georgi0588d192009-08-12 15:00:51 +0000862 conf_read_simple(name, S_DEF_AUTO);
863
Patrick Georgid5208402014-04-11 20:24:06 +0200864 getcwd(pwd, sizeof(pwd));
865 name = getenv("KCONFIG_SPLITCONFIG");
866 if (!name)
867 name = "include/config";
868 if (chdir(name))
Patrick Georgi0588d192009-08-12 15:00:51 +0000869 return 1;
870
871 res = 0;
872 for_all_symbols(i, sym) {
873 sym_calc_value(sym);
874 if ((sym->flags & SYMBOL_AUTO) || !sym->name)
875 continue;
876 if (sym->flags & SYMBOL_WRITE) {
877 if (sym->flags & SYMBOL_DEF_AUTO) {
878 /*
879 * symbol has old and new value,
880 * so compare them...
881 */
882 switch (sym->type) {
883 case S_BOOLEAN:
884 case S_TRISTATE:
885 if (sym_get_tristate_value(sym) ==
886 sym->def[S_DEF_AUTO].tri)
887 continue;
888 break;
889 case S_STRING:
890 case S_HEX:
891 case S_INT:
892 if (!strcmp(sym_get_string_value(sym),
893 sym->def[S_DEF_AUTO].val))
894 continue;
895 break;
896 default:
897 break;
898 }
899 } else {
900 /*
901 * If there is no old value, only 'no' (unset)
902 * is allowed as new value.
903 */
904 switch (sym->type) {
905 case S_BOOLEAN:
906 case S_TRISTATE:
907 if (sym_get_tristate_value(sym) == no)
908 continue;
909 break;
910 default:
911 break;
912 }
913 }
914 } else if (!(sym->flags & SYMBOL_DEF_AUTO))
915 /* There is neither an old nor a new value. */
916 continue;
917 /* else
918 * There is an old value, but no new value ('no' (unset)
919 * isn't saved in auto.conf, so the old value is always
920 * different from 'no').
921 */
922
923 /* Replace all '_' and append ".h" */
924 s = sym->name;
925 d = path;
926 while ((c = *s++)) {
927 c = tolower(c);
928 *d++ = (c == '_') ? '/' : c;
929 }
930 strcpy(d, ".h");
931
932 /* Assume directory path already exists. */
933 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
934 if (fd == -1) {
935 if (errno != ENOENT) {
936 res = 1;
937 break;
938 }
939 /*
940 * Create directory components,
941 * unless they exist already.
942 */
943 d = path;
944 while ((d = strchr(d, '/'))) {
945 *d = 0;
946 if (stat(path, &sb) && mkdir(path, 0755)) {
947 res = 1;
948 goto out;
949 }
950 *d++ = '/';
951 }
952 /* Try it again. */
953 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
954 if (fd == -1) {
955 res = 1;
956 break;
957 }
958 }
959 close(fd);
960 }
961out:
Patrick Georgid5208402014-04-11 20:24:06 +0200962 if (chdir(pwd))
Patrick Georgi0588d192009-08-12 15:00:51 +0000963 return 1;
964
965 return res;
966}
967
968int conf_write_autoconf(void)
969{
970 struct symbol *sym;
Patrick Georgid5208402014-04-11 20:24:06 +0200971 const char *name;
972 FILE *out, *tristate, *out_h;
973 int i;
974 int print_negatives;
975
976 print_negatives = getenv("KCONFIG_NEGATIVES") != NULL;
Patrick Georgi0588d192009-08-12 15:00:51 +0000977
978 sym_clear_all_valid();
979
Patrick Georgid5208402014-04-11 20:24:06 +0200980 char *dep_file = getenv("KCONFIG_DEPENDENCIES");
981 if (!dep_file)
982 dep_file = "include/config/auto.conf.cmd";
983 file_write_dep(dep_file);
Vadim Bendeburyc302d202011-10-24 14:06:23 -0700984
Patrick Georgi0588d192009-08-12 15:00:51 +0000985 if (conf_split_config())
986 return 1;
Patrick Georgi0588d192009-08-12 15:00:51 +0000987
Patrick Georgi129462d2014-11-17 14:56:49 +0100988 char *tmpconfig_name = malloc(PATH_MAX);
989 if (getenv("COREBOOT_BUILD_DIR")) {
990 sprintf(tmpconfig_name, "%s/.tmpconfig.XXXXXX",
991 getenv("COREBOOT_BUILD_DIR"));
992 } else {
993 tmpconfig_name = strdup(".tmpconfig.XXXXXX");
994 }
Patrick Georgid5208402014-04-11 20:24:06 +0200995 if ((i = mkstemp(tmpconfig_name)) == -1)
996 return 1;
997 out = fdopen(i, "w");
Patrick Georgi0588d192009-08-12 15:00:51 +0000998 if (!out)
999 return 1;
1000
Patrick Georgi129462d2014-11-17 14:56:49 +01001001 char *tmpconfig_triname = malloc(PATH_MAX);
1002 if (getenv("COREBOOT_BUILD_DIR")) {
1003 sprintf(tmpconfig_triname, "%s/.tmpconfig_tristate.XXXXXX",
1004 getenv("COREBOOT_BUILD_DIR"));
1005 } else {
1006 tmpconfig_triname = strdup(".tmpconfig_tristate.XXXXXX");
1007 }
Patrick Georgid5208402014-04-11 20:24:06 +02001008 if ((i = mkstemp(tmpconfig_triname)) == -1)
1009 return 1;
1010 tristate = fdopen(i, "w");
1011 if (!tristate) {
Patrick Georgi0588d192009-08-12 15:00:51 +00001012 fclose(out);
1013 return 1;
1014 }
1015
Patrick Georgi129462d2014-11-17 14:56:49 +01001016 char *tmpconfig_h = malloc(PATH_MAX);
1017 if (getenv("COREBOOT_BUILD_DIR")) {
1018 sprintf(tmpconfig_h, "%s/.tmpconfig_tristate.XXXXXX",
1019 getenv("COREBOOT_BUILD_DIR"));
1020 } else {
1021 tmpconfig_h = strdup(".tmpconfig_tristate.XXXXXX");
1022 }
Patrick Georgid5208402014-04-11 20:24:06 +02001023 if ((i = mkstemp(tmpconfig_h)) == -1)
1024 return 1;
1025 out_h = fdopen(i, "w");
1026 if (!out_h) {
1027 fclose(out);
1028 fclose(tristate);
1029 return 1;
1030 }
1031
1032 conf_write_heading(out, &kconfig_printer_cb, NULL);
1033
1034 conf_write_heading(tristate, &tristate_printer_cb, NULL);
1035
1036 conf_write_heading(out_h, &header_printer_cb, NULL);
Patrick Georgi0588d192009-08-12 15:00:51 +00001037
1038 for_all_symbols(i, sym) {
1039 sym_calc_value(sym);
Stefan Reinauerebc93def2011-04-18 02:07:16 +00001040 if (!sym->name)
Patrick Georgi0588d192009-08-12 15:00:51 +00001041 continue;
Patrick Georgid5208402014-04-11 20:24:06 +02001042
1043 if (!(sym->flags & SYMBOL_WRITE) && !print_negatives)
Stefan Reinauerebc93def2011-04-18 02:07:16 +00001044 continue;
Patrick Georgid5208402014-04-11 20:24:06 +02001045
1046 /* these are safe to write out, so do it all the time */
1047 if (!(sym->flags & SYMBOL_WRITE) &&
1048 !(sym->type == S_BOOLEAN ||
1049 sym->type == S_HEX ||
1050 sym->type == S_INT))
1051 continue;
1052
1053 /* write symbol to auto.conf, tristate and header files */
1054 conf_write_symbol(out, sym, &kconfig_printer_cb, print_negatives?NULL:(void *)1);
1055
1056 conf_write_symbol(tristate, sym, &tristate_printer_cb, print_negatives?NULL:(void *)1);
1057
1058 conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
Patrick Georgi0588d192009-08-12 15:00:51 +00001059 }
1060 fclose(out);
Patrick Georgid5208402014-04-11 20:24:06 +02001061 fclose(tristate);
Patrick Georgi0588d192009-08-12 15:00:51 +00001062 fclose(out_h);
1063
Patrick Georgid5208402014-04-11 20:24:06 +02001064 name = getenv("KCONFIG_AUTOHEADER");
Patrick Georgi0588d192009-08-12 15:00:51 +00001065 if (!name)
Patrick Georgid5208402014-04-11 20:24:06 +02001066 name = "include/generated/autoconf.h";
1067 if (rename(tmpconfig_h, name))
1068 return 1;
1069 name = getenv("KCONFIG_TRISTATE");
1070 if (!name)
1071 name = "include/config/tristate.conf";
1072 if (rename(tmpconfig_triname, name))
1073 return 1;
1074 name = conf_get_autoconfig_name();
Patrick Georgi0588d192009-08-12 15:00:51 +00001075 /*
1076 * This must be the last step, kbuild has a dependency on auto.conf
1077 * and this marks the successful completion of the previous steps.
1078 */
Patrick Georgid5208402014-04-11 20:24:06 +02001079 if (rename(tmpconfig_name, name))
Patrick Georgi0588d192009-08-12 15:00:51 +00001080 return 1;
1081
Patrick Georgi0588d192009-08-12 15:00:51 +00001082 return 0;
1083}
1084
1085static int sym_change_count;
1086static void (*conf_changed_callback)(void);
1087
1088void sym_set_change_count(int count)
1089{
1090 int _sym_change_count = sym_change_count;
1091 sym_change_count = count;
1092 if (conf_changed_callback &&
1093 (bool)_sym_change_count != (bool)count)
1094 conf_changed_callback();
1095}
1096
1097void sym_add_change_count(int count)
1098{
1099 sym_set_change_count(count + sym_change_count);
1100}
1101
1102bool conf_get_changed(void)
1103{
1104 return sym_change_count;
1105}
1106
1107void conf_set_changed_callback(void (*fn)(void))
1108{
1109 conf_changed_callback = fn;
1110}
Patrick Georgid5208402014-04-11 20:24:06 +02001111
1112static bool randomize_choice_values(struct symbol *csym)
1113{
1114 struct property *prop;
1115 struct symbol *sym;
1116 struct expr *e;
1117 int cnt, def;
1118
1119 /*
1120 * If choice is mod then we may have more items selected
1121 * and if no then no-one.
1122 * In both cases stop.
1123 */
1124 if (csym->curr.tri != yes)
1125 return false;
1126
1127 prop = sym_get_choice_prop(csym);
1128
1129 /* count entries in choice block */
1130 cnt = 0;
1131 expr_list_for_each_sym(prop->expr, e, sym)
1132 cnt++;
1133
1134 /*
1135 * find a random value and set it to yes,
1136 * set the rest to no so we have only one set
1137 */
1138 def = (rand() % cnt);
1139
1140 cnt = 0;
1141 expr_list_for_each_sym(prop->expr, e, sym) {
1142 if (def == cnt++) {
1143 sym->def[S_DEF_USER].tri = yes;
1144 csym->def[S_DEF_USER].val = sym;
1145 }
1146 else {
1147 sym->def[S_DEF_USER].tri = no;
1148 }
1149 sym->flags |= SYMBOL_DEF_USER;
1150 /* clear VALID to get value calculated */
1151 sym->flags &= ~SYMBOL_VALID;
1152 }
1153 csym->flags |= SYMBOL_DEF_USER;
1154 /* clear VALID to get value calculated */
1155 csym->flags &= ~(SYMBOL_VALID);
1156
1157 return true;
1158}
1159
1160void set_all_choice_values(struct symbol *csym)
1161{
1162 struct property *prop;
1163 struct symbol *sym;
1164 struct expr *e;
1165
1166 prop = sym_get_choice_prop(csym);
1167
1168 /*
1169 * Set all non-assinged choice values to no
1170 */
1171 expr_list_for_each_sym(prop->expr, e, sym) {
1172 if (!sym_has_value(sym))
1173 sym->def[S_DEF_USER].tri = no;
1174 }
1175 csym->flags |= SYMBOL_DEF_USER;
1176 /* clear VALID to get value calculated */
1177 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
1178}
1179
1180bool conf_set_all_new_symbols(enum conf_def_mode mode)
1181{
1182 struct symbol *sym, *csym;
1183 int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
1184 * pty: probability of tristate = y
1185 * ptm: probability of tristate = m
1186 */
1187
1188 pby = 50; pty = ptm = 33; /* can't go as the default in switch-case
1189 * below, otherwise gcc whines about
1190 * -Wmaybe-uninitialized */
1191 if (mode == def_random) {
1192 int n, p[3];
1193 char *env = getenv("KCONFIG_PROBABILITY");
1194 n = 0;
1195 while( env && *env ) {
1196 char *endp;
1197 int tmp = strtol( env, &endp, 10 );
1198 if( tmp >= 0 && tmp <= 100 ) {
1199 p[n++] = tmp;
1200 } else {
1201 errno = ERANGE;
1202 perror( "KCONFIG_PROBABILITY" );
1203 exit( 1 );
1204 }
1205 env = (*endp == ':') ? endp+1 : endp;
1206 if( n >=3 ) {
1207 break;
1208 }
1209 }
1210 switch( n ) {
1211 case 1:
1212 pby = p[0]; ptm = pby/2; pty = pby-ptm;
1213 break;
1214 case 2:
1215 pty = p[0]; ptm = p[1]; pby = pty + ptm;
1216 break;
1217 case 3:
1218 pby = p[0]; pty = p[1]; ptm = p[2];
1219 break;
1220 }
1221
1222 if( pty+ptm > 100 ) {
1223 errno = ERANGE;
1224 perror( "KCONFIG_PROBABILITY" );
1225 exit( 1 );
1226 }
1227 }
1228 bool has_changed = false;
1229
1230 for_all_symbols(i, sym) {
1231 if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
1232 continue;
1233 switch (sym_get_type(sym)) {
1234 case S_BOOLEAN:
1235 case S_TRISTATE:
1236 has_changed = true;
1237 switch (mode) {
1238 case def_yes:
1239 sym->def[S_DEF_USER].tri = yes;
1240 break;
1241 case def_mod:
1242 sym->def[S_DEF_USER].tri = mod;
1243 break;
1244 case def_no:
1245 if (sym->flags & SYMBOL_ALLNOCONFIG_Y)
1246 sym->def[S_DEF_USER].tri = yes;
1247 else
1248 sym->def[S_DEF_USER].tri = no;
1249 break;
1250 case def_random:
1251 sym->def[S_DEF_USER].tri = no;
1252 cnt = rand() % 100;
1253 if (sym->type == S_TRISTATE) {
1254 if (cnt < pty)
1255 sym->def[S_DEF_USER].tri = yes;
1256 else if (cnt < (pty+ptm))
1257 sym->def[S_DEF_USER].tri = mod;
1258 } else if (cnt < pby)
1259 sym->def[S_DEF_USER].tri = yes;
1260 break;
1261 default:
1262 continue;
1263 }
1264 if (!(sym_is_choice(sym) && mode == def_random))
1265 sym->flags |= SYMBOL_DEF_USER;
1266 break;
1267 default:
1268 break;
1269 }
1270
1271 }
1272
1273 sym_clear_all_valid();
1274
1275 /*
1276 * We have different type of choice blocks.
1277 * If curr.tri equals to mod then we can select several
1278 * choice symbols in one block.
1279 * In this case we do nothing.
1280 * If curr.tri equals yes then only one symbol can be
1281 * selected in a choice block and we set it to yes,
1282 * and the rest to no.
1283 */
1284 if (mode != def_random) {
1285 for_all_symbols(i, csym) {
1286 if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
1287 sym_is_choice_value(csym))
1288 csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
1289 }
1290 }
1291
1292 for_all_symbols(i, csym) {
1293 if (sym_has_value(csym) || !sym_is_choice(csym))
1294 continue;
1295
1296 sym_calc_value(csym);
1297 if (mode == def_random)
1298 has_changed = randomize_choice_values(csym);
1299 else {
1300 set_all_choice_values(csym);
1301 has_changed = true;
1302 }
1303 }
1304
1305 return has_changed;
1306}