summaryrefslogtreecommitdiff
path: root/scripts/kconfig
authorkergoth <kergoth>2003-06-17 17:03:49 (UTC)
committer kergoth <kergoth>2003-06-17 17:03:49 (UTC)
commit16e53b2a2e94742f3b55ee73700bb264e36638d4 (patch) (unidiff)
tree4f2b65a635d25c1ce0cfeea7953623c2bf7d9534 /scripts/kconfig
parent384b7f1a42f9f2f101dc8fe11c3625055d96f672 (diff)
downloadopie-16e53b2a2e94742f3b55ee73700bb264e36638d4.zip
opie-16e53b2a2e94742f3b55ee73700bb264e36638d4.tar.gz
opie-16e53b2a2e94742f3b55ee73700bb264e36638d4.tar.bz2
Update LinuxKernelConf version to 1.4.
Diffstat (limited to 'scripts/kconfig') (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,2 +1,2 @@
1VERSION=1.3 1VERSION=1.4
2CC=gcc 2CC=gcc
@@ -4,5 +4,5 @@ CXX=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
@@ -11,7 +11,9 @@ YACC=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
@@ -21,2 +23,3 @@ mconf_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
@@ -25,3 +28,3 @@ OTHER=README lkc-language.txt Makefile.kernel \
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
@@ -62,2 +65,7 @@ qconf_OBJ=$(filter %.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)
@@ -86,2 +94,3 @@ qconf.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
@@ -96,3 +105,3 @@ qconf:
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.
@@ -101,5 +110,11 @@ else
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)
@@ -128,3 +143,3 @@ lex.%.c: %.l
128%.moc: %.h 143%.moc: %.h
129 $(HOSTQTDIR)/bin/moc -i $< -o $@ 144 $(QTDIR)/bin/moc -i $< -o $@
130 145
@@ -138,10 +153,12 @@ ifdef 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
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
@@ -8,3 +8,6 @@
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
@@ -13,3 +16,3 @@ libkconfig-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
@@ -17,9 +20,13 @@ 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
@@ -32,3 +39,6 @@ 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
@@ -42,3 +52,3 @@ MOC = $(QTDIR)/bin/moc
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; \
@@ -64,2 +74,28 @@ endif
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
@@ -70,2 +106,4 @@ $(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
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
@@ -37,40 +37,2 @@ static 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)
@@ -92,2 +54,12 @@ static void strip(char *str)
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)
@@ -103,2 +75,9 @@ static void conf_askvalue(struct symbol *sym, const char *def)
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) {
@@ -110,8 +89,3 @@ static void conf_askvalue(struct symbol *sym, const char *def)
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:
@@ -296,5 +270,4 @@ static int conf_choice(struct menu *menu)
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;
@@ -316,6 +289,10 @@ static int conf_choice(struct menu *menu)
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 }
@@ -324,19 +301,38 @@ static int conf_choice(struct menu *menu)
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) {
@@ -344,42 +340,56 @@ static int conf_choice(struct menu *menu)
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 }
@@ -424,3 +434,3 @@ static void conf(struct menu *menu)
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;
@@ -458,7 +468,4 @@ static void check_conf(struct menu *menu)
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++)
@@ -468,15 +475,6 @@ static void check_conf(struct menu *menu)
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)
@@ -538,3 +536,3 @@ int main(int ac, char **av)
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"
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
@@ -21,5 +21,2 @@ const 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,
@@ -107,7 +104,7 @@ int conf_read(const char *name)
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 }
@@ -131,3 +128,3 @@ int conf_read(const char *name)
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;
@@ -156,3 +153,3 @@ int conf_read(const char *name)
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;
@@ -162,3 +159,3 @@ int conf_read(const char *name)
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;
@@ -167,3 +164,3 @@ int conf_read(const char *name)
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;
@@ -189,3 +186,3 @@ int conf_read(const char *name)
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;
@@ -200,6 +197,6 @@ int conf_read(const char *name)
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? */;
@@ -207,5 +204,5 @@ int conf_read(const char *name)
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;
@@ -214,3 +211,3 @@ int conf_read(const char *name)
214 } 211 }
215 S_TRI(prop->def->def) = S_TRI(sym->def); 212 cs->user.tri = sym->user.tri;
216 } 213 }
@@ -226,2 +223,16 @@ int conf_read(const char *name)
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))
@@ -230,4 +241,5 @@ int conf_read(const char *name)
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 }
@@ -244,3 +256,4 @@ int conf_write(const char *name)
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;
@@ -248,8 +261,28 @@ int conf_write(const char *name)
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"
@@ -257,6 +290,7 @@ int conf_write(const char *name)
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
@@ -276,6 +310,7 @@ int conf_write(const char *name)
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)) {
@@ -288,3 +323,3 @@ int conf_write(const char *name)
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;
@@ -297,3 +332,4 @@ int conf_write(const char *name)
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;
@@ -301,3 +337,4 @@ int conf_write(const char *name)
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;
@@ -305,3 +342,4 @@ int conf_write(const char *name)
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;
@@ -313,3 +351,4 @@ int conf_write(const char *name)
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 {
@@ -318,3 +357,4 @@ int conf_write(const char *name)
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 }
@@ -323,3 +363,4 @@ int conf_write(const char *name)
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++;
@@ -328,3 +369,4 @@ int conf_write(const char *name)
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;
@@ -334,3 +376,4 @@ int conf_write(const char *name)
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;
@@ -340,3 +383,4 @@ int conf_write(const char *name)
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;
@@ -360,14 +404,14 @@ int conf_write(const char *name)
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;
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
@@ -57,2 +57,9 @@ struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
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)
@@ -160,5 +167,18 @@ void 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);
@@ -197,2 +217,3 @@ int expr_eq(struct expr *e1, struct expr *e2)
197 case E_CHOICE: 217 case E_CHOICE:
218 case E_RANGE:
198 case E_NONE: 219 case E_NONE:
@@ -899,2 +920,3 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
899 case E_CHOICE: 920 case E_CHOICE:
921 case E_RANGE:
900 case E_NONE: 922 case E_NONE:
@@ -916,3 +938,3 @@ tristate expr_calc_value(struct expr *e)
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:
@@ -1019,7 +1041,14 @@ void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, in
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;
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
@@ -20,6 +20,2 @@ struct file {
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;
@@ -38,3 +34,3 @@ typedef enum tristate {
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};
@@ -47,7 +43,3 @@ union expr_data {
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;
@@ -55,6 +47,2 @@ struct expr {
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))
@@ -68,8 +56,4 @@ struct expr_value {
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;
@@ -85,8 +69,4 @@ struct symbol {
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;
@@ -95,3 +75,3 @@ struct symbol {
95 struct expr *dep, *dep2; 75 struct expr *dep, *dep2;
96 struct menu *menu; 76 struct expr_value rev_dep;
97}; 77};
@@ -100,12 +80,2 @@ struct symbol {
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
@@ -124,2 +94,5 @@ struct symbol {
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
@@ -130,3 +103,3 @@ struct symbol {
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};
@@ -136,12 +109,6 @@ struct property {
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;
@@ -149,5 +116,2 @@ struct property {
149 int lineno; 116 int lineno;
150#ifdef CML1
151 struct property *next_pos;
152#endif
153}; 117};
@@ -157,5 +121,7 @@ struct property {
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
@@ -176,2 +142,3 @@ struct menu {
176 #define MENU_CHANGED 0x0001 142 #define MENU_CHANGED 0x0001
143 #define MENU_ROOT 0x0002
177 144
@@ -186,9 +153,3 @@ extern 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);
@@ -196,4 +157,4 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e
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);
@@ -217,13 +178,2 @@ void 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)
@@ -238,3 +188,2 @@ static inline int expr_is_no(struct expr *e)
238#endif 188#endif
239#endif
240 189
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
@@ -292 +292,35 @@ static const char *xpm_menu_inv[] = {
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
@@ -20,3 +20,3 @@ organized in a tree structure:
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.
@@ -52,3 +52,3 @@ applicable everywhere (see syntax).
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
@@ -66,3 +66,3 @@ applicable everywhere (see syntax).
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
@@ -71,3 +71,3 @@ applicable everywhere (see syntax).
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
@@ -83,3 +83,3 @@ applicable everywhere (see syntax).
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
@@ -92,5 +92,20 @@ applicable everywhere (see syntax).
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.
@@ -125,4 +140,4 @@ Expressions are listed in decreasing order of 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
@@ -132,3 +147,3 @@ expression 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
@@ -144,3 +159,3 @@ Menu structure
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
@@ -161,4 +176,4 @@ The 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:
@@ -179,3 +194,3 @@ MODVERSIONS 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).
@@ -190,2 +205,3 @@ end a menu entry:
190- config 205- config
206- menuconfig
191- choice/endchoice 207- choice/endchoice
@@ -195,3 +211,3 @@ end a menu entry:
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
@@ -205,2 +221,10 @@ attributes 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:
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
@@ -51,5 +51,7 @@ void 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);
@@ -66,2 +68,5 @@ void 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
@@ -69,3 +74,3 @@ static inline tristate sym_get_tristate_value(struct symbol *sym)
69{ 74{
70 return S_TRI(sym->curr); 75 return sym->curr.tri;
71} 76}
@@ -75,3 +80,3 @@ static 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}
@@ -100,3 +105,2 @@ static 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;
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
@@ -20,5 +20,5 @@ P(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));
@@ -27,2 +27,3 @@ P(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));
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
@@ -51,3 +51,3 @@ setmod_text[] =
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[] =
@@ -58,3 +58,3 @@ load_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"
@@ -62,3 +62,3 @@ load_config_help[] =
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"
@@ -72,3 +72,3 @@ save_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"
@@ -149,2 +149,3 @@ static void cprint_init(void)
149{ 149{
150 char *env = getenv("LXDIALOG");
150 bufptr = buf; 151 bufptr = buf;
@@ -154,3 +155,7 @@ static void cprint_init(void)
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");
@@ -304,7 +309,4 @@ static void build_conf(struct menu *menu)
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
@@ -375,2 +377,7 @@ static void build_conf(struct menu *menu)
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++;
@@ -384,3 +391,6 @@ static void build_conf(struct menu *menu)
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;
@@ -393,3 +403,6 @@ static void build_conf(struct menu *menu)
393 } 403 }
394 cprint1("<%c>", ch); 404 if (sym_is_changable(sym))
405 cprint1("<%c>", ch);
406 else
407 cprint1("---");
395 break; 408 break;
@@ -402,3 +415,4 @@ static void build_conf(struct menu *menu)
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();
@@ -408,3 +422,9 @@ static void build_conf(struct menu *menu)
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();
@@ -447,5 +467,5 @@ static void conf(struct menu *menu)
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 }
@@ -486,2 +506,4 @@ static void conf(struct menu *menu)
486 conf_choice(submenu); 506 conf_choice(submenu);
507 else if (submenu->prompt->type == P_MENU)
508 conf(submenu);
487 break; 509 break;
@@ -746,4 +768,3 @@ int main(int ac, char **av)
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
@@ -772,7 +793,8 @@ int main(int ac, char **av)
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
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
@@ -56,5 +56,30 @@ void menu_end_menu(void)
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}
@@ -71,3 +96,3 @@ void menu_set_type(int type)
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,
@@ -76,34 +101,16 @@ void menu_set_type(int type)
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 }
@@ -113,10 +120,15 @@ struct property *menu_add_prop(int token, char *prompt, struct symbol *def, stru
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}
@@ -128,3 +140,3 @@ void menu_finalize(struct menu *parent)
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
@@ -145,3 +157,3 @@ void menu_finalize(struct menu *parent)
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
@@ -161,3 +173,3 @@ void menu_finalize(struct menu *parent)
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);
@@ -166,3 +178,8 @@ void menu_finalize(struct menu *parent)
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 }
@@ -171,4 +188,4 @@ void menu_finalize(struct menu *parent)
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);
@@ -177,3 +194,3 @@ void menu_finalize(struct menu *parent)
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))
@@ -206,10 +223,23 @@ void menu_finalize(struct menu *parent)
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 }
@@ -226,2 +256,49 @@ void menu_finalize(struct menu *parent)
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}
@@ -230,2 +307,4 @@ bool menu_is_visible(struct menu *menu)
230{ 307{
308 struct menu *child;
309 struct symbol *sym;
231 tristate visible; 310 tristate visible;
@@ -234,8 +313,18 @@ bool menu_is_visible(struct menu *menu)
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}
@@ -260,6 +349,5 @@ struct menu *menu_get_parent_menu(struct menu *menu)
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;
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
@@ -44,6 +44,5 @@ static QSettings *configSettings;
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;
@@ -51,4 +50,2 @@ static void updateMenuList(P* parent, struct menu* menu)
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;
@@ -61,3 +58,5 @@ static void updateMenuList(P* parent, struct menu* menu)
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) {
@@ -68,3 +67,3 @@ static void updateMenuList(P* parent, struct menu* menu)
68 case menuMode: 67 case menuMode:
69 if (type != P_ROOTMENU) 68 if (!(child->flags & MENU_ROOT))
70 goto hide; 69 goto hide;
@@ -72,3 +71,3 @@ static void updateMenuList(P* parent, struct menu* menu)
72 case symbolMode: 71 case symbolMode:
73 if (type == P_ROOTMENU) 72 if (child->flags & MENU_ROOT)
74 goto hide; 73 goto hide;
@@ -83,15 +82,6 @@ static void updateMenuList(P* parent, struct menu* menu)
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);
@@ -102,3 +92,3 @@ static void updateMenuList(P* parent, struct menu* menu)
102 } 92 }
103 hide: 93 hide:
104 if (item && item->menu == child) { 94 if (item && item->menu == child) {
@@ -133,5 +123,5 @@ void ConfigItem::updateMenu(void)
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;
@@ -139,14 +129,35 @@ void ConfigItem::updateMenu(void)
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
@@ -160,4 +171,4 @@ void ConfigItem::updateMenu(void)
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);
@@ -213,5 +224,5 @@ void ConfigItem::updateMenu(void)
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;
@@ -220,2 +231,3 @@ void ConfigItem::updateMenu(void)
220 prompt += " (NEW)"; 231 prompt += " (NEW)";
232set_prompt:
221 setText(promptColIdx, prompt); 233 setText(promptColIdx, prompt);
@@ -223,12 +235,18 @@ void ConfigItem::updateMenu(void)
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}
@@ -253,10 +271,11 @@ void 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();
@@ -269,7 +288,9 @@ ConfigItem::~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 }
@@ -312,3 +333,4 @@ ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv)
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),
@@ -368,4 +390,6 @@ void ConfigList::updateSelection(void)
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);
@@ -375,3 +399,24 @@ void 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);
@@ -394,3 +439,3 @@ void ConfigList::setValue(ConfigItem* item, tristate val)
394 439
395 sym = item->menu->sym; 440 sym = item->menu ? item->menu->sym : 0;
396 if (!sym) 441 if (!sym)
@@ -420,2 +465,4 @@ void ConfigList::changeValue(ConfigItem* item)
420 menu = item->menu; 465 menu = item->menu;
466 if (!menu)
467 return;
421 sym = menu->sym; 468 sym = menu->sym;
@@ -462,3 +509,3 @@ void ConfigList::setRootMenu(struct menu *menu)
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;
@@ -473,9 +520,8 @@ void ConfigList::setParentMenu(void)
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
@@ -513,5 +559,12 @@ void ConfigList::keyPressEvent(QKeyEvent* ev)
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);
@@ -550,2 +603,3 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
550 struct menu *menu; 603 struct menu *menu;
604 enum prop_type ptype;
551 const QPixmap* pm; 605 const QPixmap* pm;
@@ -566,6 +620,13 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
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 }
@@ -608,6 +669,11 @@ void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
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);
@@ -679,3 +745,2 @@ ConfigMainWindow::ConfigMainWindow(void)
679{ 745{
680 ConfigView* view;
681 QMenuBar* menu; 746 QMenuBar* menu;
@@ -709,4 +774,4 @@ ConfigMainWindow::ConfigMainWindow(void)
709 774
710 view = new ConfigView(split1, this); 775 menuView = new ConfigView(split1, this);
711 menuList = view->list; 776 menuList = menuView->list;
712 777
@@ -716,4 +781,4 @@ ConfigMainWindow::ConfigMainWindow(void)
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
@@ -820,3 +885,2 @@ ConfigMainWindow::ConfigMainWindow(void)
820 885
821 //showFullView();
822 showSplitView(); 886 showSplitView();
@@ -866,77 +930,81 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
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>";
@@ -944,7 +1012,21 @@ void ConfigMainWindow::setHelp(QListViewItem* item)
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}
@@ -1012,3 +1094,3 @@ void ConfigMainWindow::showSingleView(void)
1012{ 1094{
1013 menuList->hide(); 1095 menuView->hide();
1014 menuList->setRootMenu(0); 1096 menuList->setRootMenu(0);
@@ -1034,4 +1116,4 @@ void ConfigMainWindow::showSplitView(void)
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();
@@ -1041,3 +1123,3 @@ void ConfigMainWindow::showFullView(void)
1041{ 1123{
1042 menuList->hide(); 1124 menuView->hide();
1043 menuList->setRootMenu(0); 1125 menuList->setRootMenu(0);
@@ -1075,2 +1157,4 @@ void ConfigMainWindow::setShowName(bool b)
1075 configList->reinit(); 1157 configList->reinit();
1158 menuList->showName = b;
1159 menuList->reinit();
1076} 1160}
@@ -1083,2 +1167,4 @@ void ConfigMainWindow::setShowRange(bool b)
1083 configList->reinit(); 1167 configList->reinit();
1168 menuList->showRange = b;
1169 menuList->reinit();
1084} 1170}
@@ -1091,2 +1177,4 @@ void ConfigMainWindow::setShowData(bool b)
1091 configList->reinit(); 1177 configList->reinit();
1178 menuList->showData = b;
1179 menuList->reinit();
1092} 1180}
@@ -1148,8 +1236,21 @@ void fixup_rootmenu(struct menu *menu)
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}
@@ -1165,2 +1266,3 @@ int main(int ac, char** av)
1165 1266
1267 progname = av[0];
1166 configApp = new QApplication(ac, av); 1268 configApp = new QApplication(ac, av);
@@ -1171,9 +1273,5 @@ int main(int ac, char** av)
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 }
@@ -1182,2 +1280,5 @@ int main(int ac, char** av)
1182 name = av[1]; 1280 name = av[1];
1281 if (!name)
1282 usage();
1283
1183 conf_parse(name); 1284 conf_parse(name);
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
@@ -103,2 +103,5 @@ public:
103 103
104 template <class P>
105 void ConfigList::updateMenuList(P*, struct menu*);
106
104 bool updateAll; 107 bool updateAll;
@@ -106,3 +109,4 @@ public:
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
@@ -123,3 +127,3 @@ public:
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 {
@@ -128,3 +132,8 @@ public:
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 {
@@ -138,3 +147,3 @@ public:
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
@@ -172,2 +181,3 @@ public:
172 bool visible; 181 bool visible;
182 bool goParent;
173}; 183};
@@ -218,3 +228,5 @@ protected:
218 228
229 ConfigView *menuView;
219 ConfigList *menuList; 230 ConfigList *menuList;
231 ConfigView *configView;
220 ConfigList *configList; 232 ConfigList *configList;
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
@@ -36,14 +36,5 @@ void 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}
@@ -83,5 +74,6 @@ void sym_init(void)
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) {
@@ -91,3 +83,3 @@ int sym_get_type(struct symbol *sym)
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;
@@ -98,3 +90,3 @@ int sym_get_type(struct symbol *sym)
98 90
99const char *sym_type_name(int type) 91const char *sym_type_name(enum symbol_type type)
100{ 92{
@@ -113,2 +105,4 @@ const char *sym_type_name(int type)
113 return "unknown"; 105 return "unknown";
106 case S_OTHER:
107 break;
114 } 108 }
@@ -129,7 +123,6 @@ struct property *sym_get_default_prop(struct symbol *sym)
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;
@@ -139,14 +132,36 @@ struct property *sym_get_default_prop(struct symbol *sym)
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);
@@ -155,2 +170,41 @@ void sym_calc_visibility(struct symbol *sym)
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)
@@ -158,8 +212,11 @@ void sym_calc_value(struct symbol *sym)
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
@@ -178,13 +235,6 @@ void sym_calc_value(struct symbol *sym)
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))
@@ -197,86 +247,64 @@ void sym_calc_value(struct symbol *sym)
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
@@ -285,3 +313,3 @@ out:
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;
@@ -333,15 +361,9 @@ bool sym_tristate_within_range(struct symbol *sym, tristate val)
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}
@@ -360,9 +382,9 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
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) {
@@ -431,10 +453,47 @@ bool sym_string_valid(struct symbol *sym, const char *str)
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);
@@ -457,10 +516,7 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
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);
@@ -472,3 +528,3 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
472 528
473 if (!sym_string_valid(sym, newval)) 529 if (!sym_string_within_range(sym, newval))
474 return false; 530 return false;
@@ -480,3 +536,3 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
480 536
481 oldval = S_VAL(sym->def); 537 oldval = sym->user.val;
482 size = strlen(newval) + 1; 538 size = strlen(newval) + 1;
@@ -484,3 +540,3 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
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';
@@ -488,3 +544,3 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
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
@@ -519,3 +575,3 @@ const char *sym_get_string_value(struct symbol *sym)
519 } 575 }
520 return (const char *)S_VAL(sym->curr); 576 return (const char *)sym->curr.val;
521} 577}
@@ -524,11 +580,3 @@ bool 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}
@@ -610,2 +658,100 @@ struct symbol *sym_find(const char *name)
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)
@@ -619,4 +765,2 @@ const char *prop_get_type_name(enum prop_type type)
619 return "menu"; 765 return "menu";
620 case P_ROOTMENU:
621 return "rootmenu";
622 case P_DEFAULT: 766 case P_DEFAULT:
@@ -625,5 +769,10 @@ const char *prop_get_type_name(enum prop_type type)
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
@@ -98,2 +98,3 @@ n [A-Za-z0-9_]
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;
@@ -107,4 +108,7 @@ n [A-Za-z0-9_]
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;
@@ -112,2 +116,5 @@ n [A-Za-z0-9_]
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}+{
@@ -143,2 +150,3 @@ n [A-Za-z0-9_]
143 } 150 }
151 #.*/* comment */
144 \\\ncurrent_file->lineno++; 152 \\\ncurrent_file->lineno++;
@@ -154,3 +162,3 @@ n [A-Za-z0-9_]
154 zconflval.string = text; 162 zconflval.string = text;
155 return T_STRING; 163 return T_WORD_QUOTE;
156 } 164 }
@@ -162,3 +170,3 @@ n [A-Za-z0-9_]
162 zconflval.string = text; 170 zconflval.string = text;
163 return T_STRING; 171 return T_WORD_QUOTE;
164 } 172 }
@@ -171,3 +179,3 @@ n [A-Za-z0-9_]
171 zconflval.string = text; 179 zconflval.string = text;
172 return T_STRING; 180 return T_WORD_QUOTE;
173 } else 181 } else
@@ -208,5 +216,4 @@ n [A-Za-z0-9_]
208 } 216 }
209
210 } 217 }
211 \n/[^ \t\n] { 218 [ \t]*\n/[^ \t\n] {
212 current_file->lineno++; 219 current_file->lineno++;
@@ -250,3 +257,3 @@ static void zconf_endhelp(void)
250 zconflval.string = text; 257 zconflval.string = text;
251 BEGIN(INITIAL); 258 BEGIN(INITIAL);
252} 259}
@@ -254,3 +261,3 @@ static void zconf_endhelp(void)
254 261
255/* 262/*
256 * Try to open specified file with following names: 263 * Try to open specified file with following names:
@@ -347,3 +354,3 @@ int zconf_lineno(void)
347 if (current_buf) 354 if (current_buf)
348 return current_file->lineno; 355 return current_file->lineno - 1;
349 else 356 else
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
@@ -29,3 +29,3 @@ struct symbol *symbol_hash[257];
29%} 29%}
30%expect 36 30%expect 40
31 31
@@ -48,2 +48,3 @@ struct symbol *symbol_hash[257];
48%token T_CONFIG 48%token T_CONFIG
49%token T_MENUCONFIG
49%token T_HELP 50%token T_HELP
@@ -58,3 +59,6 @@ struct symbol *symbol_hash[257];
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
@@ -62,3 +66,3 @@ struct symbol *symbol_hash[257];
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
@@ -69,2 +73,4 @@ struct symbol *symbol_hash[257];
69%token T_ON 73%token T_ON
74%token T_SELECT
75%token T_RANGE
70 76
@@ -105,2 +111,3 @@ common_block:
105 | config_stmt 111 | config_stmt
112 | menuconfig_stmt
106 | source_stmt 113 | source_stmt
@@ -110,5 +117,5 @@ common_block:
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{
@@ -120,3 +127,3 @@ config_entry_start: T_CONFIG T_WORD
120 127
121config_stmt: config_entry_start T_EOL config_option_list 128config_stmt: config_entry_start config_option_list
122{ 129{
@@ -126,11 +133,29 @@ config_stmt: config_entry_start T_EOL config_option_list
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{
@@ -140,3 +165,10 @@ config_option: T_TRISTATE prompt_stmt_opt
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{
@@ -146,3 +178,10 @@ config_option: T_BOOLEAN prompt_stmt_opt
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{
@@ -152,3 +191,3 @@ config_option: T_INT prompt_stmt_opt
152 191
153config_option: T_HEX prompt_stmt_opt 192config_option: T_HEX prompt_stmt_opt T_EOL
154{ 193{
@@ -158,3 +197,3 @@ config_option: T_HEX prompt_stmt_opt
158 197
159config_option: T_STRING prompt_stmt_opt 198config_option: T_STRING prompt_stmt_opt T_EOL
160{ 199{
@@ -164,5 +203,5 @@ config_option: T_STRING prompt_stmt_opt
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());
@@ -170,5 +209,5 @@ config_option: T_PROMPT prompt if_expr
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());
@@ -176,5 +215,17 @@ config_option: T_DEFAULT symbol if_expr
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{
@@ -183,3 +234,3 @@ choice: T_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());
@@ -187,3 +238,3 @@ choice: T_CHOICE
187 238
188choice_entry: choice T_EOL choice_option_list 239choice_entry: choice choice_option_list
189{ 240{
@@ -202,3 +253,3 @@ choice_end: end
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
@@ -211,4 +262,4 @@ choice_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
@@ -217,5 +268,5 @@ choice_option_list:
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());
@@ -223,3 +274,15 @@ choice_option: T_PROMPT prompt if_expr
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{
@@ -229,5 +292,5 @@ choice_option: T_OPTIONAL
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());
@@ -242,3 +305,3 @@ choice_block:
242 305
243if: T_IF expr 306if: T_IF expr T_EOL
244{ 307{
@@ -260,4 +323,4 @@ if_end: end
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{
@@ -276,3 +339,3 @@ if_block:
276 339
277menu: T_MENU prompt 340menu: T_MENU prompt T_EOL
278{ 341{
@@ -283,3 +346,3 @@ menu: T_MENU prompt
283 346
284menu_entry: menu T_EOL depends_list 347menu_entry: menu depends_list
285{ 348{
@@ -298,3 +361,3 @@ menu_end: end
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
@@ -313,3 +376,3 @@ menu_block:
313 376
314source: T_SOURCE prompt 377source: T_SOURCE prompt T_EOL
315{ 378{
@@ -319,3 +382,3 @@ source: T_SOURCE prompt
319 382
320source_stmt: source T_EOL 383source_stmt: source
321{ 384{
@@ -326,3 +389,3 @@ source_stmt: source T_EOL
326 389
327comment: T_COMMENT prompt 390comment: T_COMMENT prompt T_EOL
328{ 391{
@@ -333,3 +396,3 @@ comment: T_COMMENT prompt
333 396
334comment_stmt: comment T_EOL depends_list 397comment_stmt: comment depends_list
335{ 398{
@@ -354,7 +417,7 @@ help: help_start T_HELPTEXT
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{
@@ -363,3 +426,3 @@ depends: T_DEPENDS T_ON expr
363} 426}
364 | T_DEPENDS expr 427 | T_DEPENDS expr T_EOL
365{ 428{
@@ -368,3 +431,3 @@ depends: T_DEPENDS T_ON expr
368} 431}
369 | T_REQUIRES expr 432 | T_REQUIRES expr T_EOL
370{ 433{
@@ -378,9 +441,5 @@ prompt_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};
@@ -388,8 +447,8 @@ prompt_stmt_opt:
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;
@@ -413,3 +472,3 @@ expr: symbol { $$ = expr_alloc_symbol($1); }
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;
@@ -420,2 +479,5 @@ void conf_parse(const char *name)
420{ 479{
480 struct symbol *sym;
481 int i;
482
421 zconf_initscan(name); 483 zconf_initscan(name);
@@ -424,3 +486,4 @@ void conf_parse(const char *name)
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
@@ -431,4 +494,8 @@ void conf_parse(const char *name)
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
@@ -448,3 +515,3 @@ const char *zconf_tokenname(int token)
448 return "<token>"; 515 return "<token>";
449} 516}
450 517
@@ -470,3 +537,3 @@ static void zconfprint(const char *err, ...)
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);
@@ -479,3 +546,3 @@ static 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}
@@ -504,4 +571,2 @@ void print_symbol(FILE *out, struct menu *menu)
504 571
505 //sym->flags |= SYMBOL_PRINTED;
506
507 if (sym_is_choice(sym)) 572 if (sym_is_choice(sym))
@@ -530,9 +595,2 @@ void print_symbol(FILE *out, struct menu *menu)
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) {
@@ -544,12 +602,5 @@ void print_symbol(FILE *out, struct menu *menu)
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 }
@@ -559,6 +610,6 @@ void print_symbol(FILE *out, struct menu *menu)
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 }
@@ -585,3 +636,2 @@ void zconfdump(FILE *out)
585{ 636{
586 //struct file *file;
587 struct property *prop; 637 struct property *prop;
@@ -596,7 +646,2 @@ void zconfdump(FILE *out)
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:
@@ -611,9 +656,2 @@ void zconfdump(FILE *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:
@@ -621,5 +659,5 @@ void zconfdump(FILE *out)
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);