aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kconfig
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2010-10-27 18:15:57 -0400
committerMichal Marek <mmarek@suse.cz>2010-10-27 18:15:57 -0400
commitb74b953b998bcc2db91b694446f3a2619ec32de6 (patch)
tree6ce24caabd730f6ae9287ed0676ec32e6ff31e9d /scripts/kconfig
parentabb438526201c6a79949ad45375c051b6681c253 (diff)
parentf6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff)
Merge commit 'v2.6.36' into kbuild/misc
Update to be able to fix a recent change to scripts/basic/docproc.c (commit eda603f).
Diffstat (limited to 'scripts/kconfig')
-rw-r--r--scripts/kconfig/Makefile93
-rw-r--r--scripts/kconfig/conf.c196
-rw-r--r--scripts/kconfig/confdata.c324
-rw-r--r--scripts/kconfig/expr.c4
-rw-r--r--scripts/kconfig/expr.h2
-rw-r--r--scripts/kconfig/gconf.c7
-rw-r--r--scripts/kconfig/lkc.h12
-rw-r--r--scripts/kconfig/lkc_proto.h1
-rw-r--r--scripts/kconfig/lxdialog/checklist.c10
-rw-r--r--scripts/kconfig/mconf.c2
-rw-r--r--scripts/kconfig/menu.c24
-rw-r--r--scripts/kconfig/nconf.c2
-rw-r--r--scripts/kconfig/nconf.gui.c2
-rw-r--r--scripts/kconfig/qconf.cc106
-rw-r--r--scripts/kconfig/qconf.h17
-rw-r--r--scripts/kconfig/streamline_config.pl68
-rw-r--r--scripts/kconfig/symbol.c296
-rw-r--r--scripts/kconfig/util.c2
18 files changed, 837 insertions, 331 deletions
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 75bdf5ae202c..de934def410f 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -21,44 +21,54 @@ menuconfig: $(obj)/mconf
21 $< $(Kconfig) 21 $< $(Kconfig)
22 22
23config: $(obj)/conf 23config: $(obj)/conf
24 $< $(Kconfig) 24 $< --oldaskconfig $(Kconfig)
25 25
26nconfig: $(obj)/nconf 26nconfig: $(obj)/nconf
27 $< $(Kconfig) 27 $< $(Kconfig)
28 28
29oldconfig: $(obj)/conf 29oldconfig: $(obj)/conf
30 $< -o $(Kconfig) 30 $< --$@ $(Kconfig)
31 31
32silentoldconfig: $(obj)/conf 32silentoldconfig: $(obj)/conf
33 $(Q)mkdir -p include/generated 33 $(Q)mkdir -p include/generated
34 $< -s $(Kconfig) 34 $< --$@ $(Kconfig)
35
36# if no path is given, then use src directory to find file
37ifdef LSMOD
38LSMOD_F := $(LSMOD)
39ifeq ($(findstring /,$(LSMOD)),)
40 LSMOD_F := $(objtree)/$(LSMOD)
41endif
42endif
35 43
36localmodconfig: $(obj)/streamline_config.pl $(obj)/conf 44localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
37 $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config 45 $(Q)mkdir -p include/generated
38 $(Q)if [ -f .config ]; then \ 46 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
39 cmp -s .tmp.config .config || \ 47 $(Q)if [ -f .config ]; then \
40 (mv -f .config .config.old.1; \ 48 cmp -s .tmp.config .config || \
41 mv -f .tmp.config .config; \ 49 (mv -f .config .config.old.1; \
42 $(obj)/conf -s $(Kconfig); \ 50 mv -f .tmp.config .config; \
43 mv -f .config.old.1 .config.old) \ 51 $(obj)/conf --silentoldconfig $(Kconfig); \
44 else \ 52 mv -f .config.old.1 .config.old) \
45 mv -f .tmp.config .config; \ 53 else \
46 $(obj)/conf -s $(Kconfig); \ 54 mv -f .tmp.config .config; \
55 $(obj)/conf --silentoldconfig $(Kconfig); \
47 fi 56 fi
48 $(Q)rm -f .tmp.config 57 $(Q)rm -f .tmp.config
49 58
50localyesconfig: $(obj)/streamline_config.pl $(obj)/conf 59localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
51 $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config 60 $(Q)mkdir -p include/generated
61 $(Q)perl $< $(srctree) $(Kconfig) $(LSMOD_F) > .tmp.config
52 $(Q)sed -i s/=m/=y/ .tmp.config 62 $(Q)sed -i s/=m/=y/ .tmp.config
53 $(Q)if [ -f .config ]; then \ 63 $(Q)if [ -f .config ]; then \
54 cmp -s .tmp.config .config || \ 64 cmp -s .tmp.config .config || \
55 (mv -f .config .config.old.1; \ 65 (mv -f .config .config.old.1; \
56 mv -f .tmp.config .config; \ 66 mv -f .tmp.config .config; \
57 $(obj)/conf -s $(Kconfig); \ 67 $(obj)/conf --silentoldconfig $(Kconfig); \
58 mv -f .config.old.1 .config.old) \ 68 mv -f .config.old.1 .config.old) \
59 else \ 69 else \
60 mv -f .tmp.config .config; \ 70 mv -f .tmp.config .config; \
61 $(obj)/conf -s $(Kconfig); \ 71 $(obj)/conf --silentoldconfig $(Kconfig); \
62 fi 72 fi
63 $(Q)rm -f .tmp.config 73 $(Q)rm -f .tmp.config
64 74
@@ -85,30 +95,29 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
85 $(Q)rm -f arch/um/Kconfig.arch 95 $(Q)rm -f arch/um/Kconfig.arch
86 $(Q)rm -f $(obj)/config.pot 96 $(Q)rm -f $(obj)/config.pot
87 97
88PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig 98PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
89 99
90randconfig: $(obj)/conf 100allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
91 $< -r $(Kconfig) 101 $< --$@ $(Kconfig)
92 102
93allyesconfig: $(obj)/conf 103PHONY += listnewconfig oldnoconfig savedefconfig defconfig
94 $< -y $(Kconfig)
95 104
96allnoconfig: $(obj)/conf 105listnewconfig oldnoconfig: $(obj)/conf
97 $< -n $(Kconfig) 106 $< --$@ $(Kconfig)
98 107
99allmodconfig: $(obj)/conf 108savedefconfig: $(obj)/conf
100 $< -m $(Kconfig) 109 $< --$@=defconfig $(Kconfig)
101 110
102defconfig: $(obj)/conf 111defconfig: $(obj)/conf
103ifeq ($(KBUILD_DEFCONFIG),) 112ifeq ($(KBUILD_DEFCONFIG),)
104 $< -d $(Kconfig) 113 $< --defconfig $(Kconfig)
105else 114else
106 @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" 115 @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
107 $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) 116 $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
108endif 117endif
109 118
110%_defconfig: $(obj)/conf 119%_defconfig: $(obj)/conf
111 $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig) 120 $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
112 121
113# Help text used by make help 122# Help text used by make help
114help: 123help:
@@ -121,11 +130,15 @@ help:
121 @echo ' localmodconfig - Update current config disabling modules not loaded' 130 @echo ' localmodconfig - Update current config disabling modules not loaded'
122 @echo ' localyesconfig - Update current config converting local mods to core' 131 @echo ' localyesconfig - Update current config converting local mods to core'
123 @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps' 132 @echo ' silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
124 @echo ' randconfig - New config with random answer to all options' 133 @echo ' defconfig - New config with default from ARCH supplied defconfig'
125 @echo ' defconfig - New config with default answer to all options' 134 @echo ' savedefconfig - Save current config as ./defconfig (minimal config)'
126 @echo ' allmodconfig - New config selecting modules when possible'
127 @echo ' allyesconfig - New config where all options are accepted with yes'
128 @echo ' allnoconfig - New config where all options are answered with no' 135 @echo ' allnoconfig - New config where all options are answered with no'
136 @echo ' allyesconfig - New config where all options are accepted with yes'
137 @echo ' allmodconfig - New config selecting modules when possible'
138 @echo ' alldefconfig - New config with all symbols set to default'
139 @echo ' randconfig - New config with random answer to all options'
140 @echo ' listnewconfig - List new options'
141 @echo ' oldnoconfig - Same as silentoldconfig but set new symbols to n (unset)'
129 142
130# lxdialog stuff 143# lxdialog stuff
131check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh 144check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
@@ -209,7 +222,7 @@ HOSTCFLAGS_zconf.tab.o := -I$(src)
209HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl 222HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl
210HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK 223HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK
211 224
212HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` 225HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` -ldl
213HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ 226HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
214 -D LKC_DIRECT_LINK 227 -D LKC_DIRECT_LINK
215 228
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 9960d1c303f8..7ef429cd5cb3 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -10,6 +10,7 @@
10#include <string.h> 10#include <string.h>
11#include <time.h> 11#include <time.h>
12#include <unistd.h> 12#include <unistd.h>
13#include <getopt.h>
13#include <sys/stat.h> 14#include <sys/stat.h>
14#include <sys/time.h> 15#include <sys/time.h>
15 16
@@ -19,16 +20,21 @@
19static void conf(struct menu *menu); 20static void conf(struct menu *menu);
20static void check_conf(struct menu *menu); 21static void check_conf(struct menu *menu);
21 22
22enum { 23enum input_mode {
23 ask_all, 24 oldaskconfig,
24 ask_new, 25 silentoldconfig,
25 ask_silent, 26 oldconfig,
26 set_default, 27 allnoconfig,
27 set_yes, 28 allyesconfig,
28 set_mod, 29 allmodconfig,
29 set_no, 30 alldefconfig,
30 set_random 31 randconfig,
31} input_mode = ask_all; 32 defconfig,
33 savedefconfig,
34 listnewconfig,
35 oldnoconfig,
36} input_mode = oldaskconfig;
37
32char *defconfig_file; 38char *defconfig_file;
33 39
34static int indent = 1; 40static int indent = 1;
@@ -93,16 +99,16 @@ static int conf_askvalue(struct symbol *sym, const char *def)
93 } 99 }
94 100
95 switch (input_mode) { 101 switch (input_mode) {
96 case ask_new: 102 case oldconfig:
97 case ask_silent: 103 case silentoldconfig:
98 if (sym_has_value(sym)) { 104 if (sym_has_value(sym)) {
99 printf("%s\n", def); 105 printf("%s\n", def);
100 return 0; 106 return 0;
101 } 107 }
102 check_stdin(); 108 check_stdin();
103 case ask_all: 109 case oldaskconfig:
104 fflush(stdout); 110 fflush(stdout);
105 fgets(line, 128, stdin); 111 xfgets(line, 128, stdin);
106 return 1; 112 return 1;
107 default: 113 default:
108 break; 114 break;
@@ -156,14 +162,12 @@ static int conf_string(struct menu *menu)
156static int conf_sym(struct menu *menu) 162static int conf_sym(struct menu *menu)
157{ 163{
158 struct symbol *sym = menu->sym; 164 struct symbol *sym = menu->sym;
159 int type;
160 tristate oldval, newval; 165 tristate oldval, newval;
161 166
162 while (1) { 167 while (1) {
163 printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); 168 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
164 if (sym->name) 169 if (sym->name)
165 printf("(%s) ", sym->name); 170 printf("(%s) ", sym->name);
166 type = sym_get_type(sym);
167 putchar('['); 171 putchar('[');
168 oldval = sym_get_tristate_value(sym); 172 oldval = sym_get_tristate_value(sym);
169 switch (oldval) { 173 switch (oldval) {
@@ -228,11 +232,9 @@ static int conf_choice(struct menu *menu)
228{ 232{
229 struct symbol *sym, *def_sym; 233 struct symbol *sym, *def_sym;
230 struct menu *child; 234 struct menu *child;
231 int type;
232 bool is_new; 235 bool is_new;
233 236
234 sym = menu->sym; 237 sym = menu->sym;
235 type = sym_get_type(sym);
236 is_new = !sym_has_value(sym); 238 is_new = !sym_has_value(sym);
237 if (sym_is_changable(sym)) { 239 if (sym_is_changable(sym)) {
238 conf_sym(menu); 240 conf_sym(menu);
@@ -294,17 +296,17 @@ static int conf_choice(struct menu *menu)
294 printf("?"); 296 printf("?");
295 printf("]: "); 297 printf("]: ");
296 switch (input_mode) { 298 switch (input_mode) {
297 case ask_new: 299 case oldconfig:
298 case ask_silent: 300 case silentoldconfig:
299 if (!is_new) { 301 if (!is_new) {
300 cnt = def; 302 cnt = def;
301 printf("%d\n", cnt); 303 printf("%d\n", cnt);
302 break; 304 break;
303 } 305 }
304 check_stdin(); 306 check_stdin();
305 case ask_all: 307 case oldaskconfig:
306 fflush(stdout); 308 fflush(stdout);
307 fgets(line, 128, stdin); 309 xfgets(line, 128, stdin);
308 strip(line); 310 strip(line);
309 if (line[0] == '?') { 311 if (line[0] == '?') {
310 print_help(menu); 312 print_help(menu);
@@ -360,7 +362,10 @@ static void conf(struct menu *menu)
360 362
361 switch (prop->type) { 363 switch (prop->type) {
362 case P_MENU: 364 case P_MENU:
363 if (input_mode == ask_silent && rootEntry != menu) { 365 if ((input_mode == silentoldconfig ||
366 input_mode == listnewconfig ||
367 input_mode == oldnoconfig) &&
368 rootEntry != menu) {
364 check_conf(menu); 369 check_conf(menu);
365 return; 370 return;
366 } 371 }
@@ -418,10 +423,16 @@ static void check_conf(struct menu *menu)
418 if (sym && !sym_has_value(sym)) { 423 if (sym && !sym_has_value(sym)) {
419 if (sym_is_changable(sym) || 424 if (sym_is_changable(sym) ||
420 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) { 425 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
421 if (!conf_cnt++) 426 if (input_mode == listnewconfig) {
422 printf(_("*\n* Restart config...\n*\n")); 427 if (sym->name && !sym_is_choice_value(sym)) {
423 rootEntry = menu_get_parent_menu(menu); 428 printf("CONFIG_%s\n", sym->name);
424 conf(rootEntry); 429 }
430 } else if (input_mode != oldnoconfig) {
431 if (!conf_cnt++)
432 printf(_("*\n* Restart config...\n*\n"));
433 rootEntry = menu_get_parent_menu(menu);
434 conf(rootEntry);
435 }
425 } 436 }
426 } 437 }
427 438
@@ -429,6 +440,22 @@ static void check_conf(struct menu *menu)
429 check_conf(child); 440 check_conf(child);
430} 441}
431 442
443static struct option long_opts[] = {
444 {"oldaskconfig", no_argument, NULL, oldaskconfig},
445 {"oldconfig", no_argument, NULL, oldconfig},
446 {"silentoldconfig", no_argument, NULL, silentoldconfig},
447 {"defconfig", optional_argument, NULL, defconfig},
448 {"savedefconfig", required_argument, NULL, savedefconfig},
449 {"allnoconfig", no_argument, NULL, allnoconfig},
450 {"allyesconfig", no_argument, NULL, allyesconfig},
451 {"allmodconfig", no_argument, NULL, allmodconfig},
452 {"alldefconfig", no_argument, NULL, alldefconfig},
453 {"randconfig", no_argument, NULL, randconfig},
454 {"listnewconfig", no_argument, NULL, listnewconfig},
455 {"oldnoconfig", no_argument, NULL, oldnoconfig},
456 {NULL, 0, NULL, 0}
457};
458
432int main(int ac, char **av) 459int main(int ac, char **av)
433{ 460{
434 int opt; 461 int opt;
@@ -439,32 +466,17 @@ int main(int ac, char **av)
439 bindtextdomain(PACKAGE, LOCALEDIR); 466 bindtextdomain(PACKAGE, LOCALEDIR);
440 textdomain(PACKAGE); 467 textdomain(PACKAGE);
441 468
442 while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) { 469 while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) {
470 input_mode = (enum input_mode)opt;
443 switch (opt) { 471 switch (opt) {
444 case 'o': 472 case silentoldconfig:
445 input_mode = ask_silent;
446 break;
447 case 's':
448 input_mode = ask_silent;
449 sync_kconfig = 1; 473 sync_kconfig = 1;
450 break; 474 break;
451 case 'd': 475 case defconfig:
452 input_mode = set_default; 476 case savedefconfig:
453 break;
454 case 'D':
455 input_mode = set_default;
456 defconfig_file = optarg; 477 defconfig_file = optarg;
457 break; 478 break;
458 case 'n': 479 case randconfig:
459 input_mode = set_no;
460 break;
461 case 'm':
462 input_mode = set_mod;
463 break;
464 case 'y':
465 input_mode = set_yes;
466 break;
467 case 'r':
468 { 480 {
469 struct timeval now; 481 struct timeval now;
470 unsigned int seed; 482 unsigned int seed;
@@ -477,17 +489,12 @@ int main(int ac, char **av)
477 489
478 seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); 490 seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
479 srand(seed); 491 srand(seed);
480
481 input_mode = set_random;
482 break; 492 break;
483 } 493 }
484 case 'h': 494 case '?':
485 printf(_("See README for usage info\n"));
486 exit(0);
487 break;
488 default:
489 fprintf(stderr, _("See README for usage info\n")); 495 fprintf(stderr, _("See README for usage info\n"));
490 exit(1); 496 exit(1);
497 break;
491 } 498 }
492 } 499 }
493 if (ac == optind) { 500 if (ac == optind) {
@@ -512,7 +519,7 @@ int main(int ac, char **av)
512 } 519 }
513 520
514 switch (input_mode) { 521 switch (input_mode) {
515 case set_default: 522 case defconfig:
516 if (!defconfig_file) 523 if (!defconfig_file)
517 defconfig_file = conf_get_default_confname(); 524 defconfig_file = conf_get_default_confname();
518 if (conf_read(defconfig_file)) { 525 if (conf_read(defconfig_file)) {
@@ -522,25 +529,32 @@ int main(int ac, char **av)
522 exit(1); 529 exit(1);
523 } 530 }
524 break; 531 break;
525 case ask_silent: 532 case savedefconfig:
526 case ask_all: 533 conf_read(NULL);
527 case ask_new: 534 break;
535 case silentoldconfig:
536 case oldaskconfig:
537 case oldconfig:
538 case listnewconfig:
539 case oldnoconfig:
528 conf_read(NULL); 540 conf_read(NULL);
529 break; 541 break;
530 case set_no: 542 case allnoconfig:
531 case set_mod: 543 case allyesconfig:
532 case set_yes: 544 case allmodconfig:
533 case set_random: 545 case alldefconfig:
546 case randconfig:
534 name = getenv("KCONFIG_ALLCONFIG"); 547 name = getenv("KCONFIG_ALLCONFIG");
535 if (name && !stat(name, &tmpstat)) { 548 if (name && !stat(name, &tmpstat)) {
536 conf_read_simple(name, S_DEF_USER); 549 conf_read_simple(name, S_DEF_USER);
537 break; 550 break;
538 } 551 }
539 switch (input_mode) { 552 switch (input_mode) {
540 case set_no: name = "allno.config"; break; 553 case allnoconfig: name = "allno.config"; break;
541 case set_mod: name = "allmod.config"; break; 554 case allyesconfig: name = "allyes.config"; break;
542 case set_yes: name = "allyes.config"; break; 555 case allmodconfig: name = "allmod.config"; break;
543 case set_random: name = "allrandom.config"; break; 556 case alldefconfig: name = "alldef.config"; break;
557 case randconfig: name = "allrandom.config"; break;
544 default: break; 558 default: break;
545 } 559 }
546 if (!stat(name, &tmpstat)) 560 if (!stat(name, &tmpstat))
@@ -565,33 +579,42 @@ int main(int ac, char **av)
565 } 579 }
566 580
567 switch (input_mode) { 581 switch (input_mode) {
568 case set_no: 582 case allnoconfig:
569 conf_set_all_new_symbols(def_no); 583 conf_set_all_new_symbols(def_no);
570 break; 584 break;
571 case set_yes: 585 case allyesconfig:
572 conf_set_all_new_symbols(def_yes); 586 conf_set_all_new_symbols(def_yes);
573 break; 587 break;
574 case set_mod: 588 case allmodconfig:
575 conf_set_all_new_symbols(def_mod); 589 conf_set_all_new_symbols(def_mod);
576 break; 590 break;
577 case set_random: 591 case alldefconfig:
592 conf_set_all_new_symbols(def_default);
593 break;
594 case randconfig:
578 conf_set_all_new_symbols(def_random); 595 conf_set_all_new_symbols(def_random);
579 break; 596 break;
580 case set_default: 597 case defconfig:
581 conf_set_all_new_symbols(def_default); 598 conf_set_all_new_symbols(def_default);
582 break; 599 break;
583 case ask_new: 600 case savedefconfig:
584 case ask_all: 601 break;
602 case oldaskconfig:
585 rootEntry = &rootmenu; 603 rootEntry = &rootmenu;
586 conf(&rootmenu); 604 conf(&rootmenu);
587 input_mode = ask_silent; 605 input_mode = silentoldconfig;
588 /* fall through */ 606 /* fall through */
589 case ask_silent: 607 case oldconfig:
608 case listnewconfig:
609 case oldnoconfig:
610 case silentoldconfig:
590 /* Update until a loop caused no more changes */ 611 /* Update until a loop caused no more changes */
591 do { 612 do {
592 conf_cnt = 0; 613 conf_cnt = 0;
593 check_conf(&rootmenu); 614 check_conf(&rootmenu);
594 } while (conf_cnt); 615 } while (conf_cnt &&
616 (input_mode != listnewconfig &&
617 input_mode != oldnoconfig));
595 break; 618 break;
596 } 619 }
597 620
@@ -607,7 +630,13 @@ int main(int ac, char **av)
607 fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n")); 630 fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
608 return 1; 631 return 1;
609 } 632 }
610 } else { 633 } else if (input_mode == savedefconfig) {
634 if (conf_write_defconfig(defconfig_file)) {
635 fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
636 defconfig_file);
637 return 1;
638 }
639 } else if (input_mode != listnewconfig) {
611 if (conf_write(NULL)) { 640 if (conf_write(NULL)) {
612 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); 641 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
613 exit(1); 642 exit(1);
@@ -615,3 +644,14 @@ int main(int ac, char **av)
615 } 644 }
616 return 0; 645 return 0;
617} 646}
647/*
648 * Helper function to facilitate fgets() by Jean Sacren.
649 */
650void xfgets(str, size, in)
651 char *str;
652 int size;
653 FILE *in;
654{
655 if (fgets(str, size, in) == NULL)
656 fprintf(stderr, "\nError in reading or end of file.\n");
657}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index c4dec80cfd8e..515253fe46cf 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -170,8 +170,11 @@ int conf_read_simple(const char *name, int def)
170 if (in) 170 if (in)
171 goto load; 171 goto load;
172 sym_add_change_count(1); 172 sym_add_change_count(1);
173 if (!sym_defconfig_list) 173 if (!sym_defconfig_list) {
174 if (modules_sym)
175 sym_calc_value(modules_sym);
174 return 1; 176 return 1;
177 }
175 178
176 for_all_defaults(sym_defconfig_list, prop) { 179 for_all_defaults(sym_defconfig_list, prop) {
177 if (expr_calc_value(prop->visible.expr) == no || 180 if (expr_calc_value(prop->visible.expr) == no ||
@@ -396,15 +399,150 @@ int conf_read(const char *name)
396 return 0; 399 return 0;
397} 400}
398 401
402/* Write a S_STRING */
403static void conf_write_string(bool headerfile, const char *name,
404 const char *str, FILE *out)
405{
406 int l;
407 if (headerfile)
408 fprintf(out, "#define CONFIG_%s \"", name);
409 else
410 fprintf(out, "CONFIG_%s=\"", name);
411
412 while (1) {
413 l = strcspn(str, "\"\\");
414 if (l) {
415 xfwrite(str, l, 1, out);
416 str += l;
417 }
418 if (!*str)
419 break;
420 fprintf(out, "\\%c", *str++);
421 }
422 fputs("\"\n", out);
423}
424
425static void conf_write_symbol(struct symbol *sym, enum symbol_type type,
426 FILE *out, bool write_no)
427{
428 const char *str;
429
430 switch (type) {
431 case S_BOOLEAN:
432 case S_TRISTATE:
433 switch (sym_get_tristate_value(sym)) {
434 case no:
435 if (write_no)
436 fprintf(out, "# CONFIG_%s is not set\n", sym->name);
437 break;
438 case mod:
439 fprintf(out, "CONFIG_%s=m\n", sym->name);
440 break;
441 case yes:
442 fprintf(out, "CONFIG_%s=y\n", sym->name);
443 break;
444 }
445 break;
446 case S_STRING:
447 conf_write_string(false, sym->name, sym_get_string_value(sym), out);
448 break;
449 case S_HEX:
450 case S_INT:
451 str = sym_get_string_value(sym);
452 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
453 break;
454 case S_OTHER:
455 case S_UNKNOWN:
456 break;
457 }
458}
459
460/*
461 * Write out a minimal config.
462 * All values that has default values are skipped as this is redundant.
463 */
464int conf_write_defconfig(const char *filename)
465{
466 struct symbol *sym;
467 struct menu *menu;
468 FILE *out;
469
470 out = fopen(filename, "w");
471 if (!out)
472 return 1;
473
474 sym_clear_all_valid();
475
476 /* Traverse all menus to find all relevant symbols */
477 menu = rootmenu.list;
478
479 while (menu != NULL)
480 {
481 sym = menu->sym;
482 if (sym == NULL) {
483 if (!menu_is_visible(menu))
484 goto next_menu;
485 } else if (!sym_is_choice(sym)) {
486 sym_calc_value(sym);
487 if (!(sym->flags & SYMBOL_WRITE))
488 goto next_menu;
489 sym->flags &= ~SYMBOL_WRITE;
490 /* If we cannot change the symbol - skip */
491 if (!sym_is_changable(sym))
492 goto next_menu;
493 /* If symbol equals to default value - skip */
494 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
495 goto next_menu;
496
497 /*
498 * If symbol is a choice value and equals to the
499 * default for a choice - skip.
500 * But only if value is bool and equal to "y" and
501 * choice is not "optional".
502 * (If choice is "optional" then all values can be "n")
503 */
504 if (sym_is_choice_value(sym)) {
505 struct symbol *cs;
506 struct symbol *ds;
507
508 cs = prop_get_symbol(sym_get_choice_prop(sym));
509 ds = sym_choice_default(cs);
510 if (!sym_is_optional(cs) && sym == ds) {
511 if ((sym->type == S_BOOLEAN) &&
512 sym_get_tristate_value(sym) == yes)
513 goto next_menu;
514 }
515 }
516 conf_write_symbol(sym, sym->type, out, true);
517 }
518next_menu:
519 if (menu->list != NULL) {
520 menu = menu->list;
521 }
522 else if (menu->next != NULL) {
523 menu = menu->next;
524 } else {
525 while ((menu = menu->parent)) {
526 if (menu->next != NULL) {
527 menu = menu->next;
528 break;
529 }
530 }
531 }
532 }
533 fclose(out);
534 return 0;
535}
536
399int conf_write(const char *name) 537int conf_write(const char *name)
400{ 538{
401 FILE *out; 539 FILE *out;
402 struct symbol *sym; 540 struct symbol *sym;
403 struct menu *menu; 541 struct menu *menu;
404 const char *basename; 542 const char *basename;
405 char dirname[128], tmpname[128], newname[128];
406 int type, l;
407 const char *str; 543 const char *str;
544 char dirname[128], tmpname[128], newname[128];
545 enum symbol_type type;
408 time_t now; 546 time_t now;
409 int use_timestamp = 1; 547 int use_timestamp = 1;
410 char *env; 548 char *env;
@@ -484,50 +622,11 @@ int conf_write(const char *name)
484 if (modules_sym->curr.tri == no) 622 if (modules_sym->curr.tri == no)
485 type = S_BOOLEAN; 623 type = S_BOOLEAN;
486 } 624 }
487 switch (type) { 625 /* Write config symbol to file */
488 case S_BOOLEAN: 626 conf_write_symbol(sym, type, out, true);
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 } 627 }
529 628
530 next: 629next:
531 if (menu->list) { 630 if (menu->list) {
532 menu = menu->list; 631 menu = menu->list;
533 continue; 632 continue;
@@ -679,7 +778,7 @@ int conf_write_autoconf(void)
679 const char *name; 778 const char *name;
680 FILE *out, *tristate, *out_h; 779 FILE *out, *tristate, *out_h;
681 time_t now; 780 time_t now;
682 int i, l; 781 int i;
683 782
684 sym_clear_all_valid(); 783 sym_clear_all_valid();
685 784
@@ -729,6 +828,11 @@ int conf_write_autoconf(void)
729 sym_calc_value(sym); 828 sym_calc_value(sym);
730 if (!(sym->flags & SYMBOL_WRITE) || !sym->name) 829 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
731 continue; 830 continue;
831
832 /* write symbol to config file */
833 conf_write_symbol(sym, sym->type, out, false);
834
835 /* update autoconf and tristate files */
732 switch (sym->type) { 836 switch (sym->type) {
733 case S_BOOLEAN: 837 case S_BOOLEAN:
734 case S_TRISTATE: 838 case S_TRISTATE:
@@ -736,12 +840,10 @@ int conf_write_autoconf(void)
736 case no: 840 case no:
737 break; 841 break;
738 case mod: 842 case mod:
739 fprintf(out, "CONFIG_%s=m\n", sym->name);
740 fprintf(tristate, "CONFIG_%s=M\n", sym->name); 843 fprintf(tristate, "CONFIG_%s=M\n", sym->name);
741 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 844 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
742 break; 845 break;
743 case yes: 846 case yes:
744 fprintf(out, "CONFIG_%s=y\n", sym->name);
745 if (sym->type == S_TRISTATE) 847 if (sym->type == S_TRISTATE)
746 fprintf(tristate, "CONFIG_%s=Y\n", 848 fprintf(tristate, "CONFIG_%s=Y\n",
747 sym->name); 849 sym->name);
@@ -750,35 +852,16 @@ int conf_write_autoconf(void)
750 } 852 }
751 break; 853 break;
752 case S_STRING: 854 case S_STRING:
753 str = sym_get_string_value(sym); 855 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; 856 break;
772 case S_HEX: 857 case S_HEX:
773 str = sym_get_string_value(sym); 858 str = sym_get_string_value(sym);
774 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 859 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
775 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
776 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); 860 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
777 break; 861 break;
778 } 862 }
779 case S_INT: 863 case S_INT:
780 str = sym_get_string_value(sym); 864 str = sym_get_string_value(sym);
781 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
782 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); 865 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
783 break; 866 break;
784 default: 867 default:
@@ -837,13 +920,73 @@ void conf_set_changed_callback(void (*fn)(void))
837 conf_changed_callback = fn; 920 conf_changed_callback = fn;
838} 921}
839 922
923static void randomize_choice_values(struct symbol *csym)
924{
925 struct property *prop;
926 struct symbol *sym;
927 struct expr *e;
928 int cnt, def;
840 929
841void conf_set_all_new_symbols(enum conf_def_mode mode) 930 /*
931 * If choice is mod then we may have more items slected
932 * and if no then no-one.
933 * In both cases stop.
934 */
935 if (csym->curr.tri != yes)
936 return;
937
938 prop = sym_get_choice_prop(csym);
939
940 /* count entries in choice block */
941 cnt = 0;
942 expr_list_for_each_sym(prop->expr, e, sym)
943 cnt++;
944
945 /*
946 * find a random value and set it to yes,
947 * set the rest to no so we have only one set
948 */
949 def = (rand() % cnt);
950
951 cnt = 0;
952 expr_list_for_each_sym(prop->expr, e, sym) {
953 if (def == cnt++) {
954 sym->def[S_DEF_USER].tri = yes;
955 csym->def[S_DEF_USER].val = sym;
956 }
957 else {
958 sym->def[S_DEF_USER].tri = no;
959 }
960 }
961 csym->flags |= SYMBOL_DEF_USER;
962 /* clear VALID to get value calculated */
963 csym->flags &= ~(SYMBOL_VALID);
964}
965
966static void set_all_choice_values(struct symbol *csym)
842{ 967{
843 struct symbol *sym, *csym;
844 struct property *prop; 968 struct property *prop;
969 struct symbol *sym;
845 struct expr *e; 970 struct expr *e;
846 int i, cnt, def; 971
972 prop = sym_get_choice_prop(csym);
973
974 /*
975 * Set all non-assinged choice values to no
976 */
977 expr_list_for_each_sym(prop->expr, e, sym) {
978 if (!sym_has_value(sym))
979 sym->def[S_DEF_USER].tri = no;
980 }
981 csym->flags |= SYMBOL_DEF_USER;
982 /* clear VALID to get value calculated */
983 csym->flags &= ~(SYMBOL_VALID);
984}
985
986void conf_set_all_new_symbols(enum conf_def_mode mode)
987{
988 struct symbol *sym, *csym;
989 int i, cnt;
847 990
848 for_all_symbols(i, sym) { 991 for_all_symbols(i, sym) {
849 if (sym_has_value(sym)) 992 if (sym_has_value(sym))
@@ -862,7 +1005,8 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
862 sym->def[S_DEF_USER].tri = no; 1005 sym->def[S_DEF_USER].tri = no;
863 break; 1006 break;
864 case def_random: 1007 case def_random:
865 sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); 1008 cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
1009 sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
866 break; 1010 break;
867 default: 1011 default:
868 continue; 1012 continue;
@@ -878,8 +1022,6 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
878 1022
879 sym_clear_all_valid(); 1023 sym_clear_all_valid();
880 1024
881 if (mode != def_random)
882 return;
883 /* 1025 /*
884 * We have different type of choice blocks. 1026 * We have different type of choice blocks.
885 * If curr.tri equal to mod then we can select several 1027 * If curr.tri equal to mod then we can select several
@@ -894,35 +1036,9 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
894 continue; 1036 continue;
895 1037
896 sym_calc_value(csym); 1038 sym_calc_value(csym);
897 1039 if (mode == def_random)
898 if (csym->curr.tri != yes) 1040 randomize_choice_values(csym);
899 continue; 1041 else
900 1042 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 } 1043 }
928} 1044}
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index d83f2322893a..330e7c0048a8 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1087,7 +1087,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
1087 1087
1088static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) 1088static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1089{ 1089{
1090 fwrite(str, strlen(str), 1, data); 1090 xfwrite(str, strlen(str), 1, data);
1091} 1091}
1092 1092
1093void expr_fprint(struct expr *e, FILE *out) 1093void expr_fprint(struct expr *e, FILE *out)
@@ -1121,7 +1121,7 @@ static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *s
1121 } 1121 }
1122 1122
1123 str_append(gs, str); 1123 str_append(gs, str);
1124 if (sym) 1124 if (sym && sym->type != S_UNKNOWN)
1125 str_printf(gs, " [=%s]", sym_str); 1125 str_printf(gs, " [=%s]", sym_str);
1126} 1126}
1127 1127
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 891cd9ce9ba2..170459c224a1 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -83,6 +83,7 @@ struct symbol {
83 tristate visible; 83 tristate visible;
84 int flags; 84 int flags;
85 struct property *prop; 85 struct property *prop;
86 struct expr_value dir_dep;
86 struct expr_value rev_dep; 87 struct expr_value rev_dep;
87}; 88};
88 89
@@ -131,6 +132,7 @@ enum prop_type {
131 P_SELECT, /* select BAR */ 132 P_SELECT, /* select BAR */
132 P_RANGE, /* range 7..100 (for a symbol) */ 133 P_RANGE, /* range 7..100 (for a symbol) */
133 P_ENV, /* value from environment variable */ 134 P_ENV, /* value from environment variable */
135 P_SYMBOL, /* where a symbol is defined */
134}; 136};
135 137
136struct property { 138struct property {
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index bef10411837f..d66988265f89 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -1114,7 +1114,7 @@ static gchar **fill_row(struct menu *menu)
1114 1114
1115 row[COL_OPTION] = 1115 row[COL_OPTION] =
1116 g_strdup_printf("%s %s", _(menu_get_prompt(menu)), 1116 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1117 sym && sym_has_value(sym) ? "(NEW)" : ""); 1117 sym && !sym_has_value(sym) ? "(NEW)" : "");
1118 1118
1119 if (opt_mode == OPT_ALL && !menu_is_visible(menu)) 1119 if (opt_mode == OPT_ALL && !menu_is_visible(menu))
1120 row[COL_COLOR] = g_strdup("DarkGray"); 1120 row[COL_COLOR] = g_strdup("DarkGray");
@@ -1343,7 +1343,8 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
1343#endif 1343#endif
1344 1344
1345 if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || 1345 if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1346 (opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) { 1346 (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
1347 (opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
1347 1348
1348 /* remove node */ 1349 /* remove node */
1349 if (gtktree_iter_find_node(dst, menu1) != NULL) { 1350 if (gtktree_iter_find_node(dst, menu1) != NULL) {
@@ -1425,7 +1426,7 @@ static void display_tree(struct menu *menu)
1425 1426
1426 if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) || 1427 if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
1427 (opt_mode == OPT_PROMPT && menu_has_prompt(child)) || 1428 (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1428 (opt_mode == OPT_ALL)) 1429 (opt_mode == OPT_ALL && menu_get_prompt(child)))
1429 place_node(child, fill_row(child)); 1430 place_node(child, fill_row(child));
1430#ifdef DEBUG 1431#ifdef DEBUG
1431 printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); 1432 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index ce6549cdaccf..bdf71bd31412 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -72,6 +72,9 @@ void zconf_nextfile(const char *name);
72int zconf_lineno(void); 72int zconf_lineno(void);
73char *zconf_curname(void); 73char *zconf_curname(void);
74 74
75/* conf.c */
76void xfgets(char *str, int size, FILE *in);
77
75/* confdata.c */ 78/* confdata.c */
76const char *conf_get_configname(void); 79const char *conf_get_configname(void);
77const char *conf_get_autoconfig_name(void); 80const char *conf_get_autoconfig_name(void);
@@ -80,6 +83,13 @@ void sym_set_change_count(int count);
80void sym_add_change_count(int count); 83void sym_add_change_count(int count);
81void conf_set_all_new_symbols(enum conf_def_mode mode); 84void conf_set_all_new_symbols(enum conf_def_mode mode);
82 85
86/* confdata.c and expr.c */
87static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
88{
89 if (fwrite(str, len, count, out) < count)
90 fprintf(stderr, "\nError in writing or end of file.\n");
91}
92
83/* kconfig_load.c */ 93/* kconfig_load.c */
84void kconfig_load(void); 94void kconfig_load(void);
85 95
@@ -126,6 +136,8 @@ void sym_init(void);
126void sym_clear_all_valid(void); 136void sym_clear_all_valid(void);
127void sym_set_all_changed(void); 137void sym_set_all_changed(void);
128void sym_set_changed(struct symbol *sym); 138void sym_set_changed(struct symbol *sym);
139struct symbol *sym_choice_default(struct symbol *sym);
140const char *sym_get_string_default(struct symbol *sym);
129struct symbol *sym_check_deps(struct symbol *sym); 141struct symbol *sym_check_deps(struct symbol *sym);
130struct property *prop_alloc(enum prop_type type, struct symbol *sym); 142struct property *prop_alloc(enum prop_type type, struct symbol *sym);
131struct symbol *prop_get_symbol(struct property *prop); 143struct symbol *prop_get_symbol(struct property *prop);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 7cadcad8233b..9a948c9ce44e 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -3,6 +3,7 @@
3P(conf_parse,void,(const char *name)); 3P(conf_parse,void,(const char *name));
4P(conf_read,int,(const char *name)); 4P(conf_read,int,(const char *name));
5P(conf_read_simple,int,(const char *name, int)); 5P(conf_read_simple,int,(const char *name, int));
6P(conf_write_defconfig,int,(const char *name));
6P(conf_write,int,(const char *name)); 7P(conf_write,int,(const char *name));
7P(conf_write_autoconf,int,(void)); 8P(conf_write_autoconf,int,(void));
8P(conf_get_changed,bool,(void)); 9P(conf_get_changed,bool,(void));
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index bcc6f19c3a35..a2eb80fbc896 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -31,6 +31,10 @@ static int list_width, check_x, item_x;
31static void print_item(WINDOW * win, int choice, int selected) 31static void print_item(WINDOW * win, int choice, int selected)
32{ 32{
33 int i; 33 int i;
34 char *list_item = malloc(list_width + 1);
35
36 strncpy(list_item, item_str(), list_width - item_x);
37 list_item[list_width - item_x] = '\0';
34 38
35 /* Clear 'residue' of last item */ 39 /* Clear 'residue' of last item */
36 wattrset(win, dlg.menubox.atr); 40 wattrset(win, dlg.menubox.atr);
@@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected)
45 wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); 49 wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
46 50
47 wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); 51 wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
48 mvwaddch(win, choice, item_x, item_str()[0]); 52 mvwaddch(win, choice, item_x, list_item[0]);
49 wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); 53 wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
50 waddstr(win, (char *)item_str() + 1); 54 waddstr(win, list_item + 1);
51 if (selected) { 55 if (selected) {
52 wmove(win, choice, check_x + 1); 56 wmove(win, choice, check_x + 1);
53 wrefresh(win); 57 wrefresh(win);
54 } 58 }
59 free(list_item);
55} 60}
56 61
57/* 62/*
@@ -175,6 +180,7 @@ do_resize:
175 check_x = 0; 180 check_x = 0;
176 item_foreach() 181 item_foreach()
177 check_x = MAX(check_x, strlen(item_str()) + 4); 182 check_x = MAX(check_x, strlen(item_str()) + 4);
183 check_x = MIN(check_x, list_width);
178 184
179 check_x = (list_width - check_x) / 2; 185 check_x = (list_width - check_x) / 2;
180 item_x = check_x + 4; 186 item_x = check_x + 4;
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 2c83d3234d30..d2f6e056c058 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -74,7 +74,7 @@ static const char mconf_readme[] = N_(
74"\n" 74"\n"
75" Shortcut: Press <H> or <?>.\n" 75" Shortcut: Press <H> or <?>.\n"
76"\n" 76"\n"
77"o To show hidden options, press <Z>.\n" 77"o To toggle the display of hidden options, press <Z>.\n"
78"\n" 78"\n"
79"\n" 79"\n"
80"Radiolists (Choice lists)\n" 80"Radiolists (Choice lists)\n"
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 203632cc30bd..edda8b49619d 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -58,6 +58,8 @@ void menu_add_entry(struct symbol *sym)
58 *last_entry_ptr = menu; 58 *last_entry_ptr = menu;
59 last_entry_ptr = &menu->next; 59 last_entry_ptr = &menu->next;
60 current_entry = menu; 60 current_entry = menu;
61 if (sym)
62 menu_add_symbol(P_SYMBOL, sym, NULL);
61} 63}
62 64
63void menu_end_entry(void) 65void menu_end_entry(void)
@@ -318,6 +320,8 @@ void menu_finalize(struct menu *parent)
318 parent->next = last_menu->next; 320 parent->next = last_menu->next;
319 last_menu->next = NULL; 321 last_menu->next = NULL;
320 } 322 }
323
324 sym->dir_dep.expr = parent->dep;
321 } 325 }
322 for (menu = parent->list; menu; menu = menu->next) { 326 for (menu = parent->list; menu; menu = menu->next) {
323 if (sym && sym_is_choice(sym) && 327 if (sym && sym_is_choice(sym) &&
@@ -419,9 +423,13 @@ bool menu_is_visible(struct menu *menu)
419 if (!sym || sym_get_tristate_value(menu->sym) == no) 423 if (!sym || sym_get_tristate_value(menu->sym) == no)
420 return false; 424 return false;
421 425
422 for (child = menu->list; child; child = child->next) 426 for (child = menu->list; child; child = child->next) {
423 if (menu_is_visible(child)) 427 if (menu_is_visible(child)) {
428 if (sym)
429 sym->flags |= SYMBOL_DEF_USER;
424 return true; 430 return true;
431 }
432 }
425 433
426 return false; 434 return false;
427} 435}
@@ -501,9 +509,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
501 bool hit; 509 bool hit;
502 struct property *prop; 510 struct property *prop;
503 511
504 if (sym && sym->name) 512 if (sym && sym->name) {
505 str_printf(r, "Symbol: %s [=%s]\n", sym->name, 513 str_printf(r, "Symbol: %s [=%s]\n", sym->name,
506 sym_get_string_value(sym)); 514 sym_get_string_value(sym));
515 str_printf(r, "Type : %s\n", sym_type_name(sym->type));
516 if (sym->type == S_INT || sym->type == S_HEX) {
517 prop = sym_get_range_prop(sym);
518 if (prop) {
519 str_printf(r, "Range : ");
520 expr_gstr_print(prop->expr, r);
521 str_append(r, "\n");
522 }
523 }
524 }
507 for_all_prompts(sym, prop) 525 for_all_prompts(sym, prop)
508 get_prompt_str(r, prop); 526 get_prompt_str(r, prop);
509 hit = false; 527 hit = false;
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 762caf80ce37..2ba71bcd38e6 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -676,6 +676,8 @@ static void *item_data(void)
676 struct mitem *mcur; 676 struct mitem *mcur;
677 677
678 cur = current_item(curses_menu); 678 cur = current_item(curses_menu);
679 if (!cur)
680 return NULL;
679 mcur = (struct mitem *) item_userptr(cur); 681 mcur = (struct mitem *) item_userptr(cur);
680 return mcur->usrptr; 682 return mcur->usrptr;
681 683
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index 115edb437fb1..a9d9344e1365 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -226,7 +226,7 @@ void fill_window(WINDOW *win, const char *text)
226 int len = get_line_length(line); 226 int len = get_line_length(line);
227 strncpy(tmp, line, min(len, x)); 227 strncpy(tmp, line, min(len, x));
228 tmp[len] = '\0'; 228 tmp[len] = '\0';
229 mvwprintw(win, i, 0, tmp); 229 mvwprintw(win, i, 0, "%s", tmp);
230 } 230 }
231} 231}
232 232
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 00c51507cfcc..820df2d1217b 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -58,11 +58,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
58{ 58{
59 QValueList<int> result; 59 QValueList<int> result;
60 QStringList entryList = readListEntry(key, ok); 60 QStringList entryList = readListEntry(key, ok);
61 if (ok) { 61 QStringList::Iterator it;
62 QStringList::Iterator it; 62
63 for (it = entryList.begin(); it != entryList.end(); ++it) 63 for (it = entryList.begin(); it != entryList.end(); ++it)
64 result.push_back((*it).toInt()); 64 result.push_back((*it).toInt());
65 }
66 65
67 return result; 66 return result;
68} 67}
@@ -149,7 +148,7 @@ void ConfigItem::updateMenu(void)
149 case S_TRISTATE: 148 case S_TRISTATE:
150 char ch; 149 char ch;
151 150
152 if (!sym_is_changable(sym) && !list->showAll) { 151 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
153 setPixmap(promptColIdx, 0); 152 setPixmap(promptColIdx, 0);
154 setText(noColIdx, QString::null); 153 setText(noColIdx, QString::null);
155 setText(modColIdx, QString::null); 154 setText(modColIdx, QString::null);
@@ -320,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
320 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), 319 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
321 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), 320 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
322 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), 321 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
323 showAll(false), showName(false), showRange(false), showData(false), 322 showName(false), showRange(false), showData(false), optMode(normalOpt),
324 rootEntry(0), headerPopup(0) 323 rootEntry(0), headerPopup(0)
325{ 324{
326 int i; 325 int i;
@@ -337,10 +336,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
337 336
338 if (name) { 337 if (name) {
339 configSettings->beginGroup(name); 338 configSettings->beginGroup(name);
340 showAll = configSettings->readBoolEntry("/showAll", false);
341 showName = configSettings->readBoolEntry("/showName", false); 339 showName = configSettings->readBoolEntry("/showName", false);
342 showRange = configSettings->readBoolEntry("/showRange", false); 340 showRange = configSettings->readBoolEntry("/showRange", false);
343 showData = configSettings->readBoolEntry("/showData", false); 341 showData = configSettings->readBoolEntry("/showData", false);
342 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
344 configSettings->endGroup(); 343 configSettings->endGroup();
345 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings())); 344 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
346 } 345 }
@@ -352,6 +351,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
352 reinit(); 351 reinit();
353} 352}
354 353
354bool ConfigList::menuSkip(struct menu *menu)
355{
356 if (optMode == normalOpt && menu_is_visible(menu))
357 return false;
358 if (optMode == promptOpt && menu_has_prompt(menu))
359 return false;
360 if (optMode == allOpt)
361 return false;
362 return true;
363}
364
355void ConfigList::reinit(void) 365void ConfigList::reinit(void)
356{ 366{
357 removeColumn(dataColIdx); 367 removeColumn(dataColIdx);
@@ -380,7 +390,7 @@ void ConfigList::saveSettings(void)
380 configSettings->writeEntry("/showName", showName); 390 configSettings->writeEntry("/showName", showName);
381 configSettings->writeEntry("/showRange", showRange); 391 configSettings->writeEntry("/showRange", showRange);
382 configSettings->writeEntry("/showData", showData); 392 configSettings->writeEntry("/showData", showData);
383 configSettings->writeEntry("/showAll", showAll); 393 configSettings->writeEntry("/optionMode", (int)optMode);
384 configSettings->endGroup(); 394 configSettings->endGroup();
385 } 395 }
386} 396}
@@ -606,7 +616,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
606 } 616 }
607 617
608 visible = menu_is_visible(child); 618 visible = menu_is_visible(child);
609 if (showAll || visible) { 619 if (!menuSkip(child)) {
610 if (!child->sym && !child->list && !child->prompt) 620 if (!child->sym && !child->list && !child->prompt)
611 continue; 621 continue;
612 if (!item || item->menu != child) 622 if (!item || item->menu != child)
@@ -835,7 +845,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
835 e->ignore(); 845 e->ignore();
836} 846}
837 847
838ConfigView* ConfigView::viewList; 848ConfigView*ConfigView::viewList;
849QAction *ConfigView::showNormalAction;
850QAction *ConfigView::showAllAction;
851QAction *ConfigView::showPromptAction;
839 852
840ConfigView::ConfigView(QWidget* parent, const char *name) 853ConfigView::ConfigView(QWidget* parent, const char *name)
841 : Parent(parent, name) 854 : Parent(parent, name)
@@ -860,13 +873,16 @@ ConfigView::~ConfigView(void)
860 } 873 }
861} 874}
862 875
863void ConfigView::setShowAll(bool b) 876void ConfigView::setOptionMode(QAction *act)
864{ 877{
865 if (list->showAll != b) { 878 if (act == showNormalAction)
866 list->showAll = b; 879 list->optMode = normalOpt;
867 list->updateListAll(); 880 else if (act == showAllAction)
868 emit showAllChanged(b); 881 list->optMode = allOpt;
869 } 882 else
883 list->optMode = promptOpt;
884
885 list->updateListAll();
870} 886}
871 887
872void ConfigView::setShowName(bool b) 888void ConfigView::setShowName(bool b)
@@ -964,34 +980,6 @@ void ConfigInfoView::setInfo(struct menu *m)
964 menuInfo(); 980 menuInfo();
965} 981}
966 982
967void ConfigInfoView::setSource(const QString& name)
968{
969 const char *p = name.latin1();
970
971 menu = NULL;
972 sym = NULL;
973
974 switch (p[0]) {
975 case 'm':
976 struct menu *m;
977
978 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
979 menu = m;
980 menuInfo();
981 emit menuSelected(menu);
982 }
983 break;
984 case 's':
985 struct symbol *s;
986
987 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
988 sym = s;
989 symbolInfo();
990 }
991 break;
992 }
993}
994
995void ConfigInfoView::symbolInfo(void) 983void ConfigInfoView::symbolInfo(void)
996{ 984{
997 QString str; 985 QString str;
@@ -1349,11 +1337,24 @@ ConfigMainWindow::ConfigMainWindow(void)
1349 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); 1337 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1350 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); 1338 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1351 showDataAction->setOn(configList->showData); 1339 showDataAction->setOn(configList->showData);
1352 QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this); 1340
1353 showAllAction->setToggleAction(TRUE); 1341 QActionGroup *optGroup = new QActionGroup(this);
1354 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool))); 1342 optGroup->setExclusive(TRUE);
1355 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool))); 1343 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1356 showAllAction->setOn(configList->showAll); 1344 SLOT(setOptionMode(QAction *)));
1345 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1346 SLOT(setOptionMode(QAction *)));
1347
1348 configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup);
1349 configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup);
1350 configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup);
1351 configView->showNormalAction->setToggleAction(TRUE);
1352 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1353 configView->showAllAction->setToggleAction(TRUE);
1354 configView->showAllAction->setOn(configList->optMode == allOpt);
1355 configView->showPromptAction->setToggleAction(TRUE);
1356 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1357
1357 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this); 1358 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
1358 showDebugAction->setToggleAction(TRUE); 1359 showDebugAction->setToggleAction(TRUE);
1359 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); 1360 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
@@ -1396,7 +1397,8 @@ ConfigMainWindow::ConfigMainWindow(void)
1396 showRangeAction->addTo(optionMenu); 1397 showRangeAction->addTo(optionMenu);
1397 showDataAction->addTo(optionMenu); 1398 showDataAction->addTo(optionMenu);
1398 optionMenu->insertSeparator(); 1399 optionMenu->insertSeparator();
1399 showAllAction->addTo(optionMenu); 1400 optGroup->addTo(optionMenu);
1401 optionMenu->insertSeparator();
1400 showDebugAction->addTo(optionMenu); 1402 showDebugAction->addTo(optionMenu);
1401 1403
1402 // create help menu 1404 // create help menu
@@ -1491,7 +1493,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
1491 ConfigList* list = NULL; 1493 ConfigList* list = NULL;
1492 ConfigItem* item; 1494 ConfigItem* item;
1493 1495
1494 if (!menu_is_visible(menu) && !configView->showAll()) 1496 if (configList->menuSkip(menu))
1495 return; 1497 return;
1496 1498
1497 switch (configList->mode) { 1499 switch (configList->mode) {
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index b3b5657b6b35..636a74b23bf9 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -44,6 +44,9 @@ enum colIdx {
44enum listMode { 44enum listMode {
45 singleMode, menuMode, symbolMode, fullMode, listMode 45 singleMode, menuMode, symbolMode, fullMode, listMode
46}; 46};
47enum optionMode {
48 normalOpt = 0, allOpt, promptOpt
49};
47 50
48class ConfigList : public QListView { 51class ConfigList : public QListView {
49 Q_OBJECT 52 Q_OBJECT
@@ -115,6 +118,8 @@ public:
115 void setAllOpen(bool open); 118 void setAllOpen(bool open);
116 void setParentMenu(void); 119 void setParentMenu(void);
117 120
121 bool menuSkip(struct menu *);
122
118 template <class P> 123 template <class P>
119 void updateMenuList(P*, struct menu*); 124 void updateMenuList(P*, struct menu*);
120 125
@@ -124,8 +129,9 @@ public:
124 QPixmap choiceYesPix, choiceNoPix; 129 QPixmap choiceYesPix, choiceNoPix;
125 QPixmap menuPix, menuInvPix, menuBackPix, voidPix; 130 QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
126 131
127 bool showAll, showName, showRange, showData; 132 bool showName, showRange, showData;
128 enum listMode mode; 133 enum listMode mode;
134 enum optionMode optMode;
129 struct menu *rootEntry; 135 struct menu *rootEntry;
130 QColorGroup disabledColorGroup; 136 QColorGroup disabledColorGroup;
131 QColorGroup inactivedColorGroup; 137 QColorGroup inactivedColorGroup;
@@ -222,17 +228,15 @@ public:
222 static void updateList(ConfigItem* item); 228 static void updateList(ConfigItem* item);
223 static void updateListAll(void); 229 static void updateListAll(void);
224 230
225 bool showAll(void) const { return list->showAll; }
226 bool showName(void) const { return list->showName; } 231 bool showName(void) const { return list->showName; }
227 bool showRange(void) const { return list->showRange; } 232 bool showRange(void) const { return list->showRange; }
228 bool showData(void) const { return list->showData; } 233 bool showData(void) const { return list->showData; }
229public slots: 234public slots:
230 void setShowAll(bool);
231 void setShowName(bool); 235 void setShowName(bool);
232 void setShowRange(bool); 236 void setShowRange(bool);
233 void setShowData(bool); 237 void setShowData(bool);
238 void setOptionMode(QAction *);
234signals: 239signals:
235 void showAllChanged(bool);
236 void showNameChanged(bool); 240 void showNameChanged(bool);
237 void showRangeChanged(bool); 241 void showRangeChanged(bool);
238 void showDataChanged(bool); 242 void showDataChanged(bool);
@@ -242,6 +246,10 @@ public:
242 246
243 static ConfigView* viewList; 247 static ConfigView* viewList;
244 ConfigView* nextView; 248 ConfigView* nextView;
249
250 static QAction *showNormalAction;
251 static QAction *showAllAction;
252 static QAction *showPromptAction;
245}; 253};
246 254
247class ConfigInfoView : public QTextBrowser { 255class ConfigInfoView : public QTextBrowser {
@@ -254,7 +262,6 @@ public:
254public slots: 262public slots:
255 void setInfo(struct menu *menu); 263 void setInfo(struct menu *menu);
256 void saveSettings(void); 264 void saveSettings(void);
257 void setSource(const QString& name);
258 void setShowDebug(bool); 265 void setShowDebug(bool);
259 266
260signals: 267signals:
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index 0d800820c3cd..c70a27d924f0 100644
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -113,14 +113,19 @@ find_config;
113# Get the build source and top level Kconfig file (passed in) 113# Get the build source and top level Kconfig file (passed in)
114my $ksource = $ARGV[0]; 114my $ksource = $ARGV[0];
115my $kconfig = $ARGV[1]; 115my $kconfig = $ARGV[1];
116my $lsmod_file = $ARGV[2];
117
118my @makefiles = `find $ksource -name Makefile 2>/dev/null`;
119chomp @makefiles;
116 120
117my @makefiles = `find $ksource -name Makefile`;
118my %depends; 121my %depends;
119my %selects; 122my %selects;
120my %prompts; 123my %prompts;
121my %objects; 124my %objects;
122my $var; 125my $var;
123my $cont = 0; 126my $cont = 0;
127my $iflevel = 0;
128my @ifdeps;
124 129
125# prevent recursion 130# prevent recursion
126my %read_kconfigs; 131my %read_kconfigs;
@@ -146,6 +151,15 @@ sub read_kconfig {
146 $state = "NEW"; 151 $state = "NEW";
147 $config = $1; 152 $config = $1;
148 153
154 for (my $i = 0; $i < $iflevel; $i++) {
155 if ($i) {
156 $depends{$config} .= " " . $ifdeps[$i];
157 } else {
158 $depends{$config} = $ifdeps[$i];
159 }
160 $state = "DEP";
161 }
162
149 # collect the depends for the config 163 # collect the depends for the config
150 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 164 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
151 $state = "DEP"; 165 $state = "DEP";
@@ -166,6 +180,21 @@ sub read_kconfig {
166 # note if the config has a prompt 180 # note if the config has a prompt
167 $prompt{$config} = 1; 181 $prompt{$config} = 1;
168 182
183 # Check for if statements
184 } elsif (/^if\s+(.*\S)\s*$/) {
185 my $deps = $1;
186 # remove beginning and ending non text
187 $deps =~ s/^[^a-zA-Z0-9_]*//;
188 $deps =~ s/[^a-zA-Z0-9_]*$//;
189
190 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
191
192 $ifdeps[$iflevel++] = join ':', @deps;
193
194 } elsif (/^endif/) {
195
196 $iflevel-- if ($iflevel);
197
169 # stop on "help" 198 # stop on "help"
170 } elsif (/^\s*help\s*$/) { 199 } elsif (/^\s*help\s*$/) {
171 $state = "NONE"; 200 $state = "NONE";
@@ -188,7 +217,6 @@ if ($kconfig) {
188 217
189# Read all Makefiles to map the configs to the objects 218# Read all Makefiles to map the configs to the objects
190foreach my $makefile (@makefiles) { 219foreach my $makefile (@makefiles) {
191 chomp $makefile;
192 220
193 open(MIN,$makefile) || die "Can't open $makefile"; 221 open(MIN,$makefile) || die "Can't open $makefile";
194 while (<MIN>) { 222 while (<MIN>) {
@@ -215,7 +243,7 @@ foreach my $makefile (@makefiles) {
215 foreach my $obj (split /\s+/,$objs) { 243 foreach my $obj (split /\s+/,$objs) {
216 $obj =~ s/-/_/g; 244 $obj =~ s/-/_/g;
217 if ($obj =~ /(.*)\.o$/) { 245 if ($obj =~ /(.*)\.o$/) {
218 # Objects may bes enabled by more than one config. 246 # Objects may be enabled by more than one config.
219 # Store configs in an array. 247 # Store configs in an array.
220 my @arr; 248 my @arr;
221 249
@@ -237,8 +265,36 @@ foreach my $makefile (@makefiles) {
237 265
238my %modules; 266my %modules;
239 267
240# see what modules are loaded on this system 268if (defined($lsmod_file)) {
241open(LIN,"/sbin/lsmod|") || die "Cant lsmod"; 269 if ( ! -f $lsmod_file) {
270 die "$lsmod_file not found";
271 }
272 if ( -x $lsmod_file) {
273 # the file is executable, run it
274 open(LIN, "$lsmod_file|");
275 } else {
276 # Just read the contents
277 open(LIN, "$lsmod_file");
278 }
279} else {
280
281 # see what modules are loaded on this system
282 my $lsmod;
283
284 foreach $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) {
285 if ( -x "$dir/lsmod" ) {
286 $lsmod = "$dir/lsmod";
287 last;
288 }
289}
290 if (!defined($lsmod)) {
291 # try just the path
292 $lsmod = "lsmod";
293 }
294
295 open(LIN,"$lsmod|") || die "Can not call lsmod with $lsmod";
296}
297
242while (<LIN>) { 298while (<LIN>) {
243 next if (/^Module/); # Skip the first line. 299 next if (/^Module/); # Skip the first line.
244 if (/^(\S+)/) { 300 if (/^(\S+)/) {
@@ -252,7 +308,7 @@ close (LIN);
252my %configs; 308my %configs;
253foreach my $module (keys(%modules)) { 309foreach my $module (keys(%modules)) {
254 if (defined($objects{$module})) { 310 if (defined($objects{$module})) {
255 @arr = @{$objects{$module}}; 311 my @arr = @{$objects{$module}};
256 foreach my $conf (@arr) { 312 foreach my $conf (@arr) {
257 $configs{$conf} = $module; 313 $configs{$conf} = $module;
258 } 314 }
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 2e7a048e0cfc..1f8b305449db 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym)
205 } 205 }
206 if (sym_is_choice_value(sym)) 206 if (sym_is_choice_value(sym))
207 return; 207 return;
208 /* defaulting to "yes" if no explicit "depends on" are given */
209 tri = yes;
210 if (sym->dir_dep.expr)
211 tri = expr_calc_value(sym->dir_dep.expr);
212 if (tri == mod)
213 tri = yes;
214 if (sym->dir_dep.tri != tri) {
215 sym->dir_dep.tri = tri;
216 sym_set_changed(sym);
217 }
208 tri = no; 218 tri = no;
209 if (sym->rev_dep.expr) 219 if (sym->rev_dep.expr)
210 tri = expr_calc_value(sym->rev_dep.expr); 220 tri = expr_calc_value(sym->rev_dep.expr);
@@ -216,44 +226,63 @@ static void sym_calc_visibility(struct symbol *sym)
216 } 226 }
217} 227}
218 228
219static struct symbol *sym_calc_choice(struct symbol *sym) 229/*
230 * Find the default symbol for a choice.
231 * First try the default values for the choice symbol
232 * Next locate the first visible choice value
233 * Return NULL if none was found
234 */
235struct symbol *sym_choice_default(struct symbol *sym)
220{ 236{
221 struct symbol *def_sym; 237 struct symbol *def_sym;
222 struct property *prop; 238 struct property *prop;
223 struct expr *e; 239 struct expr *e;
224 240
225 /* is the user choice visible? */
226 def_sym = sym->def[S_DEF_USER].val;
227 if (def_sym) {
228 sym_calc_visibility(def_sym);
229 if (def_sym->visible != no)
230 return def_sym;
231 }
232
233 /* any of the defaults visible? */ 241 /* any of the defaults visible? */
234 for_all_defaults(sym, prop) { 242 for_all_defaults(sym, prop) {
235 prop->visible.tri = expr_calc_value(prop->visible.expr); 243 prop->visible.tri = expr_calc_value(prop->visible.expr);
236 if (prop->visible.tri == no) 244 if (prop->visible.tri == no)
237 continue; 245 continue;
238 def_sym = prop_get_symbol(prop); 246 def_sym = prop_get_symbol(prop);
239 sym_calc_visibility(def_sym);
240 if (def_sym->visible != no) 247 if (def_sym->visible != no)
241 return def_sym; 248 return def_sym;
242 } 249 }
243 250
244 /* just get the first visible value */ 251 /* just get the first visible value */
245 prop = sym_get_choice_prop(sym); 252 prop = sym_get_choice_prop(sym);
246 expr_list_for_each_sym(prop->expr, e, def_sym) { 253 expr_list_for_each_sym(prop->expr, e, def_sym)
247 sym_calc_visibility(def_sym);
248 if (def_sym->visible != no) 254 if (def_sym->visible != no)
249 return def_sym; 255 return def_sym;
250 }
251 256
252 /* no choice? reset tristate value */ 257 /* failed to locate any defaults */
253 sym->curr.tri = no;
254 return NULL; 258 return NULL;
255} 259}
256 260
261static struct symbol *sym_calc_choice(struct symbol *sym)
262{
263 struct symbol *def_sym;
264 struct property *prop;
265 struct expr *e;
266
267 /* first calculate all choice values' visibilities */
268 prop = sym_get_choice_prop(sym);
269 expr_list_for_each_sym(prop->expr, e, def_sym)
270 sym_calc_visibility(def_sym);
271
272 /* is the user choice visible? */
273 def_sym = sym->def[S_DEF_USER].val;
274 if (def_sym && def_sym->visible != no)
275 return def_sym;
276
277 def_sym = sym_choice_default(sym);
278
279 if (def_sym == NULL)
280 /* no choice? reset tristate value */
281 sym->curr.tri = no;
282
283 return def_sym;
284}
285
257void sym_calc_value(struct symbol *sym) 286void sym_calc_value(struct symbol *sym)
258{ 287{
259 struct symbol_value newval, oldval; 288 struct symbol_value newval, oldval;
@@ -321,6 +350,16 @@ void sym_calc_value(struct symbol *sym)
321 } 350 }
322 } 351 }
323 calc_newval: 352 calc_newval:
353#if 0
354 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
355 fprintf(stderr, "warning: (");
356 expr_fprint(sym->rev_dep.expr, stderr);
357 fprintf(stderr, ") selects %s which has unmet direct dependencies (",
358 sym->name);
359 expr_fprint(sym->dir_dep.expr, stderr);
360 fprintf(stderr, ")\n");
361 }
362#endif
324 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); 363 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
325 } 364 }
326 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) 365 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
@@ -365,12 +404,13 @@ void sym_calc_value(struct symbol *sym)
365 404
366 if (sym_is_choice(sym)) { 405 if (sym_is_choice(sym)) {
367 struct symbol *choice_sym; 406 struct symbol *choice_sym;
368 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
369 407
370 prop = sym_get_choice_prop(sym); 408 prop = sym_get_choice_prop(sym);
371 expr_list_for_each_sym(prop->expr, e, choice_sym) { 409 expr_list_for_each_sym(prop->expr, e, choice_sym) {
372 choice_sym->flags |= flags; 410 if ((sym->flags & SYMBOL_WRITE) &&
373 if (flags & SYMBOL_CHANGED) 411 choice_sym->visible != no)
412 choice_sym->flags |= SYMBOL_WRITE;
413 if (sym->flags & SYMBOL_CHANGED)
374 sym_set_changed(choice_sym); 414 sym_set_changed(choice_sym);
375 } 415 }
376 } 416 }
@@ -623,6 +663,80 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
623 return true; 663 return true;
624} 664}
625 665
666/*
667 * Find the default value associated to a symbol.
668 * For tristate symbol handle the modules=n case
669 * in which case "m" becomes "y".
670 * If the symbol does not have any default then fallback
671 * to the fixed default values.
672 */
673const char *sym_get_string_default(struct symbol *sym)
674{
675 struct property *prop;
676 struct symbol *ds;
677 const char *str;
678 tristate val;
679
680 sym_calc_visibility(sym);
681 sym_calc_value(modules_sym);
682 val = symbol_no.curr.tri;
683 str = symbol_empty.curr.val;
684
685 /* If symbol has a default value look it up */
686 prop = sym_get_default_prop(sym);
687 if (prop != NULL) {
688 switch (sym->type) {
689 case S_BOOLEAN:
690 case S_TRISTATE:
691 /* The visibility imay limit the value from yes => mod */
692 val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
693 break;
694 default:
695 /*
696 * The following fails to handle the situation
697 * where a default value is further limited by
698 * the valid range.
699 */
700 ds = prop_get_symbol(prop);
701 if (ds != NULL) {
702 sym_calc_value(ds);
703 str = (const char *)ds->curr.val;
704 }
705 }
706 }
707
708 /* Handle select statements */
709 val = EXPR_OR(val, sym->rev_dep.tri);
710
711 /* transpose mod to yes if modules are not enabled */
712 if (val == mod)
713 if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
714 val = yes;
715
716 /* transpose mod to yes if type is bool */
717 if (sym->type == S_BOOLEAN && val == mod)
718 val = yes;
719
720 switch (sym->type) {
721 case S_BOOLEAN:
722 case S_TRISTATE:
723 switch (val) {
724 case no: return "n";
725 case mod: return "m";
726 case yes: return "y";
727 }
728 case S_INT:
729 case S_HEX:
730 return str;
731 case S_STRING:
732 return str;
733 case S_OTHER:
734 case S_UNKNOWN:
735 break;
736 }
737 return "";
738}
739
626const char *sym_get_string_value(struct symbol *sym) 740const char *sym_get_string_value(struct symbol *sym)
627{ 741{
628 tristate val; 742 tristate val;
@@ -765,6 +879,112 @@ struct symbol **sym_re_search(const char *pattern)
765 return sym_arr; 879 return sym_arr;
766} 880}
767 881
882/*
883 * When we check for recursive dependencies we use a stack to save
884 * current state so we can print out relevant info to user.
885 * The entries are located on the call stack so no need to free memory.
886 * Note inser() remove() must always match to properly clear the stack.
887 */
888static struct dep_stack {
889 struct dep_stack *prev, *next;
890 struct symbol *sym;
891 struct property *prop;
892 struct expr *expr;
893} *check_top;
894
895static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
896{
897 memset(stack, 0, sizeof(*stack));
898 if (check_top)
899 check_top->next = stack;
900 stack->prev = check_top;
901 stack->sym = sym;
902 check_top = stack;
903}
904
905static void dep_stack_remove(void)
906{
907 check_top = check_top->prev;
908 if (check_top)
909 check_top->next = NULL;
910}
911
912/*
913 * Called when we have detected a recursive dependency.
914 * check_top point to the top of the stact so we use
915 * the ->prev pointer to locate the bottom of the stack.
916 */
917static void sym_check_print_recursive(struct symbol *last_sym)
918{
919 struct dep_stack *stack;
920 struct symbol *sym, *next_sym;
921 struct menu *menu = NULL;
922 struct property *prop;
923 struct dep_stack cv_stack;
924
925 if (sym_is_choice_value(last_sym)) {
926 dep_stack_insert(&cv_stack, last_sym);
927 last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
928 }
929
930 for (stack = check_top; stack != NULL; stack = stack->prev)
931 if (stack->sym == last_sym)
932 break;
933 if (!stack) {
934 fprintf(stderr, "unexpected recursive dependency error\n");
935 return;
936 }
937
938 for (; stack; stack = stack->next) {
939 sym = stack->sym;
940 next_sym = stack->next ? stack->next->sym : last_sym;
941 prop = stack->prop;
942 if (prop == NULL)
943 prop = stack->sym->prop;
944
945 /* for choice values find the menu entry (used below) */
946 if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
947 for (prop = sym->prop; prop; prop = prop->next) {
948 menu = prop->menu;
949 if (prop->menu)
950 break;
951 }
952 }
953 if (stack->sym == last_sym)
954 fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
955 prop->file->name, prop->lineno);
956 if (stack->expr) {
957 fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
958 prop->file->name, prop->lineno,
959 sym->name ? sym->name : "<choice>",
960 prop_get_type_name(prop->type),
961 next_sym->name ? next_sym->name : "<choice>");
962 } else if (stack->prop) {
963 fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
964 prop->file->name, prop->lineno,
965 sym->name ? sym->name : "<choice>",
966 next_sym->name ? next_sym->name : "<choice>");
967 } else if (sym_is_choice(sym)) {
968 fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
969 menu->file->name, menu->lineno,
970 sym->name ? sym->name : "<choice>",
971 next_sym->name ? next_sym->name : "<choice>");
972 } else if (sym_is_choice_value(sym)) {
973 fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
974 menu->file->name, menu->lineno,
975 sym->name ? sym->name : "<choice>",
976 next_sym->name ? next_sym->name : "<choice>");
977 } else {
978 fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
979 prop->file->name, prop->lineno,
980 sym->name ? sym->name : "<choice>",
981 next_sym->name ? next_sym->name : "<choice>");
982 }
983 }
984
985 if (check_top == &cv_stack)
986 dep_stack_remove();
987}
768 988
769static struct symbol *sym_check_expr_deps(struct expr *e) 989static struct symbol *sym_check_expr_deps(struct expr *e)
770{ 990{
@@ -801,24 +1021,33 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
801{ 1021{
802 struct symbol *sym2; 1022 struct symbol *sym2;
803 struct property *prop; 1023 struct property *prop;
1024 struct dep_stack stack;
1025
1026 dep_stack_insert(&stack, sym);
804 1027
805 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 1028 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
806 if (sym2) 1029 if (sym2)
807 return sym2; 1030 goto out;
808 1031
809 for (prop = sym->prop; prop; prop = prop->next) { 1032 for (prop = sym->prop; prop; prop = prop->next) {
810 if (prop->type == P_CHOICE || prop->type == P_SELECT) 1033 if (prop->type == P_CHOICE || prop->type == P_SELECT)
811 continue; 1034 continue;
1035 stack.prop = prop;
812 sym2 = sym_check_expr_deps(prop->visible.expr); 1036 sym2 = sym_check_expr_deps(prop->visible.expr);
813 if (sym2) 1037 if (sym2)
814 break; 1038 break;
815 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 1039 if (prop->type != P_DEFAULT || sym_is_choice(sym))
816 continue; 1040 continue;
1041 stack.expr = prop->expr;
817 sym2 = sym_check_expr_deps(prop->expr); 1042 sym2 = sym_check_expr_deps(prop->expr);
818 if (sym2) 1043 if (sym2)
819 break; 1044 break;
1045 stack.expr = NULL;
820 } 1046 }
821 1047
1048out:
1049 dep_stack_remove();
1050
822 return sym2; 1051 return sym2;
823} 1052}
824 1053
@@ -827,6 +1056,9 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
827 struct symbol *sym, *sym2; 1056 struct symbol *sym, *sym2;
828 struct property *prop; 1057 struct property *prop;
829 struct expr *e; 1058 struct expr *e;
1059 struct dep_stack stack;
1060
1061 dep_stack_insert(&stack, choice);
830 1062
831 prop = sym_get_choice_prop(choice); 1063 prop = sym_get_choice_prop(choice);
832 expr_list_for_each_sym(prop->expr, e, sym) 1064 expr_list_for_each_sym(prop->expr, e, sym)
@@ -840,10 +1072,8 @@ static struct symbol *sym_check_choice_deps(struct symbol *choice)
840 1072
841 expr_list_for_each_sym(prop->expr, e, sym) { 1073 expr_list_for_each_sym(prop->expr, e, sym) {
842 sym2 = sym_check_sym_deps(sym); 1074 sym2 = sym_check_sym_deps(sym);
843 if (sym2) { 1075 if (sym2)
844 fprintf(stderr, " -> %s", sym->name);
845 break; 1076 break;
846 }
847 } 1077 }
848out: 1078out:
849 expr_list_for_each_sym(prop->expr, e, sym) 1079 expr_list_for_each_sym(prop->expr, e, sym)
@@ -853,6 +1083,8 @@ out:
853 prop_get_symbol(sym_get_choice_prop(sym2)) == choice) 1083 prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
854 sym2 = choice; 1084 sym2 = choice;
855 1085
1086 dep_stack_remove();
1087
856 return sym2; 1088 return sym2;
857} 1089}
858 1090
@@ -862,18 +1094,20 @@ struct symbol *sym_check_deps(struct symbol *sym)
862 struct property *prop; 1094 struct property *prop;
863 1095
864 if (sym->flags & SYMBOL_CHECK) { 1096 if (sym->flags & SYMBOL_CHECK) {
865 fprintf(stderr, "%s:%d:error: found recursive dependency: %s", 1097 sym_check_print_recursive(sym);
866 sym->prop->file->name, sym->prop->lineno,
867 sym->name ? sym->name : "<choice>");
868 return sym; 1098 return sym;
869 } 1099 }
870 if (sym->flags & SYMBOL_CHECKED) 1100 if (sym->flags & SYMBOL_CHECKED)
871 return NULL; 1101 return NULL;
872 1102
873 if (sym_is_choice_value(sym)) { 1103 if (sym_is_choice_value(sym)) {
1104 struct dep_stack stack;
1105
874 /* for choice groups start the check with main choice symbol */ 1106 /* for choice groups start the check with main choice symbol */
1107 dep_stack_insert(&stack, sym);
875 prop = sym_get_choice_prop(sym); 1108 prop = sym_get_choice_prop(sym);
876 sym2 = sym_check_deps(prop_get_symbol(prop)); 1109 sym2 = sym_check_deps(prop_get_symbol(prop));
1110 dep_stack_remove();
877 } else if (sym_is_choice(sym)) { 1111 } else if (sym_is_choice(sym)) {
878 sym2 = sym_check_choice_deps(sym); 1112 sym2 = sym_check_choice_deps(sym);
879 } else { 1113 } else {
@@ -882,14 +1116,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
882 sym->flags &= ~SYMBOL_CHECK; 1116 sym->flags &= ~SYMBOL_CHECK;
883 } 1117 }
884 1118
885 if (sym2) { 1119 if (sym2 && sym2 == sym)
886 fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); 1120 sym2 = NULL;
887 if (sym2 == sym) {
888 fprintf(stderr, "\n");
889 zconfnerrs++;
890 sym2 = NULL;
891 }
892 }
893 1121
894 return sym2; 1122 return sym2;
895} 1123}
@@ -943,6 +1171,8 @@ const char *prop_get_type_name(enum prop_type type)
943 return "select"; 1171 return "select";
944 case P_RANGE: 1172 case P_RANGE:
945 return "range"; 1173 return "range";
1174 case P_SYMBOL:
1175 return "symbol";
946 case P_UNKNOWN: 1176 case P_UNKNOWN:
947 break; 1177 break;
948 } 1178 }
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 81c100d953ef..78b5c04e736b 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -72,7 +72,7 @@ int file_write_dep(const char *name)
72} 72}
73 73
74 74
75/* Allocate initial growable sting */ 75/* Allocate initial growable string */
76struct gstr str_new(void) 76struct gstr str_new(void)
77{ 77{
78 struct gstr gs; 78 struct gstr gs;