summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--scripts/kconfig/Makefile51
-rw-r--r--scripts/kconfig/Makefile.kernel52
-rw-r--r--scripts/kconfig/conf.c222
-rw-r--r--scripts/kconfig/confdata.c152
-rw-r--r--scripts/kconfig/expr.c37
-rw-r--r--scripts/kconfig/expr.h79
-rw-r--r--scripts/kconfig/gconf.c1618
-rw-r--r--scripts/kconfig/gconf.glade543
-rw-r--r--scripts/kconfig/images.c34
-rw-r--r--scripts/kconfig/lkc-language.txt52
-rw-r--r--scripts/kconfig/lkc.h14
-rw-r--r--scripts/kconfig/lkc_proto.h5
-rw-r--r--scripts/kconfig/mconf.c66
-rw-r--r--scripts/kconfig/menu.c194
-rw-r--r--scripts/kconfig/qconf.cc405
-rw-r--r--scripts/kconfig/qconf.h20
-rw-r--r--scripts/kconfig/symbol.c465
-rw-r--r--scripts/kconfig/zconf.l23
-rw-r--r--scripts/kconfig/zconf.y230
19 files changed, 3489 insertions, 773 deletions
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 5a0d7e5..b918300 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -1,29 +1,32 @@
1VERSION=1.3 1VERSION=1.4
2CC=gcc 2CC=gcc
3CXX=g++ 3CXX=g++
4CFLAGS=-O0 -Wall -g -fPIC 4CFLAGS=-O0 -Wall -g -fPIC
5CXXFLAGS=$(CFLAGS) -I$(HOSTQTDIR)/include 5CXXFLAGS=$(CFLAGS) -I$(QTDIR)/include
6LDFLAGS= 6LDFLAGS=
7LXXFLAGS=$(LDFLAGS) -L$(HOSTQTDIR)/lib -Wl,-rpath,$(HOSTQTDIR)/lib 7LXXFLAGS=$(LDFLAGS) -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib
8LEX=flex 8LEX=flex
9LFLAGS=-L 9LFLAGS=-L
10YACC=bison 10YACC=bison
11YFLAGS=-l 11YFLAGS=-l
12#YFLAGS=-d -t -v -l 12#YFLAGS=-t -v -l
13ifndef HOSTQTDIR 13ifndef QTDIR
14HOSTQTDIR=/usr/share/qt 14QTDIR=/usr/share/qt3
15endif 15endif
16MOC=$(wildcard $(HOSTQTDIR)/bin/moc) 16MOC=$(wildcard $(QTDIR)/bin/moc)
17GTKCFLAGS=`pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags`
18GTKLDFLAGS=`pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
17 19
18parse_SRC=zconf.y 20parse_SRC=zconf.y
19conf_SRC=conf.c $(parse_SRC) 21conf_SRC=conf.c $(parse_SRC)
20mconf_SRC=mconf.c $(parse_SRC) 22mconf_SRC=mconf.c $(parse_SRC)
21qconf_SRC=qconf.cc 23qconf_SRC=qconf.cc
24gconf_SRC=gconf.c kconfig_load.c
22HDR=expr.h lkc.h lkc_proto.h qconf.h 25HDR=expr.h lkc.h lkc_proto.h qconf.h
23OTHER=README lkc-language.txt Makefile.kernel \ 26OTHER=README lkc-language.txt Makefile.kernel \
24 kconfig.i extconf.rb example 27 kconfig.i extconf.rb example
25INST=zconf.y zconf.l confdata.c expr.c symbol.c menu.c \ 28INST=zconf.y zconf.l confdata.c expr.c symbol.c menu.c \
26 conf.c mconf.c qconf.cc kconfig_load.c images.c $(HDR) 29 conf.c mconf.c qconf.cc gconf.c gconf.glade kconfig_load.c images.c $(HDR)
27INSTGEN=lex.zconf.c zconf.tab.c 30INSTGEN=lex.zconf.c zconf.tab.c
28 31
29#DEBUG=1 32#DEBUG=1
@@ -60,6 +63,11 @@ qconf_OBJ=$(filter %.o, \
60 $(patsubst %.y,%.tab.o, \ 63 $(patsubst %.y,%.tab.o, \
61 $(patsubst %.l,lex.%.o, \ 64 $(patsubst %.l,lex.%.o, \
62 $(qconf_SRC)))))) 65 $(qconf_SRC))))))
66gconf_OBJ=$(filter %.o, \
67 $(patsubst %.c,%.o, \
68 $(patsubst %.y,%.tab.o, \
69 $(patsubst %.l,lex.%.o, \
70 $(gconf_SRC)))))
63OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ) 71OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ)
64 72
65ifeq ($(MOC),) 73ifeq ($(MOC),)
@@ -84,6 +92,7 @@ conf.o: conf.c $(lkc_deps)
84mconf.o: mconf.c $(lkc_deps) 92mconf.o: mconf.c $(lkc_deps)
85qconf.moc: qconf.h 93qconf.moc: qconf.h
86qconf.o: qconf.cc qconf.moc images.c $(lkc_deps) 94qconf.o: qconf.cc qconf.moc images.c $(lkc_deps)
95gconf.o: gconf.c $(lkc_deps)
87 96
88mconf: $(mconf_OBJ) 97mconf: $(mconf_OBJ)
89 $(CC) $(LDFLAGS) $^ -o $@ 98 $(CC) $(LDFLAGS) $^ -o $@
@@ -94,14 +103,20 @@ conf: $(conf_OBJ)
94ifeq ($(MOC),) 103ifeq ($(MOC),)
95qconf: 104qconf:
96 @echo Unable to find the QT installation. Please make sure that the 105 @echo Unable to find the QT installation. Please make sure that the
97 @echo QT development package is correctly installed and the HOSTQTDIR 106 @echo QT development package is correctly installed and the QTDIR
98 @echo environment variable is set to the correct location. 107 @echo environment variable is set to the correct location.
99 @false 108 @false
100else 109else
101qconf: $(qconf_OBJ) 110qconf: $(qconf_OBJ)
102 $(CXX) $(LXXFLAGS) $^ -lqt -o $@ 111 $(CXX) $(LXXFLAGS) $^ -lqt-mt -o $@
103endif 112endif
104 113
114gconf.o: gconf.c
115 $(CC) $(CFLAGS) $(GTKCFLAGS) -c $< -o $@
116
117gconf: $(gconf_OBJ)
118 $(CC) $(LDFLAGS) $(GTKLDFLAGS) $^ -o $@
119
105libkconfig.so: $(parse_OBJ) 120libkconfig.so: $(parse_OBJ)
106 $(CC) -shared $^ -o $@ 121 $(CC) -shared $^ -o $@
107 122
@@ -126,7 +141,7 @@ lex.%.c: %.l
126 $(LEX) $(LFLAGS) -P$* $< 141 $(LEX) $(LFLAGS) -P$* $<
127 142
128%.moc: %.h 143%.moc: %.h
129 $(HOSTQTDIR)/bin/moc -i $< -o $@ 144 $(QTDIR)/bin/moc -i $< -o $@
130 145
131%.o: %.c 146%.o: %.c
132 $(CC) $(CFLAGS) -c $< -o $@ 147 $(CC) $(CFLAGS) -c $< -o $@
@@ -136,14 +151,16 @@ lex.%.c: %.l
136 151
137ifdef KERNELSRC 152ifdef KERNELSRC
138install: $(INSTGEN) 153install: $(INSTGEN)
139 set -x; cp $(sort $(INST)) $(KERNELSRC)/scripts/kconfig; \ 154 set -x; cp --remove-destination $(sort $(INST)) $(KERNELSRC)/scripts/kconfig; \
140 for f in $(INSTGEN); do cp $$f $(KERNELSRC)/scripts/kconfig/$${f}_shipped; done; \ 155 for f in $(INSTGEN); do cp --remove-destination $$f $(KERNELSRC)/scripts/kconfig/$${f}_shipped; done; \
141 cp Makefile.kernel $(KERNELSRC)/scripts/kconfig/Makefile 156 cp --remove-destination Makefile.kernel $(KERNELSRC)/scripts/kconfig/Makefile; \
157 cp --remove-destination lkc-language.txt $(KERNELSRC)/Documentation/kbuild/kconfig-language.txt
142 158
143diff: $(INSTGEN) 159diff: $(INSTGEN)
144 for f in $(sort $(INST)); do diff -u $(KERNELSRC)/scripts/kconfig/$$f $$f; done; \ 160 for f in $(sort $(INST)); do diff -Nu $(KERNELSRC)/scripts/kconfig/$$f $$f; done; \
145 for f in $(INSTGEN); do diff -u $(KERNELSRC)/scripts/kconfig/$${f}_shipped $$f; done; \ 161 for f in $(INSTGEN); do diff -Nu $(KERNELSRC)/scripts/kconfig/$${f}_shipped $$f; done; \
146 diff -u $(KERNELSRC)/scripts/kconfig/Makefile Makefile.kernel 162 diff -Nu $(KERNELSRC)/scripts/kconfig/Makefile Makefile.kernel; \
163 diff -Nu lkc-language.txt $(KERNELSRC)/Documentation/kbuild/kconfig-language.txt
147else 164else
148install: 165install:
149 @echo "Please use KERNELSRC=<path/to/linux-kernel> to install" 166 @echo "Please use KERNELSRC=<path/to/linux-kernel> to install"
diff --git a/scripts/kconfig/Makefile.kernel b/scripts/kconfig/Makefile.kernel
index 22724a7..bae5e29 100644
--- a/scripts/kconfig/Makefile.kernel
+++ b/scripts/kconfig/Makefile.kernel
@@ -6,22 +6,29 @@
6# Utilizes the lxdialog package 6# Utilizes the lxdialog package
7# qconf: Used for the xconfig target 7# qconf: Used for the xconfig target
8# Based on QT which needs to be installed to compile it 8# Based on QT which needs to be installed to compile it
9# gconf: Used for the gconfig target
10# Based on GTK which needs to be installed to compile it
9# 11#
12#################
10 13
11# object files used by all lkc flavours 14# object files used by all lkc flavours
12libkconfig-objs := zconf.tab.o 15libkconfig-objs := zconf.tab.o
13 16
14 host-progs:= conf mconf qconf 17 host-progs:= conf mconf qconf gconf
15 conf-objs:= conf.o libkconfig.so 18 conf-objs:= conf.o libkconfig.so
16 mconf-objs:= mconf.o libkconfig.so 19 mconf-objs:= mconf.o libkconfig.so
17 20
18 qconf-objs:= kconfig_load.o 21ifeq ($(MAKECMDGOALS),$(obj)/qconf)
19 qconf-cxxobjs:= qconf.o 22 qconf-cxxobjs:= qconf.o
23 qconf-objs:= kconfig_load.o
24endif
20 25
21 clean-files:= libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \ 26ifeq ($(MAKECMDGOALS),$(obj)/gconf)
22 zconf.tab.c zconf.tab.h lex.zconf.c 27 gconf-objs:= gconf.o kconfig_load.o
28endif
23 29
24include $(TOPDIR)/Rules.make 30 clean-files:= libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \
31 .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c
25 32
26# generated files seem to need this to find local include files 33# generated files seem to need this to find local include files
27 HOSTCFLAGS_lex.zconf.o:= -I$(src) 34 HOSTCFLAGS_lex.zconf.o:= -I$(src)
@@ -30,7 +37,10 @@ HOSTCFLAGS_zconf.tab.o := -I$(src)
30 HOSTLOADLIBES_qconf= -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib -l$(QTLIB) -ldl 37 HOSTLOADLIBES_qconf= -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib -l$(QTLIB) -ldl
31 HOSTCXXFLAGS_qconf.o= -I$(QTDIR)/include 38 HOSTCXXFLAGS_qconf.o= -I$(QTDIR)/include
32 39
33$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o: $(obj)/zconf.tab.h 40 HOSTLOADLIBES_gconf= `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
41 HOSTCFLAGS_gconf.o= `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags`
42
43$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h
34 44
35$(obj)/qconf.o: $(obj)/.tmp_qtcheck 45$(obj)/qconf.o: $(obj)/.tmp_qtcheck
36 46
@@ -40,7 +50,7 @@ MOC = $(QTDIR)/bin/moc
40 50
41# QT needs some extra effort... 51# QT needs some extra effort...
42$(obj)/.tmp_qtcheck: 52$(obj)/.tmp_qtcheck:
43 @set -e; for d in $$QTDIR /usr/share/qt /usr/lib/qt3; do \ 53 @set -e; for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
44 if [ -f $$d/include/qconfig.h ]; then DIR=$$d; break; fi; \ 54 if [ -f $$d/include/qconfig.h ]; then DIR=$$d; break; fi; \
45 done; \ 55 done; \
46 if [ -z "$$DIR" ]; then \ 56 if [ -z "$$DIR" ]; then \
@@ -62,12 +72,40 @@ $(obj)/.tmp_qtcheck:
62 fi 72 fi
63endif 73endif
64 74
75$(obj)/gconf.o: $(obj)/.tmp_gtkcheck
76
77ifeq ($(MAKECMDGOALS),$(obj)/gconf)
78-include $(obj)/.tmp_gtkcheck
79
80# GTK needs some extra effort, too...
81$(obj)/.tmp_gtkcheck:
82 @if `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --exists`; then \
83 if `pkg-config gtk+-2.0 --atleast-version=2.0.0`; then \
84 touch $@; \
85 else \
86 echo "*"; \
87 echo "* GTK+ is present but version >= 2.0.0 is required.";\
88 echo "*"; \
89 false; \
90 fi \
91 else \
92 echo "*"; \
93 echo "* Unable to find the GTK+ installation. Please make sure that"; \
94 echo "* the GTK+ 2.0 development package is correctly installed..."; \
95 echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \
96 echo "*"; \
97 false; \
98 fi
99endif
100
65$(obj)/zconf.tab.o: $(obj)/lex.zconf.c 101$(obj)/zconf.tab.o: $(obj)/lex.zconf.c
66 102
67$(obj)/kconfig_load.o: $(obj)/lkc_defs.h 103$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
68 104
69$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h 105$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h
70 106
107$(obj)/gconf.o: $(obj)/lkc_defs.h
108
71$(obj)/%.moc: $(src)/%.h 109$(obj)/%.moc: $(src)/%.h
72 $(MOC) -i $< -o $@ 110 $(MOC) -i $< -o $@
73 111
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 1602d5f..3c27a78 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -35,44 +35,6 @@ static struct menu *rootEntry;
35 35
36static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; 36static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
37 37
38#if 0
39static void printc(int ch)
40{
41 static int sep = 0;
42
43 if (!sep) {
44 putchar('[');
45 sep = 1;
46 } else if (ch)
47 putchar('/');
48 if (!ch) {
49 putchar(']');
50 putchar(' ');
51 sep = 0;
52 } else
53 putchar(ch);
54}
55#endif
56
57static void printo(const char *o)
58{
59 static int sep = 0;
60
61 if (!sep) {
62 putchar('(');
63 sep = 1;
64 } else if (o) {
65 putchar(',');
66 putchar(' ');
67 }
68 if (!o) {
69 putchar(')');
70 putchar(' ');
71 sep = 0;
72 } else
73 printf("%s", o);
74}
75
76static void strip(char *str) 38static void strip(char *str)
77{ 39{
78 char *p = str; 40 char *p = str;
@@ -90,6 +52,16 @@ static void strip(char *str)
90 *p-- = 0; 52 *p-- = 0;
91} 53}
92 54
55static void check_stdin(void)
56{
57 if (!valid_stdin && input_mode == ask_silent) {
58 printf("aborted!\n\n");
59 printf("Console input/output is redirected. ");
60 printf("Run 'make oldconfig' to update configuration.\n\n");
61 exit(1);
62 }
63}
64
93static void conf_askvalue(struct symbol *sym, const char *def) 65static void conf_askvalue(struct symbol *sym, const char *def)
94{ 66{
95 enum symbol_type type = sym_get_type(sym); 67 enum symbol_type type = sym_get_type(sym);
@@ -101,6 +73,13 @@ static void conf_askvalue(struct symbol *sym, const char *def)
101 line[0] = '\n'; 73 line[0] = '\n';
102 line[1] = 0; 74 line[1] = 0;
103 75
76 if (!sym_is_changable(sym)) {
77 printf("%s\n", def);
78 line[0] = '\n';
79 line[1] = 0;
80 return;
81 }
82
104 switch (input_mode) { 83 switch (input_mode) {
105 case ask_new: 84 case ask_new:
106 case ask_silent: 85 case ask_silent:
@@ -108,12 +87,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
108 printf("%s\n", def); 87 printf("%s\n", def);
109 return; 88 return;
110 } 89 }
111 if (!valid_stdin && input_mode == ask_silent) { 90 check_stdin();
112 printf("aborted!\n\n");
113 printf("Console input/output is redirected. ");
114 printf("Run 'make oldconfig' to update configuration.\n\n");
115 exit(1);
116 }
117 case ask_all: 91 case ask_all:
118 fflush(stdout); 92 fflush(stdout);
119 fgets(line, 128, stdin); 93 fgets(line, 128, stdin);
@@ -294,9 +268,8 @@ help:
294static int conf_choice(struct menu *menu) 268static int conf_choice(struct menu *menu)
295{ 269{
296 struct symbol *sym, *def_sym; 270 struct symbol *sym, *def_sym;
297 struct menu *cmenu, *def_menu; 271 struct menu *child;
298 const char *help; 272 int type;
299 int type, len;
300 bool is_new; 273 bool is_new;
301 274
302 sym = menu->sym; 275 sym = menu->sym;
@@ -314,74 +287,111 @@ static int conf_choice(struct menu *menu)
314 break; 287 break;
315 } 288 }
316 } else { 289 } else {
317 sym->def = sym->curr; 290 switch (sym_get_tristate_value(sym)) {
318 if (S_TRI(sym->curr) == mod) { 291 case no:
292 return 1;
293 case mod:
319 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 294 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
320 return 0; 295 return 0;
296 case yes:
297 break;
321 } 298 }
322 } 299 }
323 300
324 while (1) { 301 while (1) {
325 printf("%*s%s ", indent - 1, "", menu_get_prompt(menu)); 302 int cnt, def;
303
304 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
326 def_sym = sym_get_choice_value(sym); 305 def_sym = sym_get_choice_value(sym);
327 def_menu = NULL; 306 cnt = def = 0;
328 for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { 307 line[0] = '0';
329 if (!menu_is_visible(cmenu)) 308 line[1] = 0;
309 for (child = menu->list; child; child = child->next) {
310 if (!menu_is_visible(child))
330 continue; 311 continue;
331 printo(menu_get_prompt(cmenu)); 312 if (!child->sym) {
332 if (cmenu->sym == def_sym) 313 printf("%*c %s\n", indent, '*', menu_get_prompt(child));
333 def_menu = cmenu; 314 continue;
334 } 315 }
335 printo(NULL); 316 cnt++;
336 if (def_menu) 317 if (child->sym == def_sym) {
337 printf("[%s] ", menu_get_prompt(def_menu)); 318 def = cnt;
338 else { 319 printf("%*c", indent, '>');
320 } else
321 printf("%*c", indent, ' ');
322 printf(" %d. %s", cnt, menu_get_prompt(child));
323 if (child->sym->name)
324 printf(" (%s)", child->sym->name);
325 if (!sym_has_value(child->sym))
326 printf(" (NEW)");
339 printf("\n"); 327 printf("\n");
340 return 1;
341 } 328 }
329 printf("%*schoice", indent - 1, "");
330 if (cnt == 1) {
331 printf("[1]: 1\n");
332 goto conf_childs;
333 }
334 printf("[1-%d", cnt);
335 if (sym->help)
336 printf("?");
337 printf("]: ");
342 switch (input_mode) { 338 switch (input_mode) {
343 case ask_new: 339 case ask_new:
344 case ask_silent: 340 case ask_silent:
341 if (!is_new) {
342 cnt = def;
343 printf("%d\n", cnt);
344 break;
345 }
346 check_stdin();
345 case ask_all: 347 case ask_all:
346 if (is_new) 348 fflush(stdout);
347 sym->flags |= SYMBOL_NEW; 349 fgets(line, 128, stdin);
348 conf_askvalue(sym, menu_get_prompt(def_menu));
349 strip(line); 350 strip(line);
351 if (line[0] == '?') {
352 printf("\n%s\n", menu->sym->help ?
353 menu->sym->help : nohelp_text);
354 continue;
355 }
356 if (!line[0])
357 cnt = def;
358 else if (isdigit(line[0]))
359 cnt = atoi(line);
360 else
361 continue;
362 break;
363 case set_random:
364 def = (random() % cnt) + 1;
365 case set_default:
366 case set_yes:
367 case set_mod:
368 case set_no:
369 cnt = def;
370 printf("%d\n", cnt);
350 break; 371 break;
351 default:
352 line[0] = 0;
353 printf("\n");
354 } 372 }
355 if (line[0] == '?' && !line[1]) { 373
356 help = nohelp_text; 374 conf_childs:
357 if (menu->sym->help) 375 for (child = menu->list; child; child = child->next) {
358 help = menu->sym->help; 376 if (!child->sym || !menu_is_visible(child))
359 printf("\n%s\n", help); 377 continue;
360 continue; 378 if (!--cnt)
379 break;
361 } 380 }
362 if (line[0]) { 381 if (!child)
363 len = strlen(line); 382 continue;
364 line[len] = 0; 383 if (line[strlen(line) - 1] == '?') {
365 384 printf("\n%s\n", child->sym->help ?
366 def_menu = NULL; 385 child->sym->help : nohelp_text);
367 for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { 386 continue;
368 if (!cmenu->sym || !menu_is_visible(cmenu))
369 continue;
370 if (!strncasecmp(line, menu_get_prompt(cmenu), len)) {
371 def_menu = cmenu;
372 break;
373 }
374 }
375 } 387 }
376 if (def_menu) { 388 sym_set_choice_value(sym, child->sym);
377 sym_set_choice_value(sym, def_menu->sym); 389 if (child->list) {
378 if (def_menu->list) { 390 indent += 2;
379 indent += 2; 391 conf(child->list);
380 conf(def_menu->list); 392 indent -= 2;
381 indent -= 2;
382 }
383 return 1;
384 } 393 }
394 return 1;
385 } 395 }
386} 396}
387 397
@@ -422,7 +432,7 @@ static void conf(struct menu *menu)
422 432
423 if (sym_is_choice(sym)) { 433 if (sym_is_choice(sym)) {
424 conf_choice(menu); 434 conf_choice(menu);
425 if (S_TRI(sym->curr) != mod) 435 if (sym->curr.tri != mod)
426 return; 436 return;
427 goto conf_childs; 437 goto conf_childs;
428 } 438 }
@@ -456,29 +466,17 @@ static void check_conf(struct menu *menu)
456 return; 466 return;
457 467
458 sym = menu->sym; 468 sym = menu->sym;
459 if (!sym) 469 if (sym) {
460 goto conf_childs; 470 if (sym_is_changable(sym) && !sym_has_value(sym)) {
461
462 if (sym_is_choice(sym)) {
463 if (!sym_has_value(sym)) {
464 if (!conf_cnt++) 471 if (!conf_cnt++)
465 printf("*\n* Restart config...\n*\n"); 472 printf("*\n* Restart config...\n*\n");
466 rootEntry = menu_get_parent_menu(menu); 473 rootEntry = menu_get_parent_menu(menu);
467 conf(rootEntry); 474 conf(rootEntry);
468 } 475 }
469 if (sym_get_tristate_value(sym) != mod) 476 if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
470 return; 477 return;
471 goto conf_childs;
472 } 478 }
473 479
474 if (!sym_has_value(sym)) {
475 if (!conf_cnt++)
476 printf("*\n* Restart config...\n*\n");
477 rootEntry = menu_get_parent_menu(menu);
478 conf(rootEntry);
479 }
480
481conf_childs:
482 for (child = menu->list; child; child = child->next) 480 for (child = menu->list; child; child = child->next)
483 check_conf(child); 481 check_conf(child);
484} 482}
@@ -536,7 +534,7 @@ int main(int ac, char **av)
536 case ask_silent: 534 case ask_silent:
537 if (stat(".config", &tmpstat)) { 535 if (stat(".config", &tmpstat)) {
538 printf("***\n" 536 printf("***\n"
539 "*** You have not yet configured your kernel!\n" 537 "*** You have not yet configured!\n"
540 "***\n" 538 "***\n"
541 "*** Please run some configurator (e.g. \"make oldconfig\" or\n" 539 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
542 "*** \"make menuconfig\" or \"make xconfig\").\n" 540 "*** \"make menuconfig\" or \"make xconfig\").\n"
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 9bf7af9..f3796ce 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -19,9 +19,6 @@ const char conf_defname[] = "arch/$ARCH/defconfig";
19 19
20const char *conf_confnames[] = { 20const char *conf_confnames[] = {
21 ".config", 21 ".config",
22 "/lib/modules/$UNAME_RELEASE/.config",
23 "/etc/kernel-config",
24 "/boot/config-$UNAME_RELEASE",
25 conf_defname, 22 conf_defname,
26 NULL, 23 NULL,
27}; 24};
@@ -105,11 +102,11 @@ int conf_read(const char *name)
105 case S_INT: 102 case S_INT:
106 case S_HEX: 103 case S_HEX:
107 case S_STRING: 104 case S_STRING:
108 if (S_VAL(sym->def)) 105 if (sym->user.val)
109 free(S_VAL(sym->def)); 106 free(sym->user.val);
110 default: 107 default:
111 S_VAL(sym->def) = NULL; 108 sym->user.val = NULL;
112 S_TRI(sym->def) = no; 109 sym->user.tri = no;
113 } 110 }
114 } 111 }
115 112
@@ -129,7 +126,7 @@ int conf_read(const char *name)
129 switch (sym->type) { 126 switch (sym->type) {
130 case S_BOOLEAN: 127 case S_BOOLEAN:
131 case S_TRISTATE: 128 case S_TRISTATE:
132 sym->def = symbol_no.curr; 129 sym->user = symbol_no.curr;
133 sym->flags &= ~SYMBOL_NEW; 130 sym->flags &= ~SYMBOL_NEW;
134 break; 131 break;
135 default: 132 default:
@@ -154,18 +151,18 @@ int conf_read(const char *name)
154 switch (sym->type) { 151 switch (sym->type) {
155 case S_TRISTATE: 152 case S_TRISTATE:
156 if (p[0] == 'm') { 153 if (p[0] == 'm') {
157 S_TRI(sym->def) = mod; 154 sym->user.tri = mod;
158 sym->flags &= ~SYMBOL_NEW; 155 sym->flags &= ~SYMBOL_NEW;
159 break; 156 break;
160 } 157 }
161 case S_BOOLEAN: 158 case S_BOOLEAN:
162 if (p[0] == 'y') { 159 if (p[0] == 'y') {
163 S_TRI(sym->def) = yes; 160 sym->user.tri = yes;
164 sym->flags &= ~SYMBOL_NEW; 161 sym->flags &= ~SYMBOL_NEW;
165 break; 162 break;
166 } 163 }
167 if (p[0] == 'n') { 164 if (p[0] == 'n') {
168 S_TRI(sym->def) = no; 165 sym->user.tri = no;
169 sym->flags &= ~SYMBOL_NEW; 166 sym->flags &= ~SYMBOL_NEW;
170 break; 167 break;
171 } 168 }
@@ -187,7 +184,7 @@ int conf_read(const char *name)
187 case S_INT: 184 case S_INT:
188 case S_HEX: 185 case S_HEX:
189 if (sym_string_valid(sym, p)) { 186 if (sym_string_valid(sym, p)) {
190 S_VAL(sym->def) = strdup(p); 187 sym->user.val = strdup(p);
191 sym->flags &= ~SYMBOL_NEW; 188 sym->flags &= ~SYMBOL_NEW;
192 } else { 189 } else {
193 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); 190 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
@@ -198,21 +195,21 @@ int conf_read(const char *name)
198 ; 195 ;
199 } 196 }
200 if (sym_is_choice_value(sym)) { 197 if (sym_is_choice_value(sym)) {
201 prop = sym_get_choice_prop(sym); 198 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
202 switch (S_TRI(sym->def)) { 199 switch (sym->user.tri) {
203 case mod: 200 case mod:
204 if (S_TRI(prop->def->def) == yes) 201 if (cs->user.tri == yes)
205 /* warn? */; 202 /* warn? */;
206 break; 203 break;
207 case yes: 204 case yes:
208 if (S_TRI(prop->def->def) != no) 205 if (cs->user.tri != no)
209 /* warn? */; 206 /* warn? */;
210 S_VAL(prop->def->def) = sym; 207 cs->user.val = sym;
211 break; 208 break;
212 case no: 209 case no:
213 break; 210 break;
214 } 211 }
215 S_TRI(prop->def->def) = S_TRI(sym->def); 212 cs->user.tri = sym->user.tri;
216 } 213 }
217 break; 214 break;
218 case '\n': 215 case '\n':
@@ -224,12 +221,27 @@ int conf_read(const char *name)
224 fclose(in); 221 fclose(in);
225 222
226 for_all_symbols(i, sym) { 223 for_all_symbols(i, sym) {
224 sym_calc_value(sym);
225 if (sym_has_value(sym)) {
226 if (sym->visible == no)
227 sym->flags |= SYMBOL_NEW;
228 switch (sym->type) {
229 case S_STRING:
230 case S_INT:
231 case S_HEX:
232 if (!sym_string_within_range(sym, sym->user.val))
233 sym->flags |= SYMBOL_NEW;
234 default:
235 break;
236 }
237 }
227 if (!sym_is_choice(sym)) 238 if (!sym_is_choice(sym))
228 continue; 239 continue;
229 prop = sym_get_choice_prop(sym); 240 prop = sym_get_choice_prop(sym);
230 sym->flags &= ~SYMBOL_NEW; 241 sym->flags &= ~SYMBOL_NEW;
231 for (e = prop->dep; e; e = e->left.expr) 242 for (e = prop->expr; e; e = e->left.expr)
232 sym->flags |= e->right.sym->flags & SYMBOL_NEW; 243 if (e->right.sym->visible != no)
244 sym->flags |= e->right.sym->flags & SYMBOL_NEW;
233 } 245 }
234 246
235 sym_change_count = 1; 247 sym_change_count = 1;
@@ -242,23 +254,45 @@ int conf_write(const char *name)
242 FILE *out, *out_h; 254 FILE *out, *out_h;
243 struct symbol *sym; 255 struct symbol *sym;
244 struct menu *menu; 256 struct menu *menu;
245 char oldname[128]; 257 const char *basename;
258 char dirname[128], tmpname[128], newname[128];
246 int type, l; 259 int type, l;
247 const char *str; 260 const char *str;
248 261
249 out = fopen(".tmpconfig", "w"); 262 dirname[0] = 0;
263 if (name && name[0]) {
264 char *slash = strrchr(name, '/');
265 if (slash) {
266 int size = slash - name + 1;
267 memcpy(dirname, name, size);
268 dirname[size] = 0;
269 if (slash[1])
270 basename = slash + 1;
271 else
272 basename = conf_def_filename;
273 } else
274 basename = name;
275 } else
276 basename = conf_def_filename;
277
278 sprintf(newname, "%s.tmpconfig.%d", dirname, getpid());
279 out = fopen(newname, "w");
250 if (!out) 280 if (!out)
251 return 1; 281 return 1;
252 out_h = fopen(".tmpconfig.h", "w"); 282 out_h = NULL;
253 if (!out_h) 283 if (!name) {
254 return 1; 284 out_h = fopen(".tmpconfig.h", "w");
285 if (!out_h)
286 return 1;
287 }
255 fprintf(out, "#\n" 288 fprintf(out, "#\n"
256 "# Automatically generated make config: don't edit\n" 289 "# Automatically generated make config: don't edit\n"
257 "#\n"); 290 "#\n");
258 fprintf(out_h, "/*\n" 291 if (out_h)
259 " * Automatically generated C config: don't edit\n" 292 fprintf(out_h, "/*\n"
260 " */\n" 293 " * Automatically generated C config: don't edit\n"
261 "#define AUTOCONF_INCLUDED\n"); 294 " */\n"
295 "#define AUTOCONF_INCLUDED\n");
262 296
263 if (!sym_change_count) 297 if (!sym_change_count)
264 sym_clear_all_valid(); 298 sym_clear_all_valid();
@@ -274,10 +308,11 @@ int conf_write(const char *name)
274 "#\n" 308 "#\n"
275 "# %s\n" 309 "# %s\n"
276 "#\n", str); 310 "#\n", str);
277 fprintf(out_h, "\n" 311 if (out_h)
278 "/*\n" 312 fprintf(out_h, "\n"
279 " * %s\n" 313 "/*\n"
280 " */\n", str); 314 " * %s\n"
315 " */\n", str);
281 } else if (!(sym->flags & SYMBOL_CHOICE)) { 316 } else if (!(sym->flags & SYMBOL_CHOICE)) {
282 sym_calc_value(sym); 317 sym_calc_value(sym);
283 if (!(sym->flags & SYMBOL_WRITE)) 318 if (!(sym->flags & SYMBOL_WRITE))
@@ -286,7 +321,7 @@ int conf_write(const char *name)
286 type = sym->type; 321 type = sym->type;
287 if (type == S_TRISTATE) { 322 if (type == S_TRISTATE) {
288 sym_calc_value(modules_sym); 323 sym_calc_value(modules_sym);
289 if (S_TRI(modules_sym->curr) == no) 324 if (modules_sym->curr.tri == no)
290 type = S_BOOLEAN; 325 type = S_BOOLEAN;
291 } 326 }
292 switch (type) { 327 switch (type) {
@@ -295,15 +330,18 @@ int conf_write(const char *name)
295 switch (sym_get_tristate_value(sym)) { 330 switch (sym_get_tristate_value(sym)) {
296 case no: 331 case no:
297 fprintf(out, "# CONFIG_%s is not set\n", sym->name); 332 fprintf(out, "# CONFIG_%s is not set\n", sym->name);
298 fprintf(out_h, "#undef CONFIG_%s\n", sym->name); 333 if (out_h)
334 fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
299 break; 335 break;
300 case mod: 336 case mod:
301 fprintf(out, "CONFIG_%s=m\n", sym->name); 337 fprintf(out, "CONFIG_%s=m\n", sym->name);
302 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 338 if (out_h)
339 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
303 break; 340 break;
304 case yes: 341 case yes:
305 fprintf(out, "CONFIG_%s=y\n", sym->name); 342 fprintf(out, "CONFIG_%s=y\n", sym->name);
306 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); 343 if (out_h)
344 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
307 break; 345 break;
308 } 346 }
309 break; 347 break;
@@ -311,34 +349,40 @@ int conf_write(const char *name)
311 // fix me 349 // fix me
312 str = sym_get_string_value(sym); 350 str = sym_get_string_value(sym);
313 fprintf(out, "CONFIG_%s=\"", sym->name); 351 fprintf(out, "CONFIG_%s=\"", sym->name);
314 fprintf(out_h, "#define CONFIG_%s \"", sym->name); 352 if (out_h)
353 fprintf(out_h, "#define CONFIG_%s \"", sym->name);
315 do { 354 do {
316 l = strcspn(str, "\"\\"); 355 l = strcspn(str, "\"\\");
317 if (l) { 356 if (l) {
318 fwrite(str, l, 1, out); 357 fwrite(str, l, 1, out);
319 fwrite(str, l, 1, out_h); 358 if (out_h)
359 fwrite(str, l, 1, out_h);
320 } 360 }
321 str += l; 361 str += l;
322 while (*str == '\\' || *str == '"') { 362 while (*str == '\\' || *str == '"') {
323 fprintf(out, "\\%c", *str); 363 fprintf(out, "\\%c", *str);
324 fprintf(out_h, "\\%c", *str); 364 if (out_h)
365 fprintf(out_h, "\\%c", *str);
325 str++; 366 str++;
326 } 367 }
327 } while (*str); 368 } while (*str);
328 fputs("\"\n", out); 369 fputs("\"\n", out);
329 fputs("\"\n", out_h); 370 if (out_h)
371 fputs("\"\n", out_h);
330 break; 372 break;
331 case S_HEX: 373 case S_HEX:
332 str = sym_get_string_value(sym); 374 str = sym_get_string_value(sym);
333 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 375 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
334 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 376 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
335 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); 377 if (out_h)
378 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
336 break; 379 break;
337 } 380 }
338 case S_INT: 381 case S_INT:
339 str = sym_get_string_value(sym); 382 str = sym_get_string_value(sym);
340 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 383 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
341 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); 384 if (out_h)
385 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
342 break; 386 break;
343 } 387 }
344 } 388 }
@@ -358,18 +402,18 @@ int conf_write(const char *name)
358 } 402 }
359 } 403 }
360 fclose(out); 404 fclose(out);
361 fclose(out_h); 405 if (out_h) {
362 406 fclose(out_h);
363 if (!name) {
364 rename(".tmpconfig.h", "include/linux/autoconf.h"); 407 rename(".tmpconfig.h", "include/linux/autoconf.h");
365 name = conf_def_filename; 408 }
366 file_write_dep(NULL); 409 if (!name || basename != conf_def_filename) {
367 } else 410 if (!name)
368 unlink(".tmpconfig.h"); 411 name = conf_def_filename;
369 412 sprintf(tmpname, "%s.old", name);
370 sprintf(oldname, "%s.old", name); 413 rename(name, tmpname);
371 rename(name, oldname); 414 }
372 if (rename(".tmpconfig", name)) 415 sprintf(tmpname, "%s%s", dirname, basename);
416 if (rename(newname, tmpname))
373 return 1; 417 return 1;
374 418
375 sym_change_count = 0; 419 sym_change_count = 0;
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index d1af2a5..3f15ae8 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -55,6 +55,13 @@ struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
55 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; 55 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
56} 56}
57 57
58struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
59{
60 if (!e1)
61 return e2;
62 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
63}
64
58struct expr *expr_copy(struct expr *org) 65struct expr *expr_copy(struct expr *org)
59{ 66{
60 struct expr *e; 67 struct expr *e;
@@ -158,9 +165,22 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
158 165
159void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) 166void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
160{ 167{
161 if (!e1 || !e2 || e1->type != e2->type) 168 if (!e1 || !e2)
162 return; 169 return;
163 __expr_eliminate_eq(e1->type, ep1, ep2); 170 switch (e1->type) {
171 case E_OR:
172 case E_AND:
173 __expr_eliminate_eq(e1->type, ep1, ep2);
174 default:
175 ;
176 }
177 if (e1->type != e2->type) switch (e2->type) {
178 case E_OR:
179 case E_AND:
180 __expr_eliminate_eq(e2->type, ep1, ep2);
181 default:
182 ;
183 }
164 e1 = expr_eliminate_yn(e1); 184 e1 = expr_eliminate_yn(e1);
165 e2 = expr_eliminate_yn(e2); 185 e2 = expr_eliminate_yn(e2);
166} 186}
@@ -195,6 +215,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
195 trans_count = old_count; 215 trans_count = old_count;
196 return res; 216 return res;
197 case E_CHOICE: 217 case E_CHOICE:
218 case E_RANGE:
198 case E_NONE: 219 case E_NONE:
199 /* panic */; 220 /* panic */;
200 } 221 }
@@ -897,6 +918,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
897 case E_SYMBOL: 918 case E_SYMBOL:
898 return expr_alloc_comp(type, e->left.sym, sym); 919 return expr_alloc_comp(type, e->left.sym, sym);
899 case E_CHOICE: 920 case E_CHOICE:
921 case E_RANGE:
900 case E_NONE: 922 case E_NONE:
901 /* panic */; 923 /* panic */;
902 } 924 }
@@ -914,7 +936,7 @@ tristate expr_calc_value(struct expr *e)
914 switch (e->type) { 936 switch (e->type) {
915 case E_SYMBOL: 937 case E_SYMBOL:
916 sym_calc_value(e->left.sym); 938 sym_calc_value(e->left.sym);
917 return S_TRI(e->left.sym->curr); 939 return e->left.sym->curr.tri;
918 case E_AND: 940 case E_AND:
919 val1 = expr_calc_value(e->left.expr); 941 val1 = expr_calc_value(e->left.expr);
920 val2 = expr_calc_value(e->right.expr); 942 val2 = expr_calc_value(e->right.expr);
@@ -1017,11 +1039,18 @@ void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, in
1017 expr_print(e->right.expr, fn, data, E_AND); 1039 expr_print(e->right.expr, fn, data, E_AND);
1018 break; 1040 break;
1019 case E_CHOICE: 1041 case E_CHOICE:
1042 fn(data, e->right.sym->name);
1020 if (e->left.expr) { 1043 if (e->left.expr) {
1021 expr_print(e->left.expr, fn, data, E_CHOICE);
1022 fn(data, " ^ "); 1044 fn(data, " ^ ");
1045 expr_print(e->left.expr, fn, data, E_CHOICE);
1023 } 1046 }
1047 break;
1048 case E_RANGE:
1049 fn(data, "[");
1050 fn(data, e->left.sym->name);
1051 fn(data, " ");
1024 fn(data, e->right.sym->name); 1052 fn(data, e->right.sym->name);
1053 fn(data, "]");
1025 break; 1054 break;
1026 default: 1055 default:
1027 { 1056 {
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 896a296..cc616f1 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -18,10 +18,6 @@ extern "C" {
18struct file { 18struct file {
19 struct file *next; 19 struct file *next;
20 struct file *parent; 20 struct file *parent;
21#ifdef CML1
22 struct statement *stmt;
23 struct statement *last_stmt;
24#endif
25 char *name; 21 char *name;
26 int lineno; 22 int lineno;
27 int flags; 23 int flags;
@@ -36,7 +32,7 @@ typedef enum tristate {
36} tristate; 32} tristate;
37 33
38enum expr_type { 34enum expr_type {
39 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL 35 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
40}; 36};
41 37
42union expr_data { 38union expr_data {
@@ -45,18 +41,10 @@ union expr_data {
45}; 41};
46 42
47struct expr { 43struct expr {
48#ifdef CML1
49 int token;
50#else
51 enum expr_type type; 44 enum expr_type type;
52#endif
53 union expr_data left, right; 45 union expr_data left, right;
54}; 46};
55 47
56 #define E_TRI(ev)((ev).tri)
57 #define E_EXPR(ev)((ev).expr)
58 #define E_CALC(ev)(E_TRI(ev) = expr_calc_value(E_EXPR(ev)))
59
60 #define E_OR(dep1, dep2)(((dep1)>(dep2))?(dep1):(dep2)) 48 #define E_OR(dep1, dep2)(((dep1)>(dep2))?(dep1):(dep2))
61 #define E_AND(dep1, dep2)(((dep1)<(dep2))?(dep1):(dep2)) 49 #define E_AND(dep1, dep2)(((dep1)<(dep2))?(dep1):(dep2))
62 #define E_NOT(dep) (2-(dep)) 50 #define E_NOT(dep) (2-(dep))
@@ -66,12 +54,8 @@ struct expr_value {
66 tristate tri; 54 tristate tri;
67}; 55};
68 56
69 #define S_VAL(sv)((sv).value)
70 #define S_TRI(sv)((sv).tri)
71 #define S_EQ(sv1, sv2)(S_VAL(sv1) == S_VAL(sv2) || !strcmp(S_VAL(sv1), S_VAL(sv2)))
72
73struct symbol_value { 57struct symbol_value {
74 void *value; 58 void *val;
75 tristate tri; 59 tristate tri;
76}; 60};
77 61
@@ -83,31 +67,17 @@ struct symbol {
83 struct symbol *next; 67 struct symbol *next;
84 char *name; 68 char *name;
85 char *help; 69 char *help;
86#ifdef CML1
87 int type;
88#else
89 enum symbol_type type; 70 enum symbol_type type;
90#endif 71 struct symbol_value curr, user;
91 struct symbol_value curr, def;
92 tristate visible; 72 tristate visible;
93 int flags; 73 int flags;
94 struct property *prop; 74 struct property *prop;
95 struct expr *dep, *dep2; 75 struct expr *dep, *dep2;
96 struct menu *menu; 76 struct expr_value rev_dep;
97}; 77};
98 78
99#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) 79#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
100 80
101#ifdef CML1
102 #define SYMBOL_UNKNOWN S_UNKNOWN
103 #define SYMBOL_BOOLEAN S_BOOLEAN
104 #define SYMBOL_TRISTATE S_TRISTATE
105 #define SYMBOL_INT S_INT
106 #define SYMBOL_HEX S_HEX
107 #define SYMBOL_STRING S_STRING
108 #define SYMBOL_OTHER S_OTHER
109#endif
110
111 #define SYMBOL_YES 0x0001 81 #define SYMBOL_YES 0x0001
112 #define SYMBOL_MOD 0x0002 82 #define SYMBOL_MOD 0x0002
113 #define SYMBOL_NO 0x0004 83 #define SYMBOL_NO 0x0004
@@ -122,42 +92,38 @@ struct symbol {
122 #define SYMBOL_CHANGED 0x0400 92 #define SYMBOL_CHANGED 0x0400
123 #define SYMBOL_NEW 0x0800 93 #define SYMBOL_NEW 0x0800
124 #define SYMBOL_AUTO 0x1000 94 #define SYMBOL_AUTO 0x1000
95 #define SYMBOL_CHECKED 0x2000
96 #define SYMBOL_CHECK_DONE0x4000
97 #define SYMBOL_WARNED 0x8000
125 98
126 #define SYMBOL_MAXLENGTH256 99 #define SYMBOL_MAXLENGTH256
127 #define SYMBOL_HASHSIZE 257 100 #define SYMBOL_HASHSIZE 257
128 #define SYMBOL_HASHMASK 0xff 101 #define SYMBOL_HASHMASK 0xff
129 102
130enum prop_type { 103enum prop_type {
131 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_ROOTMENU, P_DEFAULT, P_CHOICE 104 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
132}; 105};
133 106
134struct property { 107struct property {
135 struct property *next; 108 struct property *next;
136 struct symbol *sym; 109 struct symbol *sym;
137#ifdef CML1
138 int token;
139#else
140 enum prop_type type; 110 enum prop_type type;
141#endif
142 const char *text; 111 const char *text;
143 struct symbol *def;
144 struct expr_value visible; 112 struct expr_value visible;
145 struct expr *dep; 113 struct expr *expr;
146 struct expr *dep2;
147 struct menu *menu; 114 struct menu *menu;
148 struct file *file; 115 struct file *file;
149 int lineno; 116 int lineno;
150#ifdef CML1
151 struct property *next_pos;
152#endif
153}; 117};
154 118
155#define for_all_properties(sym, st, tok) \ 119#define for_all_properties(sym, st, tok) \
156 for (st = sym->prop; st; st = st->next) \ 120 for (st = sym->prop; st; st = st->next) \
157 if (st->type == (tok)) 121 if (st->type == (tok))
158#define for_all_prompts(sym, st) for_all_properties(sym, st, P_PROMPT)
159#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) 122#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
160#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) 123#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
124#define for_all_prompts(sym, st) \
125 for (st = sym->prop; st; st = st->next) \
126 if (st->text)
161 127
162struct menu { 128struct menu {
163 struct menu *next; 129 struct menu *next;
@@ -174,6 +140,7 @@ struct menu {
174}; 140};
175 141
176 #define MENU_CHANGED 0x0001 142 #define MENU_CHANGED 0x0001
143 #define MENU_ROOT 0x0002
177 144
178#ifndef SWIG 145#ifndef SWIG
179 146
@@ -184,18 +151,12 @@ struct file *lookup_file(const char *name);
184extern struct symbol symbol_yes, symbol_no, symbol_mod; 151extern struct symbol symbol_yes, symbol_no, symbol_mod;
185extern struct symbol *modules_sym; 152extern struct symbol *modules_sym;
186extern int cdebug; 153extern int cdebug;
187extern int print_type;
188struct expr *expr_alloc_symbol(struct symbol *sym); 154struct expr *expr_alloc_symbol(struct symbol *sym);
189#ifdef CML1
190struct expr *expr_alloc_one(int token, struct expr *ce);
191struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2);
192struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2);
193#else
194struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); 155struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
195struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); 156struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
196struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); 157struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
197#endif
198struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); 158struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
159struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
199struct expr *expr_copy(struct expr *org); 160struct expr *expr_copy(struct expr *org);
200void expr_free(struct expr *e); 161void expr_free(struct expr *e);
201int expr_eq(struct expr *e1, struct expr *e2); 162int expr_eq(struct expr *e1, struct expr *e2);
@@ -215,17 +176,6 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
215void expr_fprint(struct expr *e, FILE *out); 176void expr_fprint(struct expr *e, FILE *out);
216void print_expr(int mask, struct expr *e, int prevtoken); 177void print_expr(int mask, struct expr *e, int prevtoken);
217 178
218#ifdef CML1
219static inline int expr_is_yes(struct expr *e)
220{
221 return !e || (e->token == WORD && e->left.sym == &symbol_yes);
222}
223
224static inline int expr_is_no(struct expr *e)
225{
226 return e && (e->token == WORD && e->left.sym == &symbol_no);
227}
228#else
229static inline int expr_is_yes(struct expr *e) 179static inline int expr_is_yes(struct expr *e)
230{ 180{
231 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); 181 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
@@ -236,7 +186,6 @@ static inline int expr_is_no(struct expr *e)
236 return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); 186 return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
237} 187}
238#endif 188#endif
239#endif
240 189
241#ifdef __cplusplus 190#ifdef __cplusplus
242} 191}
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
new file mode 100644
index 0000000..3227180
--- a/dev/null
+++ b/scripts/kconfig/gconf.c
@@ -0,0 +1,1618 @@
1/* Hey EMACS -*- linux-c -*- */
2/*
3 *
4 * Copyright (C) 2002-2003 Romain Lievin <roms@lpg.ticalc.org>
5 * Released under the terms of the GNU GPL v2.0.
6 *
7 */
8
9#ifdef HAVE_CONFIG_H
10# include <config.h>
11#endif
12
13#include "lkc.h"
14#include "images.c"
15
16#include <glade/glade.h>
17#include <gtk/gtk.h>
18#include <glib.h>
19#include <gdk/gdkkeysyms.h>
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24#include <time.h>
25#include <stdlib.h>
26
27//#define DEBUG
28
29enum {
30 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
31};
32
33static gint view_mode = SPLIT_VIEW;
34static gboolean show_name = TRUE;
35static gboolean show_range = TRUE;
36static gboolean show_value = TRUE;
37static gboolean show_all = FALSE;
38static gboolean show_debug = FALSE;
39static gboolean resizeable = FALSE;
40
41static gboolean config_changed = FALSE;
42
43static char nohelp_text[] =
44 "Sorry, no help available for this option yet.\n";
45
46GtkWidget *main_wnd = NULL;
47 GtkWidget *tree1_w = NULL;// left frame
48 GtkWidget *tree2_w = NULL;// right frame
49GtkWidget *text_w = NULL;
50GtkWidget *hpaned = NULL;
51GtkWidget *vpaned = NULL;
52GtkWidget *back_btn = NULL;
53
54GtkTextTag *tag1, *tag2;
55GdkColor color;
56
57GtkTreeStore *tree1, *tree2, *tree;
58GtkTreeModel *model1, *model2;
59static GtkTreeIter *parents[256] = { 0 };
60static gint indent;
61
62static struct menu *current;
63
64enum {
65 COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
66 COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF,
67 COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD,
68 COL_NUMBER
69};
70
71static void display_list(void);
72static void display_tree(struct menu *menu);
73static void display_tree_part(void);
74static void update_tree(struct menu *src, GtkTreeIter * dst);
75static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
76static gchar **fill_row(struct menu *menu);
77
78
79/* Helping/Debugging Functions */
80
81
82const char *dbg_print_stype(int val)
83{
84 static char buf[256];
85
86 bzero(buf, 256);
87
88 if (val == S_UNKNOWN)
89 strcpy(buf, "unknown");
90 if (val == S_BOOLEAN)
91 strcpy(buf, "boolean");
92 if (val == S_TRISTATE)
93 strcpy(buf, "tristate");
94 if (val == S_INT)
95 strcpy(buf, "int");
96 if (val == S_HEX)
97 strcpy(buf, "hex");
98 if (val == S_STRING)
99 strcpy(buf, "string");
100 if (val == S_OTHER)
101 strcpy(buf, "other");
102
103#ifdef DEBUG
104 printf("%s", buf);
105#endif
106
107 return buf;
108}
109
110const char *dbg_print_flags(int val)
111{
112 static char buf[256] = { 0 };
113
114 bzero(buf, 256);
115
116 if (val & SYMBOL_YES)
117 strcat(buf, "yes/");
118 if (val & SYMBOL_MOD)
119 strcat(buf, "mod/");
120 if (val & SYMBOL_NO)
121 strcat(buf, "no/");
122 if (val & SYMBOL_CONST)
123 strcat(buf, "const/");
124 if (val & SYMBOL_CHECK)
125 strcat(buf, "check/");
126 if (val & SYMBOL_CHOICE)
127 strcat(buf, "choice/");
128 if (val & SYMBOL_CHOICEVAL)
129 strcat(buf, "choiceval/");
130 if (val & SYMBOL_PRINTED)
131 strcat(buf, "printed/");
132 if (val & SYMBOL_VALID)
133 strcat(buf, "valid/");
134 if (val & SYMBOL_OPTIONAL)
135 strcat(buf, "optional/");
136 if (val & SYMBOL_WRITE)
137 strcat(buf, "write/");
138 if (val & SYMBOL_CHANGED)
139 strcat(buf, "changed/");
140 if (val & SYMBOL_NEW)
141 strcat(buf, "new/");
142 if (val & SYMBOL_AUTO)
143 strcat(buf, "auto/");
144
145 buf[strlen(buf) - 1] = '\0';
146#ifdef DEBUG
147 printf("%s", buf);
148#endif
149
150 return buf;
151}
152
153const char *dbg_print_ptype(int val)
154{
155 static char buf[256];
156
157 bzero(buf, 256);
158
159 if (val == P_UNKNOWN)
160 strcpy(buf, "unknown");
161 if (val == P_PROMPT)
162 strcpy(buf, "prompt");
163 if (val == P_COMMENT)
164 strcpy(buf, "comment");
165 if (val == P_MENU)
166 strcpy(buf, "menu");
167 if (val == P_DEFAULT)
168 strcpy(buf, "default");
169 if (val == P_CHOICE)
170 strcpy(buf, "choice");
171
172#ifdef DEBUG
173 printf("%s", buf);
174#endif
175
176 return buf;
177}
178
179
180/* Main Window Initialization */
181
182
183void init_main_window(const gchar * glade_file)
184{
185 GladeXML *xml;
186 GtkWidget *widget;
187 GtkTextBuffer *txtbuf;
188 char title[256];
189 GdkPixmap *pixmap;
190 GdkBitmap *mask;
191 GtkStyle *style;
192
193 xml = glade_xml_new(glade_file, "window1", NULL);
194 if (!xml)
195 g_error("GUI loading failed !\n");
196 glade_xml_signal_autoconnect(xml);
197
198 main_wnd = glade_xml_get_widget(xml, "window1");
199 hpaned = glade_xml_get_widget(xml, "hpaned1");
200 vpaned = glade_xml_get_widget(xml, "vpaned1");
201 tree1_w = glade_xml_get_widget(xml, "treeview1");
202 tree2_w = glade_xml_get_widget(xml, "treeview2");
203 text_w = glade_xml_get_widget(xml, "textview3");
204
205 back_btn = glade_xml_get_widget(xml, "button1");
206 gtk_widget_set_sensitive(back_btn, FALSE);
207
208 widget = glade_xml_get_widget(xml, "show_name1");
209 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
210 show_name);
211
212 widget = glade_xml_get_widget(xml, "show_range1");
213 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
214 show_range);
215
216 widget = glade_xml_get_widget(xml, "show_data1");
217 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
218 show_value);
219
220 style = gtk_widget_get_style(main_wnd);
221 widget = glade_xml_get_widget(xml, "toolbar1");
222
223 pixmap = gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
224 &style->bg[GTK_STATE_NORMAL],
225 (gchar **) xpm_single_view);
226 gtk_image_set_from_pixmap(GTK_IMAGE
227 (((GtkToolbarChild
228 *) (g_list_nth(GTK_TOOLBAR(widget)->
229 children,
230 5)->data))->icon),
231 pixmap, mask);
232 pixmap =
233 gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
234 &style->bg[GTK_STATE_NORMAL],
235 (gchar **) xpm_split_view);
236 gtk_image_set_from_pixmap(GTK_IMAGE
237 (((GtkToolbarChild
238 *) (g_list_nth(GTK_TOOLBAR(widget)->
239 children,
240 6)->data))->icon),
241 pixmap, mask);
242 pixmap =
243 gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
244 &style->bg[GTK_STATE_NORMAL],
245 (gchar **) xpm_tree_view);
246 gtk_image_set_from_pixmap(GTK_IMAGE
247 (((GtkToolbarChild
248 *) (g_list_nth(GTK_TOOLBAR(widget)->
249 children,
250 7)->data))->icon),
251 pixmap, mask);
252
253 switch (view_mode) {
254 case SINGLE_VIEW:
255 widget = glade_xml_get_widget(xml, "button4");
256 gtk_button_clicked(GTK_BUTTON(widget));
257 break;
258 case SPLIT_VIEW:
259 widget = glade_xml_get_widget(xml, "button5");
260 gtk_button_clicked(GTK_BUTTON(widget));
261 break;
262 case FULL_VIEW:
263 widget = glade_xml_get_widget(xml, "button6");
264 gtk_button_clicked(GTK_BUTTON(widget));
265 break;
266 }
267
268 txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
269 tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
270 "foreground", "red",
271 "weight", PANGO_WEIGHT_BOLD,
272 NULL);
273 tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
274 /*"style", PANGO_STYLE_OBLIQUE, */
275 NULL);
276
277 sprintf(title, "Build Configuration")
278 gtk_window_set_title(GTK_WINDOW(main_wnd), title);
279
280 gtk_widget_show(main_wnd);
281}
282
283void init_tree_model(void)
284{
285 gint i;
286
287 tree = tree2 = gtk_tree_store_new(COL_NUMBER,
288 G_TYPE_STRING, G_TYPE_STRING,
289 G_TYPE_STRING, G_TYPE_STRING,
290 G_TYPE_STRING, G_TYPE_STRING,
291 G_TYPE_POINTER, GDK_TYPE_COLOR,
292 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
293 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
294 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
295 G_TYPE_BOOLEAN);
296 model2 = GTK_TREE_MODEL(tree2);
297
298 for (parents[0] = NULL, i = 1; i < 256; i++)
299 parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
300
301 tree1 = gtk_tree_store_new(COL_NUMBER,
302 G_TYPE_STRING, G_TYPE_STRING,
303 G_TYPE_STRING, G_TYPE_STRING,
304 G_TYPE_STRING, G_TYPE_STRING,
305 G_TYPE_POINTER, GDK_TYPE_COLOR,
306 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
307 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
308 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
309 G_TYPE_BOOLEAN);
310 model1 = GTK_TREE_MODEL(tree1);
311}
312
313void init_left_tree(void)
314{
315 GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
316 GtkCellRenderer *renderer;
317 GtkTreeSelection *sel;
318
319 gtk_tree_view_set_model(view, model1);
320 gtk_tree_view_set_headers_visible(view, TRUE);
321 gtk_tree_view_set_rules_hint(view, FALSE);
322
323 renderer = gtk_cell_renderer_text_new();
324 gtk_tree_view_insert_column_with_attributes(view, -1,
325 "Options", renderer,
326 "text", COL_OPTION,
327 "foreground-gdk",
328 COL_COLOR, NULL);
329
330 sel = gtk_tree_view_get_selection(view);
331 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
332 gtk_widget_realize(tree1_w);
333}
334
335static void renderer_edited(GtkCellRendererText * cell,
336 const gchar * path_string,
337 const gchar * new_text, gpointer user_data);
338static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle,
339 gchar * arg1, gpointer user_data);
340
341void init_right_tree(void)
342{
343 GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
344 GtkCellRenderer *renderer;
345 GtkTreeSelection *sel;
346 GtkTreeViewColumn *column;
347 gint i;
348
349 gtk_tree_view_set_model(view, model2);
350 gtk_tree_view_set_headers_visible(view, TRUE);
351 gtk_tree_view_set_rules_hint(view, FALSE);
352
353 column = gtk_tree_view_column_new();
354 gtk_tree_view_append_column(view, column);
355 gtk_tree_view_column_set_title(column, "Options");
356
357 renderer = gtk_cell_renderer_pixbuf_new();
358 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
359 renderer, FALSE);
360 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
361 renderer,
362 "pixbuf", COL_PIXBUF,
363 "visible", COL_PIXVIS, NULL);
364 renderer = gtk_cell_renderer_toggle_new();
365 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
366 renderer, FALSE);
367 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
368 renderer,
369 "active", COL_BTNACT,
370 "inconsistent", COL_BTNINC,
371 "visible", COL_BTNVIS,
372 "radio", COL_BTNRAD, NULL);
373 /*g_signal_connect(G_OBJECT(renderer), "toggled",
374 G_CALLBACK(renderer_toggled), NULL); */
375 renderer = gtk_cell_renderer_text_new();
376 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
377 renderer, FALSE);
378 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
379 renderer,
380 "text", COL_OPTION,
381 "foreground-gdk",
382 COL_COLOR, NULL);
383
384 renderer = gtk_cell_renderer_text_new();
385 gtk_tree_view_insert_column_with_attributes(view, -1,
386 "Name", renderer,
387 "text", COL_NAME,
388 "foreground-gdk",
389 COL_COLOR, NULL);
390 renderer = gtk_cell_renderer_text_new();
391 gtk_tree_view_insert_column_with_attributes(view, -1,
392 "N", renderer,
393 "text", COL_NO,
394 "foreground-gdk",
395 COL_COLOR, NULL);
396 renderer = gtk_cell_renderer_text_new();
397 gtk_tree_view_insert_column_with_attributes(view, -1,
398 "M", renderer,
399 "text", COL_MOD,
400 "foreground-gdk",
401 COL_COLOR, NULL);
402 renderer = gtk_cell_renderer_text_new();
403 gtk_tree_view_insert_column_with_attributes(view, -1,
404 "Y", renderer,
405 "text", COL_YES,
406 "foreground-gdk",
407 COL_COLOR, NULL);
408 renderer = gtk_cell_renderer_text_new();
409 gtk_tree_view_insert_column_with_attributes(view, -1,
410 "Value", renderer,
411 "text", COL_VALUE,
412 "editable",
413 COL_EDIT,
414 "foreground-gdk",
415 COL_COLOR, NULL);
416 g_signal_connect(G_OBJECT(renderer), "edited",
417 G_CALLBACK(renderer_edited), NULL);
418
419 column = gtk_tree_view_get_column(view, COL_NAME);
420 gtk_tree_view_column_set_visible(column, show_name);
421 column = gtk_tree_view_get_column(view, COL_NO);
422 gtk_tree_view_column_set_visible(column, show_range);
423 column = gtk_tree_view_get_column(view, COL_MOD);
424 gtk_tree_view_column_set_visible(column, show_range);
425 column = gtk_tree_view_get_column(view, COL_YES);
426 gtk_tree_view_column_set_visible(column, show_range);
427 column = gtk_tree_view_get_column(view, COL_VALUE);
428 gtk_tree_view_column_set_visible(column, show_value);
429
430 if (resizeable) {
431 for (i = 0; i < COL_VALUE; i++) {
432 column = gtk_tree_view_get_column(view, i);
433 gtk_tree_view_column_set_resizable(column, TRUE);
434 }
435 }
436
437 sel = gtk_tree_view_get_selection(view);
438 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
439}
440
441
442/* Utility Functions */
443
444
445static void text_insert_help(struct menu *menu)
446{
447 GtkTextBuffer *buffer;
448 GtkTextIter start, end;
449 const char *prompt = menu_get_prompt(menu);
450 gchar *name;
451 const char *help = nohelp_text;
452
453 if (!menu->sym)
454 help = "";
455 else if (menu->sym->help)
456 help = menu->sym->help;
457
458 if (menu->sym && menu->sym->name)
459 name = g_strdup_printf(menu->sym->name);
460 else
461 name = g_strdup("");
462
463 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
464 gtk_text_buffer_get_bounds(buffer, &start, &end);
465 gtk_text_buffer_delete(buffer, &start, &end);
466 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
467
468 gtk_text_buffer_get_end_iter(buffer, &end);
469 gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
470 NULL);
471 gtk_text_buffer_insert_at_cursor(buffer, " ", 1);
472 gtk_text_buffer_get_end_iter(buffer, &end);
473 gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1,
474 NULL);
475 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
476 gtk_text_buffer_get_end_iter(buffer, &end);
477 gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2,
478 NULL);
479}
480
481
482static void text_insert_msg(const char *title, const char *message)
483{
484 GtkTextBuffer *buffer;
485 GtkTextIter start, end;
486 const char *msg = message;
487
488 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
489 gtk_text_buffer_get_bounds(buffer, &start, &end);
490 gtk_text_buffer_delete(buffer, &start, &end);
491 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
492
493 gtk_text_buffer_get_end_iter(buffer, &end);
494 gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
495 NULL);
496 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
497 gtk_text_buffer_get_end_iter(buffer, &end);
498 gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
499 NULL);
500}
501
502
503/* Main Windows Callbacks */
504
505void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data);
506gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
507 gpointer user_data)
508{
509 GtkWidget *dialog, *label;
510 gint result;
511
512 if (config_changed == FALSE)
513 return FALSE;
514
515 dialog = gtk_dialog_new_with_buttons("Warning !",
516 GTK_WINDOW(main_wnd),
517 (GtkDialogFlags)
518 (GTK_DIALOG_MODAL |
519 GTK_DIALOG_DESTROY_WITH_PARENT),
520 GTK_STOCK_OK,
521 GTK_RESPONSE_YES,
522 GTK_STOCK_NO,
523 GTK_RESPONSE_NO,
524 GTK_STOCK_CANCEL,
525 GTK_RESPONSE_CANCEL, NULL);
526 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
527 GTK_RESPONSE_CANCEL);
528
529 label = gtk_label_new("\nSave configuration ?\n");
530 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
531 gtk_widget_show(label);
532
533 result = gtk_dialog_run(GTK_DIALOG(dialog));
534 switch (result) {
535 case GTK_RESPONSE_YES:
536 on_save1_activate(NULL, NULL);
537 return FALSE;
538 case GTK_RESPONSE_NO:
539 return FALSE;
540 case GTK_RESPONSE_CANCEL:
541 case GTK_RESPONSE_DELETE_EVENT:
542 default:
543 gtk_widget_destroy(dialog);
544 return TRUE;
545 }
546
547 return FALSE;
548}
549
550
551void on_window1_destroy(GtkObject * object, gpointer user_data)
552{
553 gtk_main_quit();
554}
555
556
557void
558on_window1_size_request(GtkWidget * widget,
559 GtkRequisition * requisition, gpointer user_data)
560{
561 static gint old_h = 0;
562 gint w, h;
563
564 if (widget->window == NULL)
565 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
566 else
567 gdk_window_get_size(widget->window, &w, &h);
568
569 if (h == old_h)
570 return;
571 old_h = h;
572
573 gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
574}
575
576
577/* Menu & Toolbar Callbacks */
578
579
580static void
581load_filename(GtkFileSelection * file_selector, gpointer user_data)
582{
583 const gchar *fn;
584
585 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
586 (user_data));
587
588 if (conf_read(fn))
589 text_insert_msg("Error", "Unable to load configuration !");
590 else
591 display_tree(&rootmenu);
592}
593
594void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
595{
596 GtkWidget *fs;
597
598 fs = gtk_file_selection_new("Load file...");
599 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
600 "clicked",
601 G_CALLBACK(load_filename), (gpointer) fs);
602 g_signal_connect_swapped(GTK_OBJECT
603 (GTK_FILE_SELECTION(fs)->ok_button),
604 "clicked", G_CALLBACK(gtk_widget_destroy),
605 (gpointer) fs);
606 g_signal_connect_swapped(GTK_OBJECT
607 (GTK_FILE_SELECTION(fs)->cancel_button),
608 "clicked", G_CALLBACK(gtk_widget_destroy),
609 (gpointer) fs);
610 gtk_widget_show(fs);
611}
612
613
614void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
615{
616 if (conf_write(NULL))
617 text_insert_msg("Error", "Unable to save configuration !");
618
619 config_changed = FALSE;
620}
621
622
623static void
624store_filename(GtkFileSelection * file_selector, gpointer user_data)
625{
626 const gchar *fn;
627
628 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
629 (user_data));
630
631 if (conf_write(fn))
632 text_insert_msg("Error", "Unable to save configuration !");
633
634 gtk_widget_destroy(GTK_WIDGET(user_data));
635}
636
637void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
638{
639 GtkWidget *fs;
640
641 fs = gtk_file_selection_new("Save file as...");
642 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
643 "clicked",
644 G_CALLBACK(store_filename), (gpointer) fs);
645 g_signal_connect_swapped(GTK_OBJECT
646 (GTK_FILE_SELECTION(fs)->ok_button),
647 "clicked", G_CALLBACK(gtk_widget_destroy),
648 (gpointer) fs);
649 g_signal_connect_swapped(GTK_OBJECT
650 (GTK_FILE_SELECTION(fs)->cancel_button),
651 "clicked", G_CALLBACK(gtk_widget_destroy),
652 (gpointer) fs);
653 gtk_widget_show(fs);
654}
655
656
657void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
658{
659 if (!on_window1_delete_event(NULL, NULL, NULL))
660 gtk_widget_destroy(GTK_WIDGET(main_wnd));
661}
662
663
664void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
665{
666 GtkTreeViewColumn *col;
667
668 show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
669 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
670 if (col)
671 gtk_tree_view_column_set_visible(col, show_name);
672}
673
674
675void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
676{
677 GtkTreeViewColumn *col;
678
679 show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
680 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
681 if (col)
682 gtk_tree_view_column_set_visible(col, show_range);
683 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD);
684 if (col)
685 gtk_tree_view_column_set_visible(col, show_range);
686 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES);
687 if (col)
688 gtk_tree_view_column_set_visible(col, show_range);
689
690}
691
692
693void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
694{
695 GtkTreeViewColumn *col;
696
697 show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
698 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
699 if (col)
700 gtk_tree_view_column_set_visible(col, show_value);
701}
702
703
704void
705on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
706{
707 show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
708
709 gtk_tree_store_clear(tree2);
710 display_tree(&rootmenu);// instead of update_tree for speed reasons
711}
712
713
714void
715on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
716{
717 show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
718 update_tree(&rootmenu, NULL);
719}
720
721
722void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
723{
724 GtkWidget *dialog;
725 const gchar *intro_text =
726 "Welcome to gkc, the GTK+ graphical configuration tool\n"
727 "for Linux.\n"
728 "For each option, a blank box indicates the feature is disabled, a\n"
729 "check indicates it is enabled, and a dot indicates that it is to\n"
730 "be compiled as a module. Clicking on the box will cycle through the three states.\n"
731 "\n"
732 "If you do not see an option (e.g., a device driver) that you\n"
733 "believe should be present, try turning on Show All Options\n"
734 "under the Options menu.\n"
735 "Although there is no cross reference yet to help you figure out\n"
736 "what other options must be enabled to support the option you\n"
737 "are interested in, you can still view the help of a grayed-out\n"
738 "option.\n"
739 "\n"
740 "Toggling Show Debug Info under the Options menu will show \n"
741 "the dependencies, which you can then match by examining other options.";
742
743 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
744 GTK_DIALOG_DESTROY_WITH_PARENT,
745 GTK_MESSAGE_INFO,
746 GTK_BUTTONS_CLOSE, intro_text);
747 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
748 G_CALLBACK(gtk_widget_destroy),
749 GTK_OBJECT(dialog));
750 gtk_widget_show_all(dialog);
751}
752
753
754void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
755{
756 GtkWidget *dialog;
757 const gchar *about_text =
758 "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
759 "Based on the source code from Roman Zippel.\n";
760
761 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
762 GTK_DIALOG_DESTROY_WITH_PARENT,
763 GTK_MESSAGE_INFO,
764 GTK_BUTTONS_CLOSE, about_text);
765 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
766 G_CALLBACK(gtk_widget_destroy),
767 GTK_OBJECT(dialog));
768 gtk_widget_show_all(dialog);
769}
770
771
772void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
773{
774 GtkWidget *dialog;
775 const gchar *license_text =
776 "gkc is released under the terms of the GNU GPL v2.\n"
777 "For more information, please see the source code or\n"
778 "visit http://www.fsf.org/licenses/licenses.html\n";
779
780 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
781 GTK_DIALOG_DESTROY_WITH_PARENT,
782 GTK_MESSAGE_INFO,
783 GTK_BUTTONS_CLOSE, license_text);
784 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
785 G_CALLBACK(gtk_widget_destroy),
786 GTK_OBJECT(dialog));
787 gtk_widget_show_all(dialog);
788}
789
790
791void on_back_pressed(GtkButton * button, gpointer user_data)
792{
793 enum prop_type ptype;
794
795 current = current->parent;
796 ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
797 if (ptype != P_MENU)
798 current = current->parent;
799 display_tree_part();
800
801 if (current == &rootmenu)
802 gtk_widget_set_sensitive(back_btn, FALSE);
803}
804
805
806void on_load_pressed(GtkButton * button, gpointer user_data)
807{
808 on_load1_activate(NULL, user_data);
809}
810
811
812void on_save_pressed(GtkButton * button, gpointer user_data)
813{
814 on_save1_activate(NULL, user_data);
815}
816
817
818void on_single_clicked(GtkButton * button, gpointer user_data)
819{
820 view_mode = SINGLE_VIEW;
821 gtk_paned_set_position(GTK_PANED(hpaned), 0);
822 gtk_widget_hide(tree1_w);
823 current = &rootmenu;
824 display_tree_part();
825}
826
827
828void on_split_clicked(GtkButton * button, gpointer user_data)
829{
830 gint w, h;
831 view_mode = SPLIT_VIEW;
832 gtk_widget_show(tree1_w);
833 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
834 gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
835 if (tree2)
836 gtk_tree_store_clear(tree2);
837 display_list();
838}
839
840
841void on_full_clicked(GtkButton * button, gpointer user_data)
842{
843 view_mode = FULL_VIEW;
844 gtk_paned_set_position(GTK_PANED(hpaned), 0);
845 gtk_widget_hide(tree1_w);
846 if (tree2)
847 gtk_tree_store_clear(tree2);
848 display_tree(&rootmenu);
849 gtk_widget_set_sensitive(back_btn, FALSE);
850}
851
852
853void on_collapse_pressed(GtkButton * button, gpointer user_data)
854{
855 gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
856}
857
858
859void on_expand_pressed(GtkButton * button, gpointer user_data)
860{
861 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
862}
863
864
865/* CTree Callbacks */
866
867/* Change hex/int/string value in the cell */
868static void renderer_edited(GtkCellRendererText * cell,
869 const gchar * path_string,
870 const gchar * new_text, gpointer user_data)
871{
872 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
873 GtkTreeIter iter;
874 const char *old_def, *new_def;
875 struct menu *menu;
876 struct symbol *sym;
877
878 if (!gtk_tree_model_get_iter(model2, &iter, path))
879 return;
880
881 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
882 sym = menu->sym;
883
884 gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
885 new_def = new_text;
886
887 sym_set_string_value(sym, new_def);
888
889 config_changed = TRUE;
890 update_tree(&rootmenu, NULL);
891
892 gtk_tree_path_free(path);
893}
894
895/* Change the value of a symbol and update the tree */
896static void change_sym_value(struct menu *menu, gint col)
897{
898 struct symbol *sym = menu->sym;
899 tristate oldval, newval;
900
901 if (!sym)
902 return;
903
904 if (col == COL_NO)
905 newval = no;
906 else if (col == COL_MOD)
907 newval = mod;
908 else if (col == COL_YES)
909 newval = yes;
910 else
911 return;
912
913 switch (sym_get_type(sym)) {
914 case S_BOOLEAN:
915 case S_TRISTATE:
916 oldval = sym_get_tristate_value(sym);
917 if (!sym_tristate_within_range(sym, newval))
918 newval = yes;
919 sym_set_tristate_value(sym, newval);
920 config_changed = TRUE;
921 if (view_mode == FULL_VIEW)
922 update_tree(&rootmenu, NULL);
923 else if (view_mode == SPLIT_VIEW) {
924 update_tree(current, NULL);
925 display_list();
926 }
927 else if (view_mode == SINGLE_VIEW)
928 display_tree_part();//fixme: keep exp/coll
929 break;
930 case S_INT:
931 case S_HEX:
932 case S_STRING:
933 default:
934 break;
935 }
936}
937
938static void toggle_sym_value(struct menu *menu)
939{
940 const tristate next_val[3] = { no, mod, yes };
941 tristate newval;
942
943 if (!menu->sym)
944 return;
945
946 newval = next_val[(sym_get_tristate_value(menu->sym) + 1) % 3];
947 if (!sym_tristate_within_range(menu->sym, newval))
948 newval = yes;
949 sym_set_tristate_value(menu->sym, newval);
950 if (view_mode == FULL_VIEW)
951 update_tree(&rootmenu, NULL);
952 else if (view_mode == SPLIT_VIEW) {
953 update_tree(current, NULL);
954 display_list();
955 }
956 else if (view_mode == SINGLE_VIEW)
957 display_tree_part();//fixme: keep exp/coll
958}
959
960static void renderer_toggled(GtkCellRendererToggle * cell,
961 gchar * path_string, gpointer user_data)
962{
963 GtkTreePath *path, *sel_path = NULL;
964 GtkTreeIter iter, sel_iter;
965 GtkTreeSelection *sel;
966 struct menu *menu;
967
968 path = gtk_tree_path_new_from_string(path_string);
969 if (!gtk_tree_model_get_iter(model2, &iter, path))
970 return;
971
972 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w));
973 if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter))
974 sel_path = gtk_tree_model_get_path(model2, &sel_iter);
975 if (!sel_path)
976 goto out1;
977 if (gtk_tree_path_compare(path, sel_path))
978 goto out2;
979
980 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
981 toggle_sym_value(menu);
982
983 out2:
984 gtk_tree_path_free(sel_path);
985 out1:
986 gtk_tree_path_free(path);
987}
988
989static gint column2index(GtkTreeViewColumn * column)
990{
991 gint i;
992
993 for (i = 0; i < COL_NUMBER; i++) {
994 GtkTreeViewColumn *col;
995
996 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i);
997 if (col == column)
998 return i;
999 }
1000
1001 return -1;
1002}
1003
1004
1005//#define GTK_BUG_FIXED // uncomment it for GTK+ >= 2.1.4 (2.2)
1006
1007/* User click: update choice (full) or goes down (single) */
1008gboolean
1009on_treeview2_button_press_event(GtkWidget * widget,
1010 GdkEventButton * event, gpointer user_data)
1011{
1012 GtkTreeView *view = GTK_TREE_VIEW(widget);
1013 GtkTreePath *path;
1014 GtkTreeViewColumn *column;
1015 GtkTreeIter iter;
1016 struct menu *menu;
1017 gint col;
1018
1019#ifdef GTK_BUG_FIXED
1020 gint tx = (gint) event->x;
1021 gint ty = (gint) event->y;
1022 gint cx, cy;
1023
1024 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1025 &cy);
1026#else
1027 gtk_tree_view_get_cursor(view, &path, &column);
1028#endif
1029 if (path == NULL)
1030 return FALSE;
1031
1032 gtk_tree_model_get_iter(model2, &iter, path);
1033 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1034
1035 col = column2index(column);
1036 if (event->type == GDK_2BUTTON_PRESS) {
1037 enum prop_type ptype;
1038 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1039
1040 if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
1041 // goes down into menu
1042 current = menu;
1043 display_tree_part();
1044 gtk_widget_set_sensitive(back_btn, TRUE);
1045 } else if ((col == COL_OPTION)) {
1046 toggle_sym_value(menu);
1047 gtk_tree_view_expand_row(view, path, TRUE);
1048 }
1049 } else {
1050 if (col == COL_VALUE) {
1051 toggle_sym_value(menu);
1052 gtk_tree_view_expand_row(view, path, TRUE);
1053 } else if (col == COL_NO || col == COL_MOD
1054 || col == COL_YES) {
1055 change_sym_value(menu, col);
1056 gtk_tree_view_expand_row(view, path, TRUE);
1057 }
1058 }
1059
1060 return FALSE;
1061}
1062
1063/* Key pressed: update choice */
1064gboolean
1065on_treeview2_key_press_event(GtkWidget * widget,
1066 GdkEventKey * event, gpointer user_data)
1067{
1068 GtkTreeView *view = GTK_TREE_VIEW(widget);
1069 GtkTreePath *path;
1070 GtkTreeViewColumn *column;
1071 GtkTreeIter iter;
1072 struct menu *menu;
1073 gint col;
1074
1075 gtk_tree_view_get_cursor(view, &path, &column);
1076 if (path == NULL)
1077 return FALSE;
1078
1079 if (event->keyval == GDK_space) {
1080 if (gtk_tree_view_row_expanded(view, path))
1081 gtk_tree_view_collapse_row(view, path);
1082 else
1083 gtk_tree_view_expand_row(view, path, FALSE);
1084 return TRUE;
1085 }
1086 if (event->keyval == GDK_KP_Enter) {
1087 }
1088 if (widget == tree1_w)
1089 return FALSE;
1090
1091 gtk_tree_model_get_iter(model2, &iter, path);
1092 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1093
1094 if (!strcasecmp(event->string, "n"))
1095 col = COL_NO;
1096 else if (!strcasecmp(event->string, "m"))
1097 col = COL_MOD;
1098 else if (!strcasecmp(event->string, "y"))
1099 col = COL_YES;
1100 else
1101 col = -1;
1102 change_sym_value(menu, col);
1103
1104 return FALSE;
1105}
1106
1107
1108/* Row selection changed: update help */
1109void
1110on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
1111{
1112 GtkTreeSelection *selection;
1113 GtkTreeIter iter;
1114 struct menu *menu;
1115
1116 selection = gtk_tree_view_get_selection(treeview);
1117 if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
1118 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1119 text_insert_help(menu);
1120 }
1121}
1122
1123
1124/* User click: display sub-tree in the right frame. */
1125gboolean
1126on_treeview1_button_press_event(GtkWidget * widget,
1127 GdkEventButton * event, gpointer user_data)
1128{
1129 GtkTreeView *view = GTK_TREE_VIEW(widget);
1130 GtkTreePath *path;
1131 GtkTreeViewColumn *column;
1132 GtkTreeIter iter;
1133 struct menu *menu;
1134
1135 gint tx = (gint) event->x;
1136 gint ty = (gint) event->y;
1137 gint cx, cy;
1138
1139 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1140 &cy);
1141 if (path == NULL)
1142 return FALSE;
1143
1144 gtk_tree_model_get_iter(model1, &iter, path);
1145 gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
1146
1147 if (event->type == GDK_2BUTTON_PRESS) {
1148 toggle_sym_value(menu);
1149 current = menu;
1150 display_tree_part();
1151 } else {
1152 current = menu;
1153 display_tree_part();
1154 }
1155
1156 gtk_widget_realize(tree2_w);
1157 gtk_tree_view_set_cursor(view, path, NULL, FALSE);
1158 gtk_widget_grab_focus(GTK_TREE_VIEW(tree2_w));
1159
1160 return FALSE;
1161}
1162
1163
1164/* Conf management */
1165
1166
1167/* Fill a row of strings */
1168static gchar **fill_row(struct menu *menu)
1169{
1170 static gchar *row[COL_NUMBER] = { 0 };
1171 struct symbol *sym = menu->sym;
1172 const char *def;
1173 int stype;
1174 tristate val;
1175 enum prop_type ptype;
1176 int i;
1177
1178 for (i = COL_OPTION; i <= COL_COLOR; i++)
1179 g_free(row[i]);
1180 bzero(row, sizeof(row));
1181
1182 row[COL_OPTION] =
1183 g_strdup_printf("%s %s", menu_get_prompt(menu),
1184 sym ? (sym->
1185 flags & SYMBOL_NEW ? "(NEW)" : "") :
1186 "");
1187
1188 if (show_all && !menu_is_visible(menu))
1189 row[COL_COLOR] = g_strdup("DarkGray");
1190 else
1191 row[COL_COLOR] = g_strdup("Black");
1192
1193 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1194 switch (ptype) {
1195 case P_MENU:
1196 row[COL_PIXBUF] = (gchar *) xpm_menu;
1197 if (view_mode != FULL_VIEW)
1198 row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
1199 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1200 break;
1201 case P_COMMENT:
1202 row[COL_PIXBUF] = (gchar *) xpm_void;
1203 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1204 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1205 break;
1206 default:
1207 row[COL_PIXBUF] = (gchar *) xpm_void;
1208 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1209 row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1210 break;
1211 }
1212
1213 if (!sym)
1214 return row;
1215 row[COL_NAME] = g_strdup(sym->name);
1216
1217 sym_calc_value(sym);
1218 sym->flags &= ~SYMBOL_CHANGED;
1219
1220 if (sym_is_choice(sym)) {// parse childs for getting final value
1221 struct menu *child;
1222 struct symbol *def_sym = sym_get_choice_value(sym);
1223 struct menu *def_menu = NULL;
1224
1225 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1226
1227 for (child = menu->list; child; child = child->next) {
1228 if (menu_is_visible(child)
1229 && child->sym == def_sym)
1230 def_menu = child;
1231 }
1232
1233 if (def_menu)
1234 row[COL_VALUE] =
1235 g_strdup(menu_get_prompt(def_menu));
1236 }
1237 if(sym->flags & SYMBOL_CHOICEVAL)
1238 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
1239
1240 stype = sym_get_type(sym);
1241 switch (stype) {
1242 case S_BOOLEAN:
1243 if (sym_is_choice(sym))
1244 break;
1245 case S_TRISTATE:
1246 val = sym_get_tristate_value(sym);
1247 switch (val) {
1248 case no:
1249 row[COL_NO] = g_strdup("N");
1250 row[COL_VALUE] = g_strdup("N");
1251 row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
1252 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1253 break;
1254 case mod:
1255 row[COL_MOD] = g_strdup("M");
1256 row[COL_VALUE] = g_strdup("M");
1257 row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
1258 break;
1259 case yes:
1260 row[COL_YES] = g_strdup("Y");
1261 row[COL_VALUE] = g_strdup("Y");
1262 row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
1263 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1264 break;
1265 }
1266
1267 if (val != no && sym_tristate_within_range(sym, no))
1268 row[COL_NO] = g_strdup("_");
1269 if (val != mod && sym_tristate_within_range(sym, mod))
1270 row[COL_MOD] = g_strdup("_");
1271 if (val != yes && sym_tristate_within_range(sym, yes))
1272 row[COL_YES] = g_strdup("_");
1273 break;
1274 case S_INT:
1275 case S_HEX:
1276 case S_STRING:
1277 def = sym_get_string_value(sym);
1278 row[COL_VALUE] = g_strdup(def);
1279 row[COL_EDIT] = GINT_TO_POINTER(TRUE);
1280 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1281 break;
1282 }
1283
1284 return row;
1285}
1286
1287
1288/* Set the node content with a row of strings */
1289static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
1290{
1291 GdkColor color;
1292 gboolean success;
1293 GdkPixbuf *pix;
1294
1295 pix = gdk_pixbuf_new_from_xpm_data((const char **)
1296 row[COL_PIXBUF]);
1297
1298 gdk_color_parse(row[COL_COLOR], &color);
1299 gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
1300 FALSE, FALSE, &success);
1301
1302 gtk_tree_store_set(tree, node,
1303 COL_OPTION, row[COL_OPTION],
1304 COL_NAME, row[COL_NAME],
1305 COL_NO, row[COL_NO],
1306 COL_MOD, row[COL_MOD],
1307 COL_YES, row[COL_YES],
1308 COL_VALUE, row[COL_VALUE],
1309 COL_MENU, (gpointer) menu,
1310 COL_COLOR, &color,
1311 COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
1312 COL_PIXBUF, pix,
1313 COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
1314 COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
1315 COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
1316 COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
1317 COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
1318 -1);
1319
1320 g_object_unref(pix);
1321}
1322
1323
1324/* Add a node to the tree */
1325static void place_node(struct menu *menu, char **row)
1326{
1327 GtkTreeIter *parent = parents[indent - 1];
1328 GtkTreeIter *node = parents[indent];
1329
1330 gtk_tree_store_append(tree, node, parent);
1331 set_node(node, menu, row);
1332}
1333
1334
1335/* Find a node in the GTK+ tree */
1336static GtkTreeIter found;
1337
1338/*
1339 * Find a menu in the GtkTree starting at parent.
1340 */
1341GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
1342 struct menu *tofind)
1343{
1344 GtkTreeIter iter;
1345 GtkTreeIter *child = &iter;
1346 gboolean valid;
1347 GtkTreeIter *ret;
1348
1349 valid = gtk_tree_model_iter_children(model2, child, parent);
1350 while (valid) {
1351 struct menu *menu;
1352
1353 gtk_tree_model_get(model2, child, 6, &menu, -1);
1354
1355 if (menu == tofind) {
1356 memcpy(&found, child, sizeof(GtkTreeIter));
1357 return &found;
1358 }
1359
1360 ret = gtktree_iter_find_node(child, tofind);
1361 if (ret)
1362 return ret;
1363
1364 valid = gtk_tree_model_iter_next(model2, child);
1365 }
1366
1367 return NULL;
1368}
1369
1370
1371/*
1372 * Update the tree by adding/removing entries
1373 * Does not change other nodes
1374 */
1375static void update_tree(struct menu *src, GtkTreeIter * dst)
1376{
1377 struct menu *child1;
1378 GtkTreeIter iter, tmp;
1379 GtkTreeIter *child2 = &iter;
1380 gboolean valid;
1381 GtkTreeIter *sibling;
1382 struct symbol *sym;
1383 struct property *prop;
1384 struct menu *menu1, *menu2;
1385 static GtkTreePath *path = NULL;
1386
1387 if (src == &rootmenu)
1388 indent = 1;
1389
1390 valid = gtk_tree_model_iter_children(model2, child2, dst);
1391 for (child1 = src->list; child1; child1 = child1->next) {
1392
1393 prop = child1->prompt;
1394 sym = child1->sym;
1395
1396 reparse:
1397 menu1 = child1;
1398 if (valid)
1399 gtk_tree_model_get(model2, child2, COL_MENU,
1400 &menu2, -1);
1401 else
1402 menu2 = NULL;// force adding of a first child
1403
1404#ifdef DEBUG
1405 printf("%*c%s | %s\n", indent, ' ',
1406 menu1 ? menu_get_prompt(menu1) : "nil",
1407 menu2 ? menu_get_prompt(menu2) : "nil");
1408#endif
1409
1410 if (!menu_is_visible(child1) && !show_all) {// remove node
1411 if (gtktree_iter_find_node(dst, menu1) != NULL) {
1412 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1413 valid = gtk_tree_model_iter_next(model2,
1414 child2);
1415 gtk_tree_store_remove(tree2, &tmp);
1416 if (!valid)
1417 return;// next parent
1418 else
1419 goto reparse;// next child
1420 } else
1421 continue;
1422 }
1423
1424 if (menu1 != menu2) {
1425 if (gtktree_iter_find_node(dst, menu1) == NULL) {// add node
1426 if (!valid && !menu2)
1427 sibling = NULL;
1428 else
1429 sibling = child2;
1430 gtk_tree_store_insert_before(tree2,
1431 child2,
1432 dst, sibling);
1433 set_node(child2, menu1, fill_row(menu1));
1434 if (menu2 == NULL)
1435 valid = TRUE;
1436 } else {// remove node
1437 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1438 valid = gtk_tree_model_iter_next(model2,
1439 child2);
1440 gtk_tree_store_remove(tree2, &tmp);
1441 if (!valid)
1442 return;// next parent
1443 else
1444 goto reparse;// next child
1445 }
1446 } else if (sym && (sym->flags & SYMBOL_CHANGED)) {
1447 set_node(child2, menu1, fill_row(menu1));
1448 }
1449
1450 indent++;
1451 update_tree(child1, child2);
1452 indent--;
1453
1454 valid = gtk_tree_model_iter_next(model2, child2);
1455 }
1456}
1457
1458
1459/* Display the whole tree (single/split/full view) */
1460static void display_tree(struct menu *menu)
1461{
1462 struct symbol *sym;
1463 struct property *prop;
1464 struct menu *child;
1465 enum prop_type ptype;
1466
1467 if (menu == &rootmenu) {
1468 indent = 1;
1469 current = &rootmenu;
1470 }
1471
1472 for (child = menu->list; child; child = child->next) {
1473 prop = child->prompt;
1474 sym = child->sym;
1475 ptype = prop ? prop->type : P_UNKNOWN;
1476
1477 if (sym)
1478 sym->flags &= ~SYMBOL_CHANGED;
1479
1480 if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) &&
1481 (tree == tree1))
1482 continue;
1483
1484 if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) &&
1485 (tree == tree2))
1486 continue;
1487
1488 if (menu_is_visible(child) || show_all)
1489 place_node(child, fill_row(child));
1490#ifdef DEBUG
1491 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1492 dbg_print_ptype(ptype);
1493 printf(" | ");
1494 if (sym) {
1495 dbg_print_stype(sym->type);
1496 printf(" | ");
1497 dbg_print_flags(sym->flags);
1498 printf("\n");
1499 } else
1500 printf("\n");
1501#endif
1502 if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
1503 && (tree == tree2))
1504 continue;
1505
1506 if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) ||
1507 (view_mode == FULL_VIEW)
1508 || (view_mode == SPLIT_VIEW)) {
1509 indent++;
1510 display_tree(child);
1511 indent--;
1512 }
1513 }
1514}
1515
1516/* Display a part of the tree starting at current node (single/split view) */
1517static void display_tree_part(void)
1518{
1519 if (tree2)
1520 gtk_tree_store_clear(tree2);
1521 display_tree(current);
1522 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
1523}
1524
1525/* Display the list in the left frame (split view) */
1526static void display_list(void)
1527{
1528 if (tree1)
1529 gtk_tree_store_clear(tree1);
1530
1531 tree = tree1;
1532 display_tree(current = &rootmenu);
1533 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
1534 tree = tree2;
1535}
1536
1537static void fixup_rootmenu(struct menu *menu)
1538{
1539 struct menu *child;
1540
1541 if (!menu->prompt || menu->prompt->type != P_MENU)
1542 return;
1543 menu->flags |= MENU_ROOT;
1544 for (child = menu->list; child; child = child->next)
1545 fixup_rootmenu(child);
1546}
1547
1548
1549/* Main */
1550
1551
1552int main(int ac, char *av[])
1553{
1554 const char *name;
1555 gchar *cur_dir, *exe_path;
1556 gchar *glade_file;
1557
1558#ifndef LKC_DIRECT_LINK
1559 kconfig_load();
1560#endif
1561
1562 /* GTK stuffs */
1563 gtk_set_locale();
1564 gtk_init(&ac, &av);
1565 glade_init();
1566
1567 //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
1568 //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");
1569
1570 /* Determine GUI path */
1571 cur_dir = g_get_current_dir();
1572 exe_path = g_strdup(av[0]);
1573 exe_path[0] = '/';
1574 glade_file = g_strconcat(cur_dir, exe_path, ".glade", NULL);
1575 g_free(cur_dir);
1576 g_free(exe_path);
1577
1578 /* Load the interface and connect signals */
1579 init_main_window(glade_file);
1580 init_tree_model();
1581 init_left_tree();
1582 init_right_tree();
1583
1584 /* Conf stuffs */
1585 if (ac > 1 && av[1][0] == '-') {
1586 switch (av[1][1]) {
1587 case 'a':
1588 //showAll = 1;
1589 break;
1590 case 'h':
1591 case '?':
1592 printf("%s <config>\n", av[0]);
1593 exit(0);
1594 }
1595 name = av[2];
1596 } else
1597 name = av[1];
1598
1599 conf_parse(name);
1600 fixup_rootmenu(&rootmenu);
1601 conf_read(NULL);
1602
1603 switch (view_mode) {
1604 case SINGLE_VIEW:
1605 display_tree_part();
1606 break;
1607 case SPLIT_VIEW:
1608 display_list();
1609 break;
1610 case FULL_VIEW:
1611 display_tree(&rootmenu);
1612 break;
1613 }
1614
1615 gtk_main();
1616
1617 return 0;
1618}
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
new file mode 100644
index 0000000..1e1736d
--- a/dev/null
+++ b/scripts/kconfig/gconf.glade
@@ -0,0 +1,543 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
2<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
3
4<glade-interface>
5
6<widget class="GtkWindow" id="window1">
7 <property name="visible">True</property>
8 <property name="title" translatable="yes">Gtk Kernel Configurator</property>
9 <property name="type">GTK_WINDOW_TOPLEVEL</property>
10 <property name="window_position">GTK_WIN_POS_NONE</property>
11 <property name="modal">False</property>
12 <property name="default_width">640</property>
13 <property name="default_height">480</property>
14 <property name="resizable">True</property>
15 <property name="destroy_with_parent">False</property>
16 <signal name="destroy" handler="on_window1_destroy" object="window1"/>
17 <signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/>
18 <signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/>
19
20 <child>
21 <widget class="GtkVBox" id="vbox1">
22 <property name="visible">True</property>
23 <property name="homogeneous">False</property>
24 <property name="spacing">0</property>
25
26 <child>
27 <widget class="GtkMenuBar" id="menubar1">
28 <property name="visible">True</property>
29
30 <child>
31 <widget class="GtkMenuItem" id="file1">
32 <property name="visible">True</property>
33 <property name="label" translatable="yes">_File</property>
34 <property name="use_underline">True</property>
35
36 <child>
37 <widget class="GtkMenu" id="file1_menu">
38
39 <child>
40 <widget class="GtkImageMenuItem" id="load1">
41 <property name="visible">True</property>
42 <property name="tooltip" translatable="yes">Load a config file</property>
43 <property name="label" translatable="yes">_Load</property>
44 <property name="use_underline">True</property>
45 <signal name="activate" handler="on_load1_activate"/>
46 <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/>
47
48 <child internal-child="image">
49 <widget class="GtkImage" id="image27">
50 <property name="visible">True</property>
51 <property name="stock">gtk-open</property>
52 <property name="icon_size">1</property>
53 <property name="xalign">0.5</property>
54 <property name="yalign">0.5</property>
55 <property name="xpad">0</property>
56 <property name="ypad">0</property>
57 </widget>
58 </child>
59 </widget>
60 </child>
61
62 <child>
63 <widget class="GtkImageMenuItem" id="save1">
64 <property name="visible">True</property>
65 <property name="tooltip" translatable="yes">Save the config in .config</property>
66 <property name="label" translatable="yes">_Save</property>
67 <property name="use_underline">True</property>
68 <signal name="activate" handler="on_save1_activate"/>
69 <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
70
71 <child internal-child="image">
72 <widget class="GtkImage" id="image28">
73 <property name="visible">True</property>
74 <property name="stock">gtk-save</property>
75 <property name="icon_size">1</property>
76 <property name="xalign">0.5</property>
77 <property name="yalign">0.5</property>
78 <property name="xpad">0</property>
79 <property name="ypad">0</property>
80 </widget>
81 </child>
82 </widget>
83 </child>
84
85 <child>
86 <widget class="GtkImageMenuItem" id="save_as1">
87 <property name="visible">True</property>
88 <property name="tooltip" translatable="yes">Save the config in a file</property>
89 <property name="label" translatable="yes">Save _as</property>
90 <property name="use_underline">True</property>
91 <signal name="activate" handler="on_save_as1_activate"/>
92
93 <child internal-child="image">
94 <widget class="GtkImage" id="image29">
95 <property name="visible">True</property>
96 <property name="stock">gtk-save-as</property>
97 <property name="icon_size">1</property>
98 <property name="xalign">0.5</property>
99 <property name="yalign">0.5</property>
100 <property name="xpad">0</property>
101 <property name="ypad">0</property>
102 </widget>
103 </child>
104 </widget>
105 </child>
106
107 <child>
108 <widget class="GtkMenuItem" id="separator1">
109 <property name="visible">True</property>
110 </widget>
111 </child>
112
113 <child>
114 <widget class="GtkImageMenuItem" id="quit1">
115 <property name="visible">True</property>
116 <property name="label" translatable="yes">_Quit</property>
117 <property name="use_underline">True</property>
118 <signal name="activate" handler="on_quit1_activate"/>
119 <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
120
121 <child internal-child="image">
122 <widget class="GtkImage" id="image30">
123 <property name="visible">True</property>
124 <property name="stock">gtk-quit</property>
125 <property name="icon_size">1</property>
126 <property name="xalign">0.5</property>
127 <property name="yalign">0.5</property>
128 <property name="xpad">0</property>
129 <property name="ypad">0</property>
130 </widget>
131 </child>
132 </widget>
133 </child>
134 </widget>
135 </child>
136 </widget>
137 </child>
138
139 <child>
140 <widget class="GtkMenuItem" id="options1">
141 <property name="visible">True</property>
142 <property name="label" translatable="yes">_Options</property>
143 <property name="use_underline">True</property>
144
145 <child>
146 <widget class="GtkMenu" id="options1_menu">
147
148 <child>
149 <widget class="GtkCheckMenuItem" id="show_name1">
150 <property name="visible">True</property>
151 <property name="tooltip" translatable="yes">Show name</property>
152 <property name="label" translatable="yes">Show _name</property>
153 <property name="use_underline">True</property>
154 <property name="active">False</property>
155 <signal name="activate" handler="on_show_name1_activate"/>
156 </widget>
157 </child>
158
159 <child>
160 <widget class="GtkCheckMenuItem" id="show_range1">
161 <property name="visible">True</property>
162 <property name="tooltip" translatable="yes">Show range (Y/M/N)</property>
163 <property name="label" translatable="yes">Show _range</property>
164 <property name="use_underline">True</property>
165 <property name="active">False</property>
166 <signal name="activate" handler="on_show_range1_activate"/>
167 </widget>
168 </child>
169
170 <child>
171 <widget class="GtkCheckMenuItem" id="show_data1">
172 <property name="visible">True</property>
173 <property name="tooltip" translatable="yes">Show value of the option</property>
174 <property name="label" translatable="yes">Show _data</property>
175 <property name="use_underline">True</property>
176 <property name="active">False</property>
177 <signal name="activate" handler="on_show_data1_activate"/>
178 </widget>
179 </child>
180
181 <child>
182 <widget class="GtkMenuItem" id="separator2">
183 <property name="visible">True</property>
184 </widget>
185 </child>
186
187 <child>
188 <widget class="GtkCheckMenuItem" id="show_all_options1">
189 <property name="visible">True</property>
190 <property name="tooltip" translatable="yes">Show all options</property>
191 <property name="label" translatable="yes">Show all _options</property>
192 <property name="use_underline">True</property>
193 <property name="active">False</property>
194 <signal name="activate" handler="on_show_all_options1_activate"/>
195 </widget>
196 </child>
197
198 <child>
199 <widget class="GtkCheckMenuItem" id="show_debug_info1">
200 <property name="visible">True</property>
201 <property name="tooltip" translatable="yes">Show masked options</property>
202 <property name="label" translatable="yes">Show _debug info</property>
203 <property name="use_underline">True</property>
204 <property name="active">False</property>
205 <signal name="activate" handler="on_show_debug_info1_activate"/>
206 </widget>
207 </child>
208 </widget>
209 </child>
210 </widget>
211 </child>
212
213 <child>
214 <widget class="GtkMenuItem" id="help1">
215 <property name="visible">True</property>
216 <property name="label" translatable="yes">_Help</property>
217 <property name="use_underline">True</property>
218
219 <child>
220 <widget class="GtkMenu" id="help1_menu">
221
222 <child>
223 <widget class="GtkImageMenuItem" id="introduction1">
224 <property name="visible">True</property>
225 <property name="label" translatable="yes">_Introduction</property>
226 <property name="use_underline">True</property>
227 <signal name="activate" handler="on_introduction1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
228 <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/>
229
230 <child internal-child="image">
231 <widget class="GtkImage" id="image31">
232 <property name="visible">True</property>
233 <property name="stock">gtk-dialog-question</property>
234 <property name="icon_size">1</property>
235 <property name="xalign">0.5</property>
236 <property name="yalign">0.5</property>
237 <property name="xpad">0</property>
238 <property name="ypad">0</property>
239 </widget>
240 </child>
241 </widget>
242 </child>
243
244 <child>
245 <widget class="GtkImageMenuItem" id="about1">
246 <property name="visible">True</property>
247 <property name="label" translatable="yes">_About</property>
248 <property name="use_underline">True</property>
249 <signal name="activate" handler="on_about1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
250 <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
251
252 <child internal-child="image">
253 <widget class="GtkImage" id="image32">
254 <property name="visible">True</property>
255 <property name="stock">gtk-properties</property>
256 <property name="icon_size">1</property>
257 <property name="xalign">0.5</property>
258 <property name="yalign">0.5</property>
259 <property name="xpad">0</property>
260 <property name="ypad">0</property>
261 </widget>
262 </child>
263 </widget>
264 </child>
265
266 <child>
267 <widget class="GtkImageMenuItem" id="license1">
268 <property name="visible">True</property>
269 <property name="label" translatable="yes">_License</property>
270 <property name="use_underline">True</property>
271 <signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
272
273 <child internal-child="image">
274 <widget class="GtkImage" id="image33">
275 <property name="visible">True</property>
276 <property name="stock">gtk-justify-fill</property>
277 <property name="icon_size">1</property>
278 <property name="xalign">0.5</property>
279 <property name="yalign">0.5</property>
280 <property name="xpad">0</property>
281 <property name="ypad">0</property>
282 </widget>
283 </child>
284 </widget>
285 </child>
286 </widget>
287 </child>
288 </widget>
289 </child>
290 </widget>
291 <packing>
292 <property name="padding">0</property>
293 <property name="expand">False</property>
294 <property name="fill">False</property>
295 </packing>
296 </child>
297
298 <child>
299 <widget class="GtkHandleBox" id="handlebox1">
300 <property name="visible">True</property>
301 <property name="shadow_type">GTK_SHADOW_OUT</property>
302 <property name="handle_position">GTK_POS_LEFT</property>
303 <property name="snap_edge">GTK_POS_TOP</property>
304
305 <child>
306 <widget class="GtkToolbar" id="toolbar1">
307 <property name="visible">True</property>
308 <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
309 <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
310 <property name="tooltips">True</property>
311
312 <child>
313 <widget class="button" id="button1">
314 <property name="visible">True</property>
315 <property name="tooltip" translatable="yes">Goes up of one level (single view)</property>
316 <property name="label" translatable="yes">Back</property>
317 <property name="use_underline">True</property>
318 <property name="stock_pixmap">gtk-undo</property>
319 <signal name="pressed" handler="on_back_pressed"/>
320 </widget>
321 </child>
322
323 <child>
324 <widget class="GtkVSeparator" id="vseparator1">
325 <property name="visible">True</property>
326 </widget>
327 </child>
328
329 <child>
330 <widget class="button" id="button2">
331 <property name="visible">True</property>
332 <property name="tooltip" translatable="yes">Load a config file</property>
333 <property name="label" translatable="yes">Load</property>
334 <property name="use_underline">True</property>
335 <property name="stock_pixmap">gtk-open</property>
336 <signal name="pressed" handler="on_load_pressed"/>
337 </widget>
338 </child>
339
340 <child>
341 <widget class="button" id="button3">
342 <property name="visible">True</property>
343 <property name="tooltip" translatable="yes">Save a config file</property>
344 <property name="label" translatable="yes">Save</property>
345 <property name="use_underline">True</property>
346 <property name="stock_pixmap">gtk-save</property>
347 <signal name="pressed" handler="on_save_pressed"/>
348 </widget>
349 </child>
350
351 <child>
352 <widget class="GtkVSeparator" id="vseparator2">
353 <property name="visible">True</property>
354 </widget>
355 </child>
356
357 <child>
358 <widget class="button" id="button4">
359 <property name="visible">True</property>
360 <property name="tooltip" translatable="yes">Single view</property>
361 <property name="label" translatable="yes">Single</property>
362 <property name="use_underline">True</property>
363 <property name="stock_pixmap">gtk-missing-image</property>
364 <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/>
365 </widget>
366 </child>
367
368 <child>
369 <widget class="button" id="button5">
370 <property name="visible">True</property>
371 <property name="tooltip" translatable="yes">Split view</property>
372 <property name="label" translatable="yes">Split</property>
373 <property name="use_underline">True</property>
374 <property name="stock_pixmap">gtk-missing-image</property>
375 <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/>
376 </widget>
377 </child>
378
379 <child>
380 <widget class="button" id="button6">
381 <property name="visible">True</property>
382 <property name="tooltip" translatable="yes">Full view</property>
383 <property name="label" translatable="yes">Full</property>
384 <property name="use_underline">True</property>
385 <property name="stock_pixmap">gtk-missing-image</property>
386 <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/>
387 </widget>
388 </child>
389
390 <child>
391 <widget class="GtkVSeparator" id="vseparator3">
392 <property name="visible">True</property>
393 </widget>
394 </child>
395
396 <child>
397 <widget class="button" id="button7">
398 <property name="visible">True</property>
399 <property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property>
400 <property name="label" translatable="yes">Collapse</property>
401 <property name="use_underline">True</property>
402 <signal name="pressed" handler="on_collapse_pressed"/>
403 </widget>
404 </child>
405
406 <child>
407 <widget class="button" id="button8">
408 <property name="visible">True</property>
409 <property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property>
410 <property name="label" translatable="yes">Expand</property>
411 <property name="use_underline">True</property>
412 <signal name="pressed" handler="on_expand_pressed"/>
413 </widget>
414 </child>
415 </widget>
416 </child>
417 </widget>
418 <packing>
419 <property name="padding">0</property>
420 <property name="expand">False</property>
421 <property name="fill">False</property>
422 </packing>
423 </child>
424
425 <child>
426 <widget class="GtkHPaned" id="hpaned1">
427 <property name="width_request">1</property>
428 <property name="visible">True</property>
429 <property name="can_focus">True</property>
430 <property name="position">0</property>
431
432 <child>
433 <widget class="GtkScrolledWindow" id="scrolledwindow1">
434 <property name="visible">True</property>
435 <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
436 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
437 <property name="shadow_type">GTK_SHADOW_IN</property>
438 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
439
440 <child>
441 <widget class="GtkTreeView" id="treeview1">
442 <property name="visible">True</property>
443 <property name="can_focus">True</property>
444 <property name="headers_visible">True</property>
445 <property name="rules_hint">False</property>
446 <property name="reorderable">False</property>
447 <property name="enable_search">True</property>
448 <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/>
449 <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/>
450 <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/>
451 </widget>
452 </child>
453 </widget>
454 <packing>
455 <property name="shrink">True</property>
456 <property name="resize">False</property>
457 </packing>
458 </child>
459
460 <child>
461 <widget class="GtkVPaned" id="vpaned1">
462 <property name="visible">True</property>
463 <property name="can_focus">True</property>
464 <property name="position">0</property>
465
466 <child>
467 <widget class="GtkScrolledWindow" id="scrolledwindow2">
468 <property name="visible">True</property>
469 <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
470 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
471 <property name="shadow_type">GTK_SHADOW_IN</property>
472 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
473
474 <child>
475 <widget class="GtkTreeView" id="treeview2">
476 <property name="visible">True</property>
477 <property name="can_focus">True</property>
478 <property name="has_focus">True</property>
479 <property name="headers_visible">True</property>
480 <property name="rules_hint">False</property>
481 <property name="reorderable">False</property>
482 <property name="enable_search">True</property>
483 <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/>
484 <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/>
485 <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/>
486 </widget>
487 </child>
488 </widget>
489 <packing>
490 <property name="shrink">True</property>
491 <property name="resize">False</property>
492 </packing>
493 </child>
494
495 <child>
496 <widget class="GtkScrolledWindow" id="scrolledwindow3">
497 <property name="visible">True</property>
498 <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
499 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
500 <property name="shadow_type">GTK_SHADOW_IN</property>
501 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
502
503 <child>
504 <widget class="GtkTextView" id="textview3">
505 <property name="visible">True</property>
506 <property name="can_focus">True</property>
507 <property name="editable">False</property>
508 <property name="justification">GTK_JUSTIFY_LEFT</property>
509 <property name="wrap_mode">GTK_WRAP_WORD</property>
510 <property name="cursor_visible">True</property>
511 <property name="pixels_above_lines">0</property>
512 <property name="pixels_below_lines">0</property>
513 <property name="pixels_inside_wrap">0</property>
514 <property name="left_margin">0</property>
515 <property name="right_margin">0</property>
516 <property name="indent">0</property>
517 <property name="text" translatable="yes">Sorry, no help available for this option yet.</property>
518 </widget>
519 </child>
520 </widget>
521 <packing>
522 <property name="shrink">True</property>
523 <property name="resize">True</property>
524 </packing>
525 </child>
526 </widget>
527 <packing>
528 <property name="shrink">True</property>
529 <property name="resize">True</property>
530 </packing>
531 </child>
532 </widget>
533 <packing>
534 <property name="padding">0</property>
535 <property name="expand">True</property>
536 <property name="fill">True</property>
537 </packing>
538 </child>
539 </widget>
540 </child>
541</widget>
542
543</glade-interface>
diff --git a/scripts/kconfig/images.c b/scripts/kconfig/images.c
index 65a5d67..d4f84bd 100644
--- a/scripts/kconfig/images.c
+++ b/scripts/kconfig/images.c
@@ -290,3 +290,37 @@ static const char *xpm_menu_inv[] = {
290" .......... ", 290" .......... ",
291" .......... ", 291" .......... ",
292" "}; 292" "};
293
294static const char *xpm_menuback[] = {
295"12 12 2 1",
296" c white",
297". c black",
298" ",
299" .......... ",
300" . . ",
301" . .. . ",
302" . .... . ",
303" . ...... . ",
304" . ...... . ",
305" . .... . ",
306" . .. . ",
307" . . ",
308" .......... ",
309" "};
310
311static const char *xpm_void[] = {
312"12 12 2 1",
313" c white",
314". c black",
315" ",
316" ",
317" ",
318" ",
319" ",
320" ",
321" ",
322" ",
323" ",
324" ",
325" ",
326" "};
diff --git a/scripts/kconfig/lkc-language.txt b/scripts/kconfig/lkc-language.txt
index a3037ff..40f8583 100644
--- a/scripts/kconfig/lkc-language.txt
+++ b/scripts/kconfig/lkc-language.txt
@@ -18,7 +18,7 @@ organized in a tree structure:
18 +- ... 18 +- ...
19 19
20Every entry has its own dependencies. These dependencies are used 20Every entry has its own dependencies. These dependencies are used
21to determine the visible of an entry. Any child entry is only 21to determine the visibility of an entry. Any child entry is only
22visible if its parent entry is also visible. 22visible if its parent entry is also visible.
23 23
24Menu entries 24Menu entries
@@ -50,7 +50,7 @@ applicable everywhere (see syntax).
50 50
51- type definition: "bool"/"tristate"/"string"/"hex"/"integer" 51- type definition: "bool"/"tristate"/"string"/"hex"/"integer"
52 Every config option must have a type. There are only two basic types: 52 Every config option must have a type. There are only two basic types:
53 tristate and string, the other types base on these two. The type 53 tristate and string, the other types are based on these two. The type
54 definition optionally accepts an input prompt, so these two examples 54 definition optionally accepts an input prompt, so these two examples
55 are equivalent: 55 are equivalent:
56 56
@@ -64,12 +64,12 @@ applicable everywhere (see syntax).
64 to the user. Optionally dependencies only for this prompt can be added 64 to the user. Optionally dependencies only for this prompt can be added
65 with "if". 65 with "if".
66 66
67- default value: "default" <symbol> ["if" <expr>] 67- default value: "default" <expr> ["if" <expr>]
68 A config option can have any number of default values. If multiple 68 A config option can have any number of default values. If multiple
69 default values are visible, only the first defined one is active. 69 default values are visible, only the first defined one is active.
70 Default values are not limited to the menu entry, where they are 70 Default values are not limited to the menu entry, where they are
71 defined, this means the default can be defined somewhere else or be 71 defined, this means the default can be defined somewhere else or be
72 overriden by an earlier definition. 72 overridden by an earlier definition.
73 The default value is only assigned to the config symbol if no other 73 The default value is only assigned to the config symbol if no other
74 value was set by the user (via the input prompt above). If an input 74 value was set by the user (via the input prompt above). If an input
75 prompt is visible the default value is presented to the user and can 75 prompt is visible the default value is presented to the user and can
@@ -81,7 +81,7 @@ applicable everywhere (see syntax).
81 This defines a dependency for this menu entry. If multiple 81 This defines a dependency for this menu entry. If multiple
82 dependencies are defined they are connected with '&&'. Dependencies 82 dependencies are defined they are connected with '&&'. Dependencies
83 are applied to all other options within this menu entry (which also 83 are applied to all other options within this menu entry (which also
84 accept "if" expression), so these two examples are equivalent: 84 accept an "if" expression), so these two examples are equivalent:
85 85
86 bool "foo" if BAR 86 bool "foo" if BAR
87 default y if BAR 87 default y if BAR
@@ -90,9 +90,24 @@ applicable everywhere (see syntax).
90 bool "foo" 90 bool "foo"
91 default y 91 default y
92 92
93- reverse dependencies: "select" <symbol> ["if" <expr>]
94 While normal dependencies reduce the upper limit of a symbol (see
95 below), reverse dependencies can be used to force a lower limit of
96 another symbol. The value of the current menu symbol is used as the
97 minimal value <symbol> can be set to. If <symbol> is selected multiple
98 times, the limit is set to the largest selection.
99 Reverse dependencies can only be used with boolean or tristate
100 symbols.
101
102- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
103 This allows to limit the range of possible input values for integer
104 and hex symbols. The user can only input a value which is larger than
105 or equal to the first symbol and smaller than or equal to the second
106 symbol.
107
93- help text: "help" 108- help text: "help"
94 This defines a help text. The end of the help text is determined by 109 This defines a help text. The end of the help text is determined by
95 the level indentation, this means it ends at the first line which has 110 the indentation level, this means it ends at the first line which has
96 a smaller indentation than the first line of the help text. 111 a smaller indentation than the first line of the help text.
97 112
98 113
@@ -123,14 +138,14 @@ Expressions are listed in decreasing order of precedence.
123 otherwise 'y'. 138 otherwise 'y'.
124(4) Returns the value of the expression. Used to override precedence. 139(4) Returns the value of the expression. Used to override precedence.
125(5) Returns the result of (2-/expr/). 140(5) Returns the result of (2-/expr/).
126(6) Returns the result of min(/expr/, /expr/). 141(6) Returns the result of max(/expr/, /expr/).
127(7) Returns the result of max(/expr/, /expr/). 142(7) Returns the result of min(/expr/, /expr/).
128 143
129An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 144An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
130respectively for calculations). A menu entry becomes visible when it's 145respectively for calculations). A menu entry becomes visible when it's
131expression evaluates to 'm' or 'y'. 146expression evaluates to 'm' or 'y'.
132 147
133There are two type of symbols: constant and nonconstant symbols. 148There are two types of symbols: constant and nonconstant symbols.
134Nonconstant symbols are the most common ones and are defined with the 149Nonconstant symbols are the most common ones and are defined with the
135'config' statement. Nonconstant symbols consist entirely of alphanumeric 150'config' statement. Nonconstant symbols consist entirely of alphanumeric
136characters or underscores. 151characters or underscores.
@@ -142,7 +157,7 @@ Menu structure
142-------------- 157--------------
143 158
144The position of a menu entry in the tree is determined in two ways. First 159The position of a menu entry in the tree is determined in two ways. First
145it can be specified explicitely: 160it can be specified explicitly:
146 161
147menu "Network device support" 162menu "Network device support"
148 depends NET 163 depends NET
@@ -159,8 +174,8 @@ dependency list of the config option NETDEVICES.
159 174
160The other way to generate the menu structure is done by analyzing the 175The other way to generate the menu structure is done by analyzing the
161dependencies. If a menu entry somehow depends on the previous entry, it 176dependencies. If a menu entry somehow depends on the previous entry, it
162can be made a submenu of it. First the the previous (parent) symbol must 177can be made a submenu of it. First, the previous (parent) symbol must
163be part of the dependency list and then one of these two condititions 178be part of the dependency list and then one of these two conditions
164must be true: 179must be true:
165- the child entry must become invisible, if the parent is set to 'n' 180- the child entry must become invisible, if the parent is set to 'n'
166- the child entry must only be visible, if the parent is visible 181- the child entry must only be visible, if the parent is visible
@@ -177,7 +192,7 @@ comment "module support disabled"
177 192
178MODVERSIONS directly depends on MODULES, this means it's only visible if 193MODVERSIONS directly depends on MODULES, this means it's only visible if
179MODULES is different from 'n'. The comment on the other hand is always 194MODULES is different from 'n'. The comment on the other hand is always
180visible when MODULES it's visible (the (empty) dependency of MODULES is 195visible when MODULES is visible (the (empty) dependency of MODULES is
181also part of the comment dependencies). 196also part of the comment dependencies).
182 197
183 198
@@ -188,12 +203,13 @@ The configuration file describes a series of menu entries, where every
188line starts with a keyword (except help texts). The following keywords 203line starts with a keyword (except help texts). The following keywords
189end a menu entry: 204end a menu entry:
190- config 205- config
206- menuconfig
191- choice/endchoice 207- choice/endchoice
192- comment 208- comment
193- menu/endmenu 209- menu/endmenu
194- if/endif 210- if/endif
195- source 211- source
196The first four also start the definition of a menu entry. 212The first five also start the definition of a menu entry.
197 213
198config: 214config:
199 215
@@ -203,6 +219,14 @@ config:
203This defines a config symbol <symbol> and accepts any of above 219This defines a config symbol <symbol> and accepts any of above
204attributes as options. 220attributes as options.
205 221
222menuconfig:
223 "menuconfig" <symbol>
224 <config options>
225
226This is similiar to the simple config entry above, but it also gives a
227hint to front ends, that all suboptions should be displayed as a
228separate list of options.
229
206choices: 230choices:
207 231
208 "choice" 232 "choice"
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index cdd04a9..dd040f7 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -49,9 +49,11 @@ void menu_add_menu(void);
49void menu_end_menu(void); 49void menu_end_menu(void);
50void menu_add_entry(struct symbol *sym); 50void menu_add_entry(struct symbol *sym);
51void menu_end_entry(void); 51void menu_end_entry(void);
52struct property *create_prop(enum prop_type type);
53void menu_add_dep(struct expr *dep); 52void menu_add_dep(struct expr *dep);
54struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep); 53struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
54void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
55void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
56void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
55void menu_finalize(struct menu *parent); 57void menu_finalize(struct menu *parent);
56void menu_set_type(int type); 58void menu_set_type(int type);
57struct file *file_lookup(const char *name); 59struct file *file_lookup(const char *name);
@@ -64,16 +66,19 @@ extern struct menu *current_menu;
64void sym_init(void); 66void sym_init(void);
65void sym_clear_all_valid(void); 67void sym_clear_all_valid(void);
66void sym_set_changed(struct symbol *sym); 68void sym_set_changed(struct symbol *sym);
69struct symbol *sym_check_deps(struct symbol *sym);
70struct property *prop_alloc(enum prop_type type, struct symbol *sym);
71struct symbol *prop_get_symbol(struct property *prop);
67 72
68static inline tristate sym_get_tristate_value(struct symbol *sym) 73static inline tristate sym_get_tristate_value(struct symbol *sym)
69{ 74{
70 return S_TRI(sym->curr); 75 return sym->curr.tri;
71} 76}
72 77
73 78
74static inline struct symbol *sym_get_choice_value(struct symbol *sym) 79static inline struct symbol *sym_get_choice_value(struct symbol *sym)
75{ 80{
76 return (struct symbol *)S_VAL(sym->curr); 81 return (struct symbol *)sym->curr.val;
77} 82}
78 83
79static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) 84static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
@@ -98,7 +103,6 @@ static inline bool sym_is_optional(struct symbol *sym)
98 103
99static inline bool sym_has_value(struct symbol *sym) 104static inline bool sym_has_value(struct symbol *sym)
100{ 105{
101 //return S_VAL(sym->def) != NULL;
102 return sym->flags & SYMBOL_NEW ? false : true; 106 return sym->flags & SYMBOL_NEW ? false : true;
103} 107}
104 108
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 116d759..97c7917 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -18,13 +18,14 @@ P(sym_change_count,int,);
18 18
19P(sym_lookup,struct symbol *,(const char *name, int isconst)); 19P(sym_lookup,struct symbol *,(const char *name, int isconst));
20P(sym_find,struct symbol *,(const char *name)); 20P(sym_find,struct symbol *,(const char *name));
21P(sym_type_name,const char *,(int type)); 21P(sym_type_name,const char *,(enum symbol_type type));
22P(sym_calc_value,void,(struct symbol *sym)); 22P(sym_calc_value,void,(struct symbol *sym));
23P(sym_get_type,int,(struct symbol *sym)); 23P(sym_get_type,enum symbol_type,(struct symbol *sym));
24P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); 24P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
25P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); 25P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
26P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); 26P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
27P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); 27P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
28P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
28P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); 29P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
29P(sym_is_changable,bool,(struct symbol *sym)); 30P(sym_is_changable,bool,(struct symbol *sym));
30P(sym_get_choice_prop,struct property *,(struct symbol *sym)); 31P(sym_get_choice_prop,struct property *,(struct symbol *sym));
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 6d82718..b9cf25f 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -49,18 +49,18 @@ setmod_text[] =
49 "This feature depends on another which has been configured as a module.\n" 49 "This feature depends on another which has been configured as a module.\n"
50 "As a result, this feature will be built as a module.", 50 "As a result, this feature will be built as a module.",
51nohelp_text[] = 51nohelp_text[] =
52 "There is no help available for this kernel option.\n", 52 "There is no help available for this option.\n",
53load_config_text[] = 53load_config_text[] =
54 "Enter the name of the configuration file you wish to load. " 54 "Enter the name of the configuration file you wish to load. "
55 "Accept the name shown to restore the configuration you " 55 "Accept the name shown to restore the configuration you "
56 "last retrieved. Leave blank to abort.", 56 "last retrieved. Leave blank to abort.",
57load_config_help[] = 57load_config_help[] =
58 "\n" 58 "\n"
59 "For various reasons, one may wish to keep several different kernel\n" 59 "For various reasons, one may wish to keep several different \n"
60 "configurations available on a single machine.\n" 60 "configurations available on a single machine.\n"
61 "\n" 61 "\n"
62 "If you have saved a previous configuration in a file other than the\n" 62 "If you have saved a previous configuration in a file other than the\n"
63 "kernel's default, entering the name of the file here will allow you\n" 63 "default, entering the name of the file here will allow you\n"
64 "to modify that configuration.\n" 64 "to modify that configuration.\n"
65 "\n" 65 "\n"
66 "If you are uncertain, then you have probably never used alternate\n" 66 "If you are uncertain, then you have probably never used alternate\n"
@@ -70,7 +70,7 @@ save_config_text[] =
70 "as an alternate. Leave blank to abort.", 70 "as an alternate. Leave blank to abort.",
71save_config_help[] = 71save_config_help[] =
72 "\n" 72 "\n"
73 "For various reasons, one may wish to keep different kernel\n" 73 "For various reasons, one may wish to keep different\n"
74 "configurations available on a single machine.\n" 74 "configurations available on a single machine.\n"
75 "\n" 75 "\n"
76 "Entering a file name here will allow you to later retrieve, modify\n" 76 "Entering a file name here will allow you to later retrieve, modify\n"
@@ -147,12 +147,17 @@ static void init_wsize(void)
147 147
148static void cprint_init(void) 148static void cprint_init(void)
149{ 149{
150 char *env = getenv("LXDIALOG");
150 bufptr = buf; 151 bufptr = buf;
151 argptr = args; 152 argptr = args;
152 memset(args, 0, sizeof(args)); 153 memset(args, 0, sizeof(args));
153 indent = 0; 154 indent = 0;
154 child_count = 0; 155 child_count = 0;
155 cprint("./scripts/lxdialog/lxdialog"); 156 if(env != NULL) {
157 cprint(env);
158 } else {
159 cprint("./scripts/lxdialog/lxdialog");
160 }
156 cprint("--backtitle"); 161 cprint("--backtitle");
157 cprint(menu_backtitle); 162 cprint(menu_backtitle);
158} 163}
@@ -302,11 +307,8 @@ static void build_conf(struct menu *menu)
302 cprint1("%s%*c%s", 307 cprint1("%s%*c%s",
303 menu->data ? "-->" : "++>", 308 menu->data ? "-->" : "++>",
304 indent + 1, ' ', prompt); 309 indent + 1, ' ', prompt);
305 } else { 310 } else
306 if (menu->parent != &rootmenu) 311 cprint1(" %*c%s --->", indent + 1, ' ', prompt);
307 cprint1(" %*c", indent + 1, ' ');
308 cprint1("%s --->", prompt);
309 }
310 312
311 cprint_done(); 313 cprint_done();
312 if (single_menu_mode && menu->data) 314 if (single_menu_mode && menu->data)
@@ -373,6 +375,11 @@ static void build_conf(struct menu *menu)
373 } 375 }
374 cprint_done(); 376 cprint_done();
375 } else { 377 } else {
378 if (menu == current_menu) {
379 cprint(":%p", menu);
380 cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
381 goto conf_childs;
382 }
376 child_count++; 383 child_count++;
377 val = sym_get_tristate_value(sym); 384 val = sym_get_tristate_value(sym);
378 if (sym_is_choice_value(sym) && val == yes) { 385 if (sym_is_choice_value(sym) && val == yes) {
@@ -382,7 +389,10 @@ static void build_conf(struct menu *menu)
382 switch (type) { 389 switch (type) {
383 case S_BOOLEAN: 390 case S_BOOLEAN:
384 cprint("t%p", menu); 391 cprint("t%p", menu);
385 cprint1("[%c]", val == no ? ' ' : '*'); 392 if (sym_is_changable(sym))
393 cprint1("[%c]", val == no ? ' ' : '*');
394 else
395 cprint1("---");
386 break; 396 break;
387 case S_TRISTATE: 397 case S_TRISTATE:
388 cprint("t%p", menu); 398 cprint("t%p", menu);
@@ -391,7 +401,10 @@ static void build_conf(struct menu *menu)
391 case mod: ch = 'M'; break; 401 case mod: ch = 'M'; break;
392 default: ch = ' '; break; 402 default: ch = ' '; break;
393 } 403 }
394 cprint1("<%c>", ch); 404 if (sym_is_changable(sym))
405 cprint1("<%c>", ch);
406 else
407 cprint1("---");
395 break; 408 break;
396 default: 409 default:
397 cprint("s%p", menu); 410 cprint("s%p", menu);
@@ -400,13 +413,20 @@ static void build_conf(struct menu *menu)
400 if (tmp < 0) 413 if (tmp < 0)
401 tmp = 0; 414 tmp = 0;
402 cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), 415 cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
403 sym_has_value(sym) ? "" : " (NEW)"); 416 (sym_has_value(sym) || !sym_is_changable(sym)) ?
417 "" : " (NEW)");
404 cprint_done(); 418 cprint_done();
405 goto conf_childs; 419 goto conf_childs;
406 } 420 }
407 } 421 }
408 cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), 422 cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
409 sym_has_value(sym) ? "" : " (NEW)"); 423 (sym_has_value(sym) || !sym_is_changable(sym)) ?
424 "" : " (NEW)");
425 if (menu->prompt->type == P_MENU) {
426 cprint1(" --->");
427 cprint_done();
428 return;
429 }
410 cprint_done(); 430 cprint_done();
411 } 431 }
412 432
@@ -445,9 +465,9 @@ static void conf(struct menu *menu)
445 cprint(":"); 465 cprint(":");
446 cprint("--- "); 466 cprint("--- ");
447 cprint("L"); 467 cprint("L");
448 cprint("Load an Alternate Configuration File"); 468 cprint(" Load an Alternate Configuration File");
449 cprint("S"); 469 cprint("S");
450 cprint("Save Configuration to an Alternate File"); 470 cprint(" Save Configuration to an Alternate File");
451 } 471 }
452 stat = exec_conf(); 472 stat = exec_conf();
453 if (stat < 0) 473 if (stat < 0)
@@ -484,6 +504,8 @@ static void conf(struct menu *menu)
484 case 't': 504 case 't':
485 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) 505 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
486 conf_choice(submenu); 506 conf_choice(submenu);
507 else if (submenu->prompt->type == P_MENU)
508 conf(submenu);
487 break; 509 break;
488 case 's': 510 case 's':
489 conf_string(submenu); 511 conf_string(submenu);
@@ -744,8 +766,7 @@ int main(int ac, char **av)
744 766
745 sym = sym_lookup("KERNELRELEASE", 0); 767 sym = sym_lookup("KERNELRELEASE", 0);
746 sym_calc_value(sym); 768 sym_calc_value(sym);
747 sprintf(menu_backtitle, "Opie %s Configuration", 769 sprintf(menu_backtitle, "Build Configuration");
748 sym_get_string_value(sym));
749 770
750 mode = getenv("MENUCONFIG_MODE"); 771 mode = getenv("MENUCONFIG_MODE");
751 if (mode) { 772 if (mode) {
@@ -770,11 +791,12 @@ int main(int ac, char **av)
770 if (stat == 0) { 791 if (stat == 0) {
771 conf_write(NULL); 792 conf_write(NULL);
772 printf("\n\n" 793 printf("\n\n"
773 "*** End of Opie configuration.\n" 794 "*** End of configuration.\n"
774 "*** Check the top-level Makefile for additional configuration.\n" 795 "\n\n");
775 "*** Next, you may run 'make'.\n\n");
776 } else 796 } else
777 printf("\n\nYour Opie configuration changes were NOT saved.\n\n"); 797 printf("\n\n"
798 "Your configuration changes were NOT saved."
799 "\n\n");
778 800
779 return 0; 801 return 0;
780} 802}
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 24be0ec..1631767 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -54,9 +54,34 @@ void menu_end_menu(void)
54 current_menu = current_menu->parent; 54 current_menu = current_menu->parent;
55} 55}
56 56
57struct expr *menu_check_dep(struct expr *e)
58{
59 if (!e)
60 return e;
61
62 switch (e->type) {
63 case E_NOT:
64 e->left.expr = menu_check_dep(e->left.expr);
65 break;
66 case E_OR:
67 case E_AND:
68 e->left.expr = menu_check_dep(e->left.expr);
69 e->right.expr = menu_check_dep(e->right.expr);
70 break;
71 case E_SYMBOL:
72 /* change 'm' into 'm' && MODULES */
73 if (e->left.sym == &symbol_mod)
74 return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
75 break;
76 default:
77 break;
78 }
79 return e;
80}
81
57void menu_add_dep(struct expr *dep) 82void menu_add_dep(struct expr *dep)
58{ 83{
59 current_entry->dep = expr_alloc_and(current_entry->dep, dep); 84 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
60} 85}
61 86
62void menu_set_type(int type) 87void menu_set_type(int type)
@@ -69,56 +94,43 @@ void menu_set_type(int type)
69 sym->type = type; 94 sym->type = type;
70 return; 95 return;
71 } 96 }
72 fprintf(stderr, "%s:%d: type of '%s' redefined from '%s' to '%s'\n", 97 fprintf(stderr, "%s:%d:warning: type of '%s' redefined from '%s' to '%s'\n",
73 current_entry->file->name, current_entry->lineno, 98 current_entry->file->name, current_entry->lineno,
74 sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type)); 99 sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type));
75} 100}
76 101
77struct property *create_prop(enum prop_type type) 102struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
78{
79 struct property *prop;
80
81 prop = malloc(sizeof(*prop));
82 memset(prop, 0, sizeof(*prop));
83 prop->type = type;
84 prop->file = current_file;
85 prop->lineno = zconf_lineno();
86
87 return prop;
88}
89
90struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep)
91{ 103{
92 struct property *prop = create_prop(token); 104 struct property *prop = prop_alloc(type, current_entry->sym);
93 struct property **propp;
94 105
95 prop->sym = current_entry->sym;
96 prop->menu = current_entry; 106 prop->menu = current_entry;
97 prop->text = prompt; 107 prop->text = prompt;
98 prop->def = def; 108 prop->expr = expr;
99 E_EXPR(prop->visible) = dep; 109 prop->visible.expr = menu_check_dep(dep);
100 110
101 if (prompt) 111 if (prompt) {
112 if (current_entry->prompt)
113 fprintf(stderr, "%s:%d: prompt redefined\n",
114 current_entry->file->name, current_entry->lineno);
102 current_entry->prompt = prop; 115 current_entry->prompt = prop;
103
104 /* append property to the prop list of symbol */
105 if (prop->sym) {
106 for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
107 ;
108 *propp = prop;
109 } 116 }
110 117
111 return prop; 118 return prop;
112} 119}
113 120
114void menu_add_prompt(int token, char *prompt, struct expr *dep) 121void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
115{ 122{
116 current_entry->prompt = menu_add_prop(token, prompt, NULL, dep); 123 menu_add_prop(type, prompt, NULL, dep);
117} 124}
118 125
119void menu_add_default(int token, struct symbol *def, struct expr *dep) 126void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
120{ 127{
121 current_entry->prompt = menu_add_prop(token, NULL, def, dep); 128 menu_add_prop(type, NULL, expr, dep);
129}
130
131void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
132{
133 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
122} 134}
123 135
124void menu_finalize(struct menu *parent) 136void menu_finalize(struct menu *parent)
@@ -126,7 +138,7 @@ void menu_finalize(struct menu *parent)
126 struct menu *menu, *last_menu; 138 struct menu *menu, *last_menu;
127 struct symbol *sym; 139 struct symbol *sym;
128 struct property *prop; 140 struct property *prop;
129 struct expr *parentdep, *basedep, *dep, *dep2; 141 struct expr *parentdep, *basedep, *dep, *dep2, **ep;
130 142
131 sym = parent->sym; 143 sym = parent->sym;
132 if (parent->list) { 144 if (parent->list) {
@@ -143,7 +155,7 @@ void menu_finalize(struct menu *parent)
143 } 155 }
144 parentdep = expr_alloc_symbol(sym); 156 parentdep = expr_alloc_symbol(sym);
145 } else if (parent->prompt) 157 } else if (parent->prompt)
146 parentdep = E_EXPR(parent->prompt->visible); 158 parentdep = parent->prompt->visible.expr;
147 else 159 else
148 parentdep = parent->dep; 160 parentdep = parent->dep;
149 161
@@ -159,23 +171,28 @@ void menu_finalize(struct menu *parent)
159 for (; prop; prop = prop->next) { 171 for (; prop; prop = prop->next) {
160 if (prop->menu != menu) 172 if (prop->menu != menu)
161 continue; 173 continue;
162 dep = expr_transform(E_EXPR(prop->visible)); 174 dep = expr_transform(prop->visible.expr);
163 dep = expr_alloc_and(expr_copy(basedep), dep); 175 dep = expr_alloc_and(expr_copy(basedep), dep);
164 dep = expr_eliminate_dups(dep); 176 dep = expr_eliminate_dups(dep);
165 if (menu->sym && menu->sym->type != S_TRISTATE) 177 if (menu->sym && menu->sym->type != S_TRISTATE)
166 dep = expr_trans_bool(dep); 178 dep = expr_trans_bool(dep);
167 E_EXPR(prop->visible) = dep; 179 prop->visible.expr = dep;
180 if (prop->type == P_SELECT) {
181 struct symbol *es = prop_get_symbol(prop);
182 es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
183 expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
184 }
168 } 185 }
169 } 186 }
170 for (menu = parent->list; menu; menu = menu->next) 187 for (menu = parent->list; menu; menu = menu->next)
171 menu_finalize(menu); 188 menu_finalize(menu);
172 } else if (sym && parent->prompt) { 189 } else if (sym) {
173 basedep = E_EXPR(parent->prompt->visible); 190 basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
174 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); 191 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
175 basedep = expr_eliminate_dups(expr_transform(basedep)); 192 basedep = expr_eliminate_dups(expr_transform(basedep));
176 last_menu = NULL; 193 last_menu = NULL;
177 for (menu = parent->next; menu; menu = menu->next) { 194 for (menu = parent->next; menu; menu = menu->next) {
178 dep = menu->prompt ? E_EXPR(menu->prompt->visible) : menu->dep; 195 dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
179 if (!expr_contains_symbol(dep, sym)) 196 if (!expr_contains_symbol(dep, sym))
180 break; 197 break;
181 if (expr_depends_symbol(dep, sym)) 198 if (expr_depends_symbol(dep, sym))
@@ -204,14 +221,27 @@ void menu_finalize(struct menu *parent)
204 for (menu = parent->list; menu; menu = menu->next) { 221 for (menu = parent->list; menu; menu = menu->next) {
205 if (sym && sym_is_choice(sym) && menu->sym) { 222 if (sym && sym_is_choice(sym) && menu->sym) {
206 menu->sym->flags |= SYMBOL_CHOICEVAL; 223 menu->sym->flags |= SYMBOL_CHOICEVAL;
224 if (!menu->prompt)
225 fprintf(stderr, "%s:%d:warning: choice value must have a prompt\n",
226 menu->file->name, menu->lineno);
227 for (prop = menu->sym->prop; prop; prop = prop->next) {
228 if (prop->type == P_PROMPT && prop->menu != menu) {
229 fprintf(stderr, "%s:%d:warning: choice values currently only support a single prompt\n",
230 prop->file->name, prop->lineno);
231
232 }
233 if (prop->type == P_DEFAULT)
234 fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n",
235 prop->file->name, prop->lineno);
236 }
207 current_entry = menu; 237 current_entry = menu;
208 menu_set_type(sym->type); 238 menu_set_type(sym->type);
209 menu_add_prop(P_CHOICE, NULL, parent->sym, NULL); 239 menu_add_symbol(P_CHOICE, sym, NULL);
210 prop = sym_get_choice_prop(parent->sym); 240 prop = sym_get_choice_prop(sym);
211 //dep = expr_alloc_one(E_CHOICE, dep); 241 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
212 //dep->right.sym = menu->sym; 242 ;
213 prop->dep = expr_alloc_one(E_CHOICE, prop->dep); 243 *ep = expr_alloc_one(E_CHOICE, NULL);
214 prop->dep->right.sym = menu->sym; 244 (*ep)->right.sym = menu->sym;
215 } 245 }
216 if (menu->list && (!menu->prompt || !menu->prompt->text)) { 246 if (menu->list && (!menu->prompt || !menu->prompt->text)) {
217 for (last_menu = menu->list; ; last_menu = last_menu->next) { 247 for (last_menu = menu->list; ; last_menu = last_menu->next) {
@@ -224,20 +254,79 @@ void menu_finalize(struct menu *parent)
224 menu->list = NULL; 254 menu->list = NULL;
225 } 255 }
226 } 256 }
257
258 if (sym && !(sym->flags & SYMBOL_WARNED)) {
259 struct symbol *sym2;
260 if (sym->type == S_UNKNOWN)
261 fprintf(stderr, "%s:%d:warning: config symbol defined without type\n",
262 parent->file->name, parent->lineno);
263
264 if (sym_is_choice(sym) && !parent->prompt)
265 fprintf(stderr, "%s:%d:warning: choice must have a prompt\n",
266 parent->file->name, parent->lineno);
267
268 for (prop = sym->prop; prop; prop = prop->next) {
269 switch (prop->type) {
270 case P_DEFAULT:
271 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
272 prop->expr->type != E_SYMBOL)
273 fprintf(stderr, "%s:%d:warning: default must be a single symbol\n",
274 prop->file->name, prop->lineno);
275 break;
276 case P_SELECT:
277 sym2 = prop_get_symbol(prop);
278 if ((sym->type != S_BOOLEAN && sym->type != S_TRISTATE) ||
279 (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE))
280 fprintf(stderr, "%s:%d:warning: enable is only allowed with boolean and tristate symbols\n",
281 prop->file->name, prop->lineno);
282 break;
283 case P_RANGE:
284 if (sym->type != S_INT && sym->type != S_HEX)
285 fprintf(stderr, "%s:%d:warning: range is only allowed for int or hex symbols\n",
286 prop->file->name, prop->lineno);
287 if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
288 !sym_string_valid(sym, prop->expr->right.sym->name))
289 fprintf(stderr, "%s:%d:warning: range is invalid\n",
290 prop->file->name, prop->lineno);
291 break;
292 default:
293 ;
294 }
295 }
296 sym->flags |= SYMBOL_WARNED;
297 }
298
299 if (sym && !sym_is_optional(sym) && parent->prompt) {
300 sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
301 expr_alloc_and(parent->prompt->visible.expr,
302 expr_alloc_symbol(&symbol_mod)));
303 }
227} 304}
228 305
229bool menu_is_visible(struct menu *menu) 306bool menu_is_visible(struct menu *menu)
230{ 307{
308 struct menu *child;
309 struct symbol *sym;
231 tristate visible; 310 tristate visible;
232 311
233 if (!menu->prompt) 312 if (!menu->prompt)
234 return false; 313 return false;
235 if (menu->sym) { 314 sym = menu->sym;
236 sym_calc_value(menu->sym); 315 if (sym) {
237 visible = E_TRI(menu->prompt->visible); 316 sym_calc_value(sym);
317 visible = menu->prompt->visible.tri;
238 } else 318 } else
239 visible = E_CALC(menu->prompt->visible); 319 visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
240 return visible != no; 320
321 if (visible != no)
322 return true;
323 if (!sym || sym_get_tristate_value(menu->sym) == no)
324 return false;
325
326 for (child = menu->list; child; child = child->next)
327 if (menu_is_visible(child))
328 return true;
329 return false;
241} 330}
242 331
243const char *menu_get_prompt(struct menu *menu) 332const char *menu_get_prompt(struct menu *menu)
@@ -258,10 +347,9 @@ struct menu *menu_get_parent_menu(struct menu *menu)
258{ 347{
259 enum prop_type type; 348 enum prop_type type;
260 349
261 while (menu != &rootmenu) { 350 for (; menu != &rootmenu; menu = menu->parent) {
262 menu = menu->parent;
263 type = menu->prompt ? menu->prompt->type : 0; 351 type = menu->prompt ? menu->prompt->type : 0;
264 if (type == P_MENU || type == P_ROOTMENU) 352 if (type == P_MENU)
265 break; 353 break;
266 } 354 }
267 return menu; 355 return menu;
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index bed541d..52419ad 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -42,15 +42,12 @@ static QSettings *configSettings;
42 * menu: entry to be updated 42 * menu: entry to be updated
43 */ 43 */
44template <class P> 44template <class P>
45static void updateMenuList(P* parent, struct menu* menu) 45void ConfigList::updateMenuList(P* parent, struct menu* menu)
46{ 46{
47 struct menu* child; 47 struct menu* child;
48 ConfigList* list = parent->listView();
49 ConfigItem* item; 48 ConfigItem* item;
50 ConfigItem* last; 49 ConfigItem* last;
51 bool visible; 50 bool visible;
52 bool showAll = list->showAll;
53 enum listMode mode = list->mode;
54 enum prop_type type; 51 enum prop_type type;
55 52
56 if (!menu) { 53 if (!menu) {
@@ -59,18 +56,20 @@ static void updateMenuList(P* parent, struct menu* menu)
59 return; 56 return;
60 } 57 }
61 58
62 last = 0; 59 last = parent->firstChild();
60 if (last && !last->goParent)
61 last = 0;
63 for (child = menu->list; child; child = child->next) { 62 for (child = menu->list; child; child = child->next) {
64 item = last ? last->nextSibling() : parent->firstChild(); 63 item = last ? last->nextSibling() : parent->firstChild();
65 type = child->prompt ? child->prompt->type : P_UNKNOWN; 64 type = child->prompt ? child->prompt->type : P_UNKNOWN;
66 65
67 switch (mode) { 66 switch (mode) {
68 case menuMode: 67 case menuMode:
69 if (type != P_ROOTMENU) 68 if (!(child->flags & MENU_ROOT))
70 goto hide; 69 goto hide;
71 break; 70 break;
72 case symbolMode: 71 case symbolMode:
73 if (type == P_ROOTMENU) 72 if (child->flags & MENU_ROOT)
74 goto hide; 73 goto hide;
75 break; 74 break;
76 default: 75 default:
@@ -81,26 +80,17 @@ static void updateMenuList(P* parent, struct menu* menu)
81 if (showAll || visible) { 80 if (showAll || visible) {
82 if (!item || item->menu != child) 81 if (!item || item->menu != child)
83 item = new ConfigItem(parent, last, child, visible); 82 item = new ConfigItem(parent, last, child, visible);
84 else { 83 else
85 item->visible = visible; 84 item->testUpdateMenu(visible);
86 if (item->updateNeeded()) {
87 ConfigItem* i = (ConfigItem*)child->data;
88 for (; i; i = i->nextItem) {
89 i->updateMenu();
90 }
91 } else if (list->updateAll)
92 item->updateMenu();
93 }
94 85
95 if (mode == fullMode || mode == menuMode || 86 if (mode == fullMode || mode == menuMode || type != P_MENU)
96 (type != P_MENU && type != P_ROOTMENU))
97 updateMenuList(item, child); 87 updateMenuList(item, child);
98 else 88 else
99 updateMenuList(item, 0); 89 updateMenuList(item, 0);
100 last = item; 90 last = item;
101 continue; 91 continue;
102 } 92 }
103 hide: 93 hide:
104 if (item && item->menu == child) { 94 if (item && item->menu == child) {
105 last = parent->firstChild(); 95 last = parent->firstChild();
106 if (last == item) 96 if (last == item)
@@ -131,24 +121,45 @@ void ConfigItem::updateMenu(void)
131{ 121{
132 ConfigList* list; 122 ConfigList* list;
133 struct symbol* sym; 123 struct symbol* sym;
124 struct property *prop;
134 QString prompt; 125 QString prompt;
135 int type; 126 int type;
136 enum prop_type ptype;
137 tristate expr; 127 tristate expr;
138 128
139 list = listView(); 129 list = listView();
130 if (goParent) {
131 setPixmap(promptColIdx, list->menuBackPix);
132 prompt = "..";
133 goto set_prompt;
134 }
140 135
141 sym = menu->sym; 136 sym = menu->sym;
142 if (!sym) { 137 prop = menu->prompt;
143 setText(promptColIdx, menu_get_prompt(menu)); 138 prompt = menu_get_prompt(menu);
144 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 139
145 if ((ptype == P_ROOTMENU || ptype == P_MENU) && 140 if (prop) switch (prop->type) {
146 (list->mode == singleMode || list->mode == symbolMode)) 141 case P_MENU:
142 if (list->mode == singleMode || list->mode == symbolMode) {
143 /* a menuconfig entry is displayed differently
144 * depending whether it's at the view root or a child.
145 */
146 if (sym && list->rootEntry == menu)
147 break;
147 setPixmap(promptColIdx, list->menuPix); 148 setPixmap(promptColIdx, list->menuPix);
148 else 149 } else {
150 if (sym)
151 break;
149 setPixmap(promptColIdx, 0); 152 setPixmap(promptColIdx, 0);
150 return; 153 }
154 goto set_prompt;
155 case P_COMMENT:
156 setPixmap(promptColIdx, 0);
157 goto set_prompt;
158 default:
159 ;
151 } 160 }
161 if (!sym)
162 goto set_prompt;
152 163
153 setText(nameColIdx, sym->name); 164 setText(nameColIdx, sym->name);
154 165
@@ -158,8 +169,8 @@ void ConfigItem::updateMenu(void)
158 case S_TRISTATE: 169 case S_TRISTATE:
159 char ch; 170 char ch;
160 171
161 prompt = menu_get_prompt(menu);
162 if (!sym_is_changable(sym) && !list->showAll) { 172 if (!sym_is_changable(sym) && !list->showAll) {
173 setPixmap(promptColIdx, 0);
163 setText(noColIdx, 0); 174 setText(noColIdx, 0);
164 setText(modColIdx, 0); 175 setText(modColIdx, 0);
165 setText(yesColIdx, 0); 176 setText(yesColIdx, 0);
@@ -211,26 +222,33 @@ void ConfigItem::updateMenu(void)
211#endif 222#endif
212 setText(dataColIdx, data); 223 setText(dataColIdx, data);
213 if (type == S_STRING) 224 if (type == S_STRING)
214 prompt.sprintf("%s: %s", menu_get_prompt(menu), data); 225 prompt.sprintf("%s: %s", prompt.latin1(), data);
215 else 226 else
216 prompt.sprintf("(%s) %s", data, menu_get_prompt(menu)); 227 prompt.sprintf("(%s) %s", data, prompt.latin1());
217 break; 228 break;
218 } 229 }
219 if (!sym_has_value(sym) && visible) 230 if (!sym_has_value(sym) && visible)
220 prompt += " (NEW)"; 231 prompt += " (NEW)";
232set_prompt:
221 setText(promptColIdx, prompt); 233 setText(promptColIdx, prompt);
222} 234}
223 235
224bool ConfigItem::updateNeeded(void) 236void ConfigItem::testUpdateMenu(bool v)
225{ 237{
226 struct symbol* sym = menu->sym; 238 ConfigItem* i;
227 if (sym) 239
228 sym_calc_value(sym); 240 visible = v;
241 if (!menu)
242 return;
243
244 sym_calc_value(menu->sym);
229 if (menu->flags & MENU_CHANGED) { 245 if (menu->flags & MENU_CHANGED) {
246 /* the menu entry changed, so update all list items */
230 menu->flags &= ~MENU_CHANGED; 247 menu->flags &= ~MENU_CHANGED;
231 return true; 248 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
232 } 249 i->updateMenu();
233 return false; 250 } else if (listView()->updateAll)
251 updateMenu();
234} 252}
235 253
236void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align) 254void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
@@ -251,14 +269,15 @@ void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int w
251 */ 269 */
252void ConfigItem::init(void) 270void ConfigItem::init(void)
253{ 271{
254 ConfigList* list = listView(); 272 if (menu) {
255 nextItem = (ConfigItem*)menu->data; 273 ConfigList* list = listView();
256 menu->data = this; 274 nextItem = (ConfigItem*)menu->data;
275 menu->data = this;
257 276
258 if (list->mode != fullMode) 277 if (list->mode != fullMode)
259 setOpen(TRUE); 278 setOpen(TRUE);
260 if (menu->sym)
261 sym_calc_value(menu->sym); 279 sym_calc_value(menu->sym);
280 }
262 updateMenu(); 281 updateMenu();
263} 282}
264 283
@@ -267,11 +286,13 @@ void ConfigItem::init(void)
267 */ 286 */
268ConfigItem::~ConfigItem(void) 287ConfigItem::~ConfigItem(void)
269{ 288{
270 ConfigItem** ip = &(ConfigItem*)menu->data; 289 if (menu) {
271 for (; *ip; ip = &(*ip)->nextItem) { 290 ConfigItem** ip = (ConfigItem**)&menu->data;
272 if (*ip == this) { 291 for (; *ip; ip = &(*ip)->nextItem) {
273 *ip = nextItem; 292 if (*ip == this) {
274 break; 293 *ip = nextItem;
294 break;
295 }
275 } 296 }
276 } 297 }
277} 298}
@@ -310,7 +331,8 @@ ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv)
310 : Parent(p), cview(cv), 331 : Parent(p), cview(cv),
311 updateAll(false), 332 updateAll(false),
312 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), 333 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
313 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), 334 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
335 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
314 showAll(false), showName(false), showRange(false), showData(false), 336 showAll(false), showName(false), showRange(false), showData(false),
315 rootEntry(0) 337 rootEntry(0)
316{ 338{
@@ -366,14 +388,37 @@ void ConfigList::updateSelection(void)
366 cview->setHelp(item); 388 cview->setHelp(item);
367 389
368 menu = item->menu; 390 menu = item->menu;
391 if (!menu)
392 return;
369 type = menu->prompt ? menu->prompt->type : P_UNKNOWN; 393 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
370 if (mode == menuMode && (type == P_MENU || type == P_ROOTMENU)) 394 if (mode == menuMode && type == P_MENU)
371 emit menuSelected(menu); 395 emit menuSelected(menu);
372} 396}
373 397
374void ConfigList::updateList(ConfigItem* item) 398void ConfigList::updateList(ConfigItem* item)
375{ 399{
376 (void)item;// unused so far 400 ConfigItem* last = 0;
401
402 if (!rootEntry)
403 goto update;
404
405 if (rootEntry != &rootmenu && (mode == singleMode ||
406 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
407 item = firstChild();
408 if (!item)
409 item = new ConfigItem(this, 0, true);
410 last = item;
411 }
412 if (mode == singleMode && rootEntry->sym && rootEntry->prompt) {
413 item = last ? last->nextSibling() : firstChild();
414 if (!item)
415 item = new ConfigItem(this, last, rootEntry, true);
416
417 updateMenuList(item, rootEntry);
418 triggerUpdate();
419 return;
420 }
421update:
377 updateMenuList(this, rootEntry); 422 updateMenuList(this, rootEntry);
378 triggerUpdate(); 423 triggerUpdate();
379} 424}
@@ -392,7 +437,7 @@ void ConfigList::setValue(ConfigItem* item, tristate val)
392 int type; 437 int type;
393 tristate oldval; 438 tristate oldval;
394 439
395 sym = item->menu->sym; 440 sym = item->menu ? item->menu->sym : 0;
396 if (!sym) 441 if (!sym)
397 return; 442 return;
398 443
@@ -418,6 +463,8 @@ void ConfigList::changeValue(ConfigItem* item)
418 int type, oldexpr, newexpr; 463 int type, oldexpr, newexpr;
419 464
420 menu = item->menu; 465 menu = item->menu;
466 if (!menu)
467 return;
421 sym = menu->sym; 468 sym = menu->sym;
422 if (!sym) { 469 if (!sym) {
423 if (item->menu->list) 470 if (item->menu->list)
@@ -460,7 +507,7 @@ void ConfigList::setRootMenu(struct menu *menu)
460 if (rootEntry == menu) 507 if (rootEntry == menu)
461 return; 508 return;
462 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN; 509 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
463 if (type != P_MENU && type != P_ROOTMENU) 510 if (type != P_MENU)
464 return; 511 return;
465 updateMenuList(this, 0); 512 updateMenuList(this, 0);
466 rootEntry = menu; 513 rootEntry = menu;
@@ -471,13 +518,12 @@ void ConfigList::setRootMenu(struct menu *menu)
471void ConfigList::setParentMenu(void) 518void ConfigList::setParentMenu(void)
472{ 519{
473 ConfigItem* item; 520 ConfigItem* item;
474 struct menu *oldroot, *newroot; 521 struct menu *oldroot;
475 522
476 oldroot = rootEntry; 523 oldroot = rootEntry;
477 newroot = menu_get_parent_menu(oldroot); 524 if (rootEntry == &rootmenu)
478 if (newroot == oldroot)
479 return; 525 return;
480 setRootMenu(newroot); 526 setRootMenu(menu_get_parent_menu(rootEntry->parent));
481 527
482 QListViewItemIterator it(this); 528 QListViewItemIterator it(this);
483 for (; (item = (ConfigItem*)it.current()); it++) { 529 for (; (item = (ConfigItem*)it.current()); it++) {
@@ -511,9 +557,16 @@ void ConfigList::keyPressEvent(QKeyEvent* ev)
511 switch (ev->key()) { 557 switch (ev->key()) {
512 case Key_Return: 558 case Key_Return:
513 case Key_Enter: 559 case Key_Enter:
560 if (item->goParent) {
561 emit parentSelected();
562 break;
563 }
514 menu = item->menu; 564 menu = item->menu;
565 if (!menu)
566 break;
515 type = menu->prompt ? menu->prompt->type : P_UNKNOWN; 567 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
516 if ((type == P_MENU || type == P_ROOTMENU) && mode != fullMode) { 568 if (type == P_MENU && rootEntry != menu &&
569 mode != fullMode && mode != menuMode) {
517 emit menuSelected(menu); 570 emit menuSelected(menu);
518 break; 571 break;
519 } 572 }
@@ -548,6 +601,7 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
548 QPoint p(contentsToViewport(e->pos())); 601 QPoint p(contentsToViewport(e->pos()));
549 ConfigItem* item = (ConfigItem*)itemAt(p); 602 ConfigItem* item = (ConfigItem*)itemAt(p);
550 struct menu *menu; 603 struct menu *menu;
604 enum prop_type ptype;
551 const QPixmap* pm; 605 const QPixmap* pm;
552 int idx, x; 606 int idx, x;
553 607
@@ -564,10 +618,17 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
564 int off = header()->sectionPos(0) + itemMargin() + 618 int off = header()->sectionPos(0) + itemMargin() +
565 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0)); 619 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
566 if (x >= off && x < off + pm->width()) { 620 if (x >= off && x < off + pm->width()) {
567 if (menu->sym) 621 if (item->goParent) {
568 changeValue(item); 622 emit parentSelected();
569 else 623 break;
624 } else if (!menu)
625 break;
626 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
627 if (ptype == P_MENU && rootEntry != menu &&
628 mode != fullMode && mode != menuMode)
570 emit menuSelected(menu); 629 emit menuSelected(menu);
630 else
631 changeValue(item);
571 } 632 }
572 } 633 }
573 break; 634 break;
@@ -606,10 +667,15 @@ void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
606 667
607 if (!item) 668 if (!item)
608 goto skip; 669 goto skip;
670 if (item->goParent) {
671 emit parentSelected();
672 goto skip;
673 }
609 menu = item->menu; 674 menu = item->menu;
675 if (!menu)
676 goto skip;
610 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 677 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
611 if ((ptype == P_ROOTMENU || ptype == P_MENU) && 678 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
612 (mode == singleMode || mode == symbolMode))
613 emit menuSelected(menu); 679 emit menuSelected(menu);
614 else if (menu->sym) 680 else if (menu->sym)
615 changeValue(item); 681 changeValue(item);
@@ -677,7 +743,6 @@ void ConfigView::updateListAll(void)
677 */ 743 */
678ConfigMainWindow::ConfigMainWindow(void) 744ConfigMainWindow::ConfigMainWindow(void)
679{ 745{
680 ConfigView* view;
681 QMenuBar* menu; 746 QMenuBar* menu;
682 QSplitter* split1; 747 QSplitter* split1;
683 QSplitter* split2; 748 QSplitter* split2;
@@ -707,15 +772,15 @@ ConfigMainWindow::ConfigMainWindow(void)
707 split1->setOrientation(QSplitter::Horizontal); 772 split1->setOrientation(QSplitter::Horizontal);
708 setCentralWidget(split1); 773 setCentralWidget(split1);
709 774
710 view = new ConfigView(split1, this); 775 menuView = new ConfigView(split1, this);
711 menuList = view->list; 776 menuList = menuView->list;
712 777
713 split2 = new QSplitter(split1); 778 split2 = new QSplitter(split1);
714 split2->setOrientation(QSplitter::Vertical); 779 split2->setOrientation(QSplitter::Vertical);
715 780
716 // create config tree 781 // create config tree
717 view = new ConfigView(split2, this); 782 configView = new ConfigView(split2, this);
718 configList = view->list; 783 configList = configView->list;
719 784
720 helpText = new QTextView(split2); 785 helpText = new QTextView(split2);
721 helpText->setTextFormat(Qt::RichText); 786 helpText->setTextFormat(Qt::RichText);
@@ -818,7 +883,6 @@ ConfigMainWindow::ConfigMainWindow(void)
818 connect(menuList, SIGNAL(gotFocus(void)), 883 connect(menuList, SIGNAL(gotFocus(void)),
819 SLOT(listFocusChanged(void))); 884 SLOT(listFocusChanged(void)));
820 885
821 //showFullView();
822 showSplitView(); 886 showSplitView();
823} 887}
824 888
@@ -864,89 +928,107 @@ static void expr_print_help(void *data, const char *str)
864void ConfigMainWindow::setHelp(QListViewItem* item) 928void ConfigMainWindow::setHelp(QListViewItem* item)
865{ 929{
866 struct symbol* sym; 930 struct symbol* sym;
867 struct menu* menu; 931 struct menu* menu = 0;
868 932
869 configList->parent()->lineEdit->hide(); 933 configList->parent()->lineEdit->hide();
870 if (item) { 934 if (item)
871 QString head, debug, help;
872 menu = ((ConfigItem*)item)->menu; 935 menu = ((ConfigItem*)item)->menu;
873 sym = menu->sym; 936 if (!menu) {
874 if (sym) { 937 helpText->setText(NULL);
875 if (menu->prompt) { 938 return;
876 head += "<big><b>"; 939 }
877 head += print_filter(menu->prompt->text); 940
878 head += "</b></big>"; 941 QString head, debug, help;
879 if (sym->name) { 942 menu = ((ConfigItem*)item)->menu;
880 head += " ("; 943 sym = menu->sym;
881 head += print_filter(sym->name); 944 if (sym) {
882 head += ")"; 945 if (menu->prompt) {
883 } 946 head += "<big><b>";
884 } else if (sym->name) { 947 head += print_filter(menu->prompt->text);
885 head += "<big><b>"; 948 head += "</b></big>";
949 if (sym->name) {
950 head += " (";
886 head += print_filter(sym->name); 951 head += print_filter(sym->name);
887 head += "</b></big>"; 952 head += ")";
888 } 953 }
889 head += "<br><br>"; 954 } else if (sym->name) {
890 955 head += "<big><b>";
891 if (showDebug) { 956 head += print_filter(sym->name);
892 debug += "type: "; 957 head += "</b></big>";
893 debug += print_filter(sym_type_name(sym->type)); 958 }
959 head += "<br><br>";
960
961 if (showDebug) {
962 debug += "type: ";
963 debug += print_filter(sym_type_name(sym->type));
964 if (sym_is_choice(sym))
965 debug += " (choice)";
966 debug += "<br>";
967 if (sym->rev_dep.expr) {
968 debug += "reverse dep: ";
969 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
894 debug += "<br>"; 970 debug += "<br>";
895 for (struct property *prop = sym->prop; prop; prop = prop->next) { 971 }
896 switch (prop->type) { 972 for (struct property *prop = sym->prop; prop; prop = prop->next) {
897 case P_PROMPT: 973 switch (prop->type) {
898 debug += "prompt: "; 974 case P_PROMPT:
899 debug += print_filter(prop->text); 975 case P_MENU:
900 debug += "<br>"; 976 debug += "prompt: ";
901 if (prop->visible.expr) { 977 debug += print_filter(prop->text);
902 debug += "&nbsp;&nbsp;dep: "; 978 debug += "<br>";
903 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); 979 break;
904 debug += "<br>"; 980 case P_DEFAULT:
905 } 981 debug += "default: ";
906 break; 982 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
907 case P_DEFAULT: 983 debug += "<br>";
908 debug += "default: "; 984 break;
909 if (sym_is_choice(sym)) 985 case P_CHOICE:
910 debug += print_filter(prop->def->name); 986 if (sym_is_choice(sym)) {
911 else { 987 debug += "choice: ";
912 sym_calc_value(prop->def); 988 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
913 debug += print_filter(sym_get_string_value(prop->def));
914 }
915 debug += "<br>";
916 if (prop->visible.expr) {
917 debug += "&nbsp;&nbsp;dep: ";
918 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
919 debug += "<br>";
920 }
921 break;
922 case P_CHOICE:
923 break;
924 default:
925 debug += "unknown property: ";
926 debug += prop_get_type_name(prop->type);
927 debug += "<br>"; 989 debug += "<br>";
928 } 990 }
991 break;
992 case P_SELECT:
993 debug += "select: ";
994 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
995 debug += "<br>";
996 break;
997 case P_RANGE:
998 debug += "range: ";
999 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1000 debug += "<br>";
1001 break;
1002 default:
1003 debug += "unknown property: ";
1004 debug += prop_get_type_name(prop->type);
1005 debug += "<br>";
929 } 1006 }
930 debug += "<br>"; 1007 if (prop->visible.expr) {
931 } 1008 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
932 1009 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
933 help = print_filter(sym->help);
934 } else if (menu->prompt) {
935 head += "<big><b>";
936 head += print_filter(menu->prompt->text);
937 head += "</b></big><br><br>";
938 if (showDebug) {
939 if (menu->prompt->visible.expr) {
940 debug += "&nbsp;&nbsp;dep: ";
941 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
942 debug += "<br>"; 1010 debug += "<br>";
943 } 1011 }
944 } 1012 }
1013 debug += "<br>";
1014 }
1015
1016 help = print_filter(sym->help);
1017 } else if (menu->prompt) {
1018 head += "<big><b>";
1019 head += print_filter(menu->prompt->text);
1020 head += "</b></big><br><br>";
1021 if (showDebug) {
1022 if (menu->prompt->visible.expr) {
1023 debug += "&nbsp;&nbsp;dep: ";
1024 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1025 debug += "<br><br>";
1026 }
945 } 1027 }
946 helpText->setText(head + debug + help);
947 return;
948 } 1028 }
949 helpText->setText(NULL); 1029 if (showDebug)
1030 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1031 helpText->setText(head + debug + help);
950} 1032}
951 1033
952void ConfigMainWindow::loadConfig(void) 1034void ConfigMainWindow::loadConfig(void)
@@ -1010,7 +1092,7 @@ void ConfigMainWindow::goBack(void)
1010 1092
1011void ConfigMainWindow::showSingleView(void) 1093void ConfigMainWindow::showSingleView(void)
1012{ 1094{
1013 menuList->hide(); 1095 menuView->hide();
1014 menuList->setRootMenu(0); 1096 menuList->setRootMenu(0);
1015 configList->mode = singleMode; 1097 configList->mode = singleMode;
1016 if (configList->rootEntry == &rootmenu) 1098 if (configList->rootEntry == &rootmenu)
@@ -1032,14 +1114,14 @@ void ConfigMainWindow::showSplitView(void)
1032 configApp->processEvents(); 1114 configApp->processEvents();
1033 menuList->mode = menuMode; 1115 menuList->mode = menuMode;
1034 menuList->setRootMenu(&rootmenu); 1116 menuList->setRootMenu(&rootmenu);
1035 menuList->show();
1036 menuList->setAllOpen(TRUE); 1117 menuList->setAllOpen(TRUE);
1118 menuView->show();
1037 menuList->setFocus(); 1119 menuList->setFocus();
1038} 1120}
1039 1121
1040void ConfigMainWindow::showFullView(void) 1122void ConfigMainWindow::showFullView(void)
1041{ 1123{
1042 menuList->hide(); 1124 menuView->hide();
1043 menuList->setRootMenu(0); 1125 menuList->setRootMenu(0);
1044 configList->mode = fullMode; 1126 configList->mode = fullMode;
1045 if (configList->rootEntry == &rootmenu) 1127 if (configList->rootEntry == &rootmenu)
@@ -1073,6 +1155,8 @@ void ConfigMainWindow::setShowName(bool b)
1073 return; 1155 return;
1074 configList->showName = b; 1156 configList->showName = b;
1075 configList->reinit(); 1157 configList->reinit();
1158 menuList->showName = b;
1159 menuList->reinit();
1076} 1160}
1077 1161
1078void ConfigMainWindow::setShowRange(bool b) 1162void ConfigMainWindow::setShowRange(bool b)
@@ -1081,6 +1165,8 @@ void ConfigMainWindow::setShowRange(bool b)
1081 return; 1165 return;
1082 configList->showRange = b; 1166 configList->showRange = b;
1083 configList->reinit(); 1167 configList->reinit();
1168 menuList->showRange = b;
1169 menuList->reinit();
1084} 1170}
1085 1171
1086void ConfigMainWindow::setShowData(bool b) 1172void ConfigMainWindow::setShowData(bool b)
@@ -1089,6 +1175,8 @@ void ConfigMainWindow::setShowData(bool b)
1089 return; 1175 return;
1090 configList->showData = b; 1176 configList->showData = b;
1091 configList->reinit(); 1177 configList->reinit();
1178 menuList->showData = b;
1179 menuList->reinit();
1092} 1180}
1093 1181
1094/* 1182/*
@@ -1146,12 +1234,25 @@ void ConfigMainWindow::showAbout(void)
1146void fixup_rootmenu(struct menu *menu) 1234void fixup_rootmenu(struct menu *menu)
1147{ 1235{
1148 struct menu *child; 1236 struct menu *child;
1237 static int menu_cnt = 0;
1149 1238
1150 if (!menu->prompt || menu->prompt->type != P_MENU) 1239 menu->flags |= MENU_ROOT;
1151 return; 1240 for (child = menu->list; child; child = child->next) {
1152 menu->prompt->type = P_ROOTMENU; 1241 if (child->prompt && child->prompt->type == P_MENU) {
1153 for (child = menu->list; child; child = child->next) 1242 menu_cnt++;
1154 fixup_rootmenu(child); 1243 fixup_rootmenu(child);
1244 menu_cnt--;
1245 } else if (!menu_cnt)
1246 fixup_rootmenu(child);
1247 }
1248}
1249
1250static const char *progname;
1251
1252static void usage(void)
1253{
1254 printf("%s <config>\n", progname);
1255 exit(0);
1155} 1256}
1156 1257
1157int main(int ac, char** av) 1258int main(int ac, char** av)
@@ -1163,23 +1264,23 @@ int main(int ac, char** av)
1163 kconfig_load(); 1264 kconfig_load();
1164#endif 1265#endif
1165 1266
1267 progname = av[0];
1166 configApp = new QApplication(ac, av); 1268 configApp = new QApplication(ac, av);
1167#if QT_VERSION >= 300 1269#if QT_VERSION >= 300
1168 configSettings = new QSettings; 1270 configSettings = new QSettings;
1169#endif 1271#endif
1170 if (ac > 1 && av[1][0] == '-') { 1272 if (ac > 1 && av[1][0] == '-') {
1171 switch (av[1][1]) { 1273 switch (av[1][1]) {
1172 case 'a':
1173 //showAll = 1;
1174 break;
1175 case 'h': 1274 case 'h':
1176 case '?': 1275 case '?':
1177 printf("%s <config>\n", av[0]); 1276 usage();
1178 exit(0);
1179 } 1277 }
1180 name = av[2]; 1278 name = av[2];
1181 } else 1279 } else
1182 name = av[1]; 1280 name = av[1];
1281 if (!name)
1282 usage();
1283
1183 conf_parse(name); 1284 conf_parse(name);
1184 fixup_rootmenu(&rootmenu); 1285 fixup_rootmenu(&rootmenu);
1185 conf_read(NULL); 1286 conf_read(NULL);
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 6f096b4..c548884 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -101,10 +101,14 @@ public:
101 void setAllOpen(bool open); 101 void setAllOpen(bool open);
102 void setParentMenu(void); 102 void setParentMenu(void);
103 103
104 template <class P>
105 void ConfigList::updateMenuList(P*, struct menu*);
106
104 bool updateAll; 107 bool updateAll;
105 108
106 QPixmap symbolYesPix, symbolModPix, symbolNoPix; 109 QPixmap symbolYesPix, symbolModPix, symbolNoPix;
107 QPixmap choiceYesPix, choiceNoPix, menuPix, menuInvPix; 110 QPixmap choiceYesPix, choiceNoPix;
111 QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
108 112
109 bool showAll, showName, showRange, showData; 113 bool showAll, showName, showRange, showData;
110 enum listMode mode; 114 enum listMode mode;
@@ -121,12 +125,17 @@ class ConfigItem : public QListViewItem {
121 typedef class QListViewItem Parent; 125 typedef class QListViewItem Parent;
122public: 126public:
123 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) 127 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v)
124 : Parent(parent, after), menu(m), visible(v) 128 : Parent(parent, after), menu(m), visible(v), goParent(false)
125 { 129 {
126 init(); 130 init();
127 } 131 }
128 ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) 132 ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
129 : Parent(parent, after), menu(m), visible(v) 133 : Parent(parent, after), menu(m), visible(v), goParent(false)
134 {
135 init();
136 }
137 ConfigItem(QListView *parent, ConfigItem *after, bool v)
138 : Parent(parent, after), menu(0), visible(v), goParent(true)
130 { 139 {
131 init(); 140 init();
132 } 141 }
@@ -136,7 +145,7 @@ public:
136 void okRename(int col); 145 void okRename(int col);
137#endif 146#endif
138 void updateMenu(void); 147 void updateMenu(void);
139 bool updateNeeded(void); 148 void testUpdateMenu(bool v);
140 ConfigList* listView() const 149 ConfigList* listView() const
141 { 150 {
142 return (ConfigList*)Parent::listView(); 151 return (ConfigList*)Parent::listView();
@@ -170,6 +179,7 @@ public:
170 ConfigItem* nextItem; 179 ConfigItem* nextItem;
171 struct menu *menu; 180 struct menu *menu;
172 bool visible; 181 bool visible;
182 bool goParent;
173}; 183};
174 184
175class ConfigLineEdit : public QLineEdit { 185class ConfigLineEdit : public QLineEdit {
@@ -216,7 +226,9 @@ public slots:
216protected: 226protected:
217 void closeEvent(QCloseEvent *e); 227 void closeEvent(QCloseEvent *e);
218 228
229 ConfigView *menuView;
219 ConfigList *menuList; 230 ConfigList *menuList;
231 ConfigView *configView;
220 ConfigList *configList; 232 ConfigList *configList;
221 QTextView *helpText; 233 QTextView *helpText;
222 QToolBar *toolBar; 234 QToolBar *toolBar;
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 845d8a3..11318d9 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -34,18 +34,9 @@ struct symbol *modules_sym;
34 34
35void sym_add_default(struct symbol *sym, const char *def) 35void sym_add_default(struct symbol *sym, const char *def)
36{ 36{
37 struct property *prop = create_prop(P_DEFAULT); 37 struct property *prop = prop_alloc(P_DEFAULT, sym);
38 struct property **propp;
39
40 prop->sym = sym;
41 prop->def = sym_lookup(def, 1);
42 38
43 /* append property to the prop list of symbol */ 39 prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
44 if (prop->sym) {
45 for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
46 ;
47 *propp = prop;
48 }
49} 40}
50 41
51void sym_init(void) 42void sym_init(void)
@@ -81,22 +72,23 @@ void sym_init(void)
81 sym_add_default(sym, uts.release); 72 sym_add_default(sym, uts.release);
82} 73}
83 74
84int sym_get_type(struct symbol *sym) 75enum symbol_type sym_get_type(struct symbol *sym)
85{ 76{
86 int type = sym->type; 77 enum symbol_type type = sym->type;
78
87 if (type == S_TRISTATE) { 79 if (type == S_TRISTATE) {
88 if (sym_is_choice_value(sym) && sym->visible == yes) 80 if (sym_is_choice_value(sym) && sym->visible == yes)
89 type = S_BOOLEAN; 81 type = S_BOOLEAN;
90 else { 82 else {
91 sym_calc_value(modules_sym); 83 sym_calc_value(modules_sym);
92 if (S_TRI(modules_sym->curr) == no) 84 if (modules_sym->curr.tri == no)
93 type = S_BOOLEAN; 85 type = S_BOOLEAN;
94 } 86 }
95 } 87 }
96 return type; 88 return type;
97} 89}
98 90
99const char *sym_type_name(int type) 91const char *sym_type_name(enum symbol_type type)
100{ 92{
101 switch (type) { 93 switch (type) {
102 case S_BOOLEAN: 94 case S_BOOLEAN:
@@ -111,6 +103,8 @@ const char *sym_type_name(int type)
111 return "string"; 103 return "string";
112 case S_UNKNOWN: 104 case S_UNKNOWN:
113 return "unknown"; 105 return "unknown";
106 case S_OTHER:
107 break;
114 } 108 }
115 return "???"; 109 return "???";
116} 110}
@@ -127,41 +121,104 @@ struct property *sym_get_choice_prop(struct symbol *sym)
127struct property *sym_get_default_prop(struct symbol *sym) 121struct property *sym_get_default_prop(struct symbol *sym)
128{ 122{
129 struct property *prop; 123 struct property *prop;
130 tristate visible;
131 124
132 for_all_defaults(sym, prop) { 125 for_all_defaults(sym, prop) {
133 visible = E_CALC(prop->visible); 126 prop->visible.tri = expr_calc_value(prop->visible.expr);
134 if (visible != no) 127 if (prop->visible.tri != no)
135 return prop; 128 return prop;
136 } 129 }
137 return NULL; 130 return NULL;
138} 131}
139 132
140void sym_calc_visibility(struct symbol *sym) 133struct property *sym_get_range_prop(struct symbol *sym)
141{ 134{
142 struct property *prop; 135 struct property *prop;
143 tristate visible, oldvisible; 136
137 for_all_properties(sym, prop, P_RANGE) {
138 prop->visible.tri = expr_calc_value(prop->visible.expr);
139 if (prop->visible.tri != no)
140 return prop;
141 }
142 return NULL;
143}
144
145static void sym_calc_visibility(struct symbol *sym)
146{
147 struct property *prop;
148 tristate tri;
144 149
145 /* any prompt visible? */ 150 /* any prompt visible? */
146 oldvisible = sym->visible; 151 tri = no;
147 visible = no; 152 for_all_prompts(sym, prop) {
148 for_all_prompts(sym, prop) 153 prop->visible.tri = expr_calc_value(prop->visible.expr);
149 visible = E_OR(visible, E_CALC(prop->visible)); 154 tri = E_OR(tri, prop->visible.tri);
150 if (oldvisible != visible) { 155 }
151 sym->visible = visible; 156 if (sym->visible != tri) {
157 sym->visible = tri;
158 sym_set_changed(sym);
159 }
160 if (sym_is_choice_value(sym))
161 return;
162 tri = no;
163 if (sym->rev_dep.expr)
164 tri = expr_calc_value(sym->rev_dep.expr);
165 if (sym->rev_dep.tri != tri) {
166 sym->rev_dep.tri = tri;
152 sym_set_changed(sym); 167 sym_set_changed(sym);
153 } 168 }
154} 169}
155 170
171static struct symbol *sym_calc_choice(struct symbol *sym)
172{
173 struct symbol *def_sym;
174 struct property *prop;
175 struct expr *e;
176
177 /* is the user choice visible? */
178 def_sym = sym->user.val;
179 if (def_sym) {
180 sym_calc_visibility(def_sym);
181 if (def_sym->visible != no)
182 return def_sym;
183 }
184
185 /* any of the defaults visible? */
186 for_all_defaults(sym, prop) {
187 prop->visible.tri = expr_calc_value(prop->visible.expr);
188 if (prop->visible.tri == no)
189 continue;
190 def_sym = prop_get_symbol(prop);
191 sym_calc_visibility(def_sym);
192 if (def_sym->visible != no)
193 return def_sym;
194 }
195
196 /* just get the first visible value */
197 prop = sym_get_choice_prop(sym);
198 for (e = prop->expr; e; e = e->left.expr) {
199 def_sym = e->right.sym;
200 sym_calc_visibility(def_sym);
201 if (def_sym->visible != no)
202 return def_sym;
203 }
204
205 /* no choice? reset tristate value */
206 sym->curr.tri = no;
207 return NULL;
208}
209
156void sym_calc_value(struct symbol *sym) 210void sym_calc_value(struct symbol *sym)
157{ 211{
158 struct symbol_value newval, oldval; 212 struct symbol_value newval, oldval;
159 struct property *prop, *def_prop; 213 struct property *prop;
160 struct symbol *def_sym;
161 struct expr *e; 214 struct expr *e;
162 215
216 if (!sym)
217 return;
218
163 if (sym->flags & SYMBOL_VALID) 219 if (sym->flags & SYMBOL_VALID)
164 return; 220 return;
221 sym->flags |= SYMBOL_VALID;
165 222
166 oldval = sym->curr; 223 oldval = sym->curr;
167 224
@@ -176,17 +233,10 @@ void sym_calc_value(struct symbol *sym)
176 newval = symbol_no.curr; 233 newval = symbol_no.curr;
177 break; 234 break;
178 default: 235 default:
179 S_VAL(newval) = sym->name; 236 sym->curr.val = sym->name;
180 S_TRI(newval) = no; 237 sym->curr.tri = no;
181 if (sym->flags & SYMBOL_CONST) { 238 return;
182 goto out;
183 }
184 //newval = symbol_empty.curr;
185 // generate warning somewhere here later
186 //S_TRI(newval) = yes;
187 goto out;
188 } 239 }
189 sym->flags |= SYMBOL_VALID;
190 if (!sym_is_choice_value(sym)) 240 if (!sym_is_choice_value(sym))
191 sym->flags &= ~SYMBOL_WRITE; 241 sym->flags &= ~SYMBOL_WRITE;
192 242
@@ -195,95 +245,73 @@ void sym_calc_value(struct symbol *sym)
195 /* set default if recursively called */ 245 /* set default if recursively called */
196 sym->curr = newval; 246 sym->curr = newval;
197 247
198 if (sym->visible != no) { 248 switch (sym_get_type(sym)) {
199 sym->flags |= SYMBOL_WRITE; 249 case S_BOOLEAN:
200 if (!sym_has_value(sym)) { 250 case S_TRISTATE:
201 if (!sym_is_choice(sym)) {
202 prop = sym_get_default_prop(sym);
203 if (prop) {
204 sym_calc_value(prop->def);
205 newval = prop->def->curr;
206 }
207 } else
208 S_TRI(newval) = S_TRI(sym->def);
209 } else
210 newval = sym->def;
211
212 S_TRI(newval) = E_AND(S_TRI(newval), sym->visible);
213 /* if the symbol is visible and not optionial,
214 * possibly ignore old user choice. */
215 if (!sym_is_optional(sym) && S_TRI(newval) == no)
216 S_TRI(newval) = sym->visible;
217 if (sym_is_choice_value(sym) && sym->visible == yes) { 251 if (sym_is_choice_value(sym) && sym->visible == yes) {
218 prop = sym_get_choice_prop(sym); 252 prop = sym_get_choice_prop(sym);
219 S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; 253 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
220 } 254 } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
221 } else {
222 prop = sym_get_default_prop(sym);
223 if (prop) {
224 sym->flags |= SYMBOL_WRITE; 255 sym->flags |= SYMBOL_WRITE;
225 sym_calc_value(prop->def); 256 if (sym_has_value(sym))
226 newval = prop->def->curr; 257 newval.tri = sym->user.tri;
258 else if (!sym_is_choice(sym)) {
259 prop = sym_get_default_prop(sym);
260 if (prop)
261 newval.tri = expr_calc_value(prop->expr);
262 }
263 newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
264 } else if (!sym_is_choice(sym)) {
265 prop = sym_get_default_prop(sym);
266 if (prop) {
267 sym->flags |= SYMBOL_WRITE;
268 newval.tri = expr_calc_value(prop->expr);
269 }
227 } 270 }
228 } 271 if (sym_get_type(sym) == S_BOOLEAN) {
229 272 if (newval.tri == mod)
230 switch (sym_get_type(sym)) { 273 newval.tri = yes;
231 case S_TRISTATE: 274 if (sym->visible == mod)
232 if (S_TRI(newval) != mod) 275 sym->visible = yes;
233 break; 276 if (sym->rev_dep.tri == mod)
234 sym_calc_value(modules_sym); 277 sym->rev_dep.tri = yes;
235 if (S_TRI(modules_sym->curr) == no)
236 S_TRI(newval) = yes;
237 break;
238 case S_BOOLEAN:
239 if (S_TRI(newval) == mod)
240 S_TRI(newval) = yes;
241 }
242
243out:
244 sym->curr = newval;
245
246 if (sym_is_choice(sym) && S_TRI(newval) == yes) {
247 def_sym = S_VAL(sym->def);
248 if (def_sym) {
249 sym_calc_visibility(def_sym);
250 if (def_sym->visible == no)
251 def_sym = NULL;
252 } 278 }
253 if (!def_sym) { 279 break;
254 for_all_defaults(sym, def_prop) { 280 case S_STRING:
255 if (E_CALC(def_prop->visible) == no) 281 case S_HEX:
256 continue; 282 case S_INT:
257 sym_calc_visibility(def_prop->def); 283 if (sym->visible != no) {
258 if (def_prop->def->visible != no) { 284 sym->flags |= SYMBOL_WRITE;
259 def_sym = def_prop->def; 285 if (sym_has_value(sym)) {
260 break; 286 newval.val = sym->user.val;
261 } 287 break;
262 } 288 }
263 } 289 }
264 290 prop = sym_get_default_prop(sym);
265 if (!def_sym) { 291 if (prop) {
266 prop = sym_get_choice_prop(sym); 292 struct symbol *ds = prop_get_symbol(prop);
267 for (e = prop->dep; e; e = e->left.expr) { 293 if (ds) {
268 sym_calc_visibility(e->right.sym); 294 sym->flags |= SYMBOL_WRITE;
269 if (e->right.sym->visible != no) { 295 sym_calc_value(ds);
270 def_sym = e->right.sym; 296 newval.val = ds->curr.val;
271 break;
272 }
273 } 297 }
274 } 298 }
275 299 break;
276 S_VAL(newval) = def_sym; 300 default:
301 ;
277 } 302 }
278 303
279 if (memcmp(&oldval, &newval, sizeof(newval)))
280 sym_set_changed(sym);
281 sym->curr = newval; 304 sym->curr = newval;
305 if (sym_is_choice(sym) && newval.tri == yes)
306 sym->curr.val = sym_calc_choice(sym);
307
308 if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
309 sym_set_changed(sym);
282 310
283 if (sym_is_choice(sym)) { 311 if (sym_is_choice(sym)) {
284 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); 312 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
285 prop = sym_get_choice_prop(sym); 313 prop = sym_get_choice_prop(sym);
286 for (e = prop->dep; e; e = e->left.expr) { 314 for (e = prop->expr; e; e = e->left.expr) {
287 e->right.sym->flags |= flags; 315 e->right.sym->flags |= flags;
288 if (flags & SYMBOL_CHANGED) 316 if (flags & SYMBOL_CHANGED)
289 sym_set_changed(e->right.sym); 317 sym_set_changed(e->right.sym);
@@ -331,19 +359,13 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
331 if (type != S_BOOLEAN && type != S_TRISTATE) 359 if (type != S_BOOLEAN && type != S_TRISTATE)
332 return false; 360 return false;
333 361
334 switch (val) { 362 if (type == S_BOOLEAN && val == mod)
335 case no: 363 return false;
336 if (sym_is_choice_value(sym) && sym->visible == yes) 364 if (sym->visible <= sym->rev_dep.tri)
337 return false; 365 return false;
338 return sym_is_optional(sym); 366 if (sym_is_choice_value(sym) && sym->visible == yes)
339 case mod: 367 return val == yes;
340 if (sym_is_choice_value(sym) && sym->visible == yes) 368 return val >= sym->rev_dep.tri && val <= sym->visible;
341 return false;
342 return type == S_TRISTATE;
343 case yes:
344 return type == S_BOOLEAN || sym->visible == yes;
345 }
346 return false;
347} 369}
348 370
349bool sym_set_tristate_value(struct symbol *sym, tristate val) 371bool sym_set_tristate_value(struct symbol *sym, tristate val)
@@ -358,13 +380,13 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
358 sym_set_changed(sym); 380 sym_set_changed(sym);
359 } 381 }
360 if (sym_is_choice_value(sym) && val == yes) { 382 if (sym_is_choice_value(sym) && val == yes) {
361 struct property *prop = sym_get_choice_prop(sym); 383 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
362 384
363 S_VAL(prop->def->def) = sym; 385 cs->user.val = sym;
364 prop->def->flags &= ~SYMBOL_NEW; 386 cs->flags &= ~SYMBOL_NEW;
365 } 387 }
366 388
367 S_TRI(sym->def) = val; 389 sym->user.tri = val;
368 if (oldval != val) { 390 if (oldval != val) {
369 sym_clear_all_valid(); 391 sym_clear_all_valid();
370 if (sym == modules_sym) 392 if (sym == modules_sym)
@@ -429,14 +451,51 @@ bool sym_string_valid(struct symbol *sym, const char *str)
429 case S_BOOLEAN: 451 case S_BOOLEAN:
430 case S_TRISTATE: 452 case S_TRISTATE:
431 switch (str[0]) { 453 switch (str[0]) {
432 case 'y': 454 case 'y': case 'Y':
433 case 'Y': 455 case 'm': case 'M':
456 case 'n': case 'N':
457 return true;
458 }
459 return false;
460 default:
461 return false;
462 }
463}
464
465bool sym_string_within_range(struct symbol *sym, const char *str)
466{
467 struct property *prop;
468 int val;
469
470 switch (sym->type) {
471 case S_STRING:
472 return sym_string_valid(sym, str);
473 case S_INT:
474 if (!sym_string_valid(sym, str))
475 return false;
476 prop = sym_get_range_prop(sym);
477 if (!prop)
478 return true;
479 val = strtol(str, NULL, 10);
480 return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
481 val <= strtol(prop->expr->right.sym->name, NULL, 10);
482 case S_HEX:
483 if (!sym_string_valid(sym, str))
484 return false;
485 prop = sym_get_range_prop(sym);
486 if (!prop)
487 return true;
488 val = strtol(str, NULL, 16);
489 return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
490 val <= strtol(prop->expr->right.sym->name, NULL, 16);
491 case S_BOOLEAN:
492 case S_TRISTATE:
493 switch (str[0]) {
494 case 'y': case 'Y':
434 return sym_tristate_within_range(sym, yes); 495 return sym_tristate_within_range(sym, yes);
435 case 'm': 496 case 'm': case 'M':
436 case 'M':
437 return sym_tristate_within_range(sym, mod); 497 return sym_tristate_within_range(sym, mod);
438 case 'n': 498 case 'n': case 'N':
439 case 'N':
440 return sym_tristate_within_range(sym, no); 499 return sym_tristate_within_range(sym, no);
441 } 500 }
442 return false; 501 return false;
@@ -455,14 +514,11 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
455 case S_BOOLEAN: 514 case S_BOOLEAN:
456 case S_TRISTATE: 515 case S_TRISTATE:
457 switch (newval[0]) { 516 switch (newval[0]) {
458 case 'y': 517 case 'y': case 'Y':
459 case 'Y':
460 return sym_set_tristate_value(sym, yes); 518 return sym_set_tristate_value(sym, yes);
461 case 'm': 519 case 'm': case 'M':
462 case 'M':
463 return sym_set_tristate_value(sym, mod); 520 return sym_set_tristate_value(sym, mod);
464 case 'n': 521 case 'n': case 'N':
465 case 'N':
466 return sym_set_tristate_value(sym, no); 522 return sym_set_tristate_value(sym, no);
467 } 523 }
468 return false; 524 return false;
@@ -470,7 +526,7 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
470 ; 526 ;
471 } 527 }
472 528
473 if (!sym_string_valid(sym, newval)) 529 if (!sym_string_within_range(sym, newval))
474 return false; 530 return false;
475 531
476 if (sym->flags & SYMBOL_NEW) { 532 if (sym->flags & SYMBOL_NEW) {
@@ -478,15 +534,15 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
478 sym_set_changed(sym); 534 sym_set_changed(sym);
479 } 535 }
480 536
481 oldval = S_VAL(sym->def); 537 oldval = sym->user.val;
482 size = strlen(newval) + 1; 538 size = strlen(newval) + 1;
483 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { 539 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
484 size += 2; 540 size += 2;
485 S_VAL(sym->def) = val = malloc(size); 541 sym->user.val = val = malloc(size);
486 *val++ = '0'; 542 *val++ = '0';
487 *val++ = 'x'; 543 *val++ = 'x';
488 } else if (!oldval || strcmp(oldval, newval)) 544 } else if (!oldval || strcmp(oldval, newval))
489 S_VAL(sym->def) = val = malloc(size); 545 sym->user.val = val = malloc(size);
490 else 546 else
491 return true; 547 return true;
492 548
@@ -517,20 +573,12 @@ const char *sym_get_string_value(struct symbol *sym)
517 default: 573 default:
518 ; 574 ;
519 } 575 }
520 return (const char *)S_VAL(sym->curr); 576 return (const char *)sym->curr.val;
521} 577}
522 578
523bool sym_is_changable(struct symbol *sym) 579bool sym_is_changable(struct symbol *sym)
524{ 580{
525 if (sym->visible == no) 581 return sym->visible > sym->rev_dep.tri;
526 return false;
527 /* at least 'n' and 'y'/'m' is selectable */
528 if (sym_is_optional(sym))
529 return true;
530 /* no 'n', so 'y' and 'm' must be selectable */
531 if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes)
532 return true;
533 return false;
534} 582}
535 583
536struct symbol *sym_lookup(const char *name, int isconst) 584struct symbol *sym_lookup(const char *name, int isconst)
@@ -608,6 +656,104 @@ struct symbol *sym_find(const char *name)
608 return symbol; 656 return symbol;
609} 657}
610 658
659struct symbol *sym_check_deps(struct symbol *sym);
660
661static struct symbol *sym_check_expr_deps(struct expr *e)
662{
663 struct symbol *sym;
664
665 if (!e)
666 return NULL;
667 switch (e->type) {
668 case E_OR:
669 case E_AND:
670 sym = sym_check_expr_deps(e->left.expr);
671 if (sym)
672 return sym;
673 return sym_check_expr_deps(e->right.expr);
674 case E_NOT:
675 return sym_check_expr_deps(e->left.expr);
676 case E_EQUAL:
677 case E_UNEQUAL:
678 sym = sym_check_deps(e->left.sym);
679 if (sym)
680 return sym;
681 return sym_check_deps(e->right.sym);
682 case E_SYMBOL:
683 return sym_check_deps(e->left.sym);
684 default:
685 break;
686 }
687 printf("Oops! How to check %d?\n", e->type);
688 return NULL;
689}
690
691struct symbol *sym_check_deps(struct symbol *sym)
692{
693 struct symbol *sym2;
694 struct property *prop;
695
696 if (sym->flags & SYMBOL_CHECK_DONE)
697 return NULL;
698 if (sym->flags & SYMBOL_CHECK) {
699 printf("Warning! Found recursive dependency: %s", sym->name);
700 return sym;
701 }
702
703 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
704 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
705 if (sym2)
706 goto out;
707
708 for (prop = sym->prop; prop; prop = prop->next) {
709 if (prop->type == P_CHOICE)
710 continue;
711 sym2 = sym_check_expr_deps(prop->visible.expr);
712 if (sym2)
713 goto out;
714 if (prop->type != P_DEFAULT || sym_is_choice(sym))
715 continue;
716 sym2 = sym_check_expr_deps(prop->expr);
717 if (sym2)
718 goto out;
719 }
720out:
721 if (sym2)
722 printf(" %s", sym->name);
723 sym->flags &= ~SYMBOL_CHECK;
724 return sym2;
725}
726
727struct property *prop_alloc(enum prop_type type, struct symbol *sym)
728{
729 struct property *prop;
730 struct property **propp;
731
732 prop = malloc(sizeof(*prop));
733 memset(prop, 0, sizeof(*prop));
734 prop->type = type;
735 prop->sym = sym;
736 prop->file = current_file;
737 prop->lineno = zconf_lineno();
738
739 /* append property to the prop list of symbol */
740 if (sym) {
741 for (propp = &sym->prop; *propp; propp = &(*propp)->next)
742 ;
743 *propp = prop;
744 }
745
746 return prop;
747}
748
749struct symbol *prop_get_symbol(struct property *prop)
750{
751 if (prop->expr && (prop->expr->type == E_SYMBOL ||
752 prop->expr->type == E_CHOICE))
753 return prop->expr->left.sym;
754 return NULL;
755}
756
611const char *prop_get_type_name(enum prop_type type) 757const char *prop_get_type_name(enum prop_type type)
612{ 758{
613 switch (type) { 759 switch (type) {
@@ -617,13 +763,16 @@ const char *prop_get_type_name(enum prop_type type)
617 return "comment"; 763 return "comment";
618 case P_MENU: 764 case P_MENU:
619 return "menu"; 765 return "menu";
620 case P_ROOTMENU:
621 return "rootmenu";
622 case P_DEFAULT: 766 case P_DEFAULT:
623 return "default"; 767 return "default";
624 case P_CHOICE: 768 case P_CHOICE:
625 return "choice"; 769 return "choice";
626 default: 770 case P_SELECT:
627 return "unknown"; 771 return "select";
772 case P_RANGE:
773 return "range";
774 case P_UNKNOWN:
775 break;
628 } 776 }
777 return "unknown";
629} 778}
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 1471630..55517b2 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -96,6 +96,7 @@ n [A-Za-z0-9_]
96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE; 96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
97 "comment" BEGIN(PARAM); return T_COMMENT; 97 "comment" BEGIN(PARAM); return T_COMMENT;
98 "config" BEGIN(PARAM); return T_CONFIG; 98 "config" BEGIN(PARAM); return T_CONFIG;
99 "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
99 "help" BEGIN(PARAM); return T_HELP; 100 "help" BEGIN(PARAM); return T_HELP;
100 "if" BEGIN(PARAM); return T_IF; 101 "if" BEGIN(PARAM); return T_IF;
101 "endif" BEGIN(PARAM); return T_ENDIF; 102 "endif" BEGIN(PARAM); return T_ENDIF;
@@ -105,11 +106,17 @@ n [A-Za-z0-9_]
105 "default" BEGIN(PARAM); return T_DEFAULT; 106 "default" BEGIN(PARAM); return T_DEFAULT;
106 "prompt" BEGIN(PARAM); return T_PROMPT; 107 "prompt" BEGIN(PARAM); return T_PROMPT;
107 "tristate" BEGIN(PARAM); return T_TRISTATE; 108 "tristate" BEGIN(PARAM); return T_TRISTATE;
109 "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
108 "bool" BEGIN(PARAM); return T_BOOLEAN; 110 "bool" BEGIN(PARAM); return T_BOOLEAN;
109 "boolean" BEGIN(PARAM); return T_BOOLEAN; 111 "boolean" BEGIN(PARAM); return T_BOOLEAN;
112 "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
113 "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
110 "int" BEGIN(PARAM); return T_INT; 114 "int" BEGIN(PARAM); return T_INT;
111 "hex" BEGIN(PARAM); return T_HEX; 115 "hex" BEGIN(PARAM); return T_HEX;
112 "string" BEGIN(PARAM); return T_STRING; 116 "string" BEGIN(PARAM); return T_STRING;
117 "select" BEGIN(PARAM); return T_SELECT;
118 "enable" BEGIN(PARAM); return T_SELECT;
119 "range" BEGIN(PARAM); return T_RANGE;
113 {n}+{ 120 {n}+{
114 alloc_string(yytext, yyleng); 121 alloc_string(yytext, yyleng);
115 zconflval.string = text; 122 zconflval.string = text;
@@ -141,6 +148,7 @@ n [A-Za-z0-9_]
141 zconflval.string = text; 148 zconflval.string = text;
142 return T_WORD; 149 return T_WORD;
143 } 150 }
151 #.*/* comment */
144 \\\ncurrent_file->lineno++; 152 \\\ncurrent_file->lineno++;
145 . 153 .
146 <<EOF>> { 154 <<EOF>> {
@@ -152,7 +160,7 @@ n [A-Za-z0-9_]
152 [^'"\\\n]+/\n{ 160 [^'"\\\n]+/\n{
153 append_string(yytext, yyleng); 161 append_string(yytext, yyleng);
154 zconflval.string = text; 162 zconflval.string = text;
155 return T_STRING; 163 return T_WORD_QUOTE;
156 } 164 }
157 [^'"\\\n]+{ 165 [^'"\\\n]+{
158 append_string(yytext, yyleng); 166 append_string(yytext, yyleng);
@@ -160,7 +168,7 @@ n [A-Za-z0-9_]
160 \\.?/\n{ 168 \\.?/\n{
161 append_string(yytext + 1, yyleng - 1); 169 append_string(yytext + 1, yyleng - 1);
162 zconflval.string = text; 170 zconflval.string = text;
163 return T_STRING; 171 return T_WORD_QUOTE;
164 } 172 }
165 \\.?{ 173 \\.?{
166 append_string(yytext + 1, yyleng - 1); 174 append_string(yytext + 1, yyleng - 1);
@@ -169,7 +177,7 @@ n [A-Za-z0-9_]
169 if (str == yytext[0]) { 177 if (str == yytext[0]) {
170 BEGIN(PARAM); 178 BEGIN(PARAM);
171 zconflval.string = text; 179 zconflval.string = text;
172 return T_STRING; 180 return T_WORD_QUOTE;
173 } else 181 } else
174 append_string(yytext, 1); 182 append_string(yytext, 1);
175 } 183 }
@@ -206,9 +214,8 @@ n [A-Za-z0-9_]
206 } 214 }
207 append_string(" ", ts); 215 append_string(" ", ts);
208 } 216 }
209
210 } 217 }
211 \n/[^ \t\n] { 218 [ \t]*\n/[^ \t\n] {
212 current_file->lineno++; 219 current_file->lineno++;
213 zconf_endhelp(); 220 zconf_endhelp();
214 return T_HELPTEXT; 221 return T_HELPTEXT;
@@ -248,11 +255,11 @@ void zconf_starthelp(void)
248static void zconf_endhelp(void) 255static void zconf_endhelp(void)
249{ 256{
250 zconflval.string = text; 257 zconflval.string = text;
251 BEGIN(INITIAL); 258 BEGIN(INITIAL);
252} 259}
253 260
254 261
255/* 262/*
256 * Try to open specified file with following names: 263 * Try to open specified file with following names:
257 * ./name 264 * ./name
258 * $(srctree)/name 265 * $(srctree)/name
@@ -345,7 +352,7 @@ static struct buffer *zconf_endfile(void)
345int zconf_lineno(void) 352int zconf_lineno(void)
346{ 353{
347 if (current_buf) 354 if (current_buf)
348 return current_file->lineno; 355 return current_file->lineno - 1;
349 else 356 else
350 return 0; 357 return 0;
351} 358}
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 996b10a..2468068 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -27,7 +27,7 @@ struct symbol *symbol_hash[257];
27 27
28#define YYERROR_VERBOSE 28#define YYERROR_VERBOSE
29%} 29%}
30%expect 36 30%expect 40
31 31
32%union 32%union
33{ 33{
@@ -46,6 +46,7 @@ struct symbol *symbol_hash[257];
46%token T_ENDCHOICE 46%token T_ENDCHOICE
47%token T_COMMENT 47%token T_COMMENT
48%token T_CONFIG 48%token T_CONFIG
49%token T_MENUCONFIG
49%token T_HELP 50%token T_HELP
50%token <string> T_HELPTEXT 51%token <string> T_HELPTEXT
51%token T_IF 52%token T_IF
@@ -56,17 +57,22 @@ struct symbol *symbol_hash[257];
56%token T_PROMPT 57%token T_PROMPT
57%token T_DEFAULT 58%token T_DEFAULT
58%token T_TRISTATE 59%token T_TRISTATE
60%token T_DEF_TRISTATE
59%token T_BOOLEAN 61%token T_BOOLEAN
62%token T_DEF_BOOLEAN
63%token T_STRING
60%token T_INT 64%token T_INT
61%token T_HEX 65%token T_HEX
62%token <string> T_WORD 66%token <string> T_WORD
63%token <string> T_STRING 67%token <string> T_WORD_QUOTE
64%token T_UNEQUAL 68%token T_UNEQUAL
65%token T_EOF 69%token T_EOF
66%token T_EOL 70%token T_EOL
67%token T_CLOSE_PAREN 71%token T_CLOSE_PAREN
68%token T_OPEN_PAREN 72%token T_OPEN_PAREN
69%token T_ON 73%token T_ON
74%token T_SELECT
75%token T_RANGE
70 76
71%left T_OR 77%left T_OR
72%left T_AND 78%left T_AND
@@ -103,14 +109,15 @@ common_block:
103 if_stmt 109 if_stmt
104 | comment_stmt 110 | comment_stmt
105 | config_stmt 111 | config_stmt
112 | menuconfig_stmt
106 | source_stmt 113 | source_stmt
107 | nl_or_eof 114 | nl_or_eof
108; 115;
109 116
110 117
111/* config entry */ 118/* config/menuconfig entry */
112 119
113config_entry_start: T_CONFIG T_WORD 120config_entry_start: T_CONFIG T_WORD T_EOL
114{ 121{
115 struct symbol *sym = sym_lookup($2, 0); 122 struct symbol *sym = sym_lookup($2, 0);
116 sym->flags |= SYMBOL_OPTIONAL; 123 sym->flags |= SYMBOL_OPTIONAL;
@@ -118,74 +125,118 @@ config_entry_start: T_CONFIG T_WORD
118 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); 125 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
119}; 126};
120 127
121config_stmt: config_entry_start T_EOL config_option_list 128config_stmt: config_entry_start config_option_list
122{ 129{
123 menu_end_entry(); 130 menu_end_entry();
124 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); 131 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
125}; 132};
126 133
134menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
135{
136 struct symbol *sym = sym_lookup($2, 0);
137 sym->flags |= SYMBOL_OPTIONAL;
138 menu_add_entry(sym);
139 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
140};
141
142menuconfig_stmt: menuconfig_entry_start config_option_list
143{
144 if (current_entry->prompt)
145 current_entry->prompt->type = P_MENU;
146 else
147 zconfprint("warning: menuconfig statement without prompt");
148 menu_end_entry();
149 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
150};
151
127config_option_list: 152config_option_list:
128 /* empty */ 153 /* empty */
129 | config_option_list config_option T_EOL 154 | config_option_list config_option
130 | config_option_list depends T_EOL 155 | config_option_list depends
131 | config_option_list help 156 | config_option_list help
132 | config_option_list T_EOL 157 | config_option_list T_EOL
133{ }; 158;
134 159
135config_option: T_TRISTATE prompt_stmt_opt 160config_option: T_TRISTATE prompt_stmt_opt T_EOL
136{ 161{
137 menu_set_type(S_TRISTATE); 162 menu_set_type(S_TRISTATE);
138 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); 163 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
139}; 164};
140 165
141config_option: T_BOOLEAN prompt_stmt_opt 166config_option: T_DEF_TRISTATE expr if_expr T_EOL
167{
168 menu_add_expr(P_DEFAULT, $2, $3);
169 menu_set_type(S_TRISTATE);
170 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
171};
172
173config_option: T_BOOLEAN prompt_stmt_opt T_EOL
142{ 174{
143 menu_set_type(S_BOOLEAN); 175 menu_set_type(S_BOOLEAN);
144 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); 176 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
145}; 177};
146 178
147config_option: T_INT prompt_stmt_opt 179config_option: T_DEF_BOOLEAN expr if_expr T_EOL
180{
181 menu_add_expr(P_DEFAULT, $2, $3);
182 menu_set_type(S_BOOLEAN);
183 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
184};
185
186config_option: T_INT prompt_stmt_opt T_EOL
148{ 187{
149 menu_set_type(S_INT); 188 menu_set_type(S_INT);
150 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno()); 189 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
151}; 190};
152 191
153config_option: T_HEX prompt_stmt_opt 192config_option: T_HEX prompt_stmt_opt T_EOL
154{ 193{
155 menu_set_type(S_HEX); 194 menu_set_type(S_HEX);
156 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno()); 195 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
157}; 196};
158 197
159config_option: T_STRING prompt_stmt_opt 198config_option: T_STRING prompt_stmt_opt T_EOL
160{ 199{
161 menu_set_type(S_STRING); 200 menu_set_type(S_STRING);
162 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); 201 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
163}; 202};
164 203
165config_option: T_PROMPT prompt if_expr 204config_option: T_PROMPT prompt if_expr T_EOL
166{ 205{
167 menu_add_prop(P_PROMPT, $2, NULL, $3); 206 menu_add_prompt(P_PROMPT, $2, $3);
168 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 207 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
169}; 208};
170 209
171config_option: T_DEFAULT symbol if_expr 210config_option: T_DEFAULT expr if_expr T_EOL
172{ 211{
173 menu_add_prop(P_DEFAULT, NULL, $2, $3); 212 menu_add_expr(P_DEFAULT, $2, $3);
174 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 213 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
175}; 214};
176 215
216config_option: T_SELECT T_WORD if_expr T_EOL
217{
218 menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
219 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
220};
221
222config_option: T_RANGE symbol symbol if_expr T_EOL
223{
224 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
225 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
226};
227
177/* choice entry */ 228/* choice entry */
178 229
179choice: T_CHOICE 230choice: T_CHOICE T_EOL
180{ 231{
181 struct symbol *sym = sym_lookup(NULL, 0); 232 struct symbol *sym = sym_lookup(NULL, 0);
182 sym->flags |= SYMBOL_CHOICE; 233 sym->flags |= SYMBOL_CHOICE;
183 menu_add_entry(sym); 234 menu_add_entry(sym);
184 menu_add_prop(P_CHOICE, NULL, NULL, NULL); 235 menu_add_expr(P_CHOICE, NULL, NULL);
185 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); 236 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
186}; 237};
187 238
188choice_entry: choice T_EOL choice_option_list 239choice_entry: choice choice_option_list
189{ 240{
190 menu_end_entry(); 241 menu_end_entry();
191 menu_add_menu(); 242 menu_add_menu();
@@ -200,7 +251,7 @@ choice_end: end
200}; 251};
201 252
202choice_stmt: 253choice_stmt:
203 choice_entry choice_block choice_end T_EOL 254 choice_entry choice_block choice_end
204 | choice_entry choice_block 255 | choice_entry choice_block
205{ 256{
206 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno); 257 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
@@ -209,27 +260,39 @@ choice_stmt:
209 260
210choice_option_list: 261choice_option_list:
211 /* empty */ 262 /* empty */
212 | choice_option_list choice_option T_EOL 263 | choice_option_list choice_option
213 | choice_option_list depends T_EOL 264 | choice_option_list depends
214 | choice_option_list help 265 | choice_option_list help
215 | choice_option_list T_EOL 266 | choice_option_list T_EOL
216; 267;
217 268
218choice_option: T_PROMPT prompt if_expr 269choice_option: T_PROMPT prompt if_expr T_EOL
219{ 270{
220 menu_add_prop(P_PROMPT, $2, NULL, $3); 271 menu_add_prompt(P_PROMPT, $2, $3);
221 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 272 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
222}; 273};
223 274
224choice_option: T_OPTIONAL 275choice_option: T_TRISTATE prompt_stmt_opt T_EOL
276{
277 menu_set_type(S_TRISTATE);
278 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
279};
280
281choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
282{
283 menu_set_type(S_BOOLEAN);
284 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
285};
286
287choice_option: T_OPTIONAL T_EOL
225{ 288{
226 current_entry->sym->flags |= SYMBOL_OPTIONAL; 289 current_entry->sym->flags |= SYMBOL_OPTIONAL;
227 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); 290 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
228}; 291};
229 292
230choice_option: T_DEFAULT symbol if_expr 293choice_option: T_DEFAULT T_WORD if_expr T_EOL
231{ 294{
232 menu_add_prop(P_DEFAULT, NULL, $2, $3); 295 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
233 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 296 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
234}; 297};
235 298
@@ -240,7 +303,7 @@ choice_block:
240 303
241/* if entry */ 304/* if entry */
242 305
243if: T_IF expr 306if: T_IF expr T_EOL
244{ 307{
245 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 308 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
246 menu_add_entry(NULL); 309 menu_add_entry(NULL);
@@ -258,8 +321,8 @@ if_end: end
258}; 321};
259 322
260if_stmt: 323if_stmt:
261 if T_EOL if_block if_end T_EOL 324 if if_block if_end
262 | if T_EOL if_block 325 | if if_block
263{ 326{
264 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno); 327 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
265 zconfnerrs++; 328 zconfnerrs++;
@@ -274,14 +337,14 @@ if_block:
274 337
275/* menu entry */ 338/* menu entry */
276 339
277menu: T_MENU prompt 340menu: T_MENU prompt T_EOL
278{ 341{
279 menu_add_entry(NULL); 342 menu_add_entry(NULL);
280 menu_add_prop(P_MENU, $2, NULL, NULL); 343 menu_add_prop(P_MENU, $2, NULL, NULL);
281 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); 344 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
282}; 345};
283 346
284menu_entry: menu T_EOL depends_list 347menu_entry: menu depends_list
285{ 348{
286 menu_end_entry(); 349 menu_end_entry();
287 menu_add_menu(); 350 menu_add_menu();
@@ -296,7 +359,7 @@ menu_end: end
296}; 359};
297 360
298menu_stmt: 361menu_stmt:
299 menu_entry menu_block menu_end T_EOL 362 menu_entry menu_block menu_end
300 | menu_entry menu_block 363 | menu_entry menu_block
301{ 364{
302 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno); 365 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
@@ -311,27 +374,27 @@ menu_block:
311 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; } 374 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
312; 375;
313 376
314source: T_SOURCE prompt 377source: T_SOURCE prompt T_EOL
315{ 378{
316 $$ = $2; 379 $$ = $2;
317 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); 380 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
318}; 381};
319 382
320source_stmt: source T_EOL 383source_stmt: source
321{ 384{
322 zconf_nextfile($1); 385 zconf_nextfile($1);
323}; 386};
324 387
325/* comment entry */ 388/* comment entry */
326 389
327comment: T_COMMENT prompt 390comment: T_COMMENT prompt T_EOL
328{ 391{
329 menu_add_entry(NULL); 392 menu_add_entry(NULL);
330 menu_add_prop(P_COMMENT, $2, NULL, NULL); 393 menu_add_prop(P_COMMENT, $2, NULL, NULL);
331 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); 394 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
332}; 395};
333 396
334comment_stmt: comment T_EOL depends_list 397comment_stmt: comment depends_list
335{ 398{
336 menu_end_entry(); 399 menu_end_entry();
337}; 400};
@@ -352,21 +415,21 @@ help: help_start T_HELPTEXT
352/* depends option */ 415/* depends option */
353 416
354 depends_list: /* empty */ 417 depends_list: /* empty */
355 | depends_list depends T_EOL 418 | depends_list depends
356 | depends_list T_EOL 419 | depends_list T_EOL
357{ }; 420;
358 421
359depends: T_DEPENDS T_ON expr 422depends: T_DEPENDS T_ON expr T_EOL
360{ 423{
361 menu_add_dep($3); 424 menu_add_dep($3);
362 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); 425 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
363} 426}
364 | T_DEPENDS expr 427 | T_DEPENDS expr T_EOL
365{ 428{
366 menu_add_dep($2); 429 menu_add_dep($2);
367 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); 430 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
368} 431}
369 | T_REQUIRES expr 432 | T_REQUIRES expr T_EOL
370{ 433{
371 menu_add_dep($2); 434 menu_add_dep($2);
372 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); 435 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
@@ -376,22 +439,18 @@ depends: T_DEPENDS T_ON expr
376 439
377prompt_stmt_opt: 440prompt_stmt_opt:
378 /* empty */ 441 /* empty */
379 | prompt 442 | prompt if_expr
380{
381 menu_add_prop(P_PROMPT, $1, NULL, NULL);
382}
383 | prompt T_IF expr
384{ 443{
385 menu_add_prop(P_PROMPT, $1, NULL, $3); 444 menu_add_prop(P_PROMPT, $1, NULL, $2);
386}; 445};
387 446
388 prompt: T_WORD 447 prompt: T_WORD
389 | T_STRING 448 | T_WORD_QUOTE
390; 449;
391 450
392 end: T_ENDMENU { $$ = T_ENDMENU; } 451 end: T_ENDMENU nl_or_eof{ $$ = T_ENDMENU; }
393 | T_ENDCHOICE { $$ = T_ENDCHOICE; } 452 | T_ENDCHOICE nl_or_eof{ $$ = T_ENDCHOICE; }
394 | T_ENDIF { $$ = T_ENDIF; } 453 | T_ENDIF nl_or_eof{ $$ = T_ENDIF; }
395; 454;
396 455
397nl_or_eof: 456nl_or_eof:
@@ -411,26 +470,34 @@ expr: symbol { $$ = expr_alloc_symbol($1); }
411; 470;
412 471
413 symbol: T_WORD{ $$ = sym_lookup($1, 0); free($1); } 472 symbol: T_WORD{ $$ = sym_lookup($1, 0); free($1); }
414 | T_STRING{ $$ = sym_lookup($1, 1); free($1); } 473 | T_WORD_QUOTE{ $$ = sym_lookup($1, 1); free($1); }
415; 474;
416 475
417%% 476%%
418 477
419void conf_parse(const char *name) 478void conf_parse(const char *name)
420{ 479{
480 struct symbol *sym;
481 int i;
482
421 zconf_initscan(name); 483 zconf_initscan(name);
422 484
423 sym_init(); 485 sym_init();
424 menu_init(); 486 menu_init();
425 rootmenu.prompt = menu_add_prop(P_MENU, "Configuration", NULL, NULL); 487 modules_sym = sym_lookup("MODULES", 0);
488 rootmenu.prompt = menu_add_prop(P_MENU, "Build Configuration", NULL, NULL);
426 489
427 //zconfdebug = 1; 490 //zconfdebug = 1;
428 zconfparse(); 491 zconfparse();
429 if (zconfnerrs) 492 if (zconfnerrs)
430 exit(1); 493 exit(1);
431 menu_finalize(&rootmenu); 494 menu_finalize(&rootmenu);
432 495 for_all_symbols(i, sym) {
433 modules_sym = sym_lookup("MODULES", 0); 496 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
497 printf("\n");
498 else
499 sym->flags |= SYMBOL_CHECK_DONE;
500 }
434 501
435 sym_change_count = 1; 502 sym_change_count = 1;
436} 503}
@@ -446,7 +513,7 @@ const char *zconf_tokenname(int token)
446 case T_ENDIF: return "endif"; 513 case T_ENDIF: return "endif";
447 } 514 }
448 return "<token>"; 515 return "<token>";
449} 516}
450 517
451static bool zconf_endtoken(int token, int starttoken, int endtoken) 518static bool zconf_endtoken(int token, int starttoken, int endtoken)
452{ 519{
@@ -468,7 +535,7 @@ static void zconfprint(const char *err, ...)
468{ 535{
469 va_list ap; 536 va_list ap;
470 537
471 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); 538 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
472 va_start(ap, err); 539 va_start(ap, err);
473 vfprintf(stderr, err, ap); 540 vfprintf(stderr, err, ap);
474 va_end(ap); 541 va_end(ap);
@@ -477,7 +544,7 @@ static void zconfprint(const char *err, ...)
477 544
478static void zconferror(const char *err) 545static void zconferror(const char *err)
479{ 546{
480 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err); 547 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
481} 548}
482 549
483void print_quoted_string(FILE *out, const char *str) 550void print_quoted_string(FILE *out, const char *str)
@@ -502,8 +569,6 @@ void print_symbol(FILE *out, struct menu *menu)
502 struct symbol *sym = menu->sym; 569 struct symbol *sym = menu->sym;
503 struct property *prop; 570 struct property *prop;
504 571
505 //sym->flags |= SYMBOL_PRINTED;
506
507 if (sym_is_choice(sym)) 572 if (sym_is_choice(sym))
508 fprintf(out, "choice\n"); 573 fprintf(out, "choice\n");
509 else 574 else
@@ -528,13 +593,6 @@ void print_symbol(FILE *out, struct menu *menu)
528 fputs(" ???\n", out); 593 fputs(" ???\n", out);
529 break; 594 break;
530 } 595 }
531#if 0
532 if (!expr_is_yes(sym->dep)) {
533 fputs(" depends ", out);
534 expr_fprint(sym->dep, out);
535 fputc('\n', out);
536 }
537#endif
538 for (prop = sym->prop; prop; prop = prop->next) { 596 for (prop = sym->prop; prop; prop = prop->next) {
539 if (prop->menu != menu) 597 if (prop->menu != menu)
540 continue; 598 continue;
@@ -542,25 +600,18 @@ void print_symbol(FILE *out, struct menu *menu)
542 case P_PROMPT: 600 case P_PROMPT:
543 fputs(" prompt ", out); 601 fputs(" prompt ", out);
544 print_quoted_string(out, prop->text); 602 print_quoted_string(out, prop->text);
545 if (prop->def) { 603 if (!expr_is_yes(prop->visible.expr)) {
546 fputc(' ', out);
547 if (prop->def->flags & SYMBOL_CONST)
548 print_quoted_string(out, prop->def->name);
549 else
550 fputs(prop->def->name, out);
551 }
552 if (!expr_is_yes(E_EXPR(prop->visible))) {
553 fputs(" if ", out); 604 fputs(" if ", out);
554 expr_fprint(E_EXPR(prop->visible), out); 605 expr_fprint(prop->visible.expr, out);
555 } 606 }
556 fputc('\n', out); 607 fputc('\n', out);
557 break; 608 break;
558 case P_DEFAULT: 609 case P_DEFAULT:
559 fputs( " default ", out); 610 fputs( " default ", out);
560 print_quoted_string(out, prop->def->name); 611 expr_fprint(prop->expr, out);
561 if (!expr_is_yes(E_EXPR(prop->visible))) { 612 if (!expr_is_yes(prop->visible.expr)) {
562 fputs(" if ", out); 613 fputs(" if ", out);
563 expr_fprint(E_EXPR(prop->visible), out); 614 expr_fprint(prop->visible.expr, out);
564 } 615 }
565 fputc('\n', out); 616 fputc('\n', out);
566 break; 617 break;
@@ -583,7 +634,6 @@ void print_symbol(FILE *out, struct menu *menu)
583 634
584void zconfdump(FILE *out) 635void zconfdump(FILE *out)
585{ 636{
586 //struct file *file;
587 struct property *prop; 637 struct property *prop;
588 struct symbol *sym; 638 struct symbol *sym;
589 struct menu *menu; 639 struct menu *menu;
@@ -594,11 +644,6 @@ void zconfdump(FILE *out)
594 print_symbol(out, menu); 644 print_symbol(out, menu);
595 else if ((prop = menu->prompt)) { 645 else if ((prop = menu->prompt)) {
596 switch (prop->type) { 646 switch (prop->type) {
597 //case T_MAINMENU:
598 //fputs("\nmainmenu ", out);
599 //print_quoted_string(out, prop->text);
600 //fputs("\n", out);
601 //break;
602 case P_COMMENT: 647 case P_COMMENT:
603 fputs("\ncomment ", out); 648 fputs("\ncomment ", out);
604 print_quoted_string(out, prop->text); 649 print_quoted_string(out, prop->text);
@@ -609,19 +654,12 @@ void zconfdump(FILE *out)
609 print_quoted_string(out, prop->text); 654 print_quoted_string(out, prop->text);
610 fputs("\n", out); 655 fputs("\n", out);
611 break; 656 break;
612 //case T_SOURCE:
613 //fputs("\nsource ", out);
614 //print_quoted_string(out, prop->text);
615 //fputs("\n", out);
616 //break;
617 //case T_IF:
618 //fputs("\nif\n", out);
619 default: 657 default:
620 ; 658 ;
621 } 659 }
622 if (!expr_is_yes(E_EXPR(prop->visible))) { 660 if (!expr_is_yes(prop->visible.expr)) {
623 fputs(" depends ", out); 661 fputs(" depends ", out);
624 expr_fprint(E_EXPR(prop->visible), out); 662 expr_fprint(prop->visible.expr, out);
625 fputc('\n', out); 663 fputc('\n', out);
626 } 664 }
627 fputs("\n", out); 665 fputs("\n", out);