diff options
Diffstat (limited to 'scripts/kconfig/confdata.c')
-rw-r--r-- | scripts/kconfig/confdata.c | 447 |
1 files changed, 286 insertions, 161 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c4dec80cfd8..61c35bf2d9c 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <sys/stat.h> | 6 | #include <sys/stat.h> |
7 | #include <ctype.h> | 7 | #include <ctype.h> |
8 | #include <errno.h> | ||
8 | #include <fcntl.h> | 9 | #include <fcntl.h> |
9 | #include <stdio.h> | 10 | #include <stdio.h> |
10 | #include <stdlib.h> | 11 | #include <stdlib.h> |
@@ -18,6 +19,9 @@ | |||
18 | static void conf_warning(const char *fmt, ...) | 19 | static void conf_warning(const char *fmt, ...) |
19 | __attribute__ ((format (printf, 1, 2))); | 20 | __attribute__ ((format (printf, 1, 2))); |
20 | 21 | ||
22 | static void conf_message(const char *fmt, ...) | ||
23 | __attribute__ ((format (printf, 1, 2))); | ||
24 | |||
21 | static const char *conf_filename; | 25 | static const char *conf_filename; |
22 | static int conf_lineno, conf_warnings, conf_unsaved; | 26 | static int conf_lineno, conf_warnings, conf_unsaved; |
23 | 27 | ||
@@ -34,6 +38,29 @@ static void conf_warning(const char *fmt, ...) | |||
34 | conf_warnings++; | 38 | conf_warnings++; |
35 | } | 39 | } |
36 | 40 | ||
41 | static 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 | |||
48 | static void (*conf_message_callback) (const char *fmt, va_list ap) = | ||
49 | conf_default_message_callback; | ||
50 | void conf_set_message_callback(void (*fn) (const char *fmt, va_list ap)) | ||
51 | { | ||
52 | conf_message_callback = fn; | ||
53 | } | ||
54 | |||
55 | static 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); | ||
62 | } | ||
63 | |||
37 | const char *conf_get_configname(void) | 64 | const char *conf_get_configname(void) |
38 | { | 65 | { |
39 | char *name = getenv("KCONFIG_CONFIG"); | 66 | char *name = getenv("KCONFIG_CONFIG"); |
@@ -170,8 +197,11 @@ int conf_read_simple(const char *name, int def) | |||
170 | if (in) | 197 | if (in) |
171 | goto load; | 198 | goto load; |
172 | sym_add_change_count(1); | 199 | sym_add_change_count(1); |
173 | if (!sym_defconfig_list) | 200 | if (!sym_defconfig_list) { |
201 | if (modules_sym) | ||
202 | sym_calc_value(modules_sym); | ||
174 | return 1; | 203 | return 1; |
204 | } | ||
175 | 205 | ||
176 | for_all_defaults(sym_defconfig_list, prop) { | 206 | for_all_defaults(sym_defconfig_list, prop) { |
177 | if (expr_calc_value(prop->visible.expr) == no || | 207 | if (expr_calc_value(prop->visible.expr) == no || |
@@ -180,9 +210,8 @@ int conf_read_simple(const char *name, int def) | |||
180 | name = conf_expand_value(prop->expr->left.sym->name); | 210 | name = conf_expand_value(prop->expr->left.sym->name); |
181 | in = zconf_fopen(name); | 211 | in = zconf_fopen(name); |
182 | if (in) { | 212 | if (in) { |
183 | printf(_("#\n" | 213 | conf_message(_("using defaults found in %s"), |
184 | "# using defaults found in %s\n" | 214 | name); |
185 | "#\n"), name); | ||
186 | goto load; | 215 | goto load; |
187 | } | 216 | } |
188 | } | 217 | } |
@@ -217,24 +246,23 @@ load: | |||
217 | while (fgets(line, sizeof(line), in)) { | 246 | while (fgets(line, sizeof(line), in)) { |
218 | conf_lineno++; | 247 | conf_lineno++; |
219 | sym = NULL; | 248 | sym = NULL; |
220 | switch (line[0]) { | 249 | if (line[0] == '#') { |
221 | case '#': | 250 | if (memcmp(line + 2, CONFIG_, strlen(CONFIG_))) |
222 | if (memcmp(line + 2, "CONFIG_", 7)) | ||
223 | continue; | 251 | continue; |
224 | p = strchr(line + 9, ' '); | 252 | p = strchr(line + 2 + strlen(CONFIG_), ' '); |
225 | if (!p) | 253 | if (!p) |
226 | continue; | 254 | continue; |
227 | *p++ = 0; | 255 | *p++ = 0; |
228 | if (strncmp(p, "is not set", 10)) | 256 | if (strncmp(p, "is not set", 10)) |
229 | continue; | 257 | continue; |
230 | if (def == S_DEF_USER) { | 258 | if (def == S_DEF_USER) { |
231 | sym = sym_find(line + 9); | 259 | sym = sym_find(line + 2 + strlen(CONFIG_)); |
232 | if (!sym) { | 260 | if (!sym) { |
233 | sym_add_change_count(1); | 261 | sym_add_change_count(1); |
234 | break; | 262 | goto setsym; |
235 | } | 263 | } |
236 | } else { | 264 | } else { |
237 | sym = sym_lookup(line + 9, 0); | 265 | sym = sym_lookup(line + 2 + strlen(CONFIG_), 0); |
238 | if (sym->type == S_UNKNOWN) | 266 | if (sym->type == S_UNKNOWN) |
239 | sym->type = S_BOOLEAN; | 267 | sym->type = S_BOOLEAN; |
240 | } | 268 | } |
@@ -250,13 +278,8 @@ load: | |||
250 | default: | 278 | default: |
251 | ; | 279 | ; |
252 | } | 280 | } |
253 | break; | 281 | } else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) { |
254 | case 'C': | 282 | p = strchr(line + strlen(CONFIG_), '='); |
255 | if (memcmp(line, "CONFIG_", 7)) { | ||
256 | conf_warning("unexpected data"); | ||
257 | continue; | ||
258 | } | ||
259 | p = strchr(line + 7, '='); | ||
260 | if (!p) | 283 | if (!p) |
261 | continue; | 284 | continue; |
262 | *p++ = 0; | 285 | *p++ = 0; |
@@ -267,13 +290,13 @@ load: | |||
267 | *p2 = 0; | 290 | *p2 = 0; |
268 | } | 291 | } |
269 | if (def == S_DEF_USER) { | 292 | if (def == S_DEF_USER) { |
270 | sym = sym_find(line + 7); | 293 | sym = sym_find(line + strlen(CONFIG_)); |
271 | if (!sym) { | 294 | if (!sym) { |
272 | sym_add_change_count(1); | 295 | sym_add_change_count(1); |
273 | break; | 296 | goto setsym; |
274 | } | 297 | } |
275 | } else { | 298 | } else { |
276 | sym = sym_lookup(line + 7, 0); | 299 | sym = sym_lookup(line + strlen(CONFIG_), 0); |
277 | if (sym->type == S_UNKNOWN) | 300 | if (sym->type == S_UNKNOWN) |
278 | sym->type = S_OTHER; | 301 | sym->type = S_OTHER; |
279 | } | 302 | } |
@@ -282,14 +305,12 @@ load: | |||
282 | } | 305 | } |
283 | if (conf_set_sym_val(sym, def, def_flags, p)) | 306 | if (conf_set_sym_val(sym, def, def_flags, p)) |
284 | continue; | 307 | continue; |
285 | break; | 308 | } else { |
286 | case '\r': | 309 | if (line[0] != '\r' && line[0] != '\n') |
287 | case '\n': | 310 | conf_warning("unexpected data"); |
288 | break; | ||
289 | default: | ||
290 | conf_warning("unexpected data"); | ||
291 | continue; | 311 | continue; |
292 | } | 312 | } |
313 | setsym: | ||
293 | if (sym && sym_is_choice_value(sym)) { | 314 | if (sym && sym_is_choice_value(sym)) { |
294 | struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); | 315 | struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); |
295 | switch (sym->def[def].tri) { | 316 | switch (sym->def[def].tri) { |
@@ -396,15 +417,149 @@ int conf_read(const char *name) | |||
396 | return 0; | 417 | return 0; |
397 | } | 418 | } |
398 | 419 | ||
420 | /* Write a S_STRING */ | ||
421 | static void conf_write_string(bool headerfile, const char *name, | ||
422 | const char *str, FILE *out) | ||
423 | { | ||
424 | int l; | ||
425 | if (headerfile) | ||
426 | fprintf(out, "#define %s%s \"", CONFIG_, name); | ||
427 | else | ||
428 | fprintf(out, "%s%s=\"", CONFIG_, name); | ||
429 | |||
430 | while (1) { | ||
431 | l = strcspn(str, "\"\\"); | ||
432 | if (l) { | ||
433 | xfwrite(str, l, 1, out); | ||
434 | str += l; | ||
435 | } | ||
436 | if (!*str) | ||
437 | break; | ||
438 | fprintf(out, "\\%c", *str++); | ||
439 | } | ||
440 | fputs("\"\n", out); | ||
441 | } | ||
442 | |||
443 | static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no) | ||
444 | { | ||
445 | const char *str; | ||
446 | |||
447 | switch (sym->type) { | ||
448 | case S_BOOLEAN: | ||
449 | case S_TRISTATE: | ||
450 | switch (sym_get_tristate_value(sym)) { | ||
451 | case no: | ||
452 | if (write_no) | ||
453 | fprintf(out, "# %s%s is not set\n", | ||
454 | CONFIG_, sym->name); | ||
455 | break; | ||
456 | case mod: | ||
457 | fprintf(out, "%s%s=m\n", CONFIG_, sym->name); | ||
458 | break; | ||
459 | case yes: | ||
460 | fprintf(out, "%s%s=y\n", CONFIG_, sym->name); | ||
461 | break; | ||
462 | } | ||
463 | break; | ||
464 | case S_STRING: | ||
465 | conf_write_string(false, sym->name, sym_get_string_value(sym), out); | ||
466 | break; | ||
467 | case S_HEX: | ||
468 | case S_INT: | ||
469 | str = sym_get_string_value(sym); | ||
470 | fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str); | ||
471 | break; | ||
472 | case S_OTHER: | ||
473 | case S_UNKNOWN: | ||
474 | break; | ||
475 | } | ||
476 | } | ||
477 | |||
478 | /* | ||
479 | * Write out a minimal config. | ||
480 | * All values that has default values are skipped as this is redundant. | ||
481 | */ | ||
482 | int conf_write_defconfig(const char *filename) | ||
483 | { | ||
484 | struct symbol *sym; | ||
485 | struct menu *menu; | ||
486 | FILE *out; | ||
487 | |||
488 | out = fopen(filename, "w"); | ||
489 | if (!out) | ||
490 | return 1; | ||
491 | |||
492 | sym_clear_all_valid(); | ||
493 | |||
494 | /* Traverse all menus to find all relevant symbols */ | ||
495 | menu = rootmenu.list; | ||
496 | |||
497 | while (menu != NULL) | ||
498 | { | ||
499 | sym = menu->sym; | ||
500 | if (sym == NULL) { | ||
501 | if (!menu_is_visible(menu)) | ||
502 | goto next_menu; | ||
503 | } else if (!sym_is_choice(sym)) { | ||
504 | sym_calc_value(sym); | ||
505 | if (!(sym->flags & SYMBOL_WRITE)) | ||
506 | goto next_menu; | ||
507 | sym->flags &= ~SYMBOL_WRITE; | ||
508 | /* If we cannot change the symbol - skip */ | ||
509 | if (!sym_is_changable(sym)) | ||
510 | goto next_menu; | ||
511 | /* If symbol equals to default value - skip */ | ||
512 | if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) | ||
513 | goto next_menu; | ||
514 | |||
515 | /* | ||
516 | * If symbol is a choice value and equals to the | ||
517 | * default for a choice - skip. | ||
518 | * But only if value is bool and equal to "y" and | ||
519 | * choice is not "optional". | ||
520 | * (If choice is "optional" then all values can be "n") | ||
521 | */ | ||
522 | if (sym_is_choice_value(sym)) { | ||
523 | struct symbol *cs; | ||
524 | struct symbol *ds; | ||
525 | |||
526 | cs = prop_get_symbol(sym_get_choice_prop(sym)); | ||
527 | ds = sym_choice_default(cs); | ||
528 | if (!sym_is_optional(cs) && sym == ds) { | ||
529 | if ((sym->type == S_BOOLEAN) && | ||
530 | sym_get_tristate_value(sym) == yes) | ||
531 | goto next_menu; | ||
532 | } | ||
533 | } | ||
534 | conf_write_symbol(sym, out, true); | ||
535 | } | ||
536 | next_menu: | ||
537 | if (menu->list != NULL) { | ||
538 | menu = menu->list; | ||
539 | } | ||
540 | else if (menu->next != NULL) { | ||
541 | menu = menu->next; | ||
542 | } else { | ||
543 | while ((menu = menu->parent)) { | ||
544 | if (menu->next != NULL) { | ||
545 | menu = menu->next; | ||
546 | break; | ||
547 | } | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | fclose(out); | ||
552 | return 0; | ||
553 | } | ||
554 | |||
399 | int conf_write(const char *name) | 555 | int conf_write(const char *name) |
400 | { | 556 | { |
401 | FILE *out; | 557 | FILE *out; |
402 | struct symbol *sym; | 558 | struct symbol *sym; |
403 | struct menu *menu; | 559 | struct menu *menu; |
404 | const char *basename; | 560 | const char *basename; |
405 | char dirname[128], tmpname[128], newname[128]; | ||
406 | int type, l; | ||
407 | const char *str; | 561 | const char *str; |
562 | char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; | ||
408 | time_t now; | 563 | time_t now; |
409 | int use_timestamp = 1; | 564 | int use_timestamp = 1; |
410 | char *env; | 565 | char *env; |
@@ -443,8 +598,6 @@ int conf_write(const char *name) | |||
443 | if (!out) | 598 | if (!out) |
444 | return 1; | 599 | return 1; |
445 | 600 | ||
446 | sym = sym_lookup("KERNELVERSION", 0); | ||
447 | sym_calc_value(sym); | ||
448 | time(&now); | 601 | time(&now); |
449 | env = getenv("KCONFIG_NOTIMESTAMP"); | 602 | env = getenv("KCONFIG_NOTIMESTAMP"); |
450 | if (env && *env) | 603 | if (env && *env) |
@@ -452,10 +605,10 @@ int conf_write(const char *name) | |||
452 | 605 | ||
453 | fprintf(out, _("#\n" | 606 | fprintf(out, _("#\n" |
454 | "# Automatically generated make config: don't edit\n" | 607 | "# Automatically generated make config: don't edit\n" |
455 | "# Linux kernel version: %s\n" | 608 | "# %s\n" |
456 | "%s%s" | 609 | "%s%s" |
457 | "#\n"), | 610 | "#\n"), |
458 | sym_get_string_value(sym), | 611 | rootmenu.prompt->text, |
459 | use_timestamp ? "# " : "", | 612 | use_timestamp ? "# " : "", |
460 | use_timestamp ? ctime(&now) : ""); | 613 | use_timestamp ? ctime(&now) : ""); |
461 | 614 | ||
@@ -478,56 +631,11 @@ int conf_write(const char *name) | |||
478 | if (!(sym->flags & SYMBOL_WRITE)) | 631 | if (!(sym->flags & SYMBOL_WRITE)) |
479 | goto next; | 632 | goto next; |
480 | sym->flags &= ~SYMBOL_WRITE; | 633 | sym->flags &= ~SYMBOL_WRITE; |
481 | type = sym->type; | 634 | /* Write config symbol to file */ |
482 | if (type == S_TRISTATE) { | 635 | conf_write_symbol(sym, out, true); |
483 | sym_calc_value(modules_sym); | ||
484 | if (modules_sym->curr.tri == no) | ||
485 | type = S_BOOLEAN; | ||
486 | } | ||
487 | switch (type) { | ||
488 | case S_BOOLEAN: | ||
489 | case S_TRISTATE: | ||
490 | switch (sym_get_tristate_value(sym)) { | ||
491 | case no: | ||
492 | fprintf(out, "# CONFIG_%s is not set\n", sym->name); | ||
493 | break; | ||
494 | case mod: | ||
495 | fprintf(out, "CONFIG_%s=m\n", sym->name); | ||
496 | break; | ||
497 | case yes: | ||
498 | fprintf(out, "CONFIG_%s=y\n", sym->name); | ||
499 | break; | ||
500 | } | ||
501 | break; | ||
502 | case S_STRING: | ||
503 | str = sym_get_string_value(sym); | ||
504 | fprintf(out, "CONFIG_%s=\"", sym->name); | ||
505 | while (1) { | ||
506 | l = strcspn(str, "\"\\"); | ||
507 | if (l) { | ||
508 | fwrite(str, l, 1, out); | ||
509 | str += l; | ||
510 | } | ||
511 | if (!*str) | ||
512 | break; | ||
513 | fprintf(out, "\\%c", *str++); | ||
514 | } | ||
515 | fputs("\"\n", out); | ||
516 | break; | ||
517 | case S_HEX: | ||
518 | str = sym_get_string_value(sym); | ||
519 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { | ||
520 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
521 | break; | ||
522 | } | ||
523 | case S_INT: | ||
524 | str = sym_get_string_value(sym); | ||
525 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | ||
526 | break; | ||
527 | } | ||
528 | } | 636 | } |
529 | 637 | ||
530 | next: | 638 | next: |
531 | if (menu->list) { | 639 | if (menu->list) { |
532 | menu = menu->list; | 640 | menu = menu->list; |
533 | continue; | 641 | continue; |
@@ -551,9 +659,7 @@ int conf_write(const char *name) | |||
551 | return 1; | 659 | return 1; |
552 | } | 660 | } |
553 | 661 | ||
554 | printf(_("#\n" | 662 | conf_message(_("configuration written to %s"), newname); |
555 | "# configuration written to %s\n" | ||
556 | "#\n"), newname); | ||
557 | 663 | ||
558 | sym_set_change_count(0); | 664 | sym_set_change_count(0); |
559 | 665 | ||
@@ -563,7 +669,7 @@ int conf_write(const char *name) | |||
563 | static int conf_split_config(void) | 669 | static int conf_split_config(void) |
564 | { | 670 | { |
565 | const char *name; | 671 | const char *name; |
566 | char path[128]; | 672 | char path[PATH_MAX+1]; |
567 | char *s, *d, c; | 673 | char *s, *d, c; |
568 | struct symbol *sym; | 674 | struct symbol *sym; |
569 | struct stat sb; | 675 | struct stat sb; |
@@ -679,7 +785,7 @@ int conf_write_autoconf(void) | |||
679 | const char *name; | 785 | const char *name; |
680 | FILE *out, *tristate, *out_h; | 786 | FILE *out, *tristate, *out_h; |
681 | time_t now; | 787 | time_t now; |
682 | int i, l; | 788 | int i; |
683 | 789 | ||
684 | sym_clear_all_valid(); | 790 | sym_clear_all_valid(); |
685 | 791 | ||
@@ -705,30 +811,32 @@ int conf_write_autoconf(void) | |||
705 | return 1; | 811 | return 1; |
706 | } | 812 | } |
707 | 813 | ||
708 | sym = sym_lookup("KERNELVERSION", 0); | ||
709 | sym_calc_value(sym); | ||
710 | time(&now); | 814 | time(&now); |
711 | fprintf(out, "#\n" | 815 | fprintf(out, "#\n" |
712 | "# Automatically generated make config: don't edit\n" | 816 | "# Automatically generated make config: don't edit\n" |
713 | "# Linux kernel version: %s\n" | 817 | "# %s\n" |
714 | "# %s" | 818 | "# %s" |
715 | "#\n", | 819 | "#\n", |
716 | sym_get_string_value(sym), ctime(&now)); | 820 | rootmenu.prompt->text, ctime(&now)); |
717 | fprintf(tristate, "#\n" | 821 | fprintf(tristate, "#\n" |
718 | "# Automatically generated - do not edit\n" | 822 | "# Automatically generated - do not edit\n" |
719 | "\n"); | 823 | "\n"); |
720 | fprintf(out_h, "/*\n" | 824 | fprintf(out_h, "/*\n" |
721 | " * Automatically generated C config: don't edit\n" | 825 | " * Automatically generated C config: don't edit\n" |
722 | " * Linux kernel version: %s\n" | 826 | " * %s\n" |
723 | " * %s" | 827 | " * %s" |
724 | " */\n" | 828 | " */\n", |
725 | "#define AUTOCONF_INCLUDED\n", | 829 | rootmenu.prompt->text, ctime(&now)); |
726 | sym_get_string_value(sym), ctime(&now)); | ||
727 | 830 | ||
728 | for_all_symbols(i, sym) { | 831 | for_all_symbols(i, sym) { |
729 | sym_calc_value(sym); | 832 | sym_calc_value(sym); |
730 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) | 833 | if (!(sym->flags & SYMBOL_WRITE) || !sym->name) |
731 | continue; | 834 | continue; |
835 | |||
836 | /* write symbol to config file */ | ||
837 | conf_write_symbol(sym, out, false); | ||
838 | |||
839 | /* update autoconf and tristate files */ | ||
732 | switch (sym->type) { | 840 | switch (sym->type) { |
733 | case S_BOOLEAN: | 841 | case S_BOOLEAN: |
734 | case S_TRISTATE: | 842 | case S_TRISTATE: |
@@ -736,50 +844,34 @@ int conf_write_autoconf(void) | |||
736 | case no: | 844 | case no: |
737 | break; | 845 | break; |
738 | case mod: | 846 | case mod: |
739 | fprintf(out, "CONFIG_%s=m\n", sym->name); | 847 | fprintf(tristate, "%s%s=M\n", |
740 | fprintf(tristate, "CONFIG_%s=M\n", sym->name); | 848 | CONFIG_, sym->name); |
741 | fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); | 849 | fprintf(out_h, "#define %s%s_MODULE 1\n", |
850 | CONFIG_, sym->name); | ||
742 | break; | 851 | break; |
743 | case yes: | 852 | case yes: |
744 | fprintf(out, "CONFIG_%s=y\n", sym->name); | ||
745 | if (sym->type == S_TRISTATE) | 853 | if (sym->type == S_TRISTATE) |
746 | fprintf(tristate, "CONFIG_%s=Y\n", | 854 | fprintf(tristate,"%s%s=Y\n", |
747 | sym->name); | 855 | CONFIG_, sym->name); |
748 | fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); | 856 | fprintf(out_h, "#define %s%s 1\n", |
857 | CONFIG_, sym->name); | ||
749 | break; | 858 | break; |
750 | } | 859 | } |
751 | break; | 860 | break; |
752 | case S_STRING: | 861 | case S_STRING: |
753 | str = sym_get_string_value(sym); | 862 | conf_write_string(true, sym->name, sym_get_string_value(sym), out_h); |
754 | fprintf(out, "CONFIG_%s=\"", sym->name); | ||
755 | fprintf(out_h, "#define CONFIG_%s \"", sym->name); | ||
756 | while (1) { | ||
757 | l = strcspn(str, "\"\\"); | ||
758 | if (l) { | ||
759 | fwrite(str, l, 1, out); | ||
760 | fwrite(str, l, 1, out_h); | ||
761 | str += l; | ||
762 | } | ||
763 | if (!*str) | ||
764 | break; | ||
765 | fprintf(out, "\\%c", *str); | ||
766 | fprintf(out_h, "\\%c", *str); | ||
767 | str++; | ||
768 | } | ||
769 | fputs("\"\n", out); | ||
770 | fputs("\"\n", out_h); | ||
771 | break; | 863 | break; |
772 | case S_HEX: | 864 | case S_HEX: |
773 | str = sym_get_string_value(sym); | 865 | str = sym_get_string_value(sym); |
774 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { | 866 | if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { |
775 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | 867 | fprintf(out_h, "#define %s%s 0x%s\n", |
776 | fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); | 868 | CONFIG_, sym->name, str); |
777 | break; | 869 | break; |
778 | } | 870 | } |
779 | case S_INT: | 871 | case S_INT: |
780 | str = sym_get_string_value(sym); | 872 | str = sym_get_string_value(sym); |
781 | fprintf(out, "CONFIG_%s=%s\n", sym->name, str); | 873 | fprintf(out_h, "#define %s%s %s\n", |
782 | fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); | 874 | CONFIG_, sym->name, str); |
783 | break; | 875 | break; |
784 | default: | 876 | default: |
785 | break; | 877 | break; |
@@ -837,13 +929,73 @@ void conf_set_changed_callback(void (*fn)(void)) | |||
837 | conf_changed_callback = fn; | 929 | conf_changed_callback = fn; |
838 | } | 930 | } |
839 | 931 | ||
932 | static void randomize_choice_values(struct symbol *csym) | ||
933 | { | ||
934 | struct property *prop; | ||
935 | struct symbol *sym; | ||
936 | struct expr *e; | ||
937 | int cnt, def; | ||
938 | |||
939 | /* | ||
940 | * If choice is mod then we may have more items selected | ||
941 | * and if no then no-one. | ||
942 | * In both cases stop. | ||
943 | */ | ||
944 | if (csym->curr.tri != yes) | ||
945 | return; | ||
946 | |||
947 | prop = sym_get_choice_prop(csym); | ||
948 | |||
949 | /* count entries in choice block */ | ||
950 | cnt = 0; | ||
951 | expr_list_for_each_sym(prop->expr, e, sym) | ||
952 | cnt++; | ||
953 | |||
954 | /* | ||
955 | * find a random value and set it to yes, | ||
956 | * set the rest to no so we have only one set | ||
957 | */ | ||
958 | def = (rand() % cnt); | ||
959 | |||
960 | cnt = 0; | ||
961 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
962 | if (def == cnt++) { | ||
963 | sym->def[S_DEF_USER].tri = yes; | ||
964 | csym->def[S_DEF_USER].val = sym; | ||
965 | } | ||
966 | else { | ||
967 | sym->def[S_DEF_USER].tri = no; | ||
968 | } | ||
969 | } | ||
970 | csym->flags |= SYMBOL_DEF_USER; | ||
971 | /* clear VALID to get value calculated */ | ||
972 | csym->flags &= ~(SYMBOL_VALID); | ||
973 | } | ||
974 | |||
975 | static void set_all_choice_values(struct symbol *csym) | ||
976 | { | ||
977 | struct property *prop; | ||
978 | struct symbol *sym; | ||
979 | struct expr *e; | ||
980 | |||
981 | prop = sym_get_choice_prop(csym); | ||
982 | |||
983 | /* | ||
984 | * Set all non-assinged choice values to no | ||
985 | */ | ||
986 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
987 | if (!sym_has_value(sym)) | ||
988 | sym->def[S_DEF_USER].tri = no; | ||
989 | } | ||
990 | csym->flags |= SYMBOL_DEF_USER; | ||
991 | /* clear VALID to get value calculated */ | ||
992 | csym->flags &= ~(SYMBOL_VALID); | ||
993 | } | ||
840 | 994 | ||
841 | void conf_set_all_new_symbols(enum conf_def_mode mode) | 995 | void conf_set_all_new_symbols(enum conf_def_mode mode) |
842 | { | 996 | { |
843 | struct symbol *sym, *csym; | 997 | struct symbol *sym, *csym; |
844 | struct property *prop; | 998 | int i, cnt; |
845 | struct expr *e; | ||
846 | int i, cnt, def; | ||
847 | 999 | ||
848 | for_all_symbols(i, sym) { | 1000 | for_all_symbols(i, sym) { |
849 | if (sym_has_value(sym)) | 1001 | if (sym_has_value(sym)) |
@@ -862,7 +1014,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
862 | sym->def[S_DEF_USER].tri = no; | 1014 | sym->def[S_DEF_USER].tri = no; |
863 | break; | 1015 | break; |
864 | case def_random: | 1016 | case def_random: |
865 | sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); | 1017 | cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2; |
1018 | sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt); | ||
866 | break; | 1019 | break; |
867 | default: | 1020 | default: |
868 | continue; | 1021 | continue; |
@@ -878,14 +1031,12 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
878 | 1031 | ||
879 | sym_clear_all_valid(); | 1032 | sym_clear_all_valid(); |
880 | 1033 | ||
881 | if (mode != def_random) | ||
882 | return; | ||
883 | /* | 1034 | /* |
884 | * We have different type of choice blocks. | 1035 | * We have different type of choice blocks. |
885 | * If curr.tri equal to mod then we can select several | 1036 | * If curr.tri equals to mod then we can select several |
886 | * choice symbols in one block. | 1037 | * choice symbols in one block. |
887 | * In this case we do nothing. | 1038 | * In this case we do nothing. |
888 | * If curr.tri equal yes then only one symbol can be | 1039 | * If curr.tri equals yes then only one symbol can be |
889 | * selected in a choice block and we set it to yes, | 1040 | * selected in a choice block and we set it to yes, |
890 | * and the rest to no. | 1041 | * and the rest to no. |
891 | */ | 1042 | */ |
@@ -894,35 +1045,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) | |||
894 | continue; | 1045 | continue; |
895 | 1046 | ||
896 | sym_calc_value(csym); | 1047 | sym_calc_value(csym); |
897 | 1048 | if (mode == def_random) | |
898 | if (csym->curr.tri != yes) | 1049 | randomize_choice_values(csym); |
899 | continue; | 1050 | else |
900 | 1051 | set_all_choice_values(csym); | |
901 | prop = sym_get_choice_prop(csym); | ||
902 | |||
903 | /* count entries in choice block */ | ||
904 | cnt = 0; | ||
905 | expr_list_for_each_sym(prop->expr, e, sym) | ||
906 | cnt++; | ||
907 | |||
908 | /* | ||
909 | * find a random value and set it to yes, | ||
910 | * set the rest to no so we have only one set | ||
911 | */ | ||
912 | def = (rand() % cnt); | ||
913 | |||
914 | cnt = 0; | ||
915 | expr_list_for_each_sym(prop->expr, e, sym) { | ||
916 | if (def == cnt++) { | ||
917 | sym->def[S_DEF_USER].tri = yes; | ||
918 | csym->def[S_DEF_USER].val = sym; | ||
919 | } | ||
920 | else { | ||
921 | sym->def[S_DEF_USER].tri = no; | ||
922 | } | ||
923 | } | ||
924 | csym->flags |= SYMBOL_DEF_USER; | ||
925 | /* clear VALID to get value calculated */ | ||
926 | csym->flags &= ~(SYMBOL_VALID); | ||
927 | } | 1052 | } |
928 | } | 1053 | } |