summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--scripts/kconfig/Makefile110
-rw-r--r--scripts/kconfig/Makefile.kernel44
-rw-r--r--scripts/kconfig/conf.c7
-rw-r--r--scripts/kconfig/confdata.c74
-rw-r--r--scripts/kconfig/expr.h5
-rw-r--r--scripts/kconfig/kconfig.i5
-rw-r--r--scripts/kconfig/lkc.h5
-rw-r--r--scripts/kconfig/mconf.c101
-rw-r--r--scripts/kconfig/menu.c2
-rw-r--r--scripts/kconfig/qconf.cc274
-rw-r--r--scripts/kconfig/qconf.h59
-rw-r--r--scripts/kconfig/symbol.c35
-rw-r--r--scripts/kconfig/zconf.l72
-rw-r--r--scripts/kconfig/zconf.y6
14 files changed, 542 insertions, 257 deletions
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 7e257be..5a0d7e5 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -1,207 +1,181 @@
1VERSION=1.2 1VERSION=1.3
2CC=gcc 2CC=gcc
3CXX=g++ 3CXX=g++
4CFLAGS=-O2 -Wall -g -fPIC 4CFLAGS=-O0 -Wall -g -fPIC
5CXXFLAGS=$(CFLAGS) -I$(HOSTQTDIR)/include 5CXXFLAGS=$(CFLAGS) -I$(HOSTQTDIR)/include
6LDFLAGS= 6LDFLAGS=
7LXXFLAGS=$(LDFLAGS) -L$(HOSTQTDIR)/lib -Wl,-rpath,$(HOSTQTDIR)/lib 7LXXFLAGS=$(LDFLAGS) -L$(HOSTQTDIR)/lib -Wl,-rpath,$(HOSTQTDIR)/lib
8LEX=flex 8LEX=flex
9LFLAGS=-L
9YACC=bison 10YACC=bison
10YFLAGS=-d -t #-v 11YFLAGS=-l
12#YFLAGS=-d -t -v -l
11ifndef HOSTQTDIR 13ifndef HOSTQTDIR
12ifeq ($(shell if [ -e /usr/share/qt ]; then echo foundit; fi),foundit)
13HOSTQTDIR=/usr/share/qt 14HOSTQTDIR=/usr/share/qt
14else
15ifeq ($(shell if [ -e /usr/lib/qt ]; then echo foundit; fi),foundit)
16HOSTQTDIR=/usr/lib/qt
17endif
18endif
19endif
20
21ifndef QTLIB
22ifeq ($(shell if [ -e $(HOSTQTDIR)/lib/libqt-mt.so ]; then echo foundit; fi),foundit)
23QTLIB=-lqt-mt
24else
25ifneq ($(shell if [ -e $(HOSTQTDIR)/lib/libqt.so ]; then echo foundit; fi),foundit)
26$(warning Unable to locate libqt.so!)
27endif 15endif
28QTLIB=-lqt
29endif
30endif
31
32MOC=$(wildcard $(HOSTQTDIR)/bin/moc) 16MOC=$(wildcard $(HOSTQTDIR)/bin/moc)
33 17
34parse_SRC=zconf.y 18parse_SRC=zconf.y
35conf_SRC=conf.c $(parse_SRC) 19conf_SRC=conf.c $(parse_SRC)
36mconf_SRC=mconf.c $(parse_SRC) 20mconf_SRC=mconf.c $(parse_SRC)
37qconf_SRC=qconf.cc 21qconf_SRC=qconf.cc
38lkcc_SRC=cml1.y cml1.l help.l cml1.h expr1.c
39HDR=expr.h lkc.h lkc_proto.h qconf.h 22HDR=expr.h lkc.h lkc_proto.h qconf.h
40OTHER=README lkc_spec lkc_overview Makefile.kernel convert-all prepare-all.diff fixup-all.diff \ 23OTHER=README lkc-language.txt Makefile.kernel \
41 kconfig.i extconf.rb example 24 kconfig.i extconf.rb example
42INST=zconf.y zconf.l confdata.c expr.c symbol.c menu.c conf.c mconf.c qconf.cc kconfig_load.c images.c $(parse_SRC) $(HDR) 25INST=zconf.y zconf.l confdata.c expr.c symbol.c menu.c \
43INSTGEN=lex.zconf.c zconf.tab.c zconf.tab.h 26 conf.c mconf.c qconf.cc kconfig_load.c images.c $(HDR)
27INSTGEN=lex.zconf.c zconf.tab.c
44 28
45#DEBUG=1 29#DEBUG=1
46ifdef DEBUG 30ifdef DEBUG
47CFLAGS+=-DLKC_DIRECT_LINK 31CFLAGS+=-DLKC_DIRECT_LINK
48qconf_SRC+=$(parse_SRC) 32qconf_SRC+=$(parse_SRC)
49else 33else
50qconf_SRC+=kconfig_load.c 34qconf_SRC+=kconfig_load.c
51endif 35endif
52 36
53SRC=$(conf_SRC) $(mconf_SRC) $(qconf_SRC) $(lkcc_SRC) 37SRC=$(conf_SRC) $(mconf_SRC) $(qconf_SRC)
54CSRC=$(filter %.c, $(SRC)) 38CSRC=$(filter %.c, $(SRC))
55YSRC=$(filter %.y, $(SRC)) 39YSRC=$(filter %.y, $(SRC))
56LSRC=$(filter %.l, $(SRC)) 40LSRC=$(filter %.l, $(SRC))
57 41
58parse_OBJ=$(filter %.o, \ 42parse_OBJ=$(filter %.o, \
59 $(patsubst %.c,%.o, \ 43 $(patsubst %.c,%.o, \
60 $(patsubst %.y,%.tab.o, \ 44 $(patsubst %.y,%.tab.o, \
61 $(patsubst %.l,lex.%.o, \ 45 $(patsubst %.l,lex.%.o, \
62 $(parse_SRC))))) 46 $(parse_SRC)))))
63conf_OBJ=$(filter %.o, \ 47conf_OBJ=$(filter %.o, \
64 $(patsubst %.c,%.o, \ 48 $(patsubst %.c,%.o, \
65 $(patsubst %.y,%.tab.o, \ 49 $(patsubst %.y,%.tab.o, \
66 $(patsubst %.l,lex.%.o, \ 50 $(patsubst %.l,lex.%.o, \
67 $(conf_SRC))))) 51 $(conf_SRC)))))
68mconf_OBJ=$(filter %.o, \ 52mconf_OBJ=$(filter %.o, \
69 $(patsubst %.c,%.o, \ 53 $(patsubst %.c,%.o, \
70 $(patsubst %.y,%.tab.o, \ 54 $(patsubst %.y,%.tab.o, \
71 $(patsubst %.l,lex.%.o, \ 55 $(patsubst %.l,lex.%.o, \
72 $(mconf_SRC))))) 56 $(mconf_SRC)))))
73qconf_OBJ=$(filter %.o, \ 57qconf_OBJ=$(filter %.o, \
74 $(patsubst %.c,%.o, \ 58 $(patsubst %.c,%.o, \
75 $(patsubst %.cc,%.o, \ 59 $(patsubst %.cc,%.o, \
76 $(patsubst %.y,%.tab.o, \ 60 $(patsubst %.y,%.tab.o, \
77 $(patsubst %.l,lex.%.o, \ 61 $(patsubst %.l,lex.%.o, \
78 $(qconf_SRC)))))) 62 $(qconf_SRC))))))
79lkcc_OBJ=$(filter %.o, \ 63OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ)
80 $(patsubst %.c,%.o, \
81 $(patsubst %.y,%.tab.o, \
82 $(patsubst %.l,lex.%.o, \
83 $(lkcc_SRC)))))
84OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ) $(lkcc_OBJ)
85 64
86ifeq ($(MOC),) 65ifeq ($(MOC),)
87all: lkcc conf mconf 66all: conf mconf
88else 67else
89all: lkcc conf mconf qconf libkconfig.so 68all: conf mconf qconf libkconfig.so
90endif 69endif
91 70
92lex.help.c: help.l
93lex.help.o: lex.help.c cml1.h expr.h
94lex.cml1.c: cml1.l
95lex.cml1.o: lex.cml1.c cml1.tab.h cml1.h expr.h
96cml1.tab.c: cml1.y
97cml1.tab.h: cml1.y
98cml1.tab.o: cml1.tab.c cml1.h expr.h
99expr1.o: expr1.c expr.h
100
101lkc_deps := lkc.h lkc_proto.h lkc_defs.h expr.h 71lkc_deps := lkc.h lkc_proto.h lkc_defs.h expr.h
102 72
103zconf.tab.c: zconf.y 73zconf.tab.c: zconf.y
104zconf.tab.h: zconf.y 74zconf.tab.h: zconf.y
105lex.zconf.c: zconf.l 75lex.zconf.c: zconf.l
106zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(lkc_deps) 76zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(lkc_deps)
107#lex.zconf.o: lex.zconf.c zconf.tab.h $(lkc_deps) 77#lex.zconf.o: lex.zconf.c zconf.tab.h $(lkc_deps)
108#confdata.o: confdata.c $(lkc_deps) 78#confdata.o: confdata.c $(lkc_deps)
109#expr.o: expr.c $(lkc_deps) 79#expr.o: expr.c $(lkc_deps)
110#symbol.o: symbol.c $(lkc_deps) 80#symbol.o: symbol.c $(lkc_deps)
111#menu.o: menu.c $(lkc_deps) 81#menu.o: menu.c $(lkc_deps)
112kconfig_load.o: kconfig_load.c $(lkc_deps) 82kconfig_load.o: kconfig_load.c $(lkc_deps)
113conf.o: conf.c $(lkc_deps) 83conf.o: conf.c $(lkc_deps)
114mconf.o: mconf.c $(lkc_deps) 84mconf.o: mconf.c $(lkc_deps)
115qconf.moc: qconf.h 85qconf.moc: qconf.h
116qconf.o: qconf.cc qconf.moc images.c $(lkc_deps) 86qconf.o: qconf.cc qconf.moc images.c $(lkc_deps)
117 87
118mconf: $(mconf_OBJ) 88mconf: $(mconf_OBJ)
119 $(CC) $(LDFLAGS) $^ -o $@ 89 $(CC) $(LDFLAGS) $^ -o $@
120 90
121conf: $(conf_OBJ) 91conf: $(conf_OBJ)
122 $(CC) $(LDFLAGS) $^ -o $@ 92 $(CC) $(LDFLAGS) $^ -o $@
123 93
124ifeq ($(MOC),) 94ifeq ($(MOC),)
125qconf: 95qconf:
126 @echo Unable to find the QT installation. Please make sure that the 96 @echo Unable to find the QT installation. Please make sure that the
127 @echo QT development package is correctly installed and the HOSTQTDIR 97 @echo QT development package is correctly installed and the HOSTQTDIR
128 @echo environment variable is set to the correct location. 98 @echo environment variable is set to the correct location.
129 @false 99 @false
130else 100else
131qconf: $(qconf_OBJ) libkconfig.so 101qconf: $(qconf_OBJ)
132 $(CXX) $(LXXFLAGS) $^ $(QTLIB) -o $@ 102 $(CXX) $(LXXFLAGS) $^ -lqt -o $@
133endif 103endif
134 104
135lkcc: $(lkcc_OBJ)
136 $(CC) $(LDFLAGS) $^ -o $@
137
138libkconfig.so: $(parse_OBJ) 105libkconfig.so: $(parse_OBJ)
139 $(CC) -shared $^ -o $@ 106 $(CC) -shared $^ -o $@
140 107
141lkc_defs.h: lkc_proto.h 108lkc_defs.h: lkc_proto.h
142 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' 109 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
143 110
144clean: 111clean:
145 rm -f $(OBJ) lkcc conf qconf mconf *.moc lex.* *.tab.? *.output 112 rm -f $(OBJ) conf qconf mconf *.moc lex.* *.tab.? *.output
113 rm -rf .ruby .python
146 114
147tgz: 115tgz:
148 mkdir tmp 116 mkdir tmp
149 mkdir tmp/lkc-$(VERSION) 117 mkdir tmp/lkc-$(VERSION)
150 cp -ra Makefile $(sort $(SRC) $(HDR) $(OTHER) $(INST)) tmp/lkc-$(VERSION) 118 cp -ra Makefile $(sort $(SRC) $(HDR) $(OTHER) $(INST)) tmp/lkc-$(VERSION)
151 tar -cpvz -C tmp -f lkc-$(VERSION).tar.gz lkc-$(VERSION) 119 tar -cpvz -C tmp --exclude CVS -f lkc-$(VERSION).tar.gz lkc-$(VERSION)
152 rm -rf tmp 120 rm -rf tmp
153 121
154%.tab.c %.tab.h: %.y 122%.tab.c %.tab.h: %.y
155 $(YACC) $(YFLAGS) -b $* -p $* $< 123 $(YACC) $(YFLAGS) -b $* -p $* $<
156 124
157lex.%.c: %.l 125lex.%.c: %.l
158 $(LEX) $(LFLAGS) -P$* $< 126 $(LEX) $(LFLAGS) -P$* $<
159 127
160%.moc: %.h 128%.moc: %.h
161 $(HOSTQTDIR)/bin/moc -i $< -o $@ 129 $(HOSTQTDIR)/bin/moc -i $< -o $@
162 130
163%.o: %.c 131%.o: %.c
164 $(CC) $(CFLAGS) -c $< -o $@ 132 $(CC) $(CFLAGS) -c $< -o $@
165 133
166%.o: %.cc 134%.o: %.cc
167 $(CXX) $(CXXFLAGS) -c $< -o $@ 135 $(CXX) $(CXXFLAGS) -c $< -o $@
168 136
169ifdef KERNELSRC 137ifdef KERNELSRC
170install: lkcc $(INSTGEN) 138install: $(INSTGEN)
171 set -x; mkdir $(KERNELSRC)/scripts/kconfig; \ 139 set -x; cp $(sort $(INST)) $(KERNELSRC)/scripts/kconfig; \
172 cp $(sort $(INST)) $(KERNELSRC)/scripts/kconfig; \
173 for f in $(INSTGEN); do cp $$f $(KERNELSRC)/scripts/kconfig/$${f}_shipped; done; \ 140 for f in $(INSTGEN); do cp $$f $(KERNELSRC)/scripts/kconfig/$${f}_shipped; done; \
174 cp Makefile.kernel $(KERNELSRC)/scripts/kconfig/Makefile; \ 141 cp Makefile.kernel $(KERNELSRC)/scripts/kconfig/Makefile
175 LKCSRC=$$PWD; export LKCSRC; \ 142
176 cd $(KERNELSRC); \ 143diff: $(INSTGEN)
177 patch -p0 -N < $$LKCSRC/prepare-all.diff; \ 144 for f in $(sort $(INST)); do diff -u $(KERNELSRC)/scripts/kconfig/$$f $$f; done; \
178 sh $$LKCSRC/convert-all; \ 145 for f in $(INSTGEN); do diff -u $(KERNELSRC)/scripts/kconfig/$${f}_shipped $$f; done; \
179 patch -p0 -N < $$LKCSRC/fixup-all.diff 146 diff -u $(KERNELSRC)/scripts/kconfig/Makefile Makefile.kernel
180
181 #cp Makefile $(KERNELSRC)/scripts/kconfig/Makefile; \
182
183uninstall:
184 patch -p0 -N -R -d $(KERNELSRC) < prepare-all.diff; \
185 cd $(KERNELSRC); \
186 find -name "Kconfig*" | xargs rm; \
187 rm -rf scripts/kconfig log.*
188else 147else
189install: 148install:
190 @echo "Please use KERNELSRC=<path/to/linux-kernel> to install" 149 @echo "Please use KERNELSRC=<path/to/linux-kernel> to install"
191endif 150endif
192 151
193ruby: .ruby libkconfig.so .ruby/kconfig.so 152ruby: .ruby libkconfig.so .ruby/kconfig.so
194 153
195.ruby: 154.ruby:
196 mkdir .ruby 155 mkdir .ruby
197 156
198.ruby/kconfig_wrap.c: kconfig.i kconfig_load.c expr.h lkc_proto.h 157.ruby/kconfig_wrap.c: kconfig.i kconfig_load.c expr.h lkc_proto.h
199 swig -ruby -o $@ $< 158 swig -ruby -o $@ $<
200 159
201.ruby/Makefile: extconf.rb 160.ruby/Makefile: extconf.rb
202 cd .ruby; ruby ../extconf.rb 161 cd .ruby; ruby ../extconf.rb
203 162
204.ruby/kconfig.so: .ruby/kconfig_wrap.c .ruby/Makefile 163.ruby/kconfig.so: .ruby/kconfig_wrap.c .ruby/Makefile
205 make -C .ruby 164 make -C .ruby
206 165
207.PHONY: all tgz clean ruby 166
167PYTHON_INCLUDE=$(shell python -c "import sys; print '-I'+sys.prefix+'/include/python'+sys.version[:3]")
168
169python: .python .python/kconfig.py .python/_kconfig.so
170
171.python:
172 mkdir .python
173
174.python/kconfig_wrap.c .python/kconfig.py: kconfig.i kconfig_load.c expr.h lkc_proto.h
175 swig -python -o .python/kconfig_wrap.c kconfig.i
176
177.python/_kconfig.so: .python/kconfig_wrap.c
178 cd .python; $(CC) $(CFLAGS) -shared kconfig_wrap.c -o _kconfig.so -I.. $(PYTHON_INCLUDE)
179
180
181.PHONY: all tgz clean ruby python
diff --git a/scripts/kconfig/Makefile.kernel b/scripts/kconfig/Makefile.kernel
index beb4dcf..22724a7 100644
--- a/scripts/kconfig/Makefile.kernel
+++ b/scripts/kconfig/Makefile.kernel
@@ -1,85 +1,95 @@
1################# 1#################
2# 2#
3# Shared Makefile for the various lkc executables: 3# Shared Makefile for the various lkc executables:
4 # conf: Used for defconfig, oldconfig and related targets 4 # conf: Used for defconfig, oldconfig and related targets
5# mconf: Used for the mconfig target. 5# mconf: Used for the mconfig target.
6# Utilizes the lxdialog package 6# Utilizes the lxdialog package
7# qconf: Used for the xconfig target 7# qconf: Used for the xconfig target
8# Based on QT which needs to be installed to compile it 8# Based on QT which needs to be installed to compile it
9# 9#
10 10
11# object files used by all lkc flavours 11# object files used by all lkc flavours
12libkconfig-objs := zconf.tab.o 12libkconfig-objs := zconf.tab.o
13 13
14 host-progs:= conf mconf qconf 14 host-progs:= conf mconf qconf
15 conf-objs:= conf.o libkconfig.so 15 conf-objs:= conf.o libkconfig.so
16 mconf-objs:= mconf.o libkconfig.so 16 mconf-objs:= mconf.o libkconfig.so
17 17
18 qconf-objs:= kconfig_load.o 18 qconf-objs:= kconfig_load.o
19 qconf-cxxobjs:= qconf.o 19 qconf-cxxobjs:= qconf.o
20 20
21 clean-files:= libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \ 21 clean-files:= libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \
22 zconf.tab.c zconf.tab.h lex.zconf.c 22 zconf.tab.c zconf.tab.h lex.zconf.c
23 23
24include $(TOPDIR)/Rules.make 24include $(TOPDIR)/Rules.make
25 25
26# QT needs some extra effort...
27ifndef QTDIR
28 QTDIR := /usr/share/qt
29endif
30
31# Executable to generate the .moc file
32MOC=$(wildcard $(QTDIR)/bin/moc)
33
34# generated files seem to need this to find local include files 26# generated files seem to need this to find local include files
35 HOSTCFLAGS_lex.zconf.o:= -I$(src) 27 HOSTCFLAGS_lex.zconf.o:= -I$(src)
36 HOSTCFLAGS_zconf.tab.o:= -I$(src) 28 HOSTCFLAGS_zconf.tab.o:= -I$(src)
37 29
38 HOSTLOADLIBES_qconf:= -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib -lqt -ldl 30 HOSTLOADLIBES_qconf= -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib -l$(QTLIB) -ldl
39 HOSTCXXFLAGS_qconf.o:= -I$(QTDIR)/include 31 HOSTCXXFLAGS_qconf.o= -I$(QTDIR)/include
40 32
41$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o: $(obj)/zconf.tab.h 33$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o: $(obj)/zconf.tab.h
42 34
43$(obj)/qconf.o: $(obj)/.tmp_qtcheck 35$(obj)/qconf.o: $(obj)/.tmp_qtcheck
44 36
37ifeq ($(MAKECMDGOALS),$(obj)/qconf)
38MOC = $(QTDIR)/bin/moc
39-include $(obj)/.tmp_qtcheck
40
41# QT needs some extra effort...
45$(obj)/.tmp_qtcheck: 42$(obj)/.tmp_qtcheck:
46ifeq ($(MOC),) 43 @set -e; for d in $$QTDIR /usr/share/qt /usr/lib/qt3; do \
47 @echo Unable to find the QT installation. Please make sure that the 44 if [ -f $$d/include/qconfig.h ]; then DIR=$$d; break; fi; \
48 @echo QT development package is correctly installed and the QTDIR 45 done; \
49 @echo environment variable is set to the correct location. 46 if [ -z "$$DIR" ]; then \
50 @false 47 echo "*"; \
51else 48 echo "* Unable to find the QT installation. Please make sure that the"; \
52 @touch $@ 49 echo "* QT development package is correctly installed and the QTDIR"; \
50 echo "* environment variable is set to the correct location."; \
51 echo "*"; \
52 false; \
53 fi; \
54 LIB=qt; \
55 if [ -f $$DIR/lib/libqt-mt.so ]; then LIB=qt-mt; fi; \
56 echo "QTDIR=$$DIR" > $@; echo "QTLIB=$$LIB" >> $@; \
57 if [ ! -x $$DIR/bin/moc -a -x /usr/bin/moc ]; then \
58 echo "*"; \
59 echo "* Unable to find $$DIR/bin/moc, using /usr/bin/moc instead."; \
60 echo "*"; \
61 echo "MOC=/usr/bin/moc" >> $@; \
62 fi
53endif 63endif
54 64
55$(obj)/zconf.tab.o: $(obj)/lex.zconf.c 65$(obj)/zconf.tab.o: $(obj)/lex.zconf.c
56 66
57$(obj)/kconfig_load.o: $(obj)/lkc_defs.h 67$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
58 68
59$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h 69$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h
60 70
61$(obj)/%.moc: $(src)/%.h 71$(obj)/%.moc: $(src)/%.h
62 $(MOC) -i $< -o $@ 72 $(MOC) -i $< -o $@
63 73
64$(obj)/lkc_defs.h: $(src)/lkc_proto.h 74$(obj)/lkc_defs.h: $(src)/lkc_proto.h
65 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' 75 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
66 76
67 77
68### 78###
69# The following requires flex/bison 79# The following requires flex/bison
70# By default we use the _shipped versions, uncomment the following line if 80# By default we use the _shipped versions, uncomment the following line if
71# you are modifying the flex/bison src. 81# you are modifying the flex/bison src.
72# LKC_GENPARSER := 1 82# LKC_GENPARSER := 1
73 83
74ifdef LKC_GENPARSER 84ifdef LKC_GENPARSER
75 85
76$(obj)/zconf.tab.c: $(obj)/zconf.y 86$(obj)/zconf.tab.c: $(obj)/zconf.y
77$(obj)/zconf.tab.h: $(obj)/zconf.tab.c 87$(obj)/zconf.tab.h: $(obj)/zconf.tab.c
78 88
79%.tab.c: %.y 89%.tab.c: %.y
80 bison -t -d -v -b $* -p $(notdir $*) $< 90 bison -t -d -v -b $* -p $(notdir $*) $<
81 91
82lex.%.c: %.l 92lex.%.c: %.l
83 flex -P$(notdir $*) -o$@ $< 93 flex -P$(notdir $*) -o$@ $<
84 94
85endif 95endif
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 74c94c2..1602d5f 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -70,96 +70,97 @@ static void printo(const char *o)
70 putchar(' '); 70 putchar(' ');
71 sep = 0; 71 sep = 0;
72 } else 72 } else
73 printf("%s", o); 73 printf("%s", o);
74} 74}
75 75
76static void strip(char *str) 76static void strip(char *str)
77{ 77{
78 char *p = str; 78 char *p = str;
79 int l; 79 int l;
80 80
81 while ((isspace(*p))) 81 while ((isspace(*p)))
82 p++; 82 p++;
83 l = strlen(p); 83 l = strlen(p);
84 if (p != str) 84 if (p != str)
85 memmove(str, p, l + 1); 85 memmove(str, p, l + 1);
86 if (!l) 86 if (!l)
87 return; 87 return;
88 p = str + l - 1; 88 p = str + l - 1;
89 while ((isspace(*p))) 89 while ((isspace(*p)))
90 *p-- = 0; 90 *p-- = 0;
91} 91}
92 92
93static void conf_askvalue(struct symbol *sym, const char *def) 93static void conf_askvalue(struct symbol *sym, const char *def)
94{ 94{
95 enum symbol_type type = sym_get_type(sym); 95 enum symbol_type type = sym_get_type(sym);
96 tristate val; 96 tristate val;
97 97
98 if (!sym_has_value(sym)) 98 if (!sym_has_value(sym))
99 printf("(NEW) "); 99 printf("(NEW) ");
100 100
101 line[0] = '\n'; 101 line[0] = '\n';
102 line[1] = 0; 102 line[1] = 0;
103 103
104 switch (input_mode) { 104 switch (input_mode) {
105 case ask_new: 105 case ask_new:
106 case ask_silent: 106 case ask_silent:
107 if (sym_has_value(sym)) { 107 if (sym_has_value(sym)) {
108 printf("%s\n", def); 108 printf("%s\n", def);
109 return; 109 return;
110 } 110 }
111 if (!valid_stdin && input_mode == ask_silent) { 111 if (!valid_stdin && input_mode == ask_silent) {
112 printf("aborted!\n\n"); 112 printf("aborted!\n\n");
113 printf("Console input/output is redirected. "); 113 printf("Console input/output is redirected. ");
114 printf("Run 'make oldconfig' to update configuration.\n\n"); 114 printf("Run 'make oldconfig' to update configuration.\n\n");
115 exit(1); 115 exit(1);
116 } 116 }
117 case ask_all: 117 case ask_all:
118 fflush(stdout);
118 fgets(line, 128, stdin); 119 fgets(line, 128, stdin);
119 return; 120 return;
120 case set_default: 121 case set_default:
121 printf("%s\n", def); 122 printf("%s\n", def);
122 return; 123 return;
123 default: 124 default:
124 break; 125 break;
125 } 126 }
126 127
127 switch (type) { 128 switch (type) {
128 case S_INT: 129 case S_INT:
129 case S_HEX: 130 case S_HEX:
130 case S_STRING: 131 case S_STRING:
131 printf("%s\n", def); 132 printf("%s\n", def);
132 return; 133 return;
133 default: 134 default:
134 ; 135 ;
135 } 136 }
136 switch (input_mode) { 137 switch (input_mode) {
137 case set_yes: 138 case set_yes:
138 if (sym_tristate_within_range(sym, yes)) { 139 if (sym_tristate_within_range(sym, yes)) {
139 line[0] = 'y'; 140 line[0] = 'y';
140 line[1] = '\n'; 141 line[1] = '\n';
141 line[2] = 0; 142 line[2] = 0;
142 break; 143 break;
143 } 144 }
144 case set_mod: 145 case set_mod:
145 if (type == S_TRISTATE) { 146 if (type == S_TRISTATE) {
146 if (sym_tristate_within_range(sym, mod)) { 147 if (sym_tristate_within_range(sym, mod)) {
147 line[0] = 'm'; 148 line[0] = 'm';
148 line[1] = '\n'; 149 line[1] = '\n';
149 line[2] = 0; 150 line[2] = 0;
150 break; 151 break;
151 } 152 }
152 } else { 153 } else {
153 if (sym_tristate_within_range(sym, yes)) { 154 if (sym_tristate_within_range(sym, yes)) {
154 line[0] = 'y'; 155 line[0] = 'y';
155 line[1] = '\n'; 156 line[1] = '\n';
156 line[2] = 0; 157 line[2] = 0;
157 break; 158 break;
158 } 159 }
159 } 160 }
160 case set_no: 161 case set_no:
161 if (sym_tristate_within_range(sym, no)) { 162 if (sym_tristate_within_range(sym, no)) {
162 line[0] = 'n'; 163 line[0] = 'n';
163 line[1] = '\n'; 164 line[1] = '\n';
164 line[2] = 0; 165 line[2] = 0;
165 break; 166 break;
@@ -297,119 +298,121 @@ static int conf_choice(struct menu *menu)
297 const char *help; 298 const char *help;
298 int type, len; 299 int type, len;
299 bool is_new; 300 bool is_new;
300 301
301 sym = menu->sym; 302 sym = menu->sym;
302 type = sym_get_type(sym); 303 type = sym_get_type(sym);
303 is_new = !sym_has_value(sym); 304 is_new = !sym_has_value(sym);
304 if (sym_is_changable(sym)) { 305 if (sym_is_changable(sym)) {
305 conf_sym(menu); 306 conf_sym(menu);
306 sym_calc_value(sym); 307 sym_calc_value(sym);
307 switch (sym_get_tristate_value(sym)) { 308 switch (sym_get_tristate_value(sym)) {
308 case no: 309 case no:
309 return 1; 310 return 1;
310 case mod: 311 case mod:
311 return 0; 312 return 0;
312 case yes: 313 case yes:
313 break; 314 break;
314 } 315 }
315 } else { 316 } else {
316 sym->def = sym->curr; 317 sym->def = sym->curr;
317 if (S_TRI(sym->curr) == mod) { 318 if (S_TRI(sym->curr) == mod) {
318 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 319 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
319 return 0; 320 return 0;
320 } 321 }
321 } 322 }
322 323
323 while (1) { 324 while (1) {
324 printf("%*s%s ", indent - 1, "", menu_get_prompt(menu)); 325 printf("%*s%s ", indent - 1, "", menu_get_prompt(menu));
325 def_sym = sym_get_choice_value(sym); 326 def_sym = sym_get_choice_value(sym);
326 def_menu = NULL; 327 def_menu = NULL;
327 for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { 328 for (cmenu = menu->list; cmenu; cmenu = cmenu->next) {
328 if (!menu_is_visible(cmenu)) 329 if (!menu_is_visible(cmenu))
329 continue; 330 continue;
330 printo(menu_get_prompt(cmenu)); 331 printo(menu_get_prompt(cmenu));
331 if (cmenu->sym == def_sym) 332 if (cmenu->sym == def_sym)
332 def_menu = cmenu; 333 def_menu = cmenu;
333 } 334 }
334 printo(NULL); 335 printo(NULL);
335 if (def_menu) 336 if (def_menu)
336 printf("[%s] ", menu_get_prompt(def_menu)); 337 printf("[%s] ", menu_get_prompt(def_menu));
337 else { 338 else {
338 printf("\n"); 339 printf("\n");
339 return 1; 340 return 1;
340 } 341 }
341 switch (input_mode) { 342 switch (input_mode) {
342 case ask_new: 343 case ask_new:
343 case ask_silent: 344 case ask_silent:
344 case ask_all: 345 case ask_all:
346 if (is_new)
347 sym->flags |= SYMBOL_NEW;
345 conf_askvalue(sym, menu_get_prompt(def_menu)); 348 conf_askvalue(sym, menu_get_prompt(def_menu));
346 strip(line); 349 strip(line);
347 break; 350 break;
348 default: 351 default:
349 line[0] = 0; 352 line[0] = 0;
350 printf("\n"); 353 printf("\n");
351 } 354 }
352 if (line[0] == '?' && !line[1]) { 355 if (line[0] == '?' && !line[1]) {
353 help = nohelp_text; 356 help = nohelp_text;
354 if (menu->sym->help) 357 if (menu->sym->help)
355 help = menu->sym->help; 358 help = menu->sym->help;
356 printf("\n%s\n", help); 359 printf("\n%s\n", help);
357 continue; 360 continue;
358 } 361 }
359 if (line[0]) { 362 if (line[0]) {
360 len = strlen(line) - 1; 363 len = strlen(line);
361 line[len] = 0; 364 line[len] = 0;
362 365
363 def_menu = NULL; 366 def_menu = NULL;
364 for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { 367 for (cmenu = menu->list; cmenu; cmenu = cmenu->next) {
365 if (!cmenu->sym || !menu_is_visible(cmenu)) 368 if (!cmenu->sym || !menu_is_visible(cmenu))
366 continue; 369 continue;
367 if (!strncmp(line, menu_get_prompt(cmenu), len)) { 370 if (!strncasecmp(line, menu_get_prompt(cmenu), len)) {
368 def_menu = cmenu; 371 def_menu = cmenu;
369 break; 372 break;
370 } 373 }
371 } 374 }
372 } 375 }
373 if (def_menu) { 376 if (def_menu) {
374 sym_set_choice_value(sym, def_menu->sym); 377 sym_set_choice_value(sym, def_menu->sym);
375 if (def_menu->list) { 378 if (def_menu->list) {
376 indent += 2; 379 indent += 2;
377 conf(def_menu->list); 380 conf(def_menu->list);
378 indent -= 2; 381 indent -= 2;
379 } 382 }
380 return 1; 383 return 1;
381 } 384 }
382 } 385 }
383} 386}
384 387
385static void conf(struct menu *menu) 388static void conf(struct menu *menu)
386{ 389{
387 struct symbol *sym; 390 struct symbol *sym;
388 struct property *prop; 391 struct property *prop;
389 struct menu *child; 392 struct menu *child;
390 393
391 if (!menu_is_visible(menu)) 394 if (!menu_is_visible(menu))
392 return; 395 return;
393 396
394 sym = menu->sym; 397 sym = menu->sym;
395 prop = menu->prompt; 398 prop = menu->prompt;
396 if (prop) { 399 if (prop) {
397 const char *prompt; 400 const char *prompt;
398 401
399 switch (prop->type) { 402 switch (prop->type) {
400 case P_MENU: 403 case P_MENU:
401 if (input_mode == ask_silent && rootEntry != menu) { 404 if (input_mode == ask_silent && rootEntry != menu) {
402 check_conf(menu); 405 check_conf(menu);
403 return; 406 return;
404 } 407 }
405 case P_COMMENT: 408 case P_COMMENT:
406 prompt = menu_get_prompt(menu); 409 prompt = menu_get_prompt(menu);
407 if (prompt) 410 if (prompt)
408 printf("%*c\n%*c %s\n%*c\n", 411 printf("%*c\n%*c %s\n%*c\n",
409 indent, '*', 412 indent, '*',
410 indent, '*', prompt, 413 indent, '*', prompt,
411 indent, '*'); 414 indent, '*');
412 default: 415 default:
413 ; 416 ;
414 } 417 }
415 } 418 }
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 0f5fd97..9bf7af9 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -1,224 +1,243 @@
1/* 1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#include <sys/stat.h>
6#include <ctype.h> 7#include <ctype.h>
7#include <limits.h>
8#include <stdio.h> 8#include <stdio.h>
9#include <stdlib.h> 9#include <stdlib.h>
10#include <string.h> 10#include <string.h>
11#include <unistd.h> 11#include <unistd.h>
12 12
13#define LKC_DIRECT_LINK 13#define LKC_DIRECT_LINK
14#include "lkc.h" 14#include "lkc.h"
15 15
16const char conf_def_filename[] = ".config"; 16const char conf_def_filename[] = ".config";
17char conf_filename[PATH_MAX+1];
18 17
19const char conf_defname[] = "arch/$ARCH/defconfig"; 18const char conf_defname[] = "arch/$ARCH/defconfig";
20 19
21const char *conf_confnames[] = { 20const char *conf_confnames[] = {
22 ".config", 21 ".config",
23 "/lib/modules/$UNAME_RELEASE/.config", 22 "/lib/modules/$UNAME_RELEASE/.config",
24 "/etc/kernel-config", 23 "/etc/kernel-config",
25 "/boot/config-$UNAME_RELEASE", 24 "/boot/config-$UNAME_RELEASE",
26 conf_defname, 25 conf_defname,
27 NULL, 26 NULL,
28}; 27};
29 28
30static char *conf_expand_value(const char *in) 29static char *conf_expand_value(const char *in)
31{ 30{
32 struct symbol *sym; 31 struct symbol *sym;
33 const char *src; 32 const char *src;
34 static char res_value[SYMBOL_MAXLENGTH]; 33 static char res_value[SYMBOL_MAXLENGTH];
35 char *dst, name[SYMBOL_MAXLENGTH]; 34 char *dst, name[SYMBOL_MAXLENGTH];
36 35
37 res_value[0] = 0; 36 res_value[0] = 0;
38 dst = name; 37 dst = name;
39 while ((src = strchr(in, '$'))) { 38 while ((src = strchr(in, '$'))) {
40 strncat(res_value, in, src - in); 39 strncat(res_value, in, src - in);
41 src++; 40 src++;
42 dst = name; 41 dst = name;
43 while (isalnum(*src) || *src == '_') 42 while (isalnum(*src) || *src == '_')
44 *dst++ = *src++; 43 *dst++ = *src++;
45 *dst = 0; 44 *dst = 0;
46 sym = sym_lookup(name, 0); 45 sym = sym_lookup(name, 0);
47 sym_calc_value(sym); 46 sym_calc_value(sym);
48 strcat(res_value, sym_get_string_value(sym)); 47 strcat(res_value, sym_get_string_value(sym));
49 in = src; 48 in = src;
50 } 49 }
51 strcat(res_value, in); 50 strcat(res_value, in);
52 51
53 return res_value; 52 return res_value;
54} 53}
55 54
56char *conf_get_default_confname(void) 55char *conf_get_default_confname(void)
57{ 56{
58 return conf_expand_value(conf_defname); 57 struct stat buf;
58 static char fullname[PATH_MAX+1];
59 char *env, *name;
60
61 name = conf_expand_value(conf_defname);
62 env = getenv(SRCTREE);
63 if (env) {
64 sprintf(fullname, "%s/%s", env, name);
65 if (!stat(fullname, &buf))
66 return fullname;
67 }
68 return name;
59} 69}
60 70
61int conf_read(const char *name) 71int conf_read(const char *name)
62{ 72{
63 FILE *in = NULL; 73 FILE *in = NULL;
64 char line[128]; 74 char line[1024];
65 char *p, *p2; 75 char *p, *p2;
66 int lineno = 0; 76 int lineno = 0;
67 struct symbol *sym; 77 struct symbol *sym;
68 struct property *prop; 78 struct property *prop;
69 struct expr *e; 79 struct expr *e;
70 int i; 80 int i;
71 81
72 if (name) { 82 if (name) {
73 in = fopen(name, "r"); 83 in = zconf_fopen(name);
74 if (in)
75 strcpy(conf_filename, name);
76 } else { 84 } else {
77 const char **names = conf_confnames; 85 const char **names = conf_confnames;
78 while ((name = *names++)) { 86 while ((name = *names++)) {
79 name = conf_expand_value(name); 87 name = conf_expand_value(name);
80 in = fopen(name, "r"); 88 in = zconf_fopen(name);
81 if (in) { 89 if (in) {
82 printf("#\n" 90 printf("#\n"
83 "# using defaults found in %s\n" 91 "# using defaults found in %s\n"
84 "#\n", name); 92 "#\n", name);
85 break; 93 break;
86 } 94 }
87 } 95 }
88 } 96 }
89 97
90 if (!in) 98 if (!in)
91 return 1; 99 return 1;
92 100
93 for_all_symbols(i, sym) { 101 for_all_symbols(i, sym) {
94 sym->flags |= SYMBOL_NEW; 102 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
103 sym->flags &= ~SYMBOL_VALID;
95 switch (sym->type) { 104 switch (sym->type) {
96 case S_INT: 105 case S_INT:
97 case S_HEX: 106 case S_HEX:
98 case S_STRING: 107 case S_STRING:
99 if (S_VAL(sym->def)) { 108 if (S_VAL(sym->def))
100 free(S_VAL(sym->def)); 109 free(S_VAL(sym->def));
101 S_VAL(sym->def) = NULL;
102 }
103 default: 110 default:
104 ; 111 S_VAL(sym->def) = NULL;
112 S_TRI(sym->def) = no;
105 } 113 }
106 } 114 }
107 115
108 while (fgets(line, 128, in)) { 116 while (fgets(line, sizeof(line), in)) {
109 lineno++; 117 lineno++;
110 switch (line[0]) { 118 switch (line[0]) {
111 case '#': 119 case '#':
112 if (memcmp(line + 2, "CONFIG_", 7)) 120 if (memcmp(line + 2, "CONFIG_", 7))
113 continue; 121 continue;
114 p = strchr(line + 9, ' '); 122 p = strchr(line + 9, ' ');
115 if (!p) 123 if (!p)
116 continue; 124 continue;
117 *p++ = 0; 125 *p++ = 0;
118 if (strncmp(p, "is not set", 10)) 126 if (strncmp(p, "is not set", 10))
119 continue; 127 continue;
120 //printf("%s -> n\n", line + 9);
121 sym = sym_lookup(line + 9, 0); 128 sym = sym_lookup(line + 9, 0);
122 switch (sym->type) { 129 switch (sym->type) {
123 case S_BOOLEAN: 130 case S_BOOLEAN:
124 case S_TRISTATE: 131 case S_TRISTATE:
125 sym->def = symbol_no.curr; 132 sym->def = symbol_no.curr;
126 sym->flags &= ~SYMBOL_NEW; 133 sym->flags &= ~SYMBOL_NEW;
127 break; 134 break;
128 default: 135 default:
129 ; 136 ;
130 } 137 }
131 break; 138 break;
132 case 'C': 139 case 'C':
133 if (memcmp(line, "CONFIG_", 7)) 140 if (memcmp(line, "CONFIG_", 7))
134 continue; 141 continue;
135 p = strchr(line + 7, '='); 142 p = strchr(line + 7, '=');
136 if (!p) 143 if (!p)
137 continue; 144 continue;
138 *p++ = 0; 145 *p++ = 0;
139 p2 = strchr(p, '\n'); 146 p2 = strchr(p, '\n');
140 if (p2) 147 if (p2)
141 *p2 = 0; 148 *p2 = 0;
142 //printf("%s -> %s\n", line + 7, p);
143 sym = sym_find(line + 7); 149 sym = sym_find(line + 7);
144 if (!sym) { 150 if (!sym) {
145 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7); 151 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
146 break; 152 break;
147 } 153 }
148 switch (sym->type) { 154 switch (sym->type) {
149 case S_BOOLEAN:
150 sym->def = symbol_yes.curr;
151 sym->flags &= ~SYMBOL_NEW;
152 break;
153 case S_TRISTATE: 155 case S_TRISTATE:
154 if (p[0] == 'm') 156 if (p[0] == 'm') {
155 sym->def = symbol_mod.curr; 157 S_TRI(sym->def) = mod;
156 else 158 sym->flags &= ~SYMBOL_NEW;
157 sym->def = symbol_yes.curr; 159 break;
158 sym->flags &= ~SYMBOL_NEW; 160 }
161 case S_BOOLEAN:
162 if (p[0] == 'y') {
163 S_TRI(sym->def) = yes;
164 sym->flags &= ~SYMBOL_NEW;
165 break;
166 }
167 if (p[0] == 'n') {
168 S_TRI(sym->def) = no;
169 sym->flags &= ~SYMBOL_NEW;
170 break;
171 }
159 break; 172 break;
160 case S_STRING: 173 case S_STRING:
161 if (*p++ != '"') 174 if (*p++ != '"')
162 break; 175 break;
163 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 176 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
164 if (*p2 == '"') { 177 if (*p2 == '"') {
165 *p2 = 0; 178 *p2 = 0;
166 break; 179 break;
167 } 180 }
168 memmove(p2, p2 + 1, strlen(p2)); 181 memmove(p2, p2 + 1, strlen(p2));
169 } 182 }
183 if (!p2) {
184 fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
185 exit(1);
186 }
170 case S_INT: 187 case S_INT:
171 case S_HEX: 188 case S_HEX:
172 if (sym_string_valid(sym, p)) { 189 if (sym_string_valid(sym, p)) {
173 S_VAL(sym->def) = strdup(p); 190 S_VAL(sym->def) = strdup(p);
174 sym->flags &= ~SYMBOL_NEW; 191 sym->flags &= ~SYMBOL_NEW;
175 } else 192 } else {
176 fprintf(stderr, "%s:%d:symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); 193 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
194 exit(1);
195 }
177 break; 196 break;
178 default: 197 default:
179 ; 198 ;
180 } 199 }
181 if (sym_is_choice_value(sym)) { 200 if (sym_is_choice_value(sym)) {
182 prop = sym_get_choice_prop(sym); 201 prop = sym_get_choice_prop(sym);
183 switch (S_TRI(sym->def)) { 202 switch (S_TRI(sym->def)) {
184 case mod: 203 case mod:
185 if (S_TRI(prop->def->def) == yes) 204 if (S_TRI(prop->def->def) == yes)
186 /* warn? */; 205 /* warn? */;
187 break; 206 break;
188 case yes: 207 case yes:
189 if (S_TRI(prop->def->def) != no) 208 if (S_TRI(prop->def->def) != no)
190 /* warn? */; 209 /* warn? */;
191 S_VAL(prop->def->def) = sym; 210 S_VAL(prop->def->def) = sym;
192 break; 211 break;
193 case no: 212 case no:
194 break; 213 break;
195 } 214 }
196 S_TRI(prop->def->def) = S_TRI(sym->def); 215 S_TRI(prop->def->def) = S_TRI(sym->def);
197 } 216 }
198 break; 217 break;
199 case '\n': 218 case '\n':
200 break; 219 break;
201 default: 220 default:
202 continue; 221 continue;
203 } 222 }
204 } 223 }
205 fclose(in); 224 fclose(in);
206 225
207 for_all_symbols(i, sym) { 226 for_all_symbols(i, sym) {
208 if (!sym_is_choice(sym)) 227 if (!sym_is_choice(sym))
209 continue; 228 continue;
210 prop = sym_get_choice_prop(sym); 229 prop = sym_get_choice_prop(sym);
211 sym->flags &= ~SYMBOL_NEW; 230 sym->flags &= ~SYMBOL_NEW;
212 for (e = prop->dep; e; e = e->left.expr) 231 for (e = prop->dep; e; e = e->left.expr)
213 sym->flags |= e->right.sym->flags & SYMBOL_NEW; 232 sym->flags |= e->right.sym->flags & SYMBOL_NEW;
214 } 233 }
215 234
216 sym_change_count = 1; 235 sym_change_count = 1;
217 236
218 return 0; 237 return 0;
219} 238}
220 239
221int conf_write(const char *name) 240int conf_write(const char *name)
222{ 241{
223 FILE *out, *out_h; 242 FILE *out, *out_h;
224 struct symbol *sym; 243 struct symbol *sym;
@@ -307,54 +326,53 @@ int conf_write(const char *name)
307 } 326 }
308 } while (*str); 327 } while (*str);
309 fputs("\"\n", out); 328 fputs("\"\n", out);
310 fputs("\"\n", out_h); 329 fputs("\"\n", out_h);
311 break; 330 break;
312 case S_HEX: 331 case S_HEX:
313 str = sym_get_string_value(sym); 332 str = sym_get_string_value(sym);
314 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 333 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
315 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 334 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
316 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); 335 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
317 break; 336 break;
318 } 337 }
319 case S_INT: 338 case S_INT:
320 str = sym_get_string_value(sym); 339 str = sym_get_string_value(sym);
321 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 340 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
322 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); 341 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
323 break; 342 break;
324 } 343 }
325 } 344 }
326 345
327 next: 346 next:
328 if (menu->list) { 347 if (menu->list) {
329 menu = menu->list; 348 menu = menu->list;
330 continue; 349 continue;
331 } 350 }
332 if (menu->next) 351 if (menu->next)
333 menu = menu->next; 352 menu = menu->next;
334 else while ((menu = menu->parent)) { 353 else while ((menu = menu->parent)) {
335 if (menu->next) { 354 if (menu->next) {
336 menu = menu->next; 355 menu = menu->next;
337 break; 356 break;
338 } 357 }
339 } 358 }
340 } 359 }
341 fclose(out); 360 fclose(out);
342 fclose(out_h); 361 fclose(out_h);
343 362
344 if (!name) { 363 if (!name) {
345 rename(".tmpconfig.h", "include/linux/autoconf.h"); 364 rename(".tmpconfig.h", "include/linux/autoconf.h");
346 name = conf_def_filename; 365 name = conf_def_filename;
347 file_write_dep(NULL); 366 file_write_dep(NULL);
348 } else 367 } else
349 unlink(".tmpconfig.h"); 368 unlink(".tmpconfig.h");
350 369
351 sprintf(oldname, "%s.old", name); 370 sprintf(oldname, "%s.old", name);
352 rename(name, oldname); 371 rename(name, oldname);
353 if (rename(".tmpconfig", name)) 372 if (rename(".tmpconfig", name))
354 return 1; 373 return 1;
355 strcpy(conf_filename, name);
356 374
357 sym_change_count = 0; 375 sym_change_count = 0;
358 376
359 return 0; 377 return 0;
360} 378}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index fd9c32a..896a296 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -121,102 +121,105 @@ struct symbol {
121 #define SYMBOL_WRITE 0x0200 121 #define SYMBOL_WRITE 0x0200
122 #define SYMBOL_CHANGED 0x0400 122 #define SYMBOL_CHANGED 0x0400
123 #define SYMBOL_NEW 0x0800 123 #define SYMBOL_NEW 0x0800
124 #define SYMBOL_AUTO 0x1000 124 #define SYMBOL_AUTO 0x1000
125 125
126 #define SYMBOL_MAXLENGTH256 126 #define SYMBOL_MAXLENGTH256
127 #define SYMBOL_HASHSIZE 257 127 #define SYMBOL_HASHSIZE 257
128 #define SYMBOL_HASHMASK 0xff 128 #define SYMBOL_HASHMASK 0xff
129 129
130enum prop_type { 130enum prop_type {
131 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_ROOTMENU, P_DEFAULT, P_CHOICE 131 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_ROOTMENU, P_DEFAULT, P_CHOICE
132}; 132};
133 133
134struct property { 134struct property {
135 struct property *next; 135 struct property *next;
136 struct symbol *sym; 136 struct symbol *sym;
137#ifdef CML1 137#ifdef CML1
138 int token; 138 int token;
139#else 139#else
140 enum prop_type type; 140 enum prop_type type;
141#endif 141#endif
142 const char *text; 142 const char *text;
143 struct symbol *def; 143 struct symbol *def;
144 struct expr_value visible; 144 struct expr_value visible;
145 struct expr *dep; 145 struct expr *dep;
146 struct expr *dep2; 146 struct expr *dep2;
147 struct menu *menu; 147 struct menu *menu;
148 struct file *file; 148 struct file *file;
149 int lineno; 149 int lineno;
150#ifdef CML1 150#ifdef CML1
151 struct property *next_pos; 151 struct property *next_pos;
152#endif 152#endif
153}; 153};
154 154
155#define for_all_properties(sym, st, tok) \ 155#define for_all_properties(sym, st, tok) \
156 for (st = sym->prop; st; st = st->next) \ 156 for (st = sym->prop; st; st = st->next) \
157 if (st->type == (tok)) 157 if (st->type == (tok))
158#define for_all_prompts(sym, st) for_all_properties(sym, st, P_PROMPT) 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) 159#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) 160#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
161 161
162struct menu { 162struct menu {
163 struct menu *next; 163 struct menu *next;
164 struct menu *parent; 164 struct menu *parent;
165 struct menu *list; 165 struct menu *list;
166 struct symbol *sym; 166 struct symbol *sym;
167 struct property *prompt; 167 struct property *prompt;
168 struct expr *dep; 168 struct expr *dep;
169 unsigned int flags;
169 //char *help; 170 //char *help;
170 struct file *file; 171 struct file *file;
171 int lineno; 172 int lineno;
172 //void *data; 173 void *data;
173}; 174};
174 175
176 #define MENU_CHANGED 0x0001
177
175#ifndef SWIG 178#ifndef SWIG
176 179
177extern struct file *file_list; 180extern struct file *file_list;
178extern struct file *current_file; 181extern struct file *current_file;
179struct file *lookup_file(const char *name); 182struct file *lookup_file(const char *name);
180 183
181extern struct symbol symbol_yes, symbol_no, symbol_mod; 184extern struct symbol symbol_yes, symbol_no, symbol_mod;
182extern struct symbol *modules_sym; 185extern struct symbol *modules_sym;
183extern int cdebug; 186extern int cdebug;
184extern int print_type; 187extern int print_type;
185struct expr *expr_alloc_symbol(struct symbol *sym); 188struct expr *expr_alloc_symbol(struct symbol *sym);
186#ifdef CML1 189#ifdef CML1
187struct expr *expr_alloc_one(int token, struct expr *ce); 190struct expr *expr_alloc_one(int token, struct expr *ce);
188struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2); 191struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2);
189struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2); 192struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2);
190#else 193#else
191struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); 194struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
192struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); 195struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
193struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); 196struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
194#endif 197#endif
195struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); 198struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
196struct expr *expr_copy(struct expr *org); 199struct expr *expr_copy(struct expr *org);
197void expr_free(struct expr *e); 200void expr_free(struct expr *e);
198int expr_eq(struct expr *e1, struct expr *e2); 201int expr_eq(struct expr *e1, struct expr *e2);
199void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); 202void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
200tristate expr_calc_value(struct expr *e); 203tristate expr_calc_value(struct expr *e);
201struct expr *expr_eliminate_yn(struct expr *e); 204struct expr *expr_eliminate_yn(struct expr *e);
202struct expr *expr_trans_bool(struct expr *e); 205struct expr *expr_trans_bool(struct expr *e);
203struct expr *expr_eliminate_dups(struct expr *e); 206struct expr *expr_eliminate_dups(struct expr *e);
204struct expr *expr_transform(struct expr *e); 207struct expr *expr_transform(struct expr *e);
205int expr_contains_symbol(struct expr *dep, struct symbol *sym); 208int expr_contains_symbol(struct expr *dep, struct symbol *sym);
206bool expr_depends_symbol(struct expr *dep, struct symbol *sym); 209bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
207struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); 210struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
208struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); 211struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
209void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); 212void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
210struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); 213struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
211 214
212void expr_fprint(struct expr *e, FILE *out); 215void expr_fprint(struct expr *e, FILE *out);
213void print_expr(int mask, struct expr *e, int prevtoken); 216void print_expr(int mask, struct expr *e, int prevtoken);
214 217
215#ifdef CML1 218#ifdef CML1
216static inline int expr_is_yes(struct expr *e) 219static inline int expr_is_yes(struct expr *e)
217{ 220{
218 return !e || (e->token == WORD && e->left.sym == &symbol_yes); 221 return !e || (e->token == WORD && e->left.sym == &symbol_yes);
219} 222}
220 223
221static inline int expr_is_no(struct expr *e) 224static inline int expr_is_no(struct expr *e)
222{ 225{
diff --git a/scripts/kconfig/kconfig.i b/scripts/kconfig/kconfig.i
index 699cb13..77405fc 100644
--- a/scripts/kconfig/kconfig.i
+++ b/scripts/kconfig/kconfig.i
@@ -1,81 +1,86 @@
1%module kconfig 1%module kconfig
2%{ 2%{
3#include "kconfig_load.c" 3#include "kconfig_load.c"
4%} 4%}
5 5
6%init %{ 6%init %{
7 kconfig_load(); 7 kconfig_load();
8%} 8%}
9 9
10%nodefault; 10%nodefault;
11 11
12#ifdef SWIGRUBY 12#ifdef SWIGRUBY
13%typemap (out) char * { 13%typemap (out) char * {
14 if ($1 == NULL) 14 if ($1 == NULL)
15 $result = Qnil; 15 $result = Qnil;
16 else 16 else
17 $result = rb_str_new2($1); 17 $result = rb_str_new2($1);
18} 18}
19%typemap (in) char * { 19%typemap (in) char * {
20 if ($input == Qnil) 20 if ($input == Qnil)
21 $1 = NULL; 21 $1 = NULL;
22 else 22 else
23 $1 = STR2CSTR($input); 23 $1 = STR2CSTR($input);
24} 24}
25 25
26%{ 26%{
27static void expr_to_s_help(void *data, const char *str) 27static void expr_to_s_help(void *data, const char *str)
28{ 28{
29 rb_str_cat((VALUE)data, str, strlen(str)); 29 rb_str_cat((VALUE)data, str, strlen(str));
30} 30}
31%} 31%}
32#endif 32#endif
33 33
34#ifdef SWIGPYTHON
35%rename (Property) property;
36%rename (default) def;
37#endif
38
34%immutable; 39%immutable;
35%include "expr.h" 40%include "expr.h"
36#define P(name,type,arg) extern type name arg 41#define P(name,type,arg) extern type name arg
37%include "lkc_proto.h" 42%include "lkc_proto.h"
38%mutable; 43%mutable;
39 44
40#ifdef SWIGRUBY 45#ifdef SWIGRUBY
41%predicate menu::isVisible; 46%predicate menu::isVisible;
42%predicate symbol::isChangable; 47%predicate symbol::isChangable;
43%predicate symbol::isChoice; 48%predicate symbol::isChoice;
44%predicate symbol::isChoiceValue; 49%predicate symbol::isChoiceValue;
45#endif 50#endif
46 51
47%extend menu { 52%extend menu {
48 bool isVisible(void) { 53 bool isVisible(void) {
49 return menu_is_visible(self); 54 return menu_is_visible(self);
50 } 55 }
51#ifdef SWIGRUBY 56#ifdef SWIGRUBY
52 void each(void) { 57 void each(void) {
53 struct menu *child; 58 struct menu *child;
54 for (child = self->list; child; child = child->next) 59 for (child = self->list; child; child = child->next)
55 rb_yield(SWIG_NewPointerObj(child, SWIGTYPE_p_menu, 0)); 60 rb_yield(SWIG_NewPointerObj(child, SWIGTYPE_p_menu, 0));
56 } 61 }
57 static void each_menu(void) { 62 static void each_menu(void) {
58 struct menu *child; 63 struct menu *child;
59 for (child = rootmenu.list; child; child = child->next) 64 for (child = rootmenu.list; child; child = child->next)
60 rb_yield(SWIG_NewPointerObj(child, SWIGTYPE_p_menu, 0)); 65 rb_yield(SWIG_NewPointerObj(child, SWIGTYPE_p_menu, 0));
61 } 66 }
62#endif 67#endif
63} 68}
64 69
65%extend symbol { 70%extend symbol {
66 void calc_value(void) { 71 void calc_value(void) {
67 sym_calc_value(self); 72 sym_calc_value(self);
68 } 73 }
69 tristate set_tristate(tristate val) { 74 tristate set_tristate(tristate val) {
70 return sym_set_tristate_value(self, val); 75 return sym_set_tristate_value(self, val);
71 } 76 }
72 bool set_string(char *val) { 77 bool set_string(char *val) {
73 return sym_set_string_value(self, val); 78 return sym_set_string_value(self, val);
74 } 79 }
75 const char *get_string(void) { 80 const char *get_string(void) {
76 return sym_get_string_value(self); 81 return sym_get_string_value(self);
77 } 82 }
78 bool isChangable(void) { 83 bool isChangable(void) {
79 return sym_is_changable(self); 84 return sym_is_changable(self);
80 } 85 }
81 bool isChoice(void) { 86 bool isChoice(void) {
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 688945b..cdd04a9 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -1,106 +1,109 @@
1/* 1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#ifndef LKC_H 6#ifndef LKC_H
7#define LKC_H 7#define LKC_H
8 8
9#include "expr.h" 9#include "expr.h"
10 10
11#ifdef __cplusplus 11#ifdef __cplusplus
12extern "C" { 12extern "C" {
13#endif 13#endif
14 14
15#ifdef LKC_DIRECT_LINK 15#ifdef LKC_DIRECT_LINK
16 #define P(name,type,arg)extern type name arg 16 #define P(name,type,arg)extern type name arg
17#else 17#else
18#include "lkc_defs.h" 18#include "lkc_defs.h"
19 #define P(name,type,arg)extern type (*name ## _p) arg 19 #define P(name,type,arg)extern type (*name ## _p) arg
20#endif 20#endif
21#include "lkc_proto.h" 21#include "lkc_proto.h"
22#undef P 22#undef P
23 23
24void symbol_end(char *help); 24#define SRCTREE "srctree"
25
25int zconfparse(void); 26int zconfparse(void);
26void zconfdump(FILE *out); 27void zconfdump(FILE *out);
27 28
28extern int zconfdebug; 29extern int zconfdebug;
29void zconf_starthelp(void); 30void zconf_starthelp(void);
31FILE *zconf_fopen(const char *name);
30void zconf_initscan(const char *name); 32void zconf_initscan(const char *name);
31void zconf_nextfile(const char *name); 33void zconf_nextfile(const char *name);
32int zconf_lineno(void); 34int zconf_lineno(void);
33char *zconf_curname(void); 35char *zconf_curname(void);
34 36
35/* confdata.c */ 37/* confdata.c */
36extern const char conf_def_filename[]; 38extern const char conf_def_filename[];
37extern char conf_filename[]; 39extern char conf_filename[];
38 40
39char *conf_get_default_confname(void); 41char *conf_get_default_confname(void);
40 42
41/* kconfig_load.c */ 43/* kconfig_load.c */
42void kconfig_load(void); 44void kconfig_load(void);
43 45
44/* menu.c */ 46/* menu.c */
45void menu_init(void); 47void menu_init(void);
46void menu_add_menu(void); 48void menu_add_menu(void);
47void menu_end_menu(void); 49void menu_end_menu(void);
48void menu_add_entry(struct symbol *sym); 50void menu_add_entry(struct symbol *sym);
49void menu_end_entry(void); 51void menu_end_entry(void);
50struct property *create_prop(enum prop_type type); 52struct property *create_prop(enum prop_type type);
51void menu_add_dep(struct expr *dep); 53void menu_add_dep(struct expr *dep);
52struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep); 54struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep);
53void menu_finalize(struct menu *parent); 55void menu_finalize(struct menu *parent);
54void menu_set_type(int type); 56void menu_set_type(int type);
55struct file *file_lookup(const char *name); 57struct file *file_lookup(const char *name);
56int file_write_dep(const char *name); 58int file_write_dep(const char *name);
57 59
58extern struct menu *current_entry; 60extern struct menu *current_entry;
59extern struct menu *current_menu; 61extern struct menu *current_menu;
60 62
61/* symbol.c */ 63/* symbol.c */
62void sym_init(void); 64void sym_init(void);
63void sym_clear_all_valid(void); 65void sym_clear_all_valid(void);
66void sym_set_changed(struct symbol *sym);
64 67
65static inline tristate sym_get_tristate_value(struct symbol *sym) 68static inline tristate sym_get_tristate_value(struct symbol *sym)
66{ 69{
67 return S_TRI(sym->curr); 70 return S_TRI(sym->curr);
68} 71}
69 72
70 73
71static inline struct symbol *sym_get_choice_value(struct symbol *sym) 74static inline struct symbol *sym_get_choice_value(struct symbol *sym)
72{ 75{
73 return (struct symbol *)S_VAL(sym->curr); 76 return (struct symbol *)S_VAL(sym->curr);
74} 77}
75 78
76static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) 79static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
77{ 80{
78 return sym_set_tristate_value(chval, yes); 81 return sym_set_tristate_value(chval, yes);
79} 82}
80 83
81static inline bool sym_is_choice(struct symbol *sym) 84static inline bool sym_is_choice(struct symbol *sym)
82{ 85{
83 return sym->flags & SYMBOL_CHOICE ? true : false; 86 return sym->flags & SYMBOL_CHOICE ? true : false;
84} 87}
85 88
86static inline bool sym_is_choice_value(struct symbol *sym) 89static inline bool sym_is_choice_value(struct symbol *sym)
87{ 90{
88 return sym->flags & SYMBOL_CHOICEVAL ? true : false; 91 return sym->flags & SYMBOL_CHOICEVAL ? true : false;
89} 92}
90 93
91static inline bool sym_is_optional(struct symbol *sym) 94static inline bool sym_is_optional(struct symbol *sym)
92{ 95{
93 return sym->flags & SYMBOL_OPTIONAL ? true : false; 96 return sym->flags & SYMBOL_OPTIONAL ? true : false;
94} 97}
95 98
96static inline bool sym_has_value(struct symbol *sym) 99static inline bool sym_has_value(struct symbol *sym)
97{ 100{
98 //return S_VAL(sym->def) != NULL; 101 //return S_VAL(sym->def) != NULL;
99 return sym->flags & SYMBOL_NEW ? false : true; 102 return sym->flags & SYMBOL_NEW ? false : true;
100} 103}
101 104
102#ifdef __cplusplus 105#ifdef __cplusplus
103} 106}
104#endif 107#endif
105 108
106#endif /* LKC_H */ 109#endif /* LKC_H */
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index dec8603..eba5ff7 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -1,160 +1,183 @@
1/* 1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Introduced single menu mode (show all sub-menus in one large tree).
6 * 2002-11-06 Petr Baudis <pasky@ucw.cz>
4 */ 7 */
5 8
6#include <sys/ioctl.h> 9#include <sys/ioctl.h>
7#include <sys/wait.h> 10#include <sys/wait.h>
8#include <ctype.h> 11#include <ctype.h>
9#include <errno.h> 12#include <errno.h>
10#include <fcntl.h> 13#include <fcntl.h>
14#include <limits.h>
11#include <signal.h> 15#include <signal.h>
12#include <stdarg.h> 16#include <stdarg.h>
13#include <stdlib.h> 17#include <stdlib.h>
14#include <string.h> 18#include <string.h>
19#include <termios.h>
15#include <unistd.h> 20#include <unistd.h>
16 21
17#define LKC_DIRECT_LINK 22#define LKC_DIRECT_LINK
18#include "lkc.h" 23#include "lkc.h"
19 24
20static char menu_backtitle[128]; 25static char menu_backtitle[128];
21static const char menu_instructions[] = 26static const char menu_instructions[] =
22 "Arrow keys navigate the menu. " 27 "Arrow keys navigate the menu. "
23 "<Enter> selects submenus --->. " 28 "<Enter> selects submenus --->. "
24 "Highlighted letters are hotkeys. " 29 "Highlighted letters are hotkeys. "
25 "Pressing <Y> includes, <N> excludes, <M> modularizes features. " 30 "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
26 "Press <Esc><Esc> to exit, <?> for Help. " 31 "Press <Esc><Esc> to exit, <?> for Help. "
27 "Legend: [*] built-in [ ] excluded <M> module < > module capable", 32 "Legend: [*] built-in [ ] excluded <M> module < > module capable",
28radiolist_instructions[] = 33radiolist_instructions[] =
29 "Use the arrow keys to navigate this window or " 34 "Use the arrow keys to navigate this window or "
30 "press the hotkey of the item you wish to select " 35 "press the hotkey of the item you wish to select "
31 "followed by the <SPACE BAR>. " 36 "followed by the <SPACE BAR>. "
32 "Press <?> for additional information about this option.", 37 "Press <?> for additional information about this option.",
33inputbox_instructions_int[] = 38inputbox_instructions_int[] =
34 "Please enter a decimal value. " 39 "Please enter a decimal value. "
35 "Fractions will not be accepted. " 40 "Fractions will not be accepted. "
36 "Use the <TAB> key to move from the input field to the buttons below it.", 41 "Use the <TAB> key to move from the input field to the buttons below it.",
37inputbox_instructions_hex[] = 42inputbox_instructions_hex[] =
38 "Please enter a hexadecimal value. " 43 "Please enter a hexadecimal value. "
39 "Use the <TAB> key to move from the input field to the buttons below it.", 44 "Use the <TAB> key to move from the input field to the buttons below it.",
40inputbox_instructions_string[] = 45inputbox_instructions_string[] =
41 "Please enter a string value. " 46 "Please enter a string value. "
42 "Use the <TAB> key to move from the input field to the buttons below it.", 47 "Use the <TAB> key to move from the input field to the buttons below it.",
43setmod_text[] = 48setmod_text[] =
44 "This feature depends on another which has been configured as a module.\n" 49 "This feature depends on another which has been configured as a module.\n"
45 "As a result, this feature will be built as a module.", 50 "As a result, this feature will be built as a module.",
46nohelp_text[] = 51nohelp_text[] =
47 "There is no help available for this option.\n", 52 "There is no help available for this kernel option.\n",
48load_config_text[] = 53load_config_text[] =
49 "Enter the name of the configuration file you wish to load. " 54 "Enter the name of the configuration file you wish to load. "
50 "Accept the name shown to restore the configuration you " 55 "Accept the name shown to restore the configuration you "
51 "last retrieved. Leave blank to abort.", 56 "last retrieved. Leave blank to abort.",
52load_config_help[] = 57load_config_help[] =
53 "\n" 58 "\n"
54 "For various reasons, one may wish to keep several different\n" 59 "For various reasons, one may wish to keep several different kernel\n"
55 "configurations available on a single machine.\n" 60 "configurations available on a single machine.\n"
56 "\n" 61 "\n"
57 "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"
58 "default, entering the name of the file here will allow you\n" 63 "kernel's default, entering the name of the file here will allow you\n"
59 "to modify that configuration.\n" 64 "to modify that configuration.\n"
60 "\n" 65 "\n"
61 "If you are uncertain, then you have probably never used alternate\n" 66 "If you are uncertain, then you have probably never used alternate\n"
62 "configuration files. You should therefor leave this blank to abort.\n", 67 "configuration files. You should therefor leave this blank to abort.\n",
63save_config_text[] = 68save_config_text[] =
64 "Enter a filename to which this configuration should be saved " 69 "Enter a filename to which this configuration should be saved "
65 "as an alternate. Leave blank to abort.", 70 "as an alternate. Leave blank to abort.",
66save_config_help[] = 71save_config_help[] =
67 "\n" 72 "\n"
68 "For various reasons, one may wish to keep different\n" 73 "For various reasons, one may wish to keep different kernel\n"
69 "configurations available on a single machine.\n" 74 "configurations available on a single machine.\n"
70 "\n" 75 "\n"
71 "Entering a file name here will allow you to later retrieve, modify\n" 76 "Entering a file name here will allow you to later retrieve, modify\n"
72 "and use the current configuration as an alternate to whatever\n" 77 "and use the current configuration as an alternate to whatever\n"
73 "configuration options you have selected at that time.\n" 78 "configuration options you have selected at that time.\n"
74 "\n" 79 "\n"
75 "If you are uncertain what all this means then you should probably\n" 80 "If you are uncertain what all this means then you should probably\n"
76 "leave this blank.\n" 81 "leave this blank.\n"
77; 82;
78 83
79static char buf[4096], *bufptr = buf; 84static char buf[4096], *bufptr = buf;
80static char input_buf[4096]; 85static char input_buf[4096];
86static char filename[PATH_MAX+1] = ".config";
81static char *args[1024], **argptr = args; 87static char *args[1024], **argptr = args;
82static int indent = 0; 88static int indent = 0;
89static struct termios ios_org;
83static int rows, cols; 90static int rows, cols;
84static struct menu *current_menu; 91static struct menu *current_menu;
85static int child_count; 92static int child_count;
86static int do_resize; 93static int do_resize;
94static int single_menu_mode;
87 95
88static void conf(struct menu *menu); 96static void conf(struct menu *menu);
89static void conf_choice(struct menu *menu); 97static void conf_choice(struct menu *menu);
90static void conf_string(struct menu *menu); 98static void conf_string(struct menu *menu);
91static void conf_load(void); 99static void conf_load(void);
92static void conf_save(void); 100static void conf_save(void);
93static void show_textbox(const char *title, const char *text, int r, int c); 101static void show_textbox(const char *title, const char *text, int r, int c);
94static void show_helptext(const char *title, const char *text); 102static void show_helptext(const char *title, const char *text);
95static void show_help(struct menu *menu); 103static void show_help(struct menu *menu);
96static void show_readme(void); 104static void show_readme(void);
97 105
98static void cprint_init(void); 106static void cprint_init(void);
99static int cprint1(const char *fmt, ...); 107static int cprint1(const char *fmt, ...);
100static void cprint_done(void); 108static void cprint_done(void);
101static int cprint(const char *fmt, ...); 109static int cprint(const char *fmt, ...);
102 110
103static void init_wsize(void) 111static void init_wsize(void)
104{ 112{
105 struct winsize ws; 113 struct winsize ws;
114 char *env;
106 115
107 if (ioctl(1, TIOCGWINSZ, &ws) == -1) { 116 if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
108 rows = 24; 117 rows = 24;
109 cols = 80; 118 cols = 80;
110 } else { 119 } else {
111 rows = ws.ws_row; 120 rows = ws.ws_row;
112 cols = ws.ws_col; 121 cols = ws.ws_col;
122 if (!rows) {
123 env = getenv("LINES");
124 if (env)
125 rows = atoi(env);
126 if (!rows)
127 rows = 24;
128 }
129 if (!cols) {
130 env = getenv("COLUMNS");
131 if (env)
132 cols = atoi(env);
133 if (!cols)
134 cols = 80;
135 }
113 } 136 }
114 137
115 if (rows < 19 || cols < 80) { 138 if (rows < 19 || cols < 80) {
116 fprintf(stderr, "Your display is too small to run Menuconfig!\n"); 139 fprintf(stderr, "Your display is too small to run Menuconfig!\n");
117 fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); 140 fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
118 exit(1); 141 exit(1);
119 } 142 }
120 143
121 rows -= 4; 144 rows -= 4;
122 cols -= 5; 145 cols -= 5;
123} 146}
124 147
125static void cprint_init(void) 148static void cprint_init(void)
126{ 149{
127 bufptr = buf; 150 bufptr = buf;
128 argptr = args; 151 argptr = args;
129 memset(args, 0, sizeof(args)); 152 memset(args, 0, sizeof(args));
130 indent = 0; 153 indent = 0;
131 child_count = 0; 154 child_count = 0;
132 cprint("./scripts/lxdialog/lxdialog"); 155 cprint("./scripts/lxdialog/lxdialog");
133 cprint("--backtitle"); 156 cprint("--backtitle");
134 cprint(menu_backtitle); 157 cprint(menu_backtitle);
135} 158}
136 159
137static int cprint1(const char *fmt, ...) 160static int cprint1(const char *fmt, ...)
138{ 161{
139 va_list ap; 162 va_list ap;
140 int res; 163 int res;
141 164
142 if (!*argptr) 165 if (!*argptr)
143 *argptr = bufptr; 166 *argptr = bufptr;
144 va_start(ap, fmt); 167 va_start(ap, fmt);
145 res = vsprintf(bufptr, fmt, ap); 168 res = vsprintf(bufptr, fmt, ap);
146 va_end(ap); 169 va_end(ap);
147 bufptr += res; 170 bufptr += res;
148 171
149 return res; 172 return res;
150} 173}
151 174
152static void cprint_done(void) 175static void cprint_done(void)
153{ 176{
154 *bufptr++ = 0; 177 *bufptr++ = 0;
155 argptr++; 178 argptr++;
156} 179}
157 180
158static int cprint(const char *fmt, ...) 181static int cprint(const char *fmt, ...)
159{ 182{
160 va_list ap; 183 va_list ap;
@@ -229,100 +252,110 @@ static int exec_conf(void)
229 close(pipefd[0]); 252 close(pipefd[0]);
230 waitpid(pid, &stat, 0); 253 waitpid(pid, &stat, 0);
231 254
232 if (do_resize) { 255 if (do_resize) {
233 init_wsize(); 256 init_wsize();
234 do_resize = 0; 257 do_resize = 0;
235 sigprocmask(SIG_SETMASK, &osset, NULL); 258 sigprocmask(SIG_SETMASK, &osset, NULL);
236 return -1; 259 return -1;
237 } 260 }
238 if (WIFSIGNALED(stat)) { 261 if (WIFSIGNALED(stat)) {
239 printf("\finterrupted(%d)\n", WTERMSIG(stat)); 262 printf("\finterrupted(%d)\n", WTERMSIG(stat));
240 exit(1); 263 exit(1);
241 } 264 }
242#if 0 265#if 0
243 printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf); 266 printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
244 sleep(1); 267 sleep(1);
245#endif 268#endif
246 sigpending(&sset); 269 sigpending(&sset);
247 if (sigismember(&sset, SIGINT)) { 270 if (sigismember(&sset, SIGINT)) {
248 printf("\finterrupted\n"); 271 printf("\finterrupted\n");
249 exit(1); 272 exit(1);
250 } 273 }
251 sigprocmask(SIG_SETMASK, &osset, NULL); 274 sigprocmask(SIG_SETMASK, &osset, NULL);
252 275
253 return WEXITSTATUS(stat); 276 return WEXITSTATUS(stat);
254} 277}
255 278
256static void build_conf(struct menu *menu) 279static void build_conf(struct menu *menu)
257{ 280{
258 struct symbol *sym; 281 struct symbol *sym;
259 struct property *prop; 282 struct property *prop;
260 struct menu *child; 283 struct menu *child;
261 int type, tmp, doint = 2; 284 int type, tmp, doint = 2;
262 tristate val; 285 tristate val;
263 char ch; 286 char ch;
264 287
265 if (!menu_is_visible(menu)) 288 if (!menu_is_visible(menu))
266 return; 289 return;
267 290
268 sym = menu->sym; 291 sym = menu->sym;
269 prop = menu->prompt; 292 prop = menu->prompt;
270 if (!sym) { 293 if (!sym) {
271 if (prop && menu != current_menu) { 294 if (prop && menu != current_menu) {
272 const char *prompt = menu_get_prompt(menu); 295 const char *prompt = menu_get_prompt(menu);
273 switch (prop->type) { 296 switch (prop->type) {
274 case P_MENU: 297 case P_MENU:
275 child_count++; 298 child_count++;
276 cprint("m%p", menu); 299 cprint("m%p", menu);
277 if (menu->parent != &rootmenu) 300
278 cprint1(" %*c", indent + 1, ' '); 301 if (single_menu_mode) {
279 cprint1("%s --->", prompt); 302 cprint1("%s%*c%s",
303 menu->data ? "-->" : "++>",
304 indent + 1, ' ', prompt);
305 } else {
306 if (menu->parent != &rootmenu)
307 cprint1(" %*c", indent + 1, ' ');
308 cprint1("%s --->", prompt);
309 }
310
280 cprint_done(); 311 cprint_done();
312 if (single_menu_mode && menu->data)
313 goto conf_childs;
281 return; 314 return;
282 default: 315 default:
283 if (prompt) { 316 if (prompt) {
284 child_count++; 317 child_count++;
285 cprint(":%p", menu); 318 cprint(":%p", menu);
286 cprint("---%*c%s", indent + 1, ' ', prompt); 319 cprint("---%*c%s", indent + 1, ' ', prompt);
287 } 320 }
288 } 321 }
289 } else 322 } else
290 doint = 0; 323 doint = 0;
291 goto conf_childs; 324 goto conf_childs;
292 } 325 }
293 326
294 type = sym_get_type(sym); 327 type = sym_get_type(sym);
295 if (sym_is_choice(sym)) { 328 if (sym_is_choice(sym)) {
296 struct symbol *def_sym = sym_get_choice_value(sym); 329 struct symbol *def_sym = sym_get_choice_value(sym);
297 struct menu *def_menu = NULL; 330 struct menu *def_menu = NULL;
298 331
299 child_count++; 332 child_count++;
300 for (child = menu->list; child; child = child->next) { 333 for (child = menu->list; child; child = child->next) {
301 if (menu_is_visible(child) && child->sym == def_sym) 334 if (menu_is_visible(child) && child->sym == def_sym)
302 def_menu = child; 335 def_menu = child;
303 } 336 }
304 337
305 val = sym_get_tristate_value(sym); 338 val = sym_get_tristate_value(sym);
306 if (sym_is_changable(sym)) { 339 if (sym_is_changable(sym)) {
307 cprint("t%p", menu); 340 cprint("t%p", menu);
308 switch (type) { 341 switch (type) {
309 case S_BOOLEAN: 342 case S_BOOLEAN:
310 cprint1("[%c]", val == no ? ' ' : '*'); 343 cprint1("[%c]", val == no ? ' ' : '*');
311 break; 344 break;
312 case S_TRISTATE: 345 case S_TRISTATE:
313 switch (val) { 346 switch (val) {
314 case yes: ch = '*'; break; 347 case yes: ch = '*'; break;
315 case mod: ch = 'M'; break; 348 case mod: ch = 'M'; break;
316 default: ch = ' '; break; 349 default: ch = ' '; break;
317 } 350 }
318 cprint1("<%c>", ch); 351 cprint1("<%c>", ch);
319 break; 352 break;
320 } 353 }
321 } else { 354 } else {
322 cprint("%c%p", def_menu ? 't' : ':', menu); 355 cprint("%c%p", def_menu ? 't' : ':', menu);
323 cprint1(" "); 356 cprint1(" ");
324 } 357 }
325 358
326 cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); 359 cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
327 if (val == yes) { 360 if (val == yes) {
328 if (def_menu) { 361 if (def_menu) {
@@ -347,227 +380,241 @@ static void build_conf(struct menu *menu)
347 cprint1(" "); 380 cprint1(" ");
348 } else { 381 } else {
349 switch (type) { 382 switch (type) {
350 case S_BOOLEAN: 383 case S_BOOLEAN:
351 cprint("t%p", menu); 384 cprint("t%p", menu);
352 cprint1("[%c]", val == no ? ' ' : '*'); 385 cprint1("[%c]", val == no ? ' ' : '*');
353 break; 386 break;
354 case S_TRISTATE: 387 case S_TRISTATE:
355 cprint("t%p", menu); 388 cprint("t%p", menu);
356 switch (val) { 389 switch (val) {
357 case yes: ch = '*'; break; 390 case yes: ch = '*'; break;
358 case mod: ch = 'M'; break; 391 case mod: ch = 'M'; break;
359 default: ch = ' '; break; 392 default: ch = ' '; break;
360 } 393 }
361 cprint1("<%c>", ch); 394 cprint1("<%c>", ch);
362 break; 395 break;
363 default: 396 default:
364 cprint("s%p", menu); 397 cprint("s%p", menu);
365 tmp = cprint1("(%s)", sym_get_string_value(sym)); 398 tmp = cprint1("(%s)", sym_get_string_value(sym));
366 tmp = indent - tmp + 4; 399 tmp = indent - tmp + 4;
367 if (tmp < 0) 400 if (tmp < 0)
368 tmp = 0; 401 tmp = 0;
369 cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), 402 cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
370 sym_has_value(sym) ? "" : " (NEW)"); 403 sym_has_value(sym) ? "" : " (NEW)");
371 cprint_done(); 404 cprint_done();
372 goto conf_childs; 405 goto conf_childs;
373 } 406 }
374 } 407 }
375 cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), 408 cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
376 sym_has_value(sym) ? "" : " (NEW)"); 409 sym_has_value(sym) ? "" : " (NEW)");
377 cprint_done(); 410 cprint_done();
378 } 411 }
379 412
380conf_childs: 413conf_childs:
381 indent += doint; 414 indent += doint;
382 for (child = menu->list; child; child = child->next) 415 for (child = menu->list; child; child = child->next)
383 build_conf(child); 416 build_conf(child);
384 indent -= doint; 417 indent -= doint;
385} 418}
386 419
387static void conf(struct menu *menu) 420static void conf(struct menu *menu)
388{ 421{
389 struct menu *submenu; 422 struct menu *submenu;
390 const char *prompt = menu_get_prompt(menu); 423 const char *prompt = menu_get_prompt(menu);
391 struct symbol *sym; 424 struct symbol *sym;
392 char active_entry[40]; 425 char active_entry[40];
393 int stat, type, i; 426 int stat, type, i;
394 427
428 unlink("lxdialog.scrltmp");
395 active_entry[0] = 0; 429 active_entry[0] = 0;
396 while (1) { 430 while (1) {
397 cprint_init(); 431 cprint_init();
398 cprint("--title"); 432 cprint("--title");
399 cprint("%s", prompt ? prompt : "Main Menu"); 433 cprint("%s", prompt ? prompt : "Main Menu");
400 cprint("--menu"); 434 cprint("--menu");
401 cprint(menu_instructions); 435 cprint(menu_instructions);
402 cprint("%d", rows); 436 cprint("%d", rows);
403 cprint("%d", cols); 437 cprint("%d", cols);
404 cprint("%d", rows - 10); 438 cprint("%d", rows - 10);
405 cprint("%s", active_entry); 439 cprint("%s", active_entry);
406 current_menu = menu; 440 current_menu = menu;
407 build_conf(menu); 441 build_conf(menu);
408 if (!child_count) 442 if (!child_count)
409 break; 443 break;
410 if (menu == &rootmenu) { 444 if (menu == &rootmenu) {
411 cprint(":"); 445 cprint(":");
412 cprint("--- "); 446 cprint("--- ");
413 cprint("L"); 447 cprint("L");
414 cprint("Load an Alternate Configuration File"); 448 cprint("Load an Alternate Configuration File");
415 cprint("S"); 449 cprint("S");
416 cprint("Save Configuration to an Alternate File"); 450 cprint("Save Configuration to an Alternate File");
417 } 451 }
418 stat = exec_conf(); 452 stat = exec_conf();
419 if (stat < 0) 453 if (stat < 0)
420 continue; 454 continue;
421 455
422 if (stat == 1 || stat == 255) 456 if (stat == 1 || stat == 255)
423 break; 457 break;
424 458
425 type = input_buf[0]; 459 type = input_buf[0];
426 if (!type) 460 if (!type)
427 continue; 461 continue;
428 462
429 for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++) 463 for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
430 ; 464 ;
431 if (i >= sizeof(active_entry)) 465 if (i >= sizeof(active_entry))
432 i = sizeof(active_entry) - 1; 466 i = sizeof(active_entry) - 1;
433 input_buf[i] = 0; 467 input_buf[i] = 0;
434 strcpy(active_entry, input_buf); 468 strcpy(active_entry, input_buf);
435 469
436 sym = NULL; 470 sym = NULL;
437 submenu = NULL; 471 submenu = NULL;
438 if (sscanf(input_buf + 1, "%p", &submenu) == 1) 472 if (sscanf(input_buf + 1, "%p", &submenu) == 1)
439 sym = submenu->sym; 473 sym = submenu->sym;
440 474
441 switch (stat) { 475 switch (stat) {
442 case 0: 476 case 0:
443 switch (type) { 477 switch (type) {
444 case 'm': 478 case 'm':
445 conf(submenu); 479 if (single_menu_mode)
480 submenu->data = (void *) !submenu->data;
481 else
482 conf(submenu);
446 break; 483 break;
447 case 't': 484 case 't':
448 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) 485 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
449 conf_choice(submenu); 486 conf_choice(submenu);
450 break; 487 break;
451 case 's': 488 case 's':
452 conf_string(submenu); 489 conf_string(submenu);
453 break; 490 break;
454 case 'L': 491 case 'L':
455 conf_load(); 492 conf_load();
456 break; 493 break;
457 case 'S': 494 case 'S':
458 conf_save(); 495 conf_save();
459 break; 496 break;
460 } 497 }
461 break; 498 break;
462 case 2: 499 case 2:
463 if (sym) 500 if (sym)
464 show_help(submenu); 501 show_help(submenu);
465 else 502 else
466 show_readme(); 503 show_readme();
467 break; 504 break;
468 case 3: 505 case 3:
469 if (type == 't') { 506 if (type == 't') {
470 if (sym_set_tristate_value(sym, yes)) 507 if (sym_set_tristate_value(sym, yes))
471 break; 508 break;
472 if (sym_set_tristate_value(sym, mod)) 509 if (sym_set_tristate_value(sym, mod))
473 show_textbox(NULL, setmod_text, 6, 74); 510 show_textbox(NULL, setmod_text, 6, 74);
474 } 511 }
475 break; 512 break;
476 case 4: 513 case 4:
477 if (type == 't') 514 if (type == 't')
478 sym_set_tristate_value(sym, no); 515 sym_set_tristate_value(sym, no);
479 break; 516 break;
480 case 5: 517 case 5:
481 if (type == 't') 518 if (type == 't')
482 sym_set_tristate_value(sym, mod); 519 sym_set_tristate_value(sym, mod);
483 break; 520 break;
484 case 6: 521 case 6:
485 if (type == 't') 522 if (type == 't')
486 sym_toggle_tristate_value(sym); 523 sym_toggle_tristate_value(sym);
524 else if (type == 'm')
525 conf(submenu);
487 break; 526 break;
488 } 527 }
489 } 528 }
490} 529}
491 530
492static void show_textbox(const char *title, const char *text, int r, int c) 531static void show_textbox(const char *title, const char *text, int r, int c)
493{ 532{
494 int fd; 533 int fd;
495 534
496 fd = creat(".help.tmp", 0777); 535 fd = creat(".help.tmp", 0777);
497 write(fd, text, strlen(text)); 536 write(fd, text, strlen(text));
498 close(fd); 537 close(fd);
499 do { 538 do {
500 cprint_init(); 539 cprint_init();
501 if (title) { 540 if (title) {
502 cprint("--title"); 541 cprint("--title");
503 cprint("%s", title); 542 cprint("%s", title);
504 } 543 }
505 cprint("--textbox"); 544 cprint("--textbox");
506 cprint(".help.tmp"); 545 cprint(".help.tmp");
507 cprint("%d", r); 546 cprint("%d", r);
508 cprint("%d", c); 547 cprint("%d", c);
509 } while (exec_conf() < 0); 548 } while (exec_conf() < 0);
510 unlink(".help.tmp"); 549 unlink(".help.tmp");
511} 550}
512 551
513static void show_helptext(const char *title, const char *text) 552static void show_helptext(const char *title, const char *text)
514{ 553{
515 show_textbox(title, text, rows, cols); 554 show_textbox(title, text, rows, cols);
516} 555}
517 556
518static void show_help(struct menu *menu) 557static void show_help(struct menu *menu)
519{ 558{
520 const char *help; 559 const char *help;
560 char *helptext;
561 struct symbol *sym = menu->sym;
521 562
522 help = menu->sym->help; 563 help = sym->help;
523 if (!help) 564 if (!help)
524 help = nohelp_text; 565 help = nohelp_text;
525 show_helptext(menu_get_prompt(menu), help); 566 if (sym->name) {
567 helptext = malloc(strlen(sym->name) + strlen(help) + 16);
568 sprintf(helptext, "CONFIG_%s:\n\n%s", sym->name, help);
569 show_helptext(menu_get_prompt(menu), helptext);
570 free(helptext);
571 } else
572 show_helptext(menu_get_prompt(menu), help);
526} 573}
527 574
528static void show_readme(void) 575static void show_readme(void)
529{ 576{
530 do { 577 do {
531 cprint_init(); 578 cprint_init();
532 cprint("--textbox"); 579 cprint("--textbox");
533 cprint("scripts/README.Menuconfig"); 580 cprint("scripts/README.Menuconfig");
534 cprint("%d", rows); 581 cprint("%d", rows);
535 cprint("%d", cols); 582 cprint("%d", cols);
536 } while (exec_conf() == -1); 583 } while (exec_conf() == -1);
537} 584}
538 585
539static void conf_choice(struct menu *menu) 586static void conf_choice(struct menu *menu)
540{ 587{
541 const char *prompt = menu_get_prompt(menu); 588 const char *prompt = menu_get_prompt(menu);
542 struct menu *child; 589 struct menu *child;
543 struct symbol *active; 590 struct symbol *active;
544 int stat; 591 int stat;
545 592
546 while (1) { 593 while (1) {
547 cprint_init(); 594 cprint_init();
548 cprint("--title"); 595 cprint("--title");
549 cprint("%s", prompt ? prompt : "Main Menu"); 596 cprint("%s", prompt ? prompt : "Main Menu");
550 cprint("--radiolist"); 597 cprint("--radiolist");
551 cprint(radiolist_instructions); 598 cprint(radiolist_instructions);
552 cprint("15"); 599 cprint("15");
553 cprint("70"); 600 cprint("70");
554 cprint("6"); 601 cprint("6");
555 602
556 current_menu = menu; 603 current_menu = menu;
557 active = sym_get_choice_value(menu->sym); 604 active = sym_get_choice_value(menu->sym);
558 for (child = menu->list; child; child = child->next) { 605 for (child = menu->list; child; child = child->next) {
559 if (!menu_is_visible(child)) 606 if (!menu_is_visible(child))
560 continue; 607 continue;
561 cprint("%p", child); 608 cprint("%p", child);
562 cprint("%s", menu_get_prompt(child)); 609 cprint("%s", menu_get_prompt(child));
563 cprint(child->sym == active ? "ON" : "OFF"); 610 cprint(child->sym == active ? "ON" : "OFF");
564 } 611 }
565 612
566 stat = exec_conf(); 613 stat = exec_conf();
567 switch (stat) { 614 switch (stat) {
568 case 0: 615 case 0:
569 if (sscanf(input_buf, "%p", &menu) != 1) 616 if (sscanf(input_buf, "%p", &menu) != 1)
570 break; 617 break;
571 sym_set_tristate_value(menu->sym, yes); 618 sym_set_tristate_value(menu->sym, yes);
572 return; 619 return;
573 case 1: 620 case 1:
@@ -586,126 +633,148 @@ static void conf_string(struct menu *menu)
586 633
587 while (1) { 634 while (1) {
588 cprint_init(); 635 cprint_init();
589 cprint("--title"); 636 cprint("--title");
590 cprint("%s", prompt ? prompt : "Main Menu"); 637 cprint("%s", prompt ? prompt : "Main Menu");
591 cprint("--inputbox"); 638 cprint("--inputbox");
592 switch (sym_get_type(menu->sym)) { 639 switch (sym_get_type(menu->sym)) {
593 case S_INT: 640 case S_INT:
594 cprint(inputbox_instructions_int); 641 cprint(inputbox_instructions_int);
595 break; 642 break;
596 case S_HEX: 643 case S_HEX:
597 cprint(inputbox_instructions_hex); 644 cprint(inputbox_instructions_hex);
598 break; 645 break;
599 case S_STRING: 646 case S_STRING:
600 cprint(inputbox_instructions_string); 647 cprint(inputbox_instructions_string);
601 break; 648 break;
602 default: 649 default:
603 /* panic? */; 650 /* panic? */;
604 } 651 }
605 cprint("10"); 652 cprint("10");
606 cprint("75"); 653 cprint("75");
607 cprint("%s", sym_get_string_value(menu->sym)); 654 cprint("%s", sym_get_string_value(menu->sym));
608 stat = exec_conf(); 655 stat = exec_conf();
609 switch (stat) { 656 switch (stat) {
610 case 0: 657 case 0:
611 if (sym_set_string_value(menu->sym, input_buf)) 658 if (sym_set_string_value(menu->sym, input_buf))
612 return; 659 return;
613 show_textbox(NULL, "You have made an invalid entry.", 5, 43); 660 show_textbox(NULL, "You have made an invalid entry.", 5, 43);
614 break; 661 break;
615 case 1: 662 case 1:
616 show_help(menu); 663 show_help(menu);
617 break; 664 break;
618 case 255: 665 case 255:
619 return; 666 return;
620 } 667 }
621 } 668 }
622} 669}
623 670
624static void conf_load(void) 671static void conf_load(void)
625{ 672{
626 int stat; 673 int stat;
627 674
628 while (1) { 675 while (1) {
629 cprint_init(); 676 cprint_init();
630 cprint("--inputbox"); 677 cprint("--inputbox");
631 cprint(load_config_text); 678 cprint(load_config_text);
632 cprint("11"); 679 cprint("11");
633 cprint("55"); 680 cprint("55");
634 cprint("%s", conf_filename); 681 cprint("%s", filename);
635 stat = exec_conf(); 682 stat = exec_conf();
636 switch(stat) { 683 switch(stat) {
637 case 0: 684 case 0:
638 if (!input_buf[0]) 685 if (!input_buf[0])
639 return; 686 return;
640 if (!conf_read(input_buf)) 687 if (!conf_read(input_buf))
641 return; 688 return;
642 show_textbox(NULL, "File does not exist!", 5, 38); 689 show_textbox(NULL, "File does not exist!", 5, 38);
643 break; 690 break;
644 case 1: 691 case 1:
645 show_helptext("Load Alternate Configuration", load_config_help); 692 show_helptext("Load Alternate Configuration", load_config_help);
646 break; 693 break;
647 case 255: 694 case 255:
648 return; 695 return;
649 } 696 }
650 } 697 }
651} 698}
652 699
653static void conf_save(void) 700static void conf_save(void)
654{ 701{
655 int stat; 702 int stat;
656 703
657 while (1) { 704 while (1) {
658 cprint_init(); 705 cprint_init();
659 cprint("--inputbox"); 706 cprint("--inputbox");
660 cprint(save_config_text); 707 cprint(save_config_text);
661 cprint("11"); 708 cprint("11");
662 cprint("55"); 709 cprint("55");
663 cprint("%s", conf_filename); 710 cprint("%s", filename);
664 stat = exec_conf(); 711 stat = exec_conf();
665 switch(stat) { 712 switch(stat) {
666 case 0: 713 case 0:
667 if (!input_buf[0]) 714 if (!input_buf[0])
668 return; 715 return;
669 if (!conf_write(input_buf)) 716 if (!conf_write(input_buf))
670 return; 717 return;
671 show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); 718 show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
672 break; 719 break;
673 case 1: 720 case 1:
674 show_helptext("Save Alternate Configuration", save_config_help); 721 show_helptext("Save Alternate Configuration", save_config_help);
675 break; 722 break;
676 case 255: 723 case 255:
677 return; 724 return;
678 } 725 }
679 } 726 }
680} 727}
681 728
729static void conf_cleanup(void)
730{
731 tcsetattr(1, TCSAFLUSH, &ios_org);
732 unlink(".help.tmp");
733 unlink("lxdialog.scrltmp");
734}
735
682int main(int ac, char **av) 736int main(int ac, char **av)
683{ 737{
738 struct symbol *sym;
739 char *mode;
684 int stat; 740 int stat;
741
685 conf_parse(av[1]); 742 conf_parse(av[1]);
686 conf_read(NULL); 743 conf_read(NULL);
687 744
688 sprintf(menu_backtitle, "Configuration"); 745 sym = sym_lookup("KERNELRELEASE", 0);
746 sym_calc_value(sym);
747 sprintf(menu_backtitle, "Linux Kernel v%s Configuration",
748 sym_get_string_value(sym));
749
750 mode = getenv("MENUCONFIG_MODE");
751 if (mode) {
752 if (!strcasecmp(mode, "single_menu"))
753 single_menu_mode = 1;
754 }
689 755
756 tcgetattr(1, &ios_org);
757 atexit(conf_cleanup);
690 init_wsize(); 758 init_wsize();
691 conf(&rootmenu); 759 conf(&rootmenu);
692 760
693 do { 761 do {
694 cprint_init(); 762 cprint_init();
695 cprint("--yesno"); 763 cprint("--yesno");
696 cprint("Do you wish to save your new configuration?"); 764 cprint("Do you wish to save your new configuration?");
697 cprint("5"); 765 cprint("5");
698 cprint("60"); 766 cprint("60");
699 stat = exec_conf(); 767 stat = exec_conf();
700 } while (stat < 0); 768 } while (stat < 0);
701 769
702 if (stat == 0) { 770 if (stat == 0) {
703 conf_write(NULL); 771 conf_write(NULL);
704 printf("\n\n" 772 printf("\n\n"
705 "*** End of configuration.\n" 773 "*** End of Linux kernel configuration.\n"
706 "*** Check the top-level Makefile for additional configuration.\n"); 774 "*** Check the top-level Makefile for additional configuration.\n"
775 "*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'.\n\n");
707 } else 776 } else
708 printf("\n\nYour configuration changes were NOT saved.\n\n"); 777 printf("\n\nYour kernel configuration changes were NOT saved.\n\n");
709 778
710 return 0; 779 return 0;
711} 780}
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 4595110..24be0ec 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -245,65 +245,65 @@ const char *menu_get_prompt(struct menu *menu)
245 if (menu->prompt) 245 if (menu->prompt)
246 return menu->prompt->text; 246 return menu->prompt->text;
247 else if (menu->sym) 247 else if (menu->sym)
248 return menu->sym->name; 248 return menu->sym->name;
249 return NULL; 249 return NULL;
250} 250}
251 251
252struct menu *menu_get_root_menu(struct menu *menu) 252struct menu *menu_get_root_menu(struct menu *menu)
253{ 253{
254 return &rootmenu; 254 return &rootmenu;
255} 255}
256 256
257struct menu *menu_get_parent_menu(struct menu *menu) 257struct menu *menu_get_parent_menu(struct menu *menu)
258{ 258{
259 enum prop_type type; 259 enum prop_type type;
260 260
261 while (menu != &rootmenu) { 261 while (menu != &rootmenu) {
262 menu = menu->parent; 262 menu = menu->parent;
263 type = menu->prompt ? menu->prompt->type : 0; 263 type = menu->prompt ? menu->prompt->type : 0;
264 if (type == P_MENU || type == P_ROOTMENU) 264 if (type == P_MENU || type == P_ROOTMENU)
265 break; 265 break;
266 } 266 }
267 return menu; 267 return menu;
268} 268}
269 269
270struct file *file_lookup(const char *name) 270struct file *file_lookup(const char *name)
271{ 271{
272 struct file *file; 272 struct file *file;
273 273
274 for (file = file_list; file; file = file->next) { 274 for (file = file_list; file; file = file->next) {
275 if (!strcmp(name, file->name)) 275 if (!strcmp(name, file->name))
276 return file; 276 return file;
277 } 277 }
278 278
279 file = malloc(sizeof(*file)); 279 file = malloc(sizeof(*file));
280 memset(file, 0, sizeof(*file)); 280 memset(file, 0, sizeof(*file));
281 file->name = strdup(name); 281 file->name = strdup(name);
282 file->next = file_list; 282 file->next = file_list;
283 file_list = file; 283 file_list = file;
284 return file; 284 return file;
285} 285}
286 286
287int file_write_dep(const char *name) 287int file_write_dep(const char *name)
288{ 288{
289 struct file *file; 289 struct file *file;
290 FILE *out; 290 FILE *out;
291 291
292 if (!name) 292 if (!name)
293 name = "..config.cmd"; 293 name = ".config.cmd";
294 out = fopen("..config.tmp", "w"); 294 out = fopen("..config.tmp", "w");
295 if (!out) 295 if (!out)
296 return 1; 296 return 1;
297 fprintf(out, "deps_config := \\\n"); 297 fprintf(out, "deps_config := \\\n");
298 for (file = file_list; file; file = file->next) { 298 for (file = file_list; file; file = file->next) {
299 if (file->next) 299 if (file->next)
300 fprintf(out, "\t%s \\\n", file->name); 300 fprintf(out, "\t%s \\\n", file->name);
301 else 301 else
302 fprintf(out, "\t%s\n", file->name); 302 fprintf(out, "\t%s\n", file->name);
303 } 303 }
304 fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n"); 304 fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
305 fclose(out); 305 fclose(out);
306 rename("..config.tmp", name); 306 rename("..config.tmp", name);
307 return 0; 307 return 0;
308} 308}
309 309
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index feefa1c..bed541d 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1,1073 +1,1203 @@
1/* 1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#include <qapplication.h> 6#include <qapplication.h>
7#include <qmainwindow.h> 7#include <qmainwindow.h>
8#include <qtoolbar.h> 8#include <qtoolbar.h>
9#include <qvbox.h> 9#include <qvbox.h>
10#include <qsplitter.h> 10#include <qsplitter.h>
11#include <qlistview.h> 11#include <qlistview.h>
12#include <qtextview.h> 12#include <qtextview.h>
13#include <qlineedit.h> 13#include <qlineedit.h>
14#include <qmenubar.h> 14#include <qmenubar.h>
15#include <qmessagebox.h> 15#include <qmessagebox.h>
16#include <qaction.h> 16#include <qaction.h>
17#include <qheader.h> 17#include <qheader.h>
18#include <qfiledialog.h> 18#include <qfiledialog.h>
19#include <qregexp.h> 19#include <qregexp.h>
20#if QT_VERSION >= 300
21#include <qsettings.h>
22#endif
23
20#include <stdlib.h> 24#include <stdlib.h>
21 25
22#include "lkc.h" 26#include "lkc.h"
23#include "qconf.h" 27#include "qconf.h"
24 28
25#include "qconf.moc" 29#include "qconf.moc"
26#include "images.c" 30#include "images.c"
27 31
28static QApplication *configApp; 32static QApplication *configApp;
33#if QT_VERSION >= 300
34static QSettings *configSettings;
35#endif
29 36
30/* 37/*
31 * update all the children of a menu entry 38 * update all the children of a menu entry
32 * removes/adds the entries from the parent widget as necessary 39 * removes/adds the entries from the parent widget as necessary
33 * 40 *
34 * parent: either the menu list widget or a menu entry widget 41 * parent: either the menu list widget or a menu entry widget
35 * menu: entry to be updated 42 * menu: entry to be updated
36 */ 43 */
37template <class P> 44template <class P>
38static void updateMenuList(P* parent, struct menu* menu) 45static void updateMenuList(P* parent, struct menu* menu)
39{ 46{
40 struct menu* child; 47 struct menu* child;
41 ConfigList* list = parent->listView(); 48 ConfigList* list = parent->listView();
42 ConfigItem* item; 49 ConfigItem* item;
43 ConfigItem* last; 50 ConfigItem* last;
44 bool visible; 51 bool visible;
45 bool showAll = list->showAll; 52 bool showAll = list->showAll;
46 enum listMode mode = list->mode; 53 enum listMode mode = list->mode;
47 enum prop_type type; 54 enum prop_type type;
48 55
49 if (!menu) { 56 if (!menu) {
50 while ((item = parent->firstChild())) 57 while ((item = parent->firstChild()))
51 delete item; 58 delete item;
52 return; 59 return;
53 } 60 }
54 61
55 last = 0; 62 last = 0;
56 for (child = menu->list; child; child = child->next) { 63 for (child = menu->list; child; child = child->next) {
57 item = last ? last->nextSibling() : parent->firstChild(); 64 item = last ? last->nextSibling() : parent->firstChild();
58 type = child->prompt ? child->prompt->type : P_UNKNOWN; 65 type = child->prompt ? child->prompt->type : P_UNKNOWN;
59 66
60 switch (mode) { 67 switch (mode) {
61 case menuMode: 68 case menuMode:
62 if (type != P_ROOTMENU) 69 if (type != P_ROOTMENU)
63 goto hide; 70 goto hide;
64 break; 71 break;
65 case symbolMode: 72 case symbolMode:
66 if (type == P_ROOTMENU) 73 if (type == P_ROOTMENU)
67 goto hide; 74 goto hide;
68 break; 75 break;
69 default: 76 default:
70 break; 77 break;
71 } 78 }
72 79
73 visible = menu_is_visible(child); 80 visible = menu_is_visible(child);
74 if (showAll || visible) { 81 if (showAll || visible) {
75 if (!item || item->menu != child) 82 if (!item || item->menu != child)
76 item = new ConfigItem(parent, last, child); 83 item = new ConfigItem(parent, last, child, visible);
77 item->visible = visible; 84 else {
78 item->updateMenu(); 85 item->visible = 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 }
79 94
80 if (mode == fullMode || mode == menuMode || 95 if (mode == fullMode || mode == menuMode ||
81 (type != P_MENU && type != P_ROOTMENU)) 96 (type != P_MENU && type != P_ROOTMENU))
82 updateMenuList(item, child); 97 updateMenuList(item, child);
83 else 98 else
84 updateMenuList(item, 0); 99 updateMenuList(item, 0);
85 last = item; 100 last = item;
86 continue; 101 continue;
87 } 102 }
88 hide: 103 hide:
89 if (item && item->menu == child) { 104 if (item && item->menu == child) {
90 last = parent->firstChild(); 105 last = parent->firstChild();
91 if (last == item) 106 if (last == item)
92 last = 0; 107 last = 0;
93 else while (last->nextSibling() != item) 108 else while (last->nextSibling() != item)
94 last = last->nextSibling(); 109 last = last->nextSibling();
95 delete item; 110 delete item;
96 } 111 }
97 } 112 }
98} 113}
99 114
100#if QT_VERSION >= 300 115#if QT_VERSION >= 300
101/* 116/*
102 * set the new data 117 * set the new data
103 * TODO check the value 118 * TODO check the value
104 */ 119 */
105void ConfigItem::okRename(int col) 120void ConfigItem::okRename(int col)
106{ 121{
107 Parent::okRename(col); 122 Parent::okRename(col);
108 sym_set_string_value(menu->sym, text(dataColIdx).latin1()); 123 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
109} 124}
110#endif 125#endif
111 126
112/* 127/*
113 * update the displayed of a menu entry 128 * update the displayed of a menu entry
114 */ 129 */
115void ConfigItem::updateMenu(void) 130void ConfigItem::updateMenu(void)
116{ 131{
117 ConfigList* list; 132 ConfigList* list;
118 struct symbol* sym; 133 struct symbol* sym;
119 QString prompt; 134 QString prompt;
120 int type; 135 int type;
121 enum prop_type ptype; 136 enum prop_type ptype;
122 tristate expr; 137 tristate expr;
123 bool update;
124 138
125 list = listView(); 139 list = listView();
126 update = doInit;
127 if (update)
128 doInit = false;
129 else
130 update = list->updateAll;
131 140
132 sym = menu->sym; 141 sym = menu->sym;
133 if (!sym) { 142 if (!sym) {
134 if (update) { 143 setText(promptColIdx, menu_get_prompt(menu));
135 setText(promptColIdx, menu_get_prompt(menu)); 144 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
136 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 145 if ((ptype == P_ROOTMENU || ptype == P_MENU) &&
137 if ((ptype == P_ROOTMENU || ptype == P_MENU) && 146 (list->mode == singleMode || list->mode == symbolMode))
138 (list->mode == singleMode || list->mode == symbolMode)) 147 setPixmap(promptColIdx, list->menuPix);
139 setPixmap(promptColIdx, list->menuPix); 148 else
140 else 149 setPixmap(promptColIdx, 0);
141 setPixmap(promptColIdx, 0);
142 }
143 return; 150 return;
144 } 151 }
145 152
146 sym_calc_value(sym); 153 setText(nameColIdx, sym->name);
147 if (!(sym->flags & SYMBOL_CHANGED) && !update)
148 return;
149
150 sym->flags &= ~SYMBOL_CHANGED;
151
152 setText(nameColIdx, menu->sym->name);
153 154
154 type = sym_get_type(sym); 155 type = sym_get_type(sym);
155 switch (type) { 156 switch (type) {
156 case S_BOOLEAN: 157 case S_BOOLEAN:
157 case S_TRISTATE: 158 case S_TRISTATE:
158 char ch; 159 char ch;
159 160
160 prompt = menu_get_prompt(menu); 161 prompt = menu_get_prompt(menu);
161 if (!sym_is_changable(sym) && !list->showAll) { 162 if (!sym_is_changable(sym) && !list->showAll) {
162 setText(noColIdx, 0); 163 setText(noColIdx, 0);
163 setText(modColIdx, 0); 164 setText(modColIdx, 0);
164 setText(yesColIdx, 0); 165 setText(yesColIdx, 0);
165 break; 166 break;
166 } 167 }
167 expr = sym_get_tristate_value(sym); 168 expr = sym_get_tristate_value(sym);
168 switch (expr) { 169 switch (expr) {
169 case yes: 170 case yes:
170 if (sym_is_choice_value(sym) && type == S_BOOLEAN) 171 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
171 setPixmap(promptColIdx, list->choiceYesPix); 172 setPixmap(promptColIdx, list->choiceYesPix);
172 else 173 else
173 setPixmap(promptColIdx, list->symbolYesPix); 174 setPixmap(promptColIdx, list->symbolYesPix);
174 setText(yesColIdx, "Y"); 175 setText(yesColIdx, "Y");
175 ch = 'Y'; 176 ch = 'Y';
176 break; 177 break;
177 case mod: 178 case mod:
178 setPixmap(promptColIdx, list->symbolModPix); 179 setPixmap(promptColIdx, list->symbolModPix);
179 setText(modColIdx, "M"); 180 setText(modColIdx, "M");
180 ch = 'M'; 181 ch = 'M';
181 break; 182 break;
182 default: 183 default:
183 if (sym_is_choice_value(sym) && type == S_BOOLEAN) 184 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
184 setPixmap(promptColIdx, list->choiceNoPix); 185 setPixmap(promptColIdx, list->choiceNoPix);
185 else 186 else
186 setPixmap(promptColIdx, list->symbolNoPix); 187 setPixmap(promptColIdx, list->symbolNoPix);
187 setText(noColIdx, "N"); 188 setText(noColIdx, "N");
188 ch = 'N'; 189 ch = 'N';
189 break; 190 break;
190 } 191 }
191 if (expr != no) 192 if (expr != no)
192 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0); 193 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
193 if (expr != mod) 194 if (expr != mod)
194 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0); 195 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
195 if (expr != yes) 196 if (expr != yes)
196 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0); 197 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
197 198
198 setText(dataColIdx, QChar(ch)); 199 setText(dataColIdx, QChar(ch));
199 break; 200 break;
200 case S_INT: 201 case S_INT:
201 case S_HEX: 202 case S_HEX:
202 case S_STRING: 203 case S_STRING:
203 const char* data; 204 const char* data;
204 205
205 data = sym_get_string_value(sym); 206 data = sym_get_string_value(sym);
206#if QT_VERSION >= 300 207#if QT_VERSION >= 300
207 setRenameEnabled(list->mapIdx(dataColIdx), TRUE); 208 int i = list->mapIdx(dataColIdx);
209 if (i >= 0)
210 setRenameEnabled(i, TRUE);
208#endif 211#endif
209 setText(dataColIdx, data); 212 setText(dataColIdx, data);
210 if (type == S_STRING) 213 if (type == S_STRING)
211 prompt.sprintf("%s: %s", menu_get_prompt(menu), data); 214 prompt.sprintf("%s: %s", menu_get_prompt(menu), data);
212 else 215 else
213 prompt.sprintf("(%s) %s", data, menu_get_prompt(menu)); 216 prompt.sprintf("(%s) %s", data, menu_get_prompt(menu));
214 break; 217 break;
215 } 218 }
216 if (!sym_has_value(sym) && visible) 219 if (!sym_has_value(sym) && visible)
217 prompt += " (NEW)"; 220 prompt += " (NEW)";
218 setText(promptColIdx, prompt); 221 setText(promptColIdx, prompt);
219} 222}
220 223
224bool ConfigItem::updateNeeded(void)
225{
226 struct symbol* sym = menu->sym;
227 if (sym)
228 sym_calc_value(sym);
229 if (menu->flags & MENU_CHANGED) {
230 menu->flags &= ~MENU_CHANGED;
231 return true;
232 }
233 return false;
234}
235
221void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align) 236void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
222{ 237{
223 ConfigList* list = listView(); 238 ConfigList* list = listView();
224 239
225 if (visible) { 240 if (visible) {
226 if (isSelected() && !list->hasFocus() && list->mode == menuMode) 241 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
227 Parent::paintCell(p, list->inactivedColorGroup, column, width, align); 242 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
228 else 243 else
229 Parent::paintCell(p, cg, column, width, align); 244 Parent::paintCell(p, cg, column, width, align);
230 } else 245 } else
231 Parent::paintCell(p, list->disabledColorGroup, column, width, align); 246 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
232} 247}
233 248
234/* 249/*
235 * construct a menu entry 250 * construct a menu entry
236 */ 251 */
237void ConfigItem::init(void) 252void ConfigItem::init(void)
238{ 253{
239 ConfigList* list = listView(); 254 ConfigList* list = listView();
240#if QT_VERSION < 300 255 nextItem = (ConfigItem*)menu->data;
241 visible = TRUE; 256 menu->data = this;
242#endif 257
243 //menu->data = this;
244 if (list->mode != fullMode) 258 if (list->mode != fullMode)
245 setOpen(TRUE); 259 setOpen(TRUE);
246 doInit= true; 260 if (menu->sym)
261 sym_calc_value(menu->sym);
262 updateMenu();
247} 263}
248 264
249/* 265/*
250 * destruct a menu entry 266 * destruct a menu entry
251 */ 267 */
252ConfigItem::~ConfigItem(void) 268ConfigItem::~ConfigItem(void)
253{ 269{
254 //menu->data = 0; 270 ConfigItem** ip = &(ConfigItem*)menu->data;
271 for (; *ip; ip = &(*ip)->nextItem) {
272 if (*ip == this) {
273 *ip = nextItem;
274 break;
275 }
276 }
255} 277}
256 278
257void ConfigLineEdit::show(ConfigItem* i) 279void ConfigLineEdit::show(ConfigItem* i)
258{ 280{
259 item = i; 281 item = i;
260 if (sym_get_string_value(item->menu->sym)) 282 if (sym_get_string_value(item->menu->sym))
261 setText(sym_get_string_value(item->menu->sym)); 283 setText(sym_get_string_value(item->menu->sym));
262 else 284 else
263 setText(0); 285 setText(0);
264 Parent::show(); 286 Parent::show();
265 setFocus(); 287 setFocus();
266} 288}
267 289
268void ConfigLineEdit::keyPressEvent(QKeyEvent* e) 290void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
269{ 291{
270 switch (e->key()) { 292 switch (e->key()) {
271 case Key_Escape: 293 case Key_Escape:
272 break; 294 break;
273 case Key_Return: 295 case Key_Return:
274 case Key_Enter: 296 case Key_Enter:
275 sym_set_string_value(item->menu->sym, text().latin1()); 297 sym_set_string_value(item->menu->sym, text().latin1());
276 emit lineChanged(item); 298 parent()->updateList(item);
277 break; 299 break;
278 default: 300 default:
279 Parent::keyPressEvent(e); 301 Parent::keyPressEvent(e);
280 return; 302 return;
281 } 303 }
282 e->accept(); 304 e->accept();
305 parent()->list->setFocus();
283 hide(); 306 hide();
284} 307}
285 308
286ConfigList::ConfigList(QWidget* p, ConfigView* cv) 309ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv)
287 : Parent(p), cview(cv), 310 : Parent(p), cview(cv),
288 updateAll(false), 311 updateAll(false),
289 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), 312 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
290 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), 313 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv),
291 showAll(false), showName(false), showRange(false), showData(false), 314 showAll(false), showName(false), showRange(false), showData(false),
292 rootEntry(0) 315 rootEntry(0)
293{ 316{
294 int i; 317 int i;
295 318
296 setSorting(-1); 319 setSorting(-1);
297 setRootIsDecorated(TRUE); 320 setRootIsDecorated(TRUE);
298 disabledColorGroup = palette().active(); 321 disabledColorGroup = palette().active();
299 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text()); 322 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
300 inactivedColorGroup = palette().active(); 323 inactivedColorGroup = palette().active();
301 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight()); 324 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
302 325
303 connect(this, SIGNAL(selectionChanged(void)), 326 connect(this, SIGNAL(selectionChanged(void)),
304 SLOT(updateSelection(void))); 327 SLOT(updateSelection(void)));
305 328
306 for (i = 0; i < colNr; i++) 329 for (i = 0; i < colNr; i++)
307 colMap[i] = colRevMap[i] = -1; 330 colMap[i] = colRevMap[i] = -1;
308 addColumn(promptColIdx, "Option"); 331 addColumn(promptColIdx, "Option");
309 332
310 reinit(); 333 reinit();
311} 334}
312 335
313void ConfigList::reinit(void) 336void ConfigList::reinit(void)
314{ 337{
315 removeColumn(dataColIdx); 338 removeColumn(dataColIdx);
316 removeColumn(yesColIdx); 339 removeColumn(yesColIdx);
317 removeColumn(modColIdx); 340 removeColumn(modColIdx);
318 removeColumn(noColIdx); 341 removeColumn(noColIdx);
319 removeColumn(nameColIdx); 342 removeColumn(nameColIdx);
320 343
321 if (showName) 344 if (showName)
322 addColumn(nameColIdx, "Name"); 345 addColumn(nameColIdx, "Name");
323 if (showRange) { 346 if (showRange) {
324 addColumn(noColIdx, "N"); 347 addColumn(noColIdx, "N");
325 addColumn(modColIdx, "M"); 348 addColumn(modColIdx, "M");
326 addColumn(yesColIdx, "Y"); 349 addColumn(yesColIdx, "Y");
327 } 350 }
328 if (showData) 351 if (showData)
329 addColumn(dataColIdx, "Value"); 352 addColumn(dataColIdx, "Value");
330 353
331 updateListAll(); 354 updateListAll();
332} 355}
333 356
334void ConfigList::updateSelection(void) 357void ConfigList::updateSelection(void)
335{ 358{
336 struct menu *menu; 359 struct menu *menu;
337 enum prop_type type; 360 enum prop_type type;
338 361
339 ConfigItem* item = (ConfigItem*)selectedItem(); 362 ConfigItem* item = (ConfigItem*)selectedItem();
340 if (!item) 363 if (!item)
341 return; 364 return;
342 365
343 cview->setHelp(item); 366 cview->setHelp(item);
344 367
345 menu = item->menu; 368 menu = item->menu;
346 type = menu->prompt ? menu->prompt->type : P_UNKNOWN; 369 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
347 if (mode == menuMode && (type == P_MENU || type == P_ROOTMENU)) 370 if (mode == menuMode && (type == P_MENU || type == P_ROOTMENU))
348 emit menuSelected(menu); 371 emit menuSelected(menu);
349} 372}
350 373
351void ConfigList::updateList(ConfigItem* item) 374void ConfigList::updateList(ConfigItem* item)
352{ 375{
353 (void)item;// unused so far 376 (void)item;// unused so far
354 updateMenuList(this, rootEntry); 377 updateMenuList(this, rootEntry);
378 triggerUpdate();
355} 379}
356 380
357void ConfigList::setAllOpen(bool open) 381void ConfigList::setAllOpen(bool open)
358{ 382{
359 QListViewItemIterator it(this); 383 QListViewItemIterator it(this);
360 384
361 for (; it.current(); it++) 385 for (; it.current(); it++)
362 it.current()->setOpen(open); 386 it.current()->setOpen(open);
363} 387}
364 388
365void ConfigList::setValue(ConfigItem* item, tristate val) 389void ConfigList::setValue(ConfigItem* item, tristate val)
366{ 390{
367 struct symbol* sym; 391 struct symbol* sym;
368 int type; 392 int type;
369 tristate oldval; 393 tristate oldval;
370 394
371 sym = item->menu->sym; 395 sym = item->menu->sym;
372 if (!sym) 396 if (!sym)
373 return; 397 return;
374 398
375 type = sym_get_type(sym); 399 type = sym_get_type(sym);
376 switch (type) { 400 switch (type) {
377 case S_BOOLEAN: 401 case S_BOOLEAN:
378 case S_TRISTATE: 402 case S_TRISTATE:
379 oldval = sym_get_tristate_value(sym); 403 oldval = sym_get_tristate_value(sym);
380 404
381 if (!sym_set_tristate_value(sym, val)) 405 if (!sym_set_tristate_value(sym, val))
382 return; 406 return;
383 if (oldval == no && item->menu->list) 407 if (oldval == no && item->menu->list)
384 item->setOpen(TRUE); 408 item->setOpen(TRUE);
385 emit symbolChanged(item); 409 parent()->updateList(item);
386 break; 410 break;
387 } 411 }
388} 412}
389 413
390void ConfigList::changeValue(ConfigItem* item) 414void ConfigList::changeValue(ConfigItem* item)
391{ 415{
392 struct symbol* sym; 416 struct symbol* sym;
393 struct menu* menu; 417 struct menu* menu;
394 int type, oldexpr, newexpr; 418 int type, oldexpr, newexpr;
395 419
396 menu = item->menu; 420 menu = item->menu;
397 sym = menu->sym; 421 sym = menu->sym;
398 if (!sym) { 422 if (!sym) {
399 if (item->menu->list) 423 if (item->menu->list)
400 item->setOpen(!item->isOpen()); 424 item->setOpen(!item->isOpen());
401 return; 425 return;
402 } 426 }
403 427
404 type = sym_get_type(sym); 428 type = sym_get_type(sym);
405 switch (type) { 429 switch (type) {
406 case S_BOOLEAN: 430 case S_BOOLEAN:
407 case S_TRISTATE: 431 case S_TRISTATE:
408 oldexpr = sym_get_tristate_value(sym); 432 oldexpr = sym_get_tristate_value(sym);
409 newexpr = sym_toggle_tristate_value(sym); 433 newexpr = sym_toggle_tristate_value(sym);
410 if (item->menu->list) { 434 if (item->menu->list) {
411 if (oldexpr == newexpr) 435 if (oldexpr == newexpr)
412 item->setOpen(!item->isOpen()); 436 item->setOpen(!item->isOpen());
413 else if (oldexpr == no) 437 else if (oldexpr == no)
414 item->setOpen(TRUE); 438 item->setOpen(TRUE);
415 } 439 }
416 if (oldexpr != newexpr) 440 if (oldexpr != newexpr)
417 emit symbolChanged(item); 441 parent()->updateList(item);
418 break; 442 break;
419 case S_INT: 443 case S_INT:
420 case S_HEX: 444 case S_HEX:
421 case S_STRING: 445 case S_STRING:
422#if QT_VERSION >= 300 446#if QT_VERSION >= 300
423 if (colMap[dataColIdx] >= 0) 447 if (colMap[dataColIdx] >= 0)
424 item->startRename(colMap[dataColIdx]); 448 item->startRename(colMap[dataColIdx]);
425 else 449 else
426#endif 450#endif
427 lineEdit->show(item); 451 parent()->lineEdit->show(item);
428 break; 452 break;
429 } 453 }
430} 454}
431 455
432void ConfigList::setRootMenu(struct menu *menu) 456void ConfigList::setRootMenu(struct menu *menu)
433{ 457{
434 enum prop_type type; 458 enum prop_type type;
435 459
436 if (rootEntry == menu) 460 if (rootEntry == menu)
437 return; 461 return;
438 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN; 462 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
439 if (type != P_MENU && type != P_ROOTMENU) 463 if (type != P_MENU && type != P_ROOTMENU)
440 return; 464 return;
441 updateMenuList(this, 0); 465 updateMenuList(this, 0);
442 rootEntry = menu; 466 rootEntry = menu;
443 updateListAll(); 467 updateListAll();
444 setSelected(currentItem(), hasFocus()); 468 setSelected(currentItem(), hasFocus());
445} 469}
446 470
447void ConfigList::setParentMenu(void) 471void ConfigList::setParentMenu(void)
448{ 472{
449 ConfigItem* item; 473 ConfigItem* item;
450 struct menu *oldroot, *newroot; 474 struct menu *oldroot, *newroot;
451 475
452 oldroot = rootEntry; 476 oldroot = rootEntry;
453 newroot = menu_get_parent_menu(oldroot); 477 newroot = menu_get_parent_menu(oldroot);
454 if (newroot == oldroot) 478 if (newroot == oldroot)
455 return; 479 return;
456 setRootMenu(newroot); 480 setRootMenu(newroot);
457 481
458 QListViewItemIterator it(this); 482 QListViewItemIterator it(this);
459 for (; (item = (ConfigItem*)it.current()); it++) { 483 for (; (item = (ConfigItem*)it.current()); it++) {
460 if (item->menu == oldroot) { 484 if (item->menu == oldroot) {
461 setCurrentItem(item); 485 setCurrentItem(item);
462 ensureItemVisible(item); 486 ensureItemVisible(item);
463 break; 487 break;
464 } 488 }
465 } 489 }
466} 490}
467 491
468void ConfigList::keyPressEvent(QKeyEvent* ev) 492void ConfigList::keyPressEvent(QKeyEvent* ev)
469{ 493{
470 QListViewItem* i = currentItem(); 494 QListViewItem* i = currentItem();
471 ConfigItem* item; 495 ConfigItem* item;
472 struct menu *menu; 496 struct menu *menu;
473 enum prop_type type; 497 enum prop_type type;
474 498
475 if (ev->key() == Key_Escape && mode != fullMode) { 499 if (ev->key() == Key_Escape && mode != fullMode) {
476 emit parentSelected(); 500 emit parentSelected();
477 ev->accept(); 501 ev->accept();
478 return; 502 return;
479 } 503 }
480 504
481 if (!i) { 505 if (!i) {
482 Parent::keyPressEvent(ev); 506 Parent::keyPressEvent(ev);
483 return; 507 return;
484 } 508 }
485 item = (ConfigItem*)i; 509 item = (ConfigItem*)i;
486 510
487 switch (ev->key()) { 511 switch (ev->key()) {
488 case Key_Return: 512 case Key_Return:
489 case Key_Enter: 513 case Key_Enter:
490 menu = item->menu; 514 menu = item->menu;
491 type = menu->prompt ? menu->prompt->type : P_UNKNOWN; 515 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
492 if ((type == P_MENU || type == P_ROOTMENU) && mode != fullMode) { 516 if ((type == P_MENU || type == P_ROOTMENU) && mode != fullMode) {
493 emit menuSelected(menu); 517 emit menuSelected(menu);
494 break; 518 break;
495 } 519 }
496 case Key_Space: 520 case Key_Space:
497 changeValue(item); 521 changeValue(item);
498 break; 522 break;
499 case Key_N: 523 case Key_N:
500 setValue(item, no); 524 setValue(item, no);
501 break; 525 break;
502 case Key_M: 526 case Key_M:
503 setValue(item, mod); 527 setValue(item, mod);
504 break; 528 break;
505 case Key_Y: 529 case Key_Y:
506 setValue(item, yes); 530 setValue(item, yes);
507 break; 531 break;
508 default: 532 default:
509 Parent::keyPressEvent(ev); 533 Parent::keyPressEvent(ev);
510 return; 534 return;
511 } 535 }
512 ev->accept(); 536 ev->accept();
513} 537}
514 538
515void ConfigList::contentsMousePressEvent(QMouseEvent* e) 539void ConfigList::contentsMousePressEvent(QMouseEvent* e)
516{ 540{
517 //QPoint p(contentsToViewport(e->pos())); 541 //QPoint p(contentsToViewport(e->pos()));
518 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); 542 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
519 QListView::contentsMousePressEvent(e); 543 Parent::contentsMousePressEvent(e);
520} 544}
521 545
522void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) 546void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
523{ 547{
524 QPoint p(contentsToViewport(e->pos())); 548 QPoint p(contentsToViewport(e->pos()));
525 ConfigItem* item = (ConfigItem*)itemAt(p); 549 ConfigItem* item = (ConfigItem*)itemAt(p);
526 struct menu *menu; 550 struct menu *menu;
527 const QPixmap* pm; 551 const QPixmap* pm;
528 int idx, x; 552 int idx, x;
529 553
530 if (!item) 554 if (!item)
531 goto skip; 555 goto skip;
532 556
533 menu = item->menu; 557 menu = item->menu;
534 x = header()->offset() + p.x(); 558 x = header()->offset() + p.x();
535 idx = colRevMap[header()->sectionAt(x)]; 559 idx = colRevMap[header()->sectionAt(x)];
536 switch (idx) { 560 switch (idx) {
537 case promptColIdx: 561 case promptColIdx:
538 pm = item->pixmap(promptColIdx); 562 pm = item->pixmap(promptColIdx);
539 if (pm) { 563 if (pm) {
540 int off = header()->sectionPos(0) + itemMargin() + 564 int off = header()->sectionPos(0) + itemMargin() +
541 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0)); 565 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
542 if (x >= off && x < off + pm->width()) { 566 if (x >= off && x < off + pm->width()) {
543 if (menu->sym) 567 if (menu->sym)
544 changeValue(item); 568 changeValue(item);
545 else 569 else
546 emit menuSelected(menu); 570 emit menuSelected(menu);
547 } 571 }
548 } 572 }
549 break; 573 break;
550 case noColIdx: 574 case noColIdx:
551 setValue(item, no); 575 setValue(item, no);
552 break; 576 break;
553 case modColIdx: 577 case modColIdx:
554 setValue(item, mod); 578 setValue(item, mod);
555 break; 579 break;
556 case yesColIdx: 580 case yesColIdx:
557 setValue(item, yes); 581 setValue(item, yes);
558 break; 582 break;
559 case dataColIdx: 583 case dataColIdx:
560 changeValue(item); 584 changeValue(item);
561 break; 585 break;
562 } 586 }
563 587
564skip: 588skip:
565 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y()); 589 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
566 QListView::contentsMouseReleaseEvent(e); 590 Parent::contentsMouseReleaseEvent(e);
567} 591}
568 592
569void ConfigList::contentsMouseMoveEvent(QMouseEvent* e) 593void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
570{ 594{
571 //QPoint p(contentsToViewport(e->pos())); 595 //QPoint p(contentsToViewport(e->pos()));
572 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); 596 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
573 QListView::contentsMouseMoveEvent(e); 597 Parent::contentsMouseMoveEvent(e);
574} 598}
575 599
576void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) 600void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
577{ 601{
578 QPoint p(contentsToViewport(e->pos())); 602 QPoint p(contentsToViewport(e->pos()));
579 ConfigItem* item = (ConfigItem*)itemAt(p); 603 ConfigItem* item = (ConfigItem*)itemAt(p);
580 struct menu *menu; 604 struct menu *menu;
581 enum prop_type ptype; 605 enum prop_type ptype;
582 606
583 if (!item) 607 if (!item)
584 goto skip; 608 goto skip;
585 menu = item->menu; 609 menu = item->menu;
586 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 610 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
587 if ((ptype == P_ROOTMENU || ptype == P_MENU) && 611 if ((ptype == P_ROOTMENU || ptype == P_MENU) &&
588 (mode == singleMode || mode == symbolMode)) 612 (mode == singleMode || mode == symbolMode))
589 emit menuSelected(menu); 613 emit menuSelected(menu);
614 else if (menu->sym)
615 changeValue(item);
590 616
591skip: 617skip:
592 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y()); 618 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
593 QListView::contentsMouseDoubleClickEvent(e); 619 Parent::contentsMouseDoubleClickEvent(e);
594} 620}
595 621
596void ConfigList::focusInEvent(QFocusEvent *e) 622void ConfigList::focusInEvent(QFocusEvent *e)
597{ 623{
598 Parent::focusInEvent(e); 624 Parent::focusInEvent(e);
599 625
600 QListViewItem* item = currentItem(); 626 QListViewItem* item = currentItem();
601 if (!item) 627 if (!item)
602 return; 628 return;
603 629
604 setSelected(item, TRUE); 630 setSelected(item, TRUE);
605 emit gotFocus(); 631 emit gotFocus();
606} 632}
607 633
634ConfigView* ConfigView::viewList;
635
636ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview)
637 : Parent(parent)
638{
639 list = new ConfigList(this, cview);
640 lineEdit = new ConfigLineEdit(this);
641 lineEdit->hide();
642
643 this->nextView = viewList;
644 viewList = this;
645}
646
647ConfigView::~ConfigView(void)
648{
649 ConfigView** vp;
650
651 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
652 if (*vp == this) {
653 *vp = nextView;
654 break;
655 }
656 }
657}
658
659void ConfigView::updateList(ConfigItem* item)
660{
661 ConfigView* v;
662
663 for (v = viewList; v; v = v->nextView)
664 v->list->updateList(item);
665}
666
667void ConfigView::updateListAll(void)
668{
669 ConfigView* v;
670
671 for (v = viewList; v; v = v->nextView)
672 v->list->updateListAll();
673}
674
608/* 675/*
609 * Construct the complete config widget 676 * Construct the complete config widget
610 */ 677 */
611ConfigView::ConfigView(void) 678ConfigMainWindow::ConfigMainWindow(void)
612{ 679{
680 ConfigView* view;
613 QMenuBar* menu; 681 QMenuBar* menu;
614 QSplitter* split1; 682 QSplitter* split1;
615 QSplitter* split2; 683 QSplitter* split2;
684 bool ok;
685 int x, y, width, height;
686
687 QWidget *d = configApp->desktop();
688
689#if QT_VERSION >= 300
690 width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64);
691 height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64);
692 resize(width, height);
693 x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok);
694 if (ok)
695 y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok);
696 if (ok)
697 move(x, y);
698#else
699 width = d->width() - 64;
700 height = d->height() - 64;
701 resize(width, height);
702#endif
616 703
617 showDebug = false; 704 showDebug = false;
618 705
619 split1 = new QSplitter(this); 706 split1 = new QSplitter(this);
620 split1->setOrientation(QSplitter::Horizontal); 707 split1->setOrientation(QSplitter::Horizontal);
621 setCentralWidget(split1); 708 setCentralWidget(split1);
622 709
623 menuList = new ConfigList(split1, this); 710 view = new ConfigView(split1, this);
711 menuList = view->list;
624 712
625 split2 = new QSplitter(split1); 713 split2 = new QSplitter(split1);
626 split2->setOrientation(QSplitter::Vertical); 714 split2->setOrientation(QSplitter::Vertical);
627 715
628 // create config tree 716 // create config tree
629 QVBox* box = new QVBox(split2); 717 view = new ConfigView(split2, this);
630 configList = new ConfigList(box, this); 718 configList = view->list;
631 configList->lineEdit = new ConfigLineEdit(box);
632 configList->lineEdit->hide();
633 configList->connect(configList, SIGNAL(symbolChanged(ConfigItem*)),
634 configList, SLOT(updateList(ConfigItem*)));
635 configList->connect(configList, SIGNAL(symbolChanged(ConfigItem*)),
636 menuList, SLOT(updateList(ConfigItem*)));
637 configList->connect(configList->lineEdit, SIGNAL(lineChanged(ConfigItem*)),
638 SLOT(updateList(ConfigItem*)));
639 719
640 helpText = new QTextView(split2); 720 helpText = new QTextView(split2);
641 helpText->setTextFormat(Qt::RichText); 721 helpText->setTextFormat(Qt::RichText);
642 722
643 setTabOrder(configList, helpText); 723 setTabOrder(configList, helpText);
644 configList->setFocus(); 724 configList->setFocus();
645 725
646 menu = menuBar(); 726 menu = menuBar();
647 toolBar = new QToolBar("Tools", this); 727 toolBar = new QToolBar("Tools", this);
648 728
649 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this); 729 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
650 connect(backAction, SIGNAL(activated()), SLOT(goBack())); 730 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
651 backAction->setEnabled(FALSE); 731 backAction->setEnabled(FALSE);
652 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this); 732 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
653 connect(quitAction, SIGNAL(activated()), SLOT(close())); 733 connect(quitAction, SIGNAL(activated()), SLOT(close()));
654 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this); 734 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
655 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); 735 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
656 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this); 736 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
657 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); 737 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
658 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this); 738 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
659 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); 739 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
660 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this); 740 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
661 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); 741 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
662 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this); 742 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
663 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); 743 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
664 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this); 744 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
665 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); 745 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
666 746
667 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this); 747 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
668 showNameAction->setToggleAction(TRUE); 748 showNameAction->setToggleAction(TRUE);
669 showNameAction->setOn(configList->showName); 749 showNameAction->setOn(configList->showName);
670 connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool))); 750 connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool)));
671 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this); 751 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
672 showRangeAction->setToggleAction(TRUE); 752 showRangeAction->setToggleAction(TRUE);
673 showRangeAction->setOn(configList->showRange); 753 showRangeAction->setOn(configList->showRange);
674 connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool))); 754 connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool)));
675 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this); 755 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
676 showDataAction->setToggleAction(TRUE); 756 showDataAction->setToggleAction(TRUE);
677 showDataAction->setOn(configList->showData); 757 showDataAction->setOn(configList->showData);
678 connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool))); 758 connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool)));
679 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this); 759 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
680 showAllAction->setToggleAction(TRUE); 760 showAllAction->setToggleAction(TRUE);
681 showAllAction->setOn(configList->showAll); 761 showAllAction->setOn(configList->showAll);
682 connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool))); 762 connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool)));
683 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this); 763 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
684 showDebugAction->setToggleAction(TRUE); 764 showDebugAction->setToggleAction(TRUE);
685 showDebugAction->setOn(showDebug); 765 showDebugAction->setOn(showDebug);
686 connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); 766 connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
687 767
768 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
769 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
770 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
771 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
772
688 // init tool bar 773 // init tool bar
689 backAction->addTo(toolBar); 774 backAction->addTo(toolBar);
690 toolBar->addSeparator(); 775 toolBar->addSeparator();
691 loadAction->addTo(toolBar); 776 loadAction->addTo(toolBar);
692 saveAction->addTo(toolBar); 777 saveAction->addTo(toolBar);
693 toolBar->addSeparator(); 778 toolBar->addSeparator();
694 singleViewAction->addTo(toolBar); 779 singleViewAction->addTo(toolBar);
695 splitViewAction->addTo(toolBar); 780 splitViewAction->addTo(toolBar);
696 fullViewAction->addTo(toolBar); 781 fullViewAction->addTo(toolBar);
697 782
698 // create config menu 783 // create config menu
699 QPopupMenu* config = new QPopupMenu(this); 784 QPopupMenu* config = new QPopupMenu(this);
700 menu->insertItem("&File", config); 785 menu->insertItem("&File", config);
701 loadAction->addTo(config); 786 loadAction->addTo(config);
702 saveAction->addTo(config); 787 saveAction->addTo(config);
703 saveAsAction->addTo(config); 788 saveAsAction->addTo(config);
704 config->insertSeparator(); 789 config->insertSeparator();
705 quitAction->addTo(config); 790 quitAction->addTo(config);
706 791
707 // create options menu 792 // create options menu
708 QPopupMenu* optionMenu = new QPopupMenu(this); 793 QPopupMenu* optionMenu = new QPopupMenu(this);
709 menu->insertItem("&Option", optionMenu); 794 menu->insertItem("&Option", optionMenu);
710 showNameAction->addTo(optionMenu); 795 showNameAction->addTo(optionMenu);
711 showRangeAction->addTo(optionMenu); 796 showRangeAction->addTo(optionMenu);
712 showDataAction->addTo(optionMenu); 797 showDataAction->addTo(optionMenu);
713 optionMenu->insertSeparator(); 798 optionMenu->insertSeparator();
714 showAllAction->addTo(optionMenu); 799 showAllAction->addTo(optionMenu);
715 showDebugAction->addTo(optionMenu); 800 showDebugAction->addTo(optionMenu);
716 801
802 // create help menu
803 QPopupMenu* helpMenu = new QPopupMenu(this);
804 menu->insertSeparator();
805 menu->insertItem("&Help", helpMenu);
806 showIntroAction->addTo(helpMenu);
807 showAboutAction->addTo(helpMenu);
808
717 connect(configList, SIGNAL(menuSelected(struct menu *)), 809 connect(configList, SIGNAL(menuSelected(struct menu *)),
718 SLOT(changeMenu(struct menu *))); 810 SLOT(changeMenu(struct menu *)));
719 connect(configList, SIGNAL(parentSelected()), 811 connect(configList, SIGNAL(parentSelected()),
720 SLOT(goBack())); 812 SLOT(goBack()));
721 connect(menuList, SIGNAL(menuSelected(struct menu *)), 813 connect(menuList, SIGNAL(menuSelected(struct menu *)),
722 SLOT(changeMenu(struct menu *))); 814 SLOT(changeMenu(struct menu *)));
723 815
724 connect(configList, SIGNAL(gotFocus(void)), 816 connect(configList, SIGNAL(gotFocus(void)),
725 SLOT(listFocusChanged(void))); 817 SLOT(listFocusChanged(void)));
726 connect(menuList, SIGNAL(gotFocus(void)), 818 connect(menuList, SIGNAL(gotFocus(void)),
727 SLOT(listFocusChanged(void))); 819 SLOT(listFocusChanged(void)));
728 820
729 //showFullView(); 821 //showFullView();
730 showSplitView(); 822 showSplitView();
731} 823}
732 824
733static QString print_filter(const char *str) 825static QString print_filter(const char *str)
734{ 826{
735 QRegExp re("[<>&\"\\n]"); 827 QRegExp re("[<>&\"\\n]");
736 QString res = str; 828 QString res = str;
737 for (int i = 0; (i = res.find(re, i)) >= 0;) { 829 for (int i = 0; (i = res.find(re, i)) >= 0;) {
738 switch (res[i].latin1()) { 830 switch (res[i].latin1()) {
739 case '<': 831 case '<':
740 res.replace(i, 1, "&lt;"); 832 res.replace(i, 1, "&lt;");
741 i += 4; 833 i += 4;
742 break; 834 break;
743 case '>': 835 case '>':
744 res.replace(i, 1, "&gt;"); 836 res.replace(i, 1, "&gt;");
745 i += 4; 837 i += 4;
746 break; 838 break;
747 case '&': 839 case '&':
748 res.replace(i, 1, "&amp;"); 840 res.replace(i, 1, "&amp;");
749 i += 5; 841 i += 5;
750 break; 842 break;
751 case '"': 843 case '"':
752 res.replace(i, 1, "&quot;"); 844 res.replace(i, 1, "&quot;");
753 i += 6; 845 i += 6;
754 break; 846 break;
755 case '\n': 847 case '\n':
756 res.replace(i, 1, "<br>"); 848 res.replace(i, 1, "<br>");
757 i += 4; 849 i += 4;
758 break; 850 break;
759 } 851 }
760 } 852 }
761 return res; 853 return res;
762} 854}
763 855
764static void expr_print_help(void *data, const char *str) 856static void expr_print_help(void *data, const char *str)
765{ 857{
766 ((QString*)data)->append(print_filter(str)); 858 ((QString*)data)->append(print_filter(str));
767} 859}
768 860
769/* 861/*
770 * display a new help entry as soon as a new menu entry is selected 862 * display a new help entry as soon as a new menu entry is selected
771 */ 863 */
772void ConfigView::setHelp(QListViewItem* item) 864void ConfigMainWindow::setHelp(QListViewItem* item)
773{ 865{
774 struct symbol* sym; 866 struct symbol* sym;
775 struct menu* menu; 867 struct menu* menu;
776 868
777 configList->lineEdit->hide(); 869 configList->parent()->lineEdit->hide();
778 if (item) { 870 if (item) {
779 QString head, debug, help; 871 QString head, debug, help;
780 menu = ((ConfigItem*)item)->menu; 872 menu = ((ConfigItem*)item)->menu;
781 sym = menu->sym; 873 sym = menu->sym;
782 if (sym) { 874 if (sym) {
783 if (menu->prompt) { 875 if (menu->prompt) {
784 head += "<big><b>"; 876 head += "<big><b>";
785 head += print_filter(menu->prompt->text); 877 head += print_filter(menu->prompt->text);
786 head += "</b></big>"; 878 head += "</b></big>";
787 if (sym->name) { 879 if (sym->name) {
788 head += " ("; 880 head += " (";
789 head += print_filter(sym->name); 881 head += print_filter(sym->name);
790 head += ")"; 882 head += ")";
791 } 883 }
792 } else if (sym->name) { 884 } else if (sym->name) {
793 head += "<big><b>"; 885 head += "<big><b>";
794 head += print_filter(sym->name); 886 head += print_filter(sym->name);
795 head += "</b></big>"; 887 head += "</b></big>";
796 } 888 }
797 head += "<br><br>"; 889 head += "<br><br>";
798 890
799 if (showDebug) { 891 if (showDebug) {
800 debug += "type: "; 892 debug += "type: ";
801 debug += print_filter(sym_type_name(sym->type)); 893 debug += print_filter(sym_type_name(sym->type));
802 debug += "<br>"; 894 debug += "<br>";
803 for (struct property *prop = sym->prop; prop; prop = prop->next) { 895 for (struct property *prop = sym->prop; prop; prop = prop->next) {
804 switch (prop->type) { 896 switch (prop->type) {
805 case P_PROMPT: 897 case P_PROMPT:
806 debug += "prompt: "; 898 debug += "prompt: ";
807 debug += print_filter(prop->text); 899 debug += print_filter(prop->text);
808 debug += "<br>"; 900 debug += "<br>";
809 if (prop->visible.expr) { 901 if (prop->visible.expr) {
810 debug += "&nbsp;&nbsp;dep: "; 902 debug += "&nbsp;&nbsp;dep: ";
811 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); 903 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
812 debug += "<br>"; 904 debug += "<br>";
813 } 905 }
814 break; 906 break;
815 case P_DEFAULT: 907 case P_DEFAULT:
816 debug += "default: "; 908 debug += "default: ";
817 if (sym_is_choice(sym)) 909 if (sym_is_choice(sym))
818 debug += print_filter(prop->def->name); 910 debug += print_filter(prop->def->name);
819 else { 911 else {
820 sym_calc_value(prop->def); 912 sym_calc_value(prop->def);
821 debug += print_filter(sym_get_string_value(prop->def)); 913 debug += print_filter(sym_get_string_value(prop->def));
822 } 914 }
823 debug += "<br>"; 915 debug += "<br>";
824 if (prop->visible.expr) { 916 if (prop->visible.expr) {
825 debug += "&nbsp;&nbsp;dep: "; 917 debug += "&nbsp;&nbsp;dep: ";
826 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); 918 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
827 debug += "<br>"; 919 debug += "<br>";
828 } 920 }
829 break; 921 break;
830 case P_CHOICE: 922 case P_CHOICE:
831 break; 923 break;
832 default: 924 default:
833 debug += "unknown property: "; 925 debug += "unknown property: ";
834 debug += prop_get_type_name(prop->type); 926 debug += prop_get_type_name(prop->type);
835 debug += "<br>"; 927 debug += "<br>";
836 } 928 }
837 } 929 }
838 debug += "<br>"; 930 debug += "<br>";
839 } 931 }
840 932
841 help = print_filter(sym->help); 933 help = print_filter(sym->help);
842 } else if (menu->prompt) { 934 } else if (menu->prompt) {
843 head += "<big><b>"; 935 head += "<big><b>";
844 head += print_filter(menu->prompt->text); 936 head += print_filter(menu->prompt->text);
845 head += "</b></big><br><br>"; 937 head += "</b></big><br><br>";
846 if (showDebug) { 938 if (showDebug) {
847 if (menu->prompt->visible.expr) { 939 if (menu->prompt->visible.expr) {
848 debug += "&nbsp;&nbsp;dep: "; 940 debug += "&nbsp;&nbsp;dep: ";
849 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); 941 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
850 debug += "<br>"; 942 debug += "<br>";
851 } 943 }
852 } 944 }
853 } 945 }
854 helpText->setText(head + debug + help); 946 helpText->setText(head + debug + help);
855 return; 947 return;
856 } 948 }
857 helpText->setText(NULL); 949 helpText->setText(NULL);
858} 950}
859 951
860void ConfigView::loadConfig(void) 952void ConfigMainWindow::loadConfig(void)
861{ 953{
862 QString s = QFileDialog::getOpenFileName(".config", NULL, this); 954 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
863 if (s.isNull()) 955 if (s.isNull())
864 return; 956 return;
865 if (conf_read(s.latin1())) 957 if (conf_read(s.latin1()))
866 QMessageBox::information(this, "qconf", "Unable to load configuration!"); 958 QMessageBox::information(this, "qconf", "Unable to load configuration!");
959 ConfigView::updateListAll();
867} 960}
868 961
869void ConfigView::saveConfig(void) 962void ConfigMainWindow::saveConfig(void)
870{ 963{
871 if (conf_write(NULL)) 964 if (conf_write(NULL))
872 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 965 QMessageBox::information(this, "qconf", "Unable to save configuration!");
873} 966}
874 967
875void ConfigView::saveConfigAs(void) 968void ConfigMainWindow::saveConfigAs(void)
876{ 969{
877 QString s = QFileDialog::getSaveFileName(".config", NULL, this); 970 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
878 if (s.isNull()) 971 if (s.isNull())
879 return; 972 return;
880 if (conf_write(s.latin1())) 973 if (conf_write(s.latin1()))
881 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 974 QMessageBox::information(this, "qconf", "Unable to save configuration!");
882} 975}
883 976
884void ConfigView::changeMenu(struct menu *menu) 977void ConfigMainWindow::changeMenu(struct menu *menu)
885{ 978{
886 configList->setRootMenu(menu); 979 configList->setRootMenu(menu);
887 backAction->setEnabled(TRUE); 980 backAction->setEnabled(TRUE);
888} 981}
889 982
890void ConfigView::listFocusChanged(void) 983void ConfigMainWindow::listFocusChanged(void)
891{ 984{
892 if (menuList->hasFocus()) { 985 if (menuList->hasFocus()) {
893 if (menuList->mode == menuMode) 986 if (menuList->mode == menuMode)
894 configList->clearSelection(); 987 configList->clearSelection();
895 setHelp(menuList->selectedItem()); 988 setHelp(menuList->selectedItem());
896 } else if (configList->hasFocus()) { 989 } else if (configList->hasFocus()) {
897 setHelp(configList->selectedItem()); 990 setHelp(configList->selectedItem());
898 } 991 }
899} 992}
900 993
901void ConfigView::goBack(void) 994void ConfigMainWindow::goBack(void)
902{ 995{
903 ConfigItem* item; 996 ConfigItem* item;
904 997
905 configList->setParentMenu(); 998 configList->setParentMenu();
906 if (configList->rootEntry == &rootmenu) 999 if (configList->rootEntry == &rootmenu)
907 backAction->setEnabled(FALSE); 1000 backAction->setEnabled(FALSE);
908 item = (ConfigItem*)menuList->selectedItem(); 1001 item = (ConfigItem*)menuList->selectedItem();
909 while (item) { 1002 while (item) {
910 if (item->menu == configList->rootEntry) { 1003 if (item->menu == configList->rootEntry) {
911 menuList->setSelected(item, TRUE); 1004 menuList->setSelected(item, TRUE);
912 break; 1005 break;
913 } 1006 }
914 item = (ConfigItem*)item->parent(); 1007 item = (ConfigItem*)item->parent();
915 } 1008 }
916} 1009}
917 1010
918void ConfigView::showSingleView(void) 1011void ConfigMainWindow::showSingleView(void)
919{ 1012{
920 menuList->hide(); 1013 menuList->hide();
921 menuList->setRootMenu(0); 1014 menuList->setRootMenu(0);
922 configList->mode = singleMode; 1015 configList->mode = singleMode;
923 if (configList->rootEntry == &rootmenu) 1016 if (configList->rootEntry == &rootmenu)
924 configList->updateListAll(); 1017 configList->updateListAll();
925 else 1018 else
926 configList->setRootMenu(&rootmenu); 1019 configList->setRootMenu(&rootmenu);
927 configList->setAllOpen(TRUE); 1020 configList->setAllOpen(TRUE);
928 configList->setFocus(); 1021 configList->setFocus();
929} 1022}
930 1023
931void ConfigView::showSplitView(void) 1024void ConfigMainWindow::showSplitView(void)
932{ 1025{
933 configList->mode = symbolMode; 1026 configList->mode = symbolMode;
934 if (configList->rootEntry == &rootmenu) 1027 if (configList->rootEntry == &rootmenu)
935 configList->updateListAll(); 1028 configList->updateListAll();
936 else 1029 else
937 configList->setRootMenu(&rootmenu); 1030 configList->setRootMenu(&rootmenu);
938 configList->setAllOpen(TRUE); 1031 configList->setAllOpen(TRUE);
939 configApp->processEvents(); 1032 configApp->processEvents();
940 menuList->mode = menuMode; 1033 menuList->mode = menuMode;
941 menuList->setRootMenu(&rootmenu); 1034 menuList->setRootMenu(&rootmenu);
942 menuList->show(); 1035 menuList->show();
943 menuList->setAllOpen(TRUE); 1036 menuList->setAllOpen(TRUE);
944 menuList->setFocus(); 1037 menuList->setFocus();
945} 1038}
946 1039
947void ConfigView::showFullView(void) 1040void ConfigMainWindow::showFullView(void)
948{ 1041{
949 menuList->hide(); 1042 menuList->hide();
950 menuList->setRootMenu(0); 1043 menuList->setRootMenu(0);
951 configList->mode = fullMode; 1044 configList->mode = fullMode;
952 if (configList->rootEntry == &rootmenu) 1045 if (configList->rootEntry == &rootmenu)
953 configList->updateListAll(); 1046 configList->updateListAll();
954 else 1047 else
955 configList->setRootMenu(&rootmenu); 1048 configList->setRootMenu(&rootmenu);
956 configList->setAllOpen(FALSE); 1049 configList->setAllOpen(FALSE);
957 configList->setFocus(); 1050 configList->setFocus();
958} 1051}
959 1052
960void ConfigView::setShowAll(bool b) 1053void ConfigMainWindow::setShowAll(bool b)
961{ 1054{
962 if (configList->showAll == b) 1055 if (configList->showAll == b)
963 return; 1056 return;
964 configList->showAll = b; 1057 configList->showAll = b;
965 configList->updateListAll(); 1058 configList->updateListAll();
966 menuList->showAll = b; 1059 menuList->showAll = b;
967 menuList->updateListAll(); 1060 menuList->updateListAll();
968} 1061}
969 1062
970void ConfigView::setShowDebug(bool b) 1063void ConfigMainWindow::setShowDebug(bool b)
971{ 1064{
972 if (showDebug == b) 1065 if (showDebug == b)
973 return; 1066 return;
974 showDebug = b; 1067 showDebug = b;
975} 1068}
976 1069
977void ConfigView::setShowName(bool b) 1070void ConfigMainWindow::setShowName(bool b)
978{ 1071{
979 if (configList->showName == b) 1072 if (configList->showName == b)
980 return; 1073 return;
981 configList->showName = b; 1074 configList->showName = b;
982 configList->reinit(); 1075 configList->reinit();
983} 1076}
984 1077
985void ConfigView::setShowRange(bool b) 1078void ConfigMainWindow::setShowRange(bool b)
986{ 1079{
987 if (configList->showRange == b) 1080 if (configList->showRange == b)
988 return; 1081 return;
989 configList->showRange = b; 1082 configList->showRange = b;
990 configList->reinit(); 1083 configList->reinit();
991} 1084}
992 1085
993void ConfigView::setShowData(bool b) 1086void ConfigMainWindow::setShowData(bool b)
994{ 1087{
995 if (configList->showData == b) 1088 if (configList->showData == b)
996 return; 1089 return;
997 configList->showData = b; 1090 configList->showData = b;
998 configList->reinit(); 1091 configList->reinit();
999} 1092}
1000 1093
1001/* 1094/*
1002 * ask for saving configuration before quitting 1095 * ask for saving configuration before quitting
1003 * TODO ask only when something changed 1096 * TODO ask only when something changed
1004 */ 1097 */
1005void ConfigView::closeEvent(QCloseEvent* e) 1098void ConfigMainWindow::closeEvent(QCloseEvent* e)
1006{ 1099{
1007 if (!sym_change_count) { 1100 if (!sym_change_count) {
1008 e->accept(); 1101 e->accept();
1009 return; 1102 return;
1010 } 1103 }
1011 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, 1104 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1012 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); 1105 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1013 mb.setButtonText(QMessageBox::Yes, "&Save Changes"); 1106 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1014 mb.setButtonText(QMessageBox::No, "&Discard Changes"); 1107 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1015 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit"); 1108 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1016 switch (mb.exec()) { 1109 switch (mb.exec()) {
1017 case QMessageBox::Yes: 1110 case QMessageBox::Yes:
1018 conf_write(NULL); 1111 conf_write(NULL);
1019 case QMessageBox::No: 1112 case QMessageBox::No:
1020 e->accept(); 1113 e->accept();
1021 break; 1114 break;
1022 case QMessageBox::Cancel: 1115 case QMessageBox::Cancel:
1023 e->ignore(); 1116 e->ignore();
1024 break; 1117 break;
1025 } 1118 }
1026} 1119}
1027 1120
1121void ConfigMainWindow::showIntro(void)
1122{
1123 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1124 "For each option, a blank box indicates the feature is disabled, a check\n"
1125 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1126 "as a module. Clicking on the box will cycle through the three states.\n\n"
1127 "If you do not see an option (e.g., a device driver) that you believe\n"
1128 "should be present, try turning on Show All Options under the Options menu.\n"
1129 "Although there is no cross reference yet to help you figure out what other\n"
1130 "options must be enabled to support the option you are interested in, you can\n"
1131 "still view the help of a grayed-out option.\n\n"
1132 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1133 "which you can then match by examining other options.\n\n";
1134
1135 QMessageBox::information(this, "qconf", str);
1136}
1137
1138void ConfigMainWindow::showAbout(void)
1139{
1140 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1141 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1142
1143 QMessageBox::information(this, "qconf", str);
1144}
1145
1028void fixup_rootmenu(struct menu *menu) 1146void fixup_rootmenu(struct menu *menu)
1029{ 1147{
1030 struct menu *child; 1148 struct menu *child;
1031 1149
1032 if (!menu->prompt || menu->prompt->type != P_MENU) 1150 if (!menu->prompt || menu->prompt->type != P_MENU)
1033 return; 1151 return;
1034 menu->prompt->type = P_ROOTMENU; 1152 menu->prompt->type = P_ROOTMENU;
1035 for (child = menu->list; child; child = child->next) 1153 for (child = menu->list; child; child = child->next)
1036 fixup_rootmenu(child); 1154 fixup_rootmenu(child);
1037} 1155}
1038 1156
1039int main(int ac, char** av) 1157int main(int ac, char** av)
1040{ 1158{
1041 ConfigView* v; 1159 ConfigMainWindow* v;
1042 const char *name; 1160 const char *name;
1043 1161
1044#ifndef LKC_DIRECT_LINK 1162#ifndef LKC_DIRECT_LINK
1045 kconfig_load(); 1163 kconfig_load();
1046#endif 1164#endif
1047 1165
1048 configApp = new QApplication(ac, av); 1166 configApp = new QApplication(ac, av);
1167#if QT_VERSION >= 300
1168 configSettings = new QSettings;
1169#endif
1049 if (ac > 1 && av[1][0] == '-') { 1170 if (ac > 1 && av[1][0] == '-') {
1050 switch (av[1][1]) { 1171 switch (av[1][1]) {
1051 case 'a': 1172 case 'a':
1052 //showAll = 1; 1173 //showAll = 1;
1053 break; 1174 break;
1054 case 'h': 1175 case 'h':
1055 case '?': 1176 case '?':
1056 printf("%s <config>\n", av[0]); 1177 printf("%s <config>\n", av[0]);
1057 exit(0); 1178 exit(0);
1058 } 1179 }
1059 name = av[2]; 1180 name = av[2];
1060 } else 1181 } else
1061 name = av[1]; 1182 name = av[1];
1062 conf_parse(name); 1183 conf_parse(name);
1063 fixup_rootmenu(&rootmenu); 1184 fixup_rootmenu(&rootmenu);
1064 conf_read(NULL); 1185 conf_read(NULL);
1065 //zconfdump(stdout); 1186 //zconfdump(stdout);
1066 v = new ConfigView(); 1187
1188 v = new ConfigMainWindow();
1067 1189
1068 //zconfdump(stdout); 1190 //zconfdump(stdout);
1069 v->show(); 1191 v->show();
1070 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); 1192 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1071 configApp->exec(); 1193 configApp->exec();
1194
1195#if QT_VERSION >= 300
1196 configSettings->writeEntry("/kconfig/qconf/window x", v->pos().x());
1197 configSettings->writeEntry("/kconfig/qconf/window y", v->pos().y());
1198 configSettings->writeEntry("/kconfig/qconf/window width", v->size().width());
1199 configSettings->writeEntry("/kconfig/qconf/window height", v->size().height());
1200 delete configSettings;
1201#endif
1072 return 0; 1202 return 0;
1073} 1203}
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index f8f3669..6f096b4 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -1,201 +1,226 @@
1/* 1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#include <qlistview.h> 6#include <qlistview.h>
7 7
8class ConfigLineEdit; 8class ConfigList;
9class ConfigItem; 9class ConfigItem;
10class ConfigView; 10class ConfigLineEdit;
11class ConfigMainWindow;
12
13class ConfigView : public QVBox {
14 Q_OBJECT
15 typedef class QVBox Parent;
16public:
17 ConfigView(QWidget* parent, ConfigMainWindow* cview);
18 ~ConfigView(void);
19 static void updateList(ConfigItem* item);
20 static void updateListAll(void);
21
22public:
23 ConfigList* list;
24 ConfigLineEdit* lineEdit;
25
26 static ConfigView* viewList;
27 ConfigView* nextView;
28};
11 29
12enum colIdx { 30enum colIdx {
13 promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr 31 promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
14}; 32};
15enum listMode { 33enum listMode {
16 singleMode, menuMode, symbolMode, fullMode 34 singleMode, menuMode, symbolMode, fullMode
17}; 35};
18 36
19class ConfigList : public QListView { 37class ConfigList : public QListView {
20 Q_OBJECT 38 Q_OBJECT
21 typedef class QListView Parent; 39 typedef class QListView Parent;
22public: 40public:
23 ConfigList(QWidget* p, ConfigView* cview); 41 ConfigList(ConfigView* p, ConfigMainWindow* cview);
24 void reinit(void); 42 void reinit(void);
43 ConfigView* parent(void) const
44 {
45 return (ConfigView*)Parent::parent();
46 }
25 47
26 ConfigLineEdit* lineEdit;
27protected: 48protected:
28 ConfigView* cview; 49 ConfigMainWindow* cview;
29 50
30 void keyPressEvent(QKeyEvent *e); 51 void keyPressEvent(QKeyEvent *e);
31 void contentsMousePressEvent(QMouseEvent *e); 52 void contentsMousePressEvent(QMouseEvent *e);
32 void contentsMouseReleaseEvent(QMouseEvent *e); 53 void contentsMouseReleaseEvent(QMouseEvent *e);
33 void contentsMouseMoveEvent(QMouseEvent *e); 54 void contentsMouseMoveEvent(QMouseEvent *e);
34 void contentsMouseDoubleClickEvent(QMouseEvent *e); 55 void contentsMouseDoubleClickEvent(QMouseEvent *e);
35 void focusInEvent(QFocusEvent *e); 56 void focusInEvent(QFocusEvent *e);
36public slots: 57public slots:
37 void setRootMenu(struct menu *menu); 58 void setRootMenu(struct menu *menu);
38 59
39 void updateList(ConfigItem *item); 60 void updateList(ConfigItem *item);
40 void setValue(ConfigItem* item, tristate val); 61 void setValue(ConfigItem* item, tristate val);
41 void changeValue(ConfigItem* item); 62 void changeValue(ConfigItem* item);
42 void updateSelection(void); 63 void updateSelection(void);
43signals: 64signals:
44 void menuSelected(struct menu *menu); 65 void menuSelected(struct menu *menu);
45 void parentSelected(void); 66 void parentSelected(void);
46 void symbolChanged(ConfigItem* item);
47 void gotFocus(void); 67 void gotFocus(void);
48 68
49public: 69public:
50 void updateListAll(void) 70 void updateListAll(void)
51 { 71 {
52 updateAll = true; 72 updateAll = true;
53 updateList(NULL); 73 updateList(NULL);
54 updateAll = false; 74 updateAll = false;
55 } 75 }
56 ConfigList* listView() 76 ConfigList* listView()
57 { 77 {
58 return this; 78 return this;
59 } 79 }
60 ConfigItem* firstChild() const 80 ConfigItem* firstChild() const
61 { 81 {
62 return (ConfigItem *)Parent::firstChild(); 82 return (ConfigItem *)Parent::firstChild();
63 } 83 }
64 int mapIdx(colIdx idx) 84 int mapIdx(colIdx idx)
65 { 85 {
66 return colMap[idx]; 86 return colMap[idx];
67 } 87 }
68 void addColumn(colIdx idx, const QString& label) 88 void addColumn(colIdx idx, const QString& label)
69 { 89 {
70 colMap[idx] = Parent::addColumn(label); 90 colMap[idx] = Parent::addColumn(label);
71 colRevMap[colMap[idx]] = idx; 91 colRevMap[colMap[idx]] = idx;
72 } 92 }
73 void removeColumn(colIdx idx) 93 void removeColumn(colIdx idx)
74 { 94 {
75 int col = colMap[idx]; 95 int col = colMap[idx];
76 if (col >= 0) { 96 if (col >= 0) {
77 Parent::removeColumn(col); 97 Parent::removeColumn(col);
78 colRevMap[col] = colMap[idx] = -1; 98 colRevMap[col] = colMap[idx] = -1;
79 } 99 }
80 } 100 }
81 void setAllOpen(bool open); 101 void setAllOpen(bool open);
82 void setParentMenu(void); 102 void setParentMenu(void);
83 103
84 bool updateAll; 104 bool updateAll;
85 105
86 QPixmap symbolYesPix, symbolModPix, symbolNoPix; 106 QPixmap symbolYesPix, symbolModPix, symbolNoPix;
87 QPixmap choiceYesPix, choiceNoPix, menuPix, menuInvPix; 107 QPixmap choiceYesPix, choiceNoPix, menuPix, menuInvPix;
88 108
89 bool showAll, showName, showRange, showData; 109 bool showAll, showName, showRange, showData;
90 enum listMode mode; 110 enum listMode mode;
91 struct menu *rootEntry; 111 struct menu *rootEntry;
92 QColorGroup disabledColorGroup; 112 QColorGroup disabledColorGroup;
93 QColorGroup inactivedColorGroup; 113 QColorGroup inactivedColorGroup;
94 114
95private: 115private:
96 int colMap[colNr]; 116 int colMap[colNr];
97 int colRevMap[colNr]; 117 int colRevMap[colNr];
98}; 118};
99 119
100class ConfigItem : public QListViewItem { 120class ConfigItem : public QListViewItem {
101 typedef class QListViewItem Parent; 121 typedef class QListViewItem Parent;
102public: 122public:
103 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m) 123 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v)
104 : Parent(parent, after), menu(m) 124 : Parent(parent, after), menu(m), visible(v)
105 { 125 {
106 init(); 126 init();
107 } 127 }
108 ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m) 128 ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
109 : Parent(parent, after), menu(m) 129 : Parent(parent, after), menu(m), visible(v)
110 { 130 {
111 init(); 131 init();
112 } 132 }
113 ~ConfigItem(void); 133 ~ConfigItem(void);
114 void init(void); 134 void init(void);
115#if QT_VERSION >= 300 135#if QT_VERSION >= 300
116 void okRename(int col); 136 void okRename(int col);
117#endif 137#endif
118 void updateMenu(void); 138 void updateMenu(void);
139 bool updateNeeded(void);
119 ConfigList* listView() const 140 ConfigList* listView() const
120 { 141 {
121 return (ConfigList*)Parent::listView(); 142 return (ConfigList*)Parent::listView();
122 } 143 }
123 ConfigItem* firstChild() const 144 ConfigItem* firstChild() const
124 { 145 {
125 return (ConfigItem *)Parent::firstChild(); 146 return (ConfigItem *)Parent::firstChild();
126 } 147 }
127 ConfigItem* nextSibling() const 148 ConfigItem* nextSibling() const
128 { 149 {
129 return (ConfigItem *)Parent::nextSibling(); 150 return (ConfigItem *)Parent::nextSibling();
130 } 151 }
131 void setText(colIdx idx, const QString& text) 152 void setText(colIdx idx, const QString& text)
132 { 153 {
133 Parent::setText(listView()->mapIdx(idx), text); 154 Parent::setText(listView()->mapIdx(idx), text);
134 } 155 }
135 QString text(colIdx idx) const 156 QString text(colIdx idx) const
136 { 157 {
137 return Parent::text(listView()->mapIdx(idx)); 158 return Parent::text(listView()->mapIdx(idx));
138 } 159 }
139 void setPixmap(colIdx idx, const QPixmap& pm) 160 void setPixmap(colIdx idx, const QPixmap& pm)
140 { 161 {
141 Parent::setPixmap(listView()->mapIdx(idx), pm); 162 Parent::setPixmap(listView()->mapIdx(idx), pm);
142 } 163 }
143 const QPixmap* pixmap(colIdx idx) const 164 const QPixmap* pixmap(colIdx idx) const
144 { 165 {
145 return Parent::pixmap(listView()->mapIdx(idx)); 166 return Parent::pixmap(listView()->mapIdx(idx));
146 } 167 }
147 void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align); 168 void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
148 169
170 ConfigItem* nextItem;
149 struct menu *menu; 171 struct menu *menu;
150 bool visible; 172 bool visible;
151 bool doInit;
152}; 173};
153 174
154class ConfigLineEdit : public QLineEdit { 175class ConfigLineEdit : public QLineEdit {
155 Q_OBJECT 176 Q_OBJECT
156 typedef class QLineEdit Parent; 177 typedef class QLineEdit Parent;
157public: 178public:
158 ConfigLineEdit(QWidget * parent) 179 ConfigLineEdit(ConfigView* parent)
159 : QLineEdit(parent) 180 : Parent(parent)
160 { } 181 { }
182 ConfigView* parent(void) const
183 {
184 return (ConfigView*)Parent::parent();
185 }
161 void show(ConfigItem *i); 186 void show(ConfigItem *i);
162 void keyPressEvent(QKeyEvent *e); 187 void keyPressEvent(QKeyEvent *e);
163signals:
164 void lineChanged(ConfigItem *item);
165 188
166public: 189public:
167 ConfigItem *item; 190 ConfigItem *item;
168}; 191};
169 192
170class ConfigView : public QMainWindow { 193class ConfigMainWindow : public QMainWindow {
171 Q_OBJECT 194 Q_OBJECT
172public: 195public:
173 ConfigView(void); 196 ConfigMainWindow(void);
174public slots: 197public slots:
175 void setHelp(QListViewItem* item); 198 void setHelp(QListViewItem* item);
176 void changeMenu(struct menu *); 199 void changeMenu(struct menu *);
177 void listFocusChanged(void); 200 void listFocusChanged(void);
178 void goBack(void); 201 void goBack(void);
179 void loadConfig(void); 202 void loadConfig(void);
180 void saveConfig(void); 203 void saveConfig(void);
181 void saveConfigAs(void); 204 void saveConfigAs(void);
182 void showSingleView(void); 205 void showSingleView(void);
183 void showSplitView(void); 206 void showSplitView(void);
184 void showFullView(void); 207 void showFullView(void);
185 void setShowAll(bool); 208 void setShowAll(bool);
186 void setShowDebug(bool); 209 void setShowDebug(bool);
187 void setShowRange(bool); 210 void setShowRange(bool);
188 void setShowName(bool); 211 void setShowName(bool);
189 void setShowData(bool); 212 void setShowData(bool);
213 void showIntro(void);
214 void showAbout(void);
190 215
191protected: 216protected:
192 void closeEvent(QCloseEvent *e); 217 void closeEvent(QCloseEvent *e);
193 218
194 ConfigList *menuList; 219 ConfigList *menuList;
195 ConfigList *configList; 220 ConfigList *configList;
196 QTextView *helpText; 221 QTextView *helpText;
197 QToolBar *toolBar; 222 QToolBar *toolBar;
198 QAction *backAction; 223 QAction *backAction;
199 224
200 bool showDebug; 225 bool showDebug;
201}; 226};
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 59c88d2..845d8a3 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -104,288 +104,303 @@ const char *sym_type_name(int type)
104 case S_TRISTATE: 104 case S_TRISTATE:
105 return "tristate"; 105 return "tristate";
106 case S_INT: 106 case S_INT:
107 return "integer"; 107 return "integer";
108 case S_HEX: 108 case S_HEX:
109 return "hex"; 109 return "hex";
110 case S_STRING: 110 case S_STRING:
111 return "string"; 111 return "string";
112 case S_UNKNOWN: 112 case S_UNKNOWN:
113 return "unknown"; 113 return "unknown";
114 } 114 }
115 return "???"; 115 return "???";
116} 116}
117 117
118struct property *sym_get_choice_prop(struct symbol *sym) 118struct property *sym_get_choice_prop(struct symbol *sym)
119{ 119{
120 struct property *prop; 120 struct property *prop;
121 121
122 for_all_choices(sym, prop) 122 for_all_choices(sym, prop)
123 return prop; 123 return prop;
124 return NULL; 124 return NULL;
125} 125}
126 126
127struct property *sym_get_default_prop(struct symbol *sym) 127struct property *sym_get_default_prop(struct symbol *sym)
128{ 128{
129 struct property *prop; 129 struct property *prop;
130 tristate visible; 130 tristate visible;
131 131
132 for_all_defaults(sym, prop) { 132 for_all_defaults(sym, prop) {
133 visible = E_CALC(prop->visible); 133 visible = E_CALC(prop->visible);
134 if (visible != no) 134 if (visible != no)
135 return prop; 135 return prop;
136 } 136 }
137 return NULL; 137 return NULL;
138} 138}
139 139
140void sym_calc_visibility(struct symbol *sym) 140void sym_calc_visibility(struct symbol *sym)
141{ 141{
142 struct property *prop; 142 struct property *prop;
143 tristate visible, oldvisible; 143 tristate visible, oldvisible;
144 144
145 /* any prompt visible? */ 145 /* any prompt visible? */
146 oldvisible = sym->visible; 146 oldvisible = sym->visible;
147 visible = no; 147 visible = no;
148 for_all_prompts(sym, prop) 148 for_all_prompts(sym, prop)
149 visible = E_OR(visible, E_CALC(prop->visible)); 149 visible = E_OR(visible, E_CALC(prop->visible));
150 if (oldvisible != visible) { 150 if (oldvisible != visible) {
151 sym->visible = visible; 151 sym->visible = visible;
152 sym->flags |= SYMBOL_CHANGED; 152 sym_set_changed(sym);
153 } 153 }
154} 154}
155 155
156void sym_calc_value(struct symbol *sym) 156void sym_calc_value(struct symbol *sym)
157{ 157{
158 struct symbol_value newval, oldval; 158 struct symbol_value newval, oldval;
159 struct property *prop, *def_prop; 159 struct property *prop, *def_prop;
160 struct symbol *def_sym; 160 struct symbol *def_sym;
161 struct expr *e; 161 struct expr *e;
162 162
163 if (sym->flags & SYMBOL_VALID) 163 if (sym->flags & SYMBOL_VALID)
164 return; 164 return;
165 165
166 oldval = sym->curr; 166 oldval = sym->curr;
167 167
168 switch (sym->type) { 168 switch (sym->type) {
169 case S_INT: 169 case S_INT:
170 case S_HEX: 170 case S_HEX:
171 case S_STRING: 171 case S_STRING:
172 newval = symbol_empty.curr; 172 newval = symbol_empty.curr;
173 break; 173 break;
174 case S_BOOLEAN: 174 case S_BOOLEAN:
175 case S_TRISTATE: 175 case S_TRISTATE:
176 newval = symbol_no.curr; 176 newval = symbol_no.curr;
177 break; 177 break;
178 default: 178 default:
179 S_VAL(newval) = sym->name; 179 S_VAL(newval) = sym->name;
180 S_TRI(newval) = no; 180 S_TRI(newval) = no;
181 if (sym->flags & SYMBOL_CONST) { 181 if (sym->flags & SYMBOL_CONST) {
182 goto out; 182 goto out;
183 } 183 }
184 //newval = symbol_empty.curr; 184 //newval = symbol_empty.curr;
185 // generate warning somewhere here later 185 // generate warning somewhere here later
186 //S_TRI(newval) = yes; 186 //S_TRI(newval) = yes;
187 goto out; 187 goto out;
188 } 188 }
189 sym->flags |= SYMBOL_VALID; 189 sym->flags |= SYMBOL_VALID;
190 if (!sym_is_choice_value(sym)) 190 if (!sym_is_choice_value(sym))
191 sym->flags &= ~SYMBOL_WRITE; 191 sym->flags &= ~SYMBOL_WRITE;
192 192
193 sym_calc_visibility(sym); 193 sym_calc_visibility(sym);
194 194
195 /* set default if recursively called */ 195 /* set default if recursively called */
196 sym->curr = newval; 196 sym->curr = newval;
197 197
198 if (sym->visible != no) { 198 if (sym->visible != no) {
199 sym->flags |= SYMBOL_WRITE; 199 sym->flags |= SYMBOL_WRITE;
200 if (!sym_has_value(sym)) { 200 if (!sym_has_value(sym)) {
201 if (!sym_is_choice(sym)) { 201 if (!sym_is_choice(sym)) {
202 prop = sym_get_default_prop(sym); 202 prop = sym_get_default_prop(sym);
203 if (prop) { 203 if (prop) {
204 sym_calc_value(prop->def); 204 sym_calc_value(prop->def);
205 newval = prop->def->curr; 205 newval = prop->def->curr;
206 } 206 }
207 } 207 } else
208 S_TRI(newval) = S_TRI(sym->def);
208 } else 209 } else
209 newval = sym->def; 210 newval = sym->def;
210 211
211 S_TRI(newval) = E_AND(S_TRI(newval), sym->visible); 212 S_TRI(newval) = E_AND(S_TRI(newval), sym->visible);
212 /* if the symbol is visible and not optionial, 213 /* if the symbol is visible and not optionial,
213 * possibly ignore old user choice. */ 214 * possibly ignore old user choice. */
214 if (!sym_is_optional(sym) && S_TRI(newval) == no) 215 if (!sym_is_optional(sym) && S_TRI(newval) == no)
215 S_TRI(newval) = sym->visible; 216 S_TRI(newval) = sym->visible;
216 if (sym_is_choice_value(sym) && sym->visible == yes) { 217 if (sym_is_choice_value(sym) && sym->visible == yes) {
217 prop = sym_get_choice_prop(sym); 218 prop = sym_get_choice_prop(sym);
218 S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; 219 S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no;
219 } 220 }
220 } else { 221 } else {
221 prop = sym_get_default_prop(sym); 222 prop = sym_get_default_prop(sym);
222 if (prop) { 223 if (prop) {
223 sym->flags |= SYMBOL_WRITE; 224 sym->flags |= SYMBOL_WRITE;
224 sym_calc_value(prop->def); 225 sym_calc_value(prop->def);
225 newval = prop->def->curr; 226 newval = prop->def->curr;
226 } 227 }
227 } 228 }
228 229
229 switch (sym_get_type(sym)) { 230 switch (sym_get_type(sym)) {
230 case S_TRISTATE: 231 case S_TRISTATE:
231 if (S_TRI(newval) != mod) 232 if (S_TRI(newval) != mod)
232 break; 233 break;
233 sym_calc_value(modules_sym); 234 sym_calc_value(modules_sym);
234 if (S_TRI(modules_sym->curr) == no) 235 if (S_TRI(modules_sym->curr) == no)
235 S_TRI(newval) = yes; 236 S_TRI(newval) = yes;
236 break; 237 break;
237 case S_BOOLEAN: 238 case S_BOOLEAN:
238 if (S_TRI(newval) == mod) 239 if (S_TRI(newval) == mod)
239 S_TRI(newval) = yes; 240 S_TRI(newval) = yes;
240 } 241 }
241 242
242out: 243out:
243 sym->curr = newval; 244 sym->curr = newval;
244 245
245 if (sym_is_choice(sym) && S_TRI(newval) == yes) { 246 if (sym_is_choice(sym) && S_TRI(newval) == yes) {
246 def_sym = S_VAL(sym->def); 247 def_sym = S_VAL(sym->def);
247 if (def_sym) { 248 if (def_sym) {
248 sym_calc_visibility(def_sym); 249 sym_calc_visibility(def_sym);
249 if (def_sym->visible == no) 250 if (def_sym->visible == no)
250 def_sym = NULL; 251 def_sym = NULL;
251 } 252 }
252 if (!def_sym) { 253 if (!def_sym) {
253 for_all_defaults(sym, def_prop) { 254 for_all_defaults(sym, def_prop) {
254 if (E_CALC(def_prop->visible) == no) 255 if (E_CALC(def_prop->visible) == no)
255 continue; 256 continue;
256 sym_calc_visibility(def_prop->def); 257 sym_calc_visibility(def_prop->def);
257 if (def_prop->def->visible != no) { 258 if (def_prop->def->visible != no) {
258 def_sym = def_prop->def; 259 def_sym = def_prop->def;
259 break; 260 break;
260 } 261 }
261 } 262 }
262 } 263 }
263 264
264 if (!def_sym) { 265 if (!def_sym) {
265 prop = sym_get_choice_prop(sym); 266 prop = sym_get_choice_prop(sym);
266 for (e = prop->dep; e; e = e->left.expr) { 267 for (e = prop->dep; e; e = e->left.expr) {
267 sym_calc_visibility(e->right.sym); 268 sym_calc_visibility(e->right.sym);
268 if (e->right.sym->visible != no) { 269 if (e->right.sym->visible != no) {
269 def_sym = e->right.sym; 270 def_sym = e->right.sym;
270 break; 271 break;
271 } 272 }
272 } 273 }
273 } 274 }
274 275
275 S_VAL(newval) = def_sym; 276 S_VAL(newval) = def_sym;
276 } 277 }
277 278
278 if (memcmp(&oldval, &newval, sizeof(newval))) 279 if (memcmp(&oldval, &newval, sizeof(newval)))
279 sym->flags |= SYMBOL_CHANGED; 280 sym_set_changed(sym);
280 sym->curr = newval; 281 sym->curr = newval;
281 282
282 if (sym_is_choice(sym)) { 283 if (sym_is_choice(sym)) {
283 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); 284 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
284 prop = sym_get_choice_prop(sym); 285 prop = sym_get_choice_prop(sym);
285 for (e = prop->dep; e; e = e->left.expr) 286 for (e = prop->dep; e; e = e->left.expr) {
286 e->right.sym->flags |= flags; 287 e->right.sym->flags |= flags;
288 if (flags & SYMBOL_CHANGED)
289 sym_set_changed(e->right.sym);
290 }
287 } 291 }
288} 292}
289 293
290void sym_clear_all_valid(void) 294void sym_clear_all_valid(void)
291{ 295{
292 struct symbol *sym; 296 struct symbol *sym;
293 int i; 297 int i;
294 298
295 for_all_symbols(i, sym) 299 for_all_symbols(i, sym)
296 sym->flags &= ~SYMBOL_VALID; 300 sym->flags &= ~SYMBOL_VALID;
297 sym_change_count++; 301 sym_change_count++;
298} 302}
299 303
304void sym_set_changed(struct symbol *sym)
305{
306 struct property *prop;
307
308 sym->flags |= SYMBOL_CHANGED;
309 for (prop = sym->prop; prop; prop = prop->next) {
310 if (prop->menu)
311 prop->menu->flags |= MENU_CHANGED;
312 }
313}
314
300void sym_set_all_changed(void) 315void sym_set_all_changed(void)
301{ 316{
302 struct symbol *sym; 317 struct symbol *sym;
303 int i; 318 int i;
304 319
305 for_all_symbols(i, sym) 320 for_all_symbols(i, sym)
306 sym->flags |= SYMBOL_CHANGED; 321 sym_set_changed(sym);
307} 322}
308 323
309bool sym_tristate_within_range(struct symbol *sym, tristate val) 324bool sym_tristate_within_range(struct symbol *sym, tristate val)
310{ 325{
311 int type = sym_get_type(sym); 326 int type = sym_get_type(sym);
312 327
313 if (sym->visible == no) 328 if (sym->visible == no)
314 return false; 329 return false;
315 330
316 if (type != S_BOOLEAN && type != S_TRISTATE) 331 if (type != S_BOOLEAN && type != S_TRISTATE)
317 return false; 332 return false;
318 333
319 switch (val) { 334 switch (val) {
320 case no: 335 case no:
321 if (sym_is_choice_value(sym) && sym->visible == yes) 336 if (sym_is_choice_value(sym) && sym->visible == yes)
322 return false; 337 return false;
323 return sym_is_optional(sym); 338 return sym_is_optional(sym);
324 case mod: 339 case mod:
325 if (sym_is_choice_value(sym) && sym->visible == yes) 340 if (sym_is_choice_value(sym) && sym->visible == yes)
326 return false; 341 return false;
327 return type == S_TRISTATE; 342 return type == S_TRISTATE;
328 case yes: 343 case yes:
329 return type == S_BOOLEAN || sym->visible == yes; 344 return type == S_BOOLEAN || sym->visible == yes;
330 } 345 }
331 return false; 346 return false;
332} 347}
333 348
334bool sym_set_tristate_value(struct symbol *sym, tristate val) 349bool sym_set_tristate_value(struct symbol *sym, tristate val)
335{ 350{
336 tristate oldval = sym_get_tristate_value(sym); 351 tristate oldval = sym_get_tristate_value(sym);
337 352
338 if (oldval != val && !sym_tristate_within_range(sym, val)) 353 if (oldval != val && !sym_tristate_within_range(sym, val))
339 return false; 354 return false;
340 355
341 if (sym->flags & SYMBOL_NEW) { 356 if (sym->flags & SYMBOL_NEW) {
342 sym->flags &= ~SYMBOL_NEW; 357 sym->flags &= ~SYMBOL_NEW;
343 sym->flags |= SYMBOL_CHANGED; 358 sym_set_changed(sym);
344 } 359 }
345 if (sym_is_choice_value(sym) && val == yes) { 360 if (sym_is_choice_value(sym) && val == yes) {
346 struct property *prop = sym_get_choice_prop(sym); 361 struct property *prop = sym_get_choice_prop(sym);
347 362
348 S_VAL(prop->def->def) = sym; 363 S_VAL(prop->def->def) = sym;
349 prop->def->flags &= ~SYMBOL_NEW; 364 prop->def->flags &= ~SYMBOL_NEW;
350 } 365 }
351 366
352 S_TRI(sym->def) = val; 367 S_TRI(sym->def) = val;
353 if (oldval != val) { 368 if (oldval != val) {
354 sym_clear_all_valid(); 369 sym_clear_all_valid();
355 if (sym == modules_sym) 370 if (sym == modules_sym)
356 sym_set_all_changed(); 371 sym_set_all_changed();
357 } 372 }
358 373
359 return true; 374 return true;
360} 375}
361 376
362tristate sym_toggle_tristate_value(struct symbol *sym) 377tristate sym_toggle_tristate_value(struct symbol *sym)
363{ 378{
364 tristate oldval, newval; 379 tristate oldval, newval;
365 380
366 oldval = newval = sym_get_tristate_value(sym); 381 oldval = newval = sym_get_tristate_value(sym);
367 do { 382 do {
368 switch (newval) { 383 switch (newval) {
369 case no: 384 case no:
370 newval = mod; 385 newval = mod;
371 break; 386 break;
372 case mod: 387 case mod:
373 newval = yes; 388 newval = yes;
374 break; 389 break;
375 case yes: 390 case yes:
376 newval = no; 391 newval = no;
377 break; 392 break;
378 } 393 }
379 if (sym_set_tristate_value(sym, newval)) 394 if (sym_set_tristate_value(sym, newval))
380 break; 395 break;
381 } while (oldval != newval); 396 } while (oldval != newval);
382 return newval; 397 return newval;
383} 398}
384 399
385bool sym_string_valid(struct symbol *sym, const char *str) 400bool sym_string_valid(struct symbol *sym, const char *str)
386{ 401{
387 char ch; 402 char ch;
388 403
389 switch (sym->type) { 404 switch (sym->type) {
390 case S_STRING: 405 case S_STRING:
391 return true; 406 return true;
@@ -415,201 +430,197 @@ bool sym_string_valid(struct symbol *sym, const char *str)
415 case S_TRISTATE: 430 case S_TRISTATE:
416 switch (str[0]) { 431 switch (str[0]) {
417 case 'y': 432 case 'y':
418 case 'Y': 433 case 'Y':
419 return sym_tristate_within_range(sym, yes); 434 return sym_tristate_within_range(sym, yes);
420 case 'm': 435 case 'm':
421 case 'M': 436 case 'M':
422 return sym_tristate_within_range(sym, mod); 437 return sym_tristate_within_range(sym, mod);
423 case 'n': 438 case 'n':
424 case 'N': 439 case 'N':
425 return sym_tristate_within_range(sym, no); 440 return sym_tristate_within_range(sym, no);
426 } 441 }
427 return false; 442 return false;
428 default: 443 default:
429 return false; 444 return false;
430 } 445 }
431} 446}
432 447
433bool sym_set_string_value(struct symbol *sym, const char *newval) 448bool sym_set_string_value(struct symbol *sym, const char *newval)
434{ 449{
435 const char *oldval; 450 const char *oldval;
436 char *val; 451 char *val;
437 int size; 452 int size;
438 453
439 switch (sym->type) { 454 switch (sym->type) {
440 case S_BOOLEAN: 455 case S_BOOLEAN:
441 case S_TRISTATE: 456 case S_TRISTATE:
442 switch (newval[0]) { 457 switch (newval[0]) {
443 case 'y': 458 case 'y':
444 case 'Y': 459 case 'Y':
445 return sym_set_tristate_value(sym, yes); 460 return sym_set_tristate_value(sym, yes);
446 case 'm': 461 case 'm':
447 case 'M': 462 case 'M':
448 return sym_set_tristate_value(sym, mod); 463 return sym_set_tristate_value(sym, mod);
449 case 'n': 464 case 'n':
450 case 'N': 465 case 'N':
451 return sym_set_tristate_value(sym, no); 466 return sym_set_tristate_value(sym, no);
452 } 467 }
453 return false; 468 return false;
454 default: 469 default:
455 ; 470 ;
456 } 471 }
457 472
458 if (!sym_string_valid(sym, newval)) 473 if (!sym_string_valid(sym, newval))
459 return false; 474 return false;
460 475
461 if (sym->flags & SYMBOL_NEW) { 476 if (sym->flags & SYMBOL_NEW) {
462 sym->flags &= ~SYMBOL_NEW; 477 sym->flags &= ~SYMBOL_NEW;
463 sym->flags |= SYMBOL_CHANGED; 478 sym_set_changed(sym);
464 } 479 }
465 480
466 oldval = S_VAL(sym->def); 481 oldval = S_VAL(sym->def);
467 size = strlen(newval) + 1; 482 size = strlen(newval) + 1;
468 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { 483 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
469 size += 2; 484 size += 2;
470 S_VAL(sym->def) = val = malloc(size); 485 S_VAL(sym->def) = val = malloc(size);
471 *val++ = '0'; 486 *val++ = '0';
472 *val++ = 'x'; 487 *val++ = 'x';
473 } else if (!oldval || strcmp(oldval, newval)) 488 } else if (!oldval || strcmp(oldval, newval))
474 S_VAL(sym->def) = val = malloc(size); 489 S_VAL(sym->def) = val = malloc(size);
475 else 490 else
476 return true; 491 return true;
477 492
478 strcpy(val, newval); 493 strcpy(val, newval);
479 free((void *)oldval); 494 free((void *)oldval);
480 sym_clear_all_valid(); 495 sym_clear_all_valid();
481 496
482 return true; 497 return true;
483} 498}
484 499
485const char *sym_get_string_value(struct symbol *sym) 500const char *sym_get_string_value(struct symbol *sym)
486{ 501{
487 tristate val; 502 tristate val;
488 503
489 switch (sym->type) { 504 switch (sym->type) {
490 case S_BOOLEAN: 505 case S_BOOLEAN:
491 case S_TRISTATE: 506 case S_TRISTATE:
492 val = sym_get_tristate_value(sym); 507 val = sym_get_tristate_value(sym);
493 switch (val) { 508 switch (val) {
494 case no: 509 case no:
495 return "n"; 510 return "n";
496 case mod: 511 case mod:
497 return "m"; 512 return "m";
498 case yes: 513 case yes:
499 return "y"; 514 return "y";
500 } 515 }
501 break; 516 break;
502 default: 517 default:
503 ; 518 ;
504 } 519 }
505 return (const char *)S_VAL(sym->curr); 520 return (const char *)S_VAL(sym->curr);
506} 521}
507 522
508bool sym_is_changable(struct symbol *sym) 523bool sym_is_changable(struct symbol *sym)
509{ 524{
510 if (sym->visible == no) 525 if (sym->visible == no)
511 return false; 526 return false;
512 /* at least 'n' and 'y'/'m' is selectable */ 527 /* at least 'n' and 'y'/'m' is selectable */
513 if (sym_is_optional(sym)) 528 if (sym_is_optional(sym))
514 return true; 529 return true;
515 /* no 'n', so 'y' and 'm' must be selectable */ 530 /* no 'n', so 'y' and 'm' must be selectable */
516 if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes) 531 if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes)
517 return true; 532 return true;
518 return false; 533 return false;
519} 534}
520 535
521struct symbol *sym_lookup(const char *name, int isconst) 536struct symbol *sym_lookup(const char *name, int isconst)
522{ 537{
523 struct symbol *symbol; 538 struct symbol *symbol;
524 const char *ptr; 539 const char *ptr;
525 char *new_name; 540 char *new_name;
526 int hash = 0; 541 int hash = 0;
527 542
528 //printf("lookup: %s -> ", name);
529 if (name) { 543 if (name) {
530 if (name[0] && !name[1]) { 544 if (name[0] && !name[1]) {
531 switch (name[0]) { 545 switch (name[0]) {
532 case 'y': return &symbol_yes; 546 case 'y': return &symbol_yes;
533 case 'm': return &symbol_mod; 547 case 'm': return &symbol_mod;
534 case 'n': return &symbol_no; 548 case 'n': return &symbol_no;
535 } 549 }
536 } 550 }
537 for (ptr = name; *ptr; ptr++) 551 for (ptr = name; *ptr; ptr++)
538 hash += *ptr; 552 hash += *ptr;
539 hash &= 0xff; 553 hash &= 0xff;
540 554
541 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 555 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
542 if (!strcmp(symbol->name, name)) { 556 if (!strcmp(symbol->name, name)) {
543 if ((isconst && symbol->flags & SYMBOL_CONST) || 557 if ((isconst && symbol->flags & SYMBOL_CONST) ||
544 (!isconst && !(symbol->flags & SYMBOL_CONST))) { 558 (!isconst && !(symbol->flags & SYMBOL_CONST)))
545 //printf("h:%p\n", symbol);
546 return symbol; 559 return symbol;
547 }
548 } 560 }
549 } 561 }
550 new_name = strdup(name); 562 new_name = strdup(name);
551 } else { 563 } else {
552 new_name = NULL; 564 new_name = NULL;
553 hash = 256; 565 hash = 256;
554 } 566 }
555 567
556 symbol = malloc(sizeof(*symbol)); 568 symbol = malloc(sizeof(*symbol));
557 memset(symbol, 0, sizeof(*symbol)); 569 memset(symbol, 0, sizeof(*symbol));
558 symbol->name = new_name; 570 symbol->name = new_name;
559 symbol->type = S_UNKNOWN; 571 symbol->type = S_UNKNOWN;
560 symbol->flags = SYMBOL_NEW; 572 symbol->flags = SYMBOL_NEW;
561 if (isconst) 573 if (isconst)
562 symbol->flags |= SYMBOL_CONST; 574 symbol->flags |= SYMBOL_CONST;
563 575
564 symbol->next = symbol_hash[hash]; 576 symbol->next = symbol_hash[hash];
565 symbol_hash[hash] = symbol; 577 symbol_hash[hash] = symbol;
566 578
567 //printf("n:%p\n", symbol);
568 return symbol; 579 return symbol;
569} 580}
570 581
571struct symbol *sym_find(const char *name) 582struct symbol *sym_find(const char *name)
572{ 583{
573 struct symbol *symbol = NULL; 584 struct symbol *symbol = NULL;
574 const char *ptr; 585 const char *ptr;
575 int hash = 0; 586 int hash = 0;
576 587
577 if (!name) 588 if (!name)
578 return NULL; 589 return NULL;
579 590
580 if (name[0] && !name[1]) { 591 if (name[0] && !name[1]) {
581 switch (name[0]) { 592 switch (name[0]) {
582 case 'y': return &symbol_yes; 593 case 'y': return &symbol_yes;
583 case 'm': return &symbol_mod; 594 case 'm': return &symbol_mod;
584 case 'n': return &symbol_no; 595 case 'n': return &symbol_no;
585 } 596 }
586 } 597 }
587 for (ptr = name; *ptr; ptr++) 598 for (ptr = name; *ptr; ptr++)
588 hash += *ptr; 599 hash += *ptr;
589 hash &= 0xff; 600 hash &= 0xff;
590 601
591 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 602 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
592 if (!strcmp(symbol->name, name) && 603 if (!strcmp(symbol->name, name) &&
593 !(symbol->flags & SYMBOL_CONST)) 604 !(symbol->flags & SYMBOL_CONST))
594 break; 605 break;
595 } 606 }
596 607
597 return symbol; 608 return symbol;
598} 609}
599 610
600const char *prop_get_type_name(enum prop_type type) 611const char *prop_get_type_name(enum prop_type type)
601{ 612{
602 switch (type) { 613 switch (type) {
603 case P_PROMPT: 614 case P_PROMPT:
604 return "prompt"; 615 return "prompt";
605 case P_COMMENT: 616 case P_COMMENT:
606 return "comment"; 617 return "comment";
607 case P_MENU: 618 case P_MENU:
608 return "menu"; 619 return "menu";
609 case P_ROOTMENU: 620 case P_ROOTMENU:
610 return "rootmenu"; 621 return "rootmenu";
611 case P_DEFAULT: 622 case P_DEFAULT:
612 return "default"; 623 return "default";
613 case P_CHOICE: 624 case P_CHOICE:
614 return "choice"; 625 return "choice";
615 default: 626 default:
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 6d81e5e..1471630 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -1,323 +1,359 @@
1%option backup nostdinit noyywrap full ecs 1%option backup nostdinit noyywrap never-interactive full ecs
2%option 8bit backup nodefault perf-report perf-report 2%option 8bit backup nodefault perf-report perf-report
3%x COMMAND HELP STRING PARAM 3%x COMMAND HELP STRING PARAM
4%{ 4%{
5/* 5/*
6 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 6 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
7 * Released under the terms of the GNU GPL v2.0. 7 * Released under the terms of the GNU GPL v2.0.
8 */ 8 */
9 9
10#include <limits.h>
10#include <stdio.h> 11#include <stdio.h>
11#include <stdlib.h> 12#include <stdlib.h>
12#include <string.h> 13#include <string.h>
13#include <unistd.h> 14#include <unistd.h>
14 15
15#define LKC_DIRECT_LINK 16#define LKC_DIRECT_LINK
16#include "lkc.h" 17#include "lkc.h"
17#include "zconf.tab.h"
18 18
19 #define START_STRSIZE16 19 #define START_STRSIZE16
20 20
21char *text; 21char *text;
22static char *text_ptr; 22static char *text_ptr;
23static int text_size, text_asize; 23static int text_size, text_asize;
24 24
25struct buffer { 25struct buffer {
26 struct buffer *parent; 26 struct buffer *parent;
27 YY_BUFFER_STATE state; 27 YY_BUFFER_STATE state;
28}; 28};
29 29
30struct buffer *current_buf; 30struct buffer *current_buf;
31 31
32static int last_ts, first_ts; 32static int last_ts, first_ts;
33 33
34static void zconf_endhelp(void); 34static void zconf_endhelp(void);
35static struct buffer *zconf_endfile(void); 35static struct buffer *zconf_endfile(void);
36 36
37void new_string(void) 37void new_string(void)
38{ 38{
39 text = malloc(START_STRSIZE); 39 text = malloc(START_STRSIZE);
40 text_asize = START_STRSIZE; 40 text_asize = START_STRSIZE;
41 text_ptr = text; 41 text_ptr = text;
42 text_size = 0; 42 text_size = 0;
43 *text_ptr = 0; 43 *text_ptr = 0;
44} 44}
45 45
46void append_string(const char *str, int size) 46void append_string(const char *str, int size)
47{ 47{
48 int new_size = text_size + size + 1; 48 int new_size = text_size + size + 1;
49 if (new_size > text_asize) { 49 if (new_size > text_asize) {
50 text = realloc(text, new_size); 50 text = realloc(text, new_size);
51 text_asize = new_size; 51 text_asize = new_size;
52 text_ptr = text + text_size; 52 text_ptr = text + text_size;
53 } 53 }
54 memcpy(text_ptr, str, size); 54 memcpy(text_ptr, str, size);
55 text_ptr += size; 55 text_ptr += size;
56 text_size += size; 56 text_size += size;
57 *text_ptr = 0; 57 *text_ptr = 0;
58} 58}
59 59
60void alloc_string(const char *str, int size) 60void alloc_string(const char *str, int size)
61{ 61{
62 text = malloc(size + 1); 62 text = malloc(size + 1);
63 memcpy(text, str, size); 63 memcpy(text, str, size);
64 text[size] = 0; 64 text[size] = 0;
65} 65}
66%} 66%}
67 67
68 ws[ \n\t] 68 ws[ \n\t]
69 n[A-Za-z0-9_] 69 n[A-Za-z0-9_]
70 70
71%% 71%%
72 int str = 0; 72 int str = 0;
73 int ts, i; 73 int ts, i;
74 74
75 [ \t]*#.*\ncurrent_file->lineno++; 75 [ \t]*#.*\ncurrent_file->lineno++;
76[ \t]*#.* 76[ \t]*#.*
77 77
78 [ \t]*\ncurrent_file->lineno++; return T_EOL; 78 [ \t]*\ncurrent_file->lineno++; return T_EOL;
79 79
80 [ \t]+{ 80 [ \t]+{
81 BEGIN(COMMAND); 81 BEGIN(COMMAND);
82} 82}
83 83
84 .{ 84 .{
85 unput(yytext[0]); 85 unput(yytext[0]);
86 //printf("new config: ");
87 //symbol_end(NULL);
88 BEGIN(COMMAND); 86 BEGIN(COMMAND);
89} 87}
90 88
91 89
92<COMMAND>{ 90<COMMAND>{
93 "mainmenu" BEGIN(PARAM); return T_MAINMENU; 91 "mainmenu" BEGIN(PARAM); return T_MAINMENU;
94 "menu" BEGIN(PARAM); return T_MENU; 92 "menu" BEGIN(PARAM); return T_MENU;
95 "endmenu" BEGIN(PARAM); return T_ENDMENU; 93 "endmenu" BEGIN(PARAM); return T_ENDMENU;
96 "source" BEGIN(PARAM); return T_SOURCE; 94 "source" BEGIN(PARAM); return T_SOURCE;
97 "choice" BEGIN(PARAM); return T_CHOICE; 95 "choice" BEGIN(PARAM); return T_CHOICE;
98 "endchoice" BEGIN(PARAM); return T_ENDCHOICE; 96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
99 "comment" BEGIN(PARAM); return T_COMMENT; 97 "comment" BEGIN(PARAM); return T_COMMENT;
100 "config" BEGIN(PARAM); return T_CONFIG; 98 "config" BEGIN(PARAM); return T_CONFIG;
101 "help" BEGIN(PARAM); return T_HELP; 99 "help" BEGIN(PARAM); return T_HELP;
102 "if" BEGIN(PARAM); return T_IF; 100 "if" BEGIN(PARAM); return T_IF;
103 "endif" BEGIN(PARAM); return T_ENDIF; 101 "endif" BEGIN(PARAM); return T_ENDIF;
104 "depends" BEGIN(PARAM); return T_DEPENDS; 102 "depends" BEGIN(PARAM); return T_DEPENDS;
105 "requires" BEGIN(PARAM); return T_REQUIRES; 103 "requires" BEGIN(PARAM); return T_REQUIRES;
106 "optional" BEGIN(PARAM); return T_OPTIONAL; 104 "optional" BEGIN(PARAM); return T_OPTIONAL;
107 "default" BEGIN(PARAM); return T_DEFAULT; 105 "default" BEGIN(PARAM); return T_DEFAULT;
108 "prompt" BEGIN(PARAM); return T_PROMPT; 106 "prompt" BEGIN(PARAM); return T_PROMPT;
109 "tristate" BEGIN(PARAM); return T_TRISTATE; 107 "tristate" BEGIN(PARAM); return T_TRISTATE;
110 "bool" BEGIN(PARAM); return T_BOOLEAN; 108 "bool" BEGIN(PARAM); return T_BOOLEAN;
111 "boolean" BEGIN(PARAM); return T_BOOLEAN; 109 "boolean" BEGIN(PARAM); return T_BOOLEAN;
112 "int" BEGIN(PARAM); return T_INT; 110 "int" BEGIN(PARAM); return T_INT;
113 "hex" BEGIN(PARAM); return T_HEX; 111 "hex" BEGIN(PARAM); return T_HEX;
114 "string" BEGIN(PARAM); return T_STRING; 112 "string" BEGIN(PARAM); return T_STRING;
115 {n}+{ 113 {n}+{
116 alloc_string(yytext, yyleng); 114 alloc_string(yytext, yyleng);
117 zconflval.string = text; 115 zconflval.string = text;
118 return T_WORD; 116 return T_WORD;
119 } 117 }
120 . 118 .
121 \ncurrent_file->lineno++; BEGIN(INITIAL); 119 \ncurrent_file->lineno++; BEGIN(INITIAL);
122} 120}
123 121
124<PARAM>{ 122<PARAM>{
125 "&&"return T_AND; 123 "&&"return T_AND;
126 "||"return T_OR; 124 "||"return T_OR;
127 "("return T_OPEN_PAREN; 125 "("return T_OPEN_PAREN;
128 ")"return T_CLOSE_PAREN; 126 ")"return T_CLOSE_PAREN;
129 "!"return T_NOT; 127 "!"return T_NOT;
130 "="return T_EQUAL; 128 "="return T_EQUAL;
131 "!="return T_UNEQUAL; 129 "!="return T_UNEQUAL;
132 "if"return T_IF; 130 "if"return T_IF;
133 "on"return T_ON; 131 "on"return T_ON;
134 \"|\'{ 132 \"|\'{
135 str = yytext[0]; 133 str = yytext[0];
136 new_string(); 134 new_string();
137 BEGIN(STRING); 135 BEGIN(STRING);
138 } 136 }
139 \nBEGIN(INITIAL); current_file->lineno++; return T_EOL; 137 \nBEGIN(INITIAL); current_file->lineno++; return T_EOL;
140 ---/* ignore */ 138 ---/* ignore */
141 ({n}|[-/.])+{ 139 ({n}|[-/.])+{
142 alloc_string(yytext, yyleng); 140 alloc_string(yytext, yyleng);
143 zconflval.string = text; 141 zconflval.string = text;
144 return T_WORD; 142 return T_WORD;
145 } 143 }
144 \\\ncurrent_file->lineno++;
146 . 145 .
146 <<EOF>> {
147 BEGIN(INITIAL);
148 }
147} 149}
148 150
149<STRING>{ 151<STRING>{
150 [^'"\n\\]+{ 152 [^'"\\\n]+/\n{
153 append_string(yytext, yyleng);
154 zconflval.string = text;
155 return T_STRING;
156 }
157 [^'"\\\n]+{
151 append_string(yytext, yyleng); 158 append_string(yytext, yyleng);
152 } 159 }
160 \\.?/\n{
161 append_string(yytext + 1, yyleng - 1);
162 zconflval.string = text;
163 return T_STRING;
164 }
165 \\.?{
166 append_string(yytext + 1, yyleng - 1);
167 }
153 \'|\"{ 168 \'|\"{
154 if (str == yytext[0]) { 169 if (str == yytext[0]) {
155 BEGIN(PARAM); 170 BEGIN(PARAM);
156 zconflval.string = text; 171 zconflval.string = text;
157 //printf("s:%s\n", text);
158 return T_STRING; 172 return T_STRING;
159 } else 173 } else
160 append_string(yytext, 1); 174 append_string(yytext, 1);
161 } 175 }
162 \\[ \t]*\nappend_string(yytext+yyleng-1, 1); current_file->lineno++;
163 \\[ \t]*append_string(yytext+1, yyleng-1);
164 \\. append_string(yytext+1, 1);
165 \n{ 176 \n{
166 //printf(":%d: open string!\n", current_file->lineno+1); 177 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
167 exit(0); 178 current_file->lineno++;
179 BEGIN(INITIAL);
180 return T_EOL;
168 } 181 }
169 <<EOF>>{ 182 <<EOF>>{
170 //printf(":%d: open string!\n", current_file->lineno+1); 183 BEGIN(INITIAL);
171 exit(0);
172 } 184 }
173} 185}
174 186
175<HELP>{ 187<HELP>{
176 [ \t]+{ 188 [ \t]+{
177 ts = 0; 189 ts = 0;
178 for (i = 0; i < yyleng; i++) { 190 for (i = 0; i < yyleng; i++) {
179 if (yytext[i] == '\t') 191 if (yytext[i] == '\t')
180 ts = (ts & ~7) + 8; 192 ts = (ts & ~7) + 8;
181 else 193 else
182 ts++; 194 ts++;
183 } 195 }
184 last_ts = ts; 196 last_ts = ts;
185 if (first_ts) { 197 if (first_ts) {
186 if (ts < first_ts) { 198 if (ts < first_ts) {
187 zconf_endhelp(); 199 zconf_endhelp();
188 return T_HELPTEXT; 200 return T_HELPTEXT;
189 } 201 }
190 ts -= first_ts; 202 ts -= first_ts;
191 while (ts > 8) { 203 while (ts > 8) {
192 append_string(" ", 8); 204 append_string(" ", 8);
193 ts -= 8; 205 ts -= 8;
194 } 206 }
195 append_string(" ", ts); 207 append_string(" ", ts);
196 } 208 }
197 209
198 } 210 }
199 \n/[^ \t\n] { 211 \n/[^ \t\n] {
200 current_file->lineno++; 212 current_file->lineno++;
201 zconf_endhelp(); 213 zconf_endhelp();
202 return T_HELPTEXT; 214 return T_HELPTEXT;
203 } 215 }
204 [ \t]*\n{ 216 [ \t]*\n{
205 current_file->lineno++; 217 current_file->lineno++;
206 append_string("\n", 1); 218 append_string("\n", 1);
207 } 219 }
208 [^ \t\n].* { 220 [^ \t\n].* {
209 append_string(yytext, yyleng); 221 append_string(yytext, yyleng);
210 if (!first_ts) 222 if (!first_ts)
211 first_ts = last_ts; 223 first_ts = last_ts;
212 } 224 }
213 <<EOF>>{ 225 <<EOF>>{
214 zconf_endhelp(); 226 zconf_endhelp();
215 return T_HELPTEXT; 227 return T_HELPTEXT;
216 } 228 }
217} 229}
218 230
219 <<EOF>>{ 231 <<EOF>>{
220 if (current_buf) { 232 if (current_buf) {
221 zconf_endfile(); 233 zconf_endfile();
222 return T_EOF; 234 return T_EOF;
223 } 235 }
236 fclose(yyin);
224 yyterminate(); 237 yyterminate();
225} 238}
226 239
227%% 240%%
228void zconf_starthelp(void) 241void zconf_starthelp(void)
229{ 242{
230 new_string(); 243 new_string();
231 last_ts = first_ts = 0; 244 last_ts = first_ts = 0;
232 BEGIN(HELP); 245 BEGIN(HELP);
233} 246}
234 247
235static void zconf_endhelp(void) 248static void zconf_endhelp(void)
236{ 249{
237 zconflval.string = text; 250 zconflval.string = text;
238 BEGIN(INITIAL); 251 BEGIN(INITIAL);
239} 252}
240 253
254
255/*
256 * Try to open specified file with following names:
257 * ./name
258 * $(srctree)/name
259 * The latter is used when srctree is separate from objtree
260 * when compiling the kernel.
261 * Return NULL if file is not found.
262 */
263FILE *zconf_fopen(const char *name)
264{
265 char *env, fullname[PATH_MAX+1];
266 FILE *f;
267
268 f = fopen(name, "r");
269 if (!f && name[0] != '/') {
270 env = getenv(SRCTREE);
271 if (env) {
272 sprintf(fullname, "%s/%s", env, name);
273 f = fopen(fullname, "r");
274 }
275 }
276 return f;
277}
278
241void zconf_initscan(const char *name) 279void zconf_initscan(const char *name)
242{ 280{
243 yyin = fopen(name, "r"); 281 yyin = zconf_fopen(name);
244 if (!yyin) { 282 if (!yyin) {
245 printf("can't find file %s\n", name); 283 printf("can't find file %s\n", name);
246 exit(1); 284 exit(1);
247 } 285 }
248 //fprintf(stderr, "zconf_initscan: %s\n", name);
249 286
250 current_buf = malloc(sizeof(*current_buf)); 287 current_buf = malloc(sizeof(*current_buf));
251 memset(current_buf, 0, sizeof(*current_buf)); 288 memset(current_buf, 0, sizeof(*current_buf));
252 289
253 current_file = file_lookup(name); 290 current_file = file_lookup(name);
254 current_file->lineno = 1; 291 current_file->lineno = 1;
255 current_file->flags = FILE_BUSY; 292 current_file->flags = FILE_BUSY;
256} 293}
257 294
258void zconf_nextfile(const char *name) 295void zconf_nextfile(const char *name)
259{ 296{
260 struct file *file = file_lookup(name); 297 struct file *file = file_lookup(name);
261 struct buffer *buf = malloc(sizeof(*buf)); 298 struct buffer *buf = malloc(sizeof(*buf));
262 memset(buf, 0, sizeof(*buf)); 299 memset(buf, 0, sizeof(*buf));
263 300
264 current_buf->state = YY_CURRENT_BUFFER; 301 current_buf->state = YY_CURRENT_BUFFER;
265 yyin = fopen(name, "r"); 302 yyin = zconf_fopen(name);
266 if (!yyin) { 303 if (!yyin) {
267 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); 304 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
268 exit(1); 305 exit(1);
269 } 306 }
270 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 307 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
271 buf->parent = current_buf; 308 buf->parent = current_buf;
272 current_buf = buf; 309 current_buf = buf;
273 310
274 //fprintf(stderr, "zconf_nextfile: %s\n", name);
275
276 if (file->flags & FILE_BUSY) { 311 if (file->flags & FILE_BUSY) {
277 printf("recursive scan (%s)?\n", name); 312 printf("recursive scan (%s)?\n", name);
278 exit(1); 313 exit(1);
279 } 314 }
280 if (file->flags & FILE_SCANNED) { 315 if (file->flags & FILE_SCANNED) {
281 printf("file %s already scanned?\n", name); 316 printf("file %s already scanned?\n", name);
282 exit(1); 317 exit(1);
283 } 318 }
284 file->flags |= FILE_BUSY; 319 file->flags |= FILE_BUSY;
285 file->lineno = 1; 320 file->lineno = 1;
286 file->parent = current_file; 321 file->parent = current_file;
287 current_file = file; 322 current_file = file;
288} 323}
289 324
290static struct buffer *zconf_endfile(void) 325static struct buffer *zconf_endfile(void)
291{ 326{
292 struct buffer *parent; 327 struct buffer *parent;
293 328
294 current_file->flags |= FILE_SCANNED; 329 current_file->flags |= FILE_SCANNED;
295 current_file->flags &= ~FILE_BUSY; 330 current_file->flags &= ~FILE_BUSY;
296 current_file = current_file->parent; 331 current_file = current_file->parent;
297 332
298 parent = current_buf->parent; 333 parent = current_buf->parent;
299 if (parent) { 334 if (parent) {
335 fclose(yyin);
300 yy_delete_buffer(YY_CURRENT_BUFFER); 336 yy_delete_buffer(YY_CURRENT_BUFFER);
301 yy_switch_to_buffer(parent->state); 337 yy_switch_to_buffer(parent->state);
302 } 338 }
303 free(current_buf); 339 free(current_buf);
304 current_buf = parent; 340 current_buf = parent;
305 341
306 return parent; 342 return parent;
307} 343}
308 344
309int zconf_lineno(void) 345int zconf_lineno(void)
310{ 346{
311 if (current_buf) 347 if (current_buf)
312 return current_file->lineno; 348 return current_file->lineno;
313 else 349 else
314 return 0; 350 return 0;
315} 351}
316 352
317char *zconf_curname(void) 353char *zconf_curname(void)
318{ 354{
319 if (current_buf) 355 if (current_buf)
320 return current_file->name; 356 return current_file->name;
321 else 357 else
322 return "<none>"; 358 return "<none>";
323} 359}
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index c3f1bd0..996b10a 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -182,115 +182,113 @@ choice: T_CHOICE
182 sym->flags |= SYMBOL_CHOICE; 182 sym->flags |= SYMBOL_CHOICE;
183 menu_add_entry(sym); 183 menu_add_entry(sym);
184 menu_add_prop(P_CHOICE, NULL, NULL, NULL); 184 menu_add_prop(P_CHOICE, NULL, NULL, NULL);
185 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); 185 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
186}; 186};
187 187
188choice_entry: choice T_EOL choice_option_list 188choice_entry: choice T_EOL choice_option_list
189{ 189{
190 menu_end_entry(); 190 menu_end_entry();
191 menu_add_menu(); 191 menu_add_menu();
192}; 192};
193 193
194choice_end: end 194choice_end: end
195{ 195{
196 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { 196 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
197 menu_end_menu(); 197 menu_end_menu();
198 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); 198 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
199 } 199 }
200}; 200};
201 201
202choice_stmt: 202choice_stmt:
203 choice_entry choice_block choice_end T_EOL 203 choice_entry choice_block choice_end T_EOL
204 | choice_entry choice_block 204 | choice_entry choice_block
205{ 205{
206 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno); 206 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
207 zconfnerrs++; 207 zconfnerrs++;
208}; 208};
209 209
210choice_option_list: 210choice_option_list:
211 /* empty */ 211 /* empty */
212 | choice_option_list choice_option T_EOL 212 | choice_option_list choice_option T_EOL
213 | choice_option_list depends T_EOL 213 | choice_option_list depends T_EOL
214 | choice_option_list help 214 | choice_option_list help
215 | choice_option_list T_EOL 215 | choice_option_list T_EOL
216; 216;
217 217
218choice_option: T_PROMPT prompt if_expr 218choice_option: T_PROMPT prompt if_expr
219{ 219{
220 menu_add_prop(P_PROMPT, $2, NULL, $3); 220 menu_add_prop(P_PROMPT, $2, NULL, $3);
221 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 221 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
222}; 222};
223 223
224choice_option: T_OPTIONAL 224choice_option: T_OPTIONAL
225{ 225{
226 current_entry->sym->flags |= SYMBOL_OPTIONAL; 226 current_entry->sym->flags |= SYMBOL_OPTIONAL;
227 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); 227 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
228}; 228};
229 229
230choice_option: T_DEFAULT symbol 230choice_option: T_DEFAULT symbol if_expr
231{ 231{
232 menu_add_prop(P_DEFAULT, NULL, $2, NULL); 232 menu_add_prop(P_DEFAULT, NULL, $2, $3);
233 //current_choice->prop->def = $2;
234 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 233 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
235}; 234};
236 235
237choice_block: 236choice_block:
238 /* empty */ 237 /* empty */
239 | choice_block common_block 238 | choice_block common_block
240; 239;
241 240
242/* if entry */ 241/* if entry */
243 242
244if: T_IF expr 243if: T_IF expr
245{ 244{
246 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 245 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
247 menu_add_entry(NULL); 246 menu_add_entry(NULL);
248 //current_entry->prompt = menu_add_prop(T_IF, NULL, NULL, $2);
249 menu_add_dep($2); 247 menu_add_dep($2);
250 menu_end_entry(); 248 menu_end_entry();
251 menu_add_menu(); 249 menu_add_menu();
252}; 250};
253 251
254if_end: end 252if_end: end
255{ 253{
256 if (zconf_endtoken($1, T_IF, T_ENDIF)) { 254 if (zconf_endtoken($1, T_IF, T_ENDIF)) {
257 menu_end_menu(); 255 menu_end_menu();
258 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); 256 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
259 } 257 }
260}; 258};
261 259
262if_stmt: 260if_stmt:
263 if T_EOL if_block if_end T_EOL 261 if T_EOL if_block if_end T_EOL
264 | if T_EOL if_block 262 | if T_EOL if_block
265{ 263{
266 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno); 264 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
267 zconfnerrs++; 265 zconfnerrs++;
268}; 266};
269 267
270if_block: 268if_block:
271 /* empty */ 269 /* empty */
272 | if_block common_block 270 | if_block common_block
273 | if_block menu_stmt 271 | if_block menu_stmt
274 | if_block choice_stmt 272 | if_block choice_stmt
275; 273;
276 274
277/* menu entry */ 275/* menu entry */
278 276
279menu: T_MENU prompt 277menu: T_MENU prompt
280{ 278{
281 menu_add_entry(NULL); 279 menu_add_entry(NULL);
282 menu_add_prop(P_MENU, $2, NULL, NULL); 280 menu_add_prop(P_MENU, $2, NULL, NULL);
283 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); 281 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
284}; 282};
285 283
286menu_entry: menu T_EOL depends_list 284menu_entry: menu T_EOL depends_list
287{ 285{
288 menu_end_entry(); 286 menu_end_entry();
289 menu_add_menu(); 287 menu_add_menu();
290}; 288};
291 289
292menu_end: end 290menu_end: end
293{ 291{
294 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { 292 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
295 menu_end_menu(); 293 menu_end_menu();
296 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); 294 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());