summaryrefslogtreecommitdiff
path: root/scripts
Unidiff
Diffstat (limited to 'scripts') (more/less context) (ignore whitespace changes)
-rw-r--r--scripts/kconfig/Makefile51
-rw-r--r--scripts/kconfig/Makefile.kernel52
-rw-r--r--scripts/kconfig/conf.c222
-rw-r--r--scripts/kconfig/confdata.c152
-rw-r--r--scripts/kconfig/expr.c37
-rw-r--r--scripts/kconfig/expr.h79
-rw-r--r--scripts/kconfig/gconf.c1618
-rw-r--r--scripts/kconfig/gconf.glade543
-rw-r--r--scripts/kconfig/images.c34
-rw-r--r--scripts/kconfig/lkc-language.txt52
-rw-r--r--scripts/kconfig/lkc.h14
-rw-r--r--scripts/kconfig/lkc_proto.h5
-rw-r--r--scripts/kconfig/mconf.c66
-rw-r--r--scripts/kconfig/menu.c194
-rw-r--r--scripts/kconfig/qconf.cc405
-rw-r--r--scripts/kconfig/qconf.h20
-rw-r--r--scripts/kconfig/symbol.c465
-rw-r--r--scripts/kconfig/zconf.l23
-rw-r--r--scripts/kconfig/zconf.y230
19 files changed, 3489 insertions, 773 deletions
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 5a0d7e5..b918300 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -1,181 +1,198 @@
1VERSION=1.3 1VERSION=1.4
2CC=gcc 2CC=gcc
3CXX=g++ 3CXX=g++
4CFLAGS=-O0 -Wall -g -fPIC 4CFLAGS=-O0 -Wall -g -fPIC
5CXXFLAGS=$(CFLAGS) -I$(HOSTQTDIR)/include 5CXXFLAGS=$(CFLAGS) -I$(QTDIR)/include
6LDFLAGS= 6LDFLAGS=
7LXXFLAGS=$(LDFLAGS) -L$(HOSTQTDIR)/lib -Wl,-rpath,$(HOSTQTDIR)/lib 7LXXFLAGS=$(LDFLAGS) -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib
8LEX=flex 8LEX=flex
9LFLAGS=-L 9LFLAGS=-L
10YACC=bison 10YACC=bison
11YFLAGS=-l 11YFLAGS=-l
12#YFLAGS=-d -t -v -l 12#YFLAGS=-t -v -l
13ifndef HOSTQTDIR 13ifndef QTDIR
14HOSTQTDIR=/usr/share/qt 14QTDIR=/usr/share/qt3
15endif 15endif
16MOC=$(wildcard $(HOSTQTDIR)/bin/moc) 16MOC=$(wildcard $(QTDIR)/bin/moc)
17GTKCFLAGS=`pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags`
18GTKLDFLAGS=`pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
17 19
18parse_SRC=zconf.y 20parse_SRC=zconf.y
19conf_SRC=conf.c $(parse_SRC) 21conf_SRC=conf.c $(parse_SRC)
20mconf_SRC=mconf.c $(parse_SRC) 22mconf_SRC=mconf.c $(parse_SRC)
21qconf_SRC=qconf.cc 23qconf_SRC=qconf.cc
24gconf_SRC=gconf.c kconfig_load.c
22HDR=expr.h lkc.h lkc_proto.h qconf.h 25HDR=expr.h lkc.h lkc_proto.h qconf.h
23OTHER=README lkc-language.txt Makefile.kernel \ 26OTHER=README lkc-language.txt Makefile.kernel \
24 kconfig.i extconf.rb example 27 kconfig.i extconf.rb example
25INST=zconf.y zconf.l confdata.c expr.c symbol.c menu.c \ 28INST=zconf.y zconf.l confdata.c expr.c symbol.c menu.c \
26 conf.c mconf.c qconf.cc kconfig_load.c images.c $(HDR) 29 conf.c mconf.c qconf.cc gconf.c gconf.glade kconfig_load.c images.c $(HDR)
27INSTGEN=lex.zconf.c zconf.tab.c 30INSTGEN=lex.zconf.c zconf.tab.c
28 31
29#DEBUG=1 32#DEBUG=1
30ifdef DEBUG 33ifdef DEBUG
31CFLAGS+=-DLKC_DIRECT_LINK 34CFLAGS+=-DLKC_DIRECT_LINK
32qconf_SRC+=$(parse_SRC) 35qconf_SRC+=$(parse_SRC)
33else 36else
34qconf_SRC+=kconfig_load.c 37qconf_SRC+=kconfig_load.c
35endif 38endif
36 39
37SRC=$(conf_SRC) $(mconf_SRC) $(qconf_SRC) 40SRC=$(conf_SRC) $(mconf_SRC) $(qconf_SRC)
38CSRC=$(filter %.c, $(SRC)) 41CSRC=$(filter %.c, $(SRC))
39YSRC=$(filter %.y, $(SRC)) 42YSRC=$(filter %.y, $(SRC))
40LSRC=$(filter %.l, $(SRC)) 43LSRC=$(filter %.l, $(SRC))
41 44
42parse_OBJ=$(filter %.o, \ 45parse_OBJ=$(filter %.o, \
43 $(patsubst %.c,%.o, \ 46 $(patsubst %.c,%.o, \
44 $(patsubst %.y,%.tab.o, \ 47 $(patsubst %.y,%.tab.o, \
45 $(patsubst %.l,lex.%.o, \ 48 $(patsubst %.l,lex.%.o, \
46 $(parse_SRC))))) 49 $(parse_SRC)))))
47conf_OBJ=$(filter %.o, \ 50conf_OBJ=$(filter %.o, \
48 $(patsubst %.c,%.o, \ 51 $(patsubst %.c,%.o, \
49 $(patsubst %.y,%.tab.o, \ 52 $(patsubst %.y,%.tab.o, \
50 $(patsubst %.l,lex.%.o, \ 53 $(patsubst %.l,lex.%.o, \
51 $(conf_SRC))))) 54 $(conf_SRC)))))
52mconf_OBJ=$(filter %.o, \ 55mconf_OBJ=$(filter %.o, \
53 $(patsubst %.c,%.o, \ 56 $(patsubst %.c,%.o, \
54 $(patsubst %.y,%.tab.o, \ 57 $(patsubst %.y,%.tab.o, \
55 $(patsubst %.l,lex.%.o, \ 58 $(patsubst %.l,lex.%.o, \
56 $(mconf_SRC))))) 59 $(mconf_SRC)))))
57qconf_OBJ=$(filter %.o, \ 60qconf_OBJ=$(filter %.o, \
58 $(patsubst %.c,%.o, \ 61 $(patsubst %.c,%.o, \
59 $(patsubst %.cc,%.o, \ 62 $(patsubst %.cc,%.o, \
60 $(patsubst %.y,%.tab.o, \ 63 $(patsubst %.y,%.tab.o, \
61 $(patsubst %.l,lex.%.o, \ 64 $(patsubst %.l,lex.%.o, \
62 $(qconf_SRC)))))) 65 $(qconf_SRC))))))
66gconf_OBJ=$(filter %.o, \
67 $(patsubst %.c,%.o, \
68 $(patsubst %.y,%.tab.o, \
69 $(patsubst %.l,lex.%.o, \
70 $(gconf_SRC)))))
63OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ) 71OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ)
64 72
65ifeq ($(MOC),) 73ifeq ($(MOC),)
66all: conf mconf 74all: conf mconf
67else 75else
68all: conf mconf qconf libkconfig.so 76all: conf mconf qconf libkconfig.so
69endif 77endif
70 78
71lkc_deps := lkc.h lkc_proto.h lkc_defs.h expr.h 79lkc_deps := lkc.h lkc_proto.h lkc_defs.h expr.h
72 80
73zconf.tab.c: zconf.y 81zconf.tab.c: zconf.y
74zconf.tab.h: zconf.y 82zconf.tab.h: zconf.y
75lex.zconf.c: zconf.l 83lex.zconf.c: zconf.l
76zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(lkc_deps) 84zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(lkc_deps)
77#lex.zconf.o: lex.zconf.c zconf.tab.h $(lkc_deps) 85#lex.zconf.o: lex.zconf.c zconf.tab.h $(lkc_deps)
78#confdata.o: confdata.c $(lkc_deps) 86#confdata.o: confdata.c $(lkc_deps)
79#expr.o: expr.c $(lkc_deps) 87#expr.o: expr.c $(lkc_deps)
80#symbol.o: symbol.c $(lkc_deps) 88#symbol.o: symbol.c $(lkc_deps)
81#menu.o: menu.c $(lkc_deps) 89#menu.o: menu.c $(lkc_deps)
82kconfig_load.o: kconfig_load.c $(lkc_deps) 90kconfig_load.o: kconfig_load.c $(lkc_deps)
83conf.o: conf.c $(lkc_deps) 91conf.o: conf.c $(lkc_deps)
84mconf.o: mconf.c $(lkc_deps) 92mconf.o: mconf.c $(lkc_deps)
85qconf.moc: qconf.h 93qconf.moc: qconf.h
86qconf.o: qconf.cc qconf.moc images.c $(lkc_deps) 94qconf.o: qconf.cc qconf.moc images.c $(lkc_deps)
95gconf.o: gconf.c $(lkc_deps)
87 96
88mconf: $(mconf_OBJ) 97mconf: $(mconf_OBJ)
89 $(CC) $(LDFLAGS) $^ -o $@ 98 $(CC) $(LDFLAGS) $^ -o $@
90 99
91conf: $(conf_OBJ) 100conf: $(conf_OBJ)
92 $(CC) $(LDFLAGS) $^ -o $@ 101 $(CC) $(LDFLAGS) $^ -o $@
93 102
94ifeq ($(MOC),) 103ifeq ($(MOC),)
95qconf: 104qconf:
96 @echo Unable to find the QT installation. Please make sure that the 105 @echo Unable to find the QT installation. Please make sure that the
97 @echo QT development package is correctly installed and the HOSTQTDIR 106 @echo QT development package is correctly installed and the QTDIR
98 @echo environment variable is set to the correct location. 107 @echo environment variable is set to the correct location.
99 @false 108 @false
100else 109else
101qconf: $(qconf_OBJ) 110qconf: $(qconf_OBJ)
102 $(CXX) $(LXXFLAGS) $^ -lqt -o $@ 111 $(CXX) $(LXXFLAGS) $^ -lqt-mt -o $@
103endif 112endif
104 113
114gconf.o: gconf.c
115 $(CC) $(CFLAGS) $(GTKCFLAGS) -c $< -o $@
116
117gconf: $(gconf_OBJ)
118 $(CC) $(LDFLAGS) $(GTKLDFLAGS) $^ -o $@
119
105libkconfig.so: $(parse_OBJ) 120libkconfig.so: $(parse_OBJ)
106 $(CC) -shared $^ -o $@ 121 $(CC) -shared $^ -o $@
107 122
108lkc_defs.h: lkc_proto.h 123lkc_defs.h: lkc_proto.h
109 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' 124 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
110 125
111clean: 126clean:
112 rm -f $(OBJ) conf qconf mconf *.moc lex.* *.tab.? *.output 127 rm -f $(OBJ) conf qconf mconf *.moc lex.* *.tab.? *.output
113 rm -rf .ruby .python 128 rm -rf .ruby .python
114 129
115tgz: 130tgz:
116 mkdir tmp 131 mkdir tmp
117 mkdir tmp/lkc-$(VERSION) 132 mkdir tmp/lkc-$(VERSION)
118 cp -ra Makefile $(sort $(SRC) $(HDR) $(OTHER) $(INST)) tmp/lkc-$(VERSION) 133 cp -ra Makefile $(sort $(SRC) $(HDR) $(OTHER) $(INST)) tmp/lkc-$(VERSION)
119 tar -cpvz -C tmp --exclude CVS -f lkc-$(VERSION).tar.gz lkc-$(VERSION) 134 tar -cpvz -C tmp --exclude CVS -f lkc-$(VERSION).tar.gz lkc-$(VERSION)
120 rm -rf tmp 135 rm -rf tmp
121 136
122%.tab.c %.tab.h: %.y 137%.tab.c %.tab.h: %.y
123 $(YACC) $(YFLAGS) -b $* -p $* $< 138 $(YACC) $(YFLAGS) -b $* -p $* $<
124 139
125lex.%.c: %.l 140lex.%.c: %.l
126 $(LEX) $(LFLAGS) -P$* $< 141 $(LEX) $(LFLAGS) -P$* $<
127 142
128%.moc: %.h 143%.moc: %.h
129 $(HOSTQTDIR)/bin/moc -i $< -o $@ 144 $(QTDIR)/bin/moc -i $< -o $@
130 145
131%.o: %.c 146%.o: %.c
132 $(CC) $(CFLAGS) -c $< -o $@ 147 $(CC) $(CFLAGS) -c $< -o $@
133 148
134%.o: %.cc 149%.o: %.cc
135 $(CXX) $(CXXFLAGS) -c $< -o $@ 150 $(CXX) $(CXXFLAGS) -c $< -o $@
136 151
137ifdef KERNELSRC 152ifdef KERNELSRC
138install: $(INSTGEN) 153install: $(INSTGEN)
139 set -x; cp $(sort $(INST)) $(KERNELSRC)/scripts/kconfig; \ 154 set -x; cp --remove-destination $(sort $(INST)) $(KERNELSRC)/scripts/kconfig; \
140 for f in $(INSTGEN); do cp $$f $(KERNELSRC)/scripts/kconfig/$${f}_shipped; done; \ 155 for f in $(INSTGEN); do cp --remove-destination $$f $(KERNELSRC)/scripts/kconfig/$${f}_shipped; done; \
141 cp Makefile.kernel $(KERNELSRC)/scripts/kconfig/Makefile 156 cp --remove-destination Makefile.kernel $(KERNELSRC)/scripts/kconfig/Makefile; \
157 cp --remove-destination lkc-language.txt $(KERNELSRC)/Documentation/kbuild/kconfig-language.txt
142 158
143diff: $(INSTGEN) 159diff: $(INSTGEN)
144 for f in $(sort $(INST)); do diff -u $(KERNELSRC)/scripts/kconfig/$$f $$f; done; \ 160 for f in $(sort $(INST)); do diff -Nu $(KERNELSRC)/scripts/kconfig/$$f $$f; done; \
145 for f in $(INSTGEN); do diff -u $(KERNELSRC)/scripts/kconfig/$${f}_shipped $$f; done; \ 161 for f in $(INSTGEN); do diff -Nu $(KERNELSRC)/scripts/kconfig/$${f}_shipped $$f; done; \
146 diff -u $(KERNELSRC)/scripts/kconfig/Makefile Makefile.kernel 162 diff -Nu $(KERNELSRC)/scripts/kconfig/Makefile Makefile.kernel; \
163 diff -Nu lkc-language.txt $(KERNELSRC)/Documentation/kbuild/kconfig-language.txt
147else 164else
148install: 165install:
149 @echo "Please use KERNELSRC=<path/to/linux-kernel> to install" 166 @echo "Please use KERNELSRC=<path/to/linux-kernel> to install"
150endif 167endif
151 168
152ruby: .ruby libkconfig.so .ruby/kconfig.so 169ruby: .ruby libkconfig.so .ruby/kconfig.so
153 170
154.ruby: 171.ruby:
155 mkdir .ruby 172 mkdir .ruby
156 173
157.ruby/kconfig_wrap.c: kconfig.i kconfig_load.c expr.h lkc_proto.h 174.ruby/kconfig_wrap.c: kconfig.i kconfig_load.c expr.h lkc_proto.h
158 swig -ruby -o $@ $< 175 swig -ruby -o $@ $<
159 176
160.ruby/Makefile: extconf.rb 177.ruby/Makefile: extconf.rb
161 cd .ruby; ruby ../extconf.rb 178 cd .ruby; ruby ../extconf.rb
162 179
163.ruby/kconfig.so: .ruby/kconfig_wrap.c .ruby/Makefile 180.ruby/kconfig.so: .ruby/kconfig_wrap.c .ruby/Makefile
164 make -C .ruby 181 make -C .ruby
165 182
166 183
167PYTHON_INCLUDE=$(shell python -c "import sys; print '-I'+sys.prefix+'/include/python'+sys.version[:3]") 184PYTHON_INCLUDE=$(shell python -c "import sys; print '-I'+sys.prefix+'/include/python'+sys.version[:3]")
168 185
169python: .python .python/kconfig.py .python/_kconfig.so 186python: .python .python/kconfig.py .python/_kconfig.so
170 187
171.python: 188.python:
172 mkdir .python 189 mkdir .python
173 190
174.python/kconfig_wrap.c .python/kconfig.py: kconfig.i kconfig_load.c expr.h lkc_proto.h 191.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 192 swig -python -o .python/kconfig_wrap.c kconfig.i
176 193
177.python/_kconfig.so: .python/kconfig_wrap.c 194.python/_kconfig.so: .python/kconfig_wrap.c
178 cd .python; $(CC) $(CFLAGS) -shared kconfig_wrap.c -o _kconfig.so -I.. $(PYTHON_INCLUDE) 195 cd .python; $(CC) $(CFLAGS) -shared kconfig_wrap.c -o _kconfig.so -I.. $(PYTHON_INCLUDE)
179 196
180 197
181.PHONY: all tgz clean ruby python 198.PHONY: all tgz clean ruby python
diff --git a/scripts/kconfig/Makefile.kernel b/scripts/kconfig/Makefile.kernel
index 22724a7..bae5e29 100644
--- a/scripts/kconfig/Makefile.kernel
+++ b/scripts/kconfig/Makefile.kernel
@@ -1,95 +1,133 @@
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# gconf: Used for the gconfig target
10# Based on GTK which needs to be installed to compile it
9# 11#
12#################
10 13
11# object files used by all lkc flavours 14# object files used by all lkc flavours
12libkconfig-objs := zconf.tab.o 15libkconfig-objs := zconf.tab.o
13 16
14 host-progs:= conf mconf qconf 17 host-progs:= conf mconf qconf gconf
15 conf-objs:= conf.o libkconfig.so 18 conf-objs:= conf.o libkconfig.so
16 mconf-objs:= mconf.o libkconfig.so 19 mconf-objs:= mconf.o libkconfig.so
17 20
18 qconf-objs:= kconfig_load.o 21ifeq ($(MAKECMDGOALS),$(obj)/qconf)
19 qconf-cxxobjs:= qconf.o 22 qconf-cxxobjs:= qconf.o
23 qconf-objs:= kconfig_load.o
24endif
20 25
21 clean-files:= libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \ 26ifeq ($(MAKECMDGOALS),$(obj)/gconf)
22 zconf.tab.c zconf.tab.h lex.zconf.c 27 gconf-objs:= gconf.o kconfig_load.o
28endif
23 29
24include $(TOPDIR)/Rules.make 30 clean-files:= libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \
31 .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c
25 32
26# generated files seem to need this to find local include files 33# generated files seem to need this to find local include files
27 HOSTCFLAGS_lex.zconf.o:= -I$(src) 34 HOSTCFLAGS_lex.zconf.o:= -I$(src)
28 HOSTCFLAGS_zconf.tab.o:= -I$(src) 35 HOSTCFLAGS_zconf.tab.o:= -I$(src)
29 36
30 HOSTLOADLIBES_qconf= -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib -l$(QTLIB) -ldl 37 HOSTLOADLIBES_qconf= -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib -l$(QTLIB) -ldl
31 HOSTCXXFLAGS_qconf.o= -I$(QTDIR)/include 38 HOSTCXXFLAGS_qconf.o= -I$(QTDIR)/include
32 39
33$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o: $(obj)/zconf.tab.h 40 HOSTLOADLIBES_gconf= `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
41 HOSTCFLAGS_gconf.o= `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags`
42
43$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h
34 44
35$(obj)/qconf.o: $(obj)/.tmp_qtcheck 45$(obj)/qconf.o: $(obj)/.tmp_qtcheck
36 46
37ifeq ($(MAKECMDGOALS),$(obj)/qconf) 47ifeq ($(MAKECMDGOALS),$(obj)/qconf)
38MOC = $(QTDIR)/bin/moc 48MOC = $(QTDIR)/bin/moc
39-include $(obj)/.tmp_qtcheck 49-include $(obj)/.tmp_qtcheck
40 50
41# QT needs some extra effort... 51# QT needs some extra effort...
42$(obj)/.tmp_qtcheck: 52$(obj)/.tmp_qtcheck:
43 @set -e; for d in $$QTDIR /usr/share/qt /usr/lib/qt3; do \ 53 @set -e; for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
44 if [ -f $$d/include/qconfig.h ]; then DIR=$$d; break; fi; \ 54 if [ -f $$d/include/qconfig.h ]; then DIR=$$d; break; fi; \
45 done; \ 55 done; \
46 if [ -z "$$DIR" ]; then \ 56 if [ -z "$$DIR" ]; then \
47 echo "*"; \ 57 echo "*"; \
48 echo "* Unable to find the QT installation. Please make sure that the"; \ 58 echo "* Unable to find the QT installation. Please make sure that the"; \
49 echo "* QT development package is correctly installed and the QTDIR"; \ 59 echo "* QT development package is correctly installed and the QTDIR"; \
50 echo "* environment variable is set to the correct location."; \ 60 echo "* environment variable is set to the correct location."; \
51 echo "*"; \ 61 echo "*"; \
52 false; \ 62 false; \
53 fi; \ 63 fi; \
54 LIB=qt; \ 64 LIB=qt; \
55 if [ -f $$DIR/lib/libqt-mt.so ]; then LIB=qt-mt; fi; \ 65 if [ -f $$DIR/lib/libqt-mt.so ]; then LIB=qt-mt; fi; \
56 echo "QTDIR=$$DIR" > $@; echo "QTLIB=$$LIB" >> $@; \ 66 echo "QTDIR=$$DIR" > $@; echo "QTLIB=$$LIB" >> $@; \
57 if [ ! -x $$DIR/bin/moc -a -x /usr/bin/moc ]; then \ 67 if [ ! -x $$DIR/bin/moc -a -x /usr/bin/moc ]; then \
58 echo "*"; \ 68 echo "*"; \
59 echo "* Unable to find $$DIR/bin/moc, using /usr/bin/moc instead."; \ 69 echo "* Unable to find $$DIR/bin/moc, using /usr/bin/moc instead."; \
60 echo "*"; \ 70 echo "*"; \
61 echo "MOC=/usr/bin/moc" >> $@; \ 71 echo "MOC=/usr/bin/moc" >> $@; \
62 fi 72 fi
63endif 73endif
64 74
75$(obj)/gconf.o: $(obj)/.tmp_gtkcheck
76
77ifeq ($(MAKECMDGOALS),$(obj)/gconf)
78-include $(obj)/.tmp_gtkcheck
79
80# GTK needs some extra effort, too...
81$(obj)/.tmp_gtkcheck:
82 @if `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --exists`; then \
83 if `pkg-config gtk+-2.0 --atleast-version=2.0.0`; then \
84 touch $@; \
85 else \
86 echo "*"; \
87 echo "* GTK+ is present but version >= 2.0.0 is required.";\
88 echo "*"; \
89 false; \
90 fi \
91 else \
92 echo "*"; \
93 echo "* Unable to find the GTK+ installation. Please make sure that"; \
94 echo "* the GTK+ 2.0 development package is correctly installed..."; \
95 echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \
96 echo "*"; \
97 false; \
98 fi
99endif
100
65$(obj)/zconf.tab.o: $(obj)/lex.zconf.c 101$(obj)/zconf.tab.o: $(obj)/lex.zconf.c
66 102
67$(obj)/kconfig_load.o: $(obj)/lkc_defs.h 103$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
68 104
69$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h 105$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h
70 106
107$(obj)/gconf.o: $(obj)/lkc_defs.h
108
71$(obj)/%.moc: $(src)/%.h 109$(obj)/%.moc: $(src)/%.h
72 $(MOC) -i $< -o $@ 110 $(MOC) -i $< -o $@
73 111
74$(obj)/lkc_defs.h: $(src)/lkc_proto.h 112$(obj)/lkc_defs.h: $(src)/lkc_proto.h
75 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' 113 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
76 114
77 115
78### 116###
79# The following requires flex/bison 117# The following requires flex/bison
80# By default we use the _shipped versions, uncomment the following line if 118# By default we use the _shipped versions, uncomment the following line if
81# you are modifying the flex/bison src. 119# you are modifying the flex/bison src.
82# LKC_GENPARSER := 1 120# LKC_GENPARSER := 1
83 121
84ifdef LKC_GENPARSER 122ifdef LKC_GENPARSER
85 123
86$(obj)/zconf.tab.c: $(obj)/zconf.y 124$(obj)/zconf.tab.c: $(obj)/zconf.y
87$(obj)/zconf.tab.h: $(obj)/zconf.tab.c 125$(obj)/zconf.tab.h: $(obj)/zconf.tab.c
88 126
89%.tab.c: %.y 127%.tab.c: %.y
90 bison -t -d -v -b $* -p $(notdir $*) $< 128 bison -t -d -v -b $* -p $(notdir $*) $<
91 129
92lex.%.c: %.l 130lex.%.c: %.l
93 flex -P$(notdir $*) -o$@ $< 131 flex -P$(notdir $*) -o$@ $<
94 132
95endif 133endif
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 1602d5f..3c27a78 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -1,568 +1,566 @@
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 <ctype.h> 6#include <ctype.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <string.h> 8#include <string.h>
9#include <unistd.h> 9#include <unistd.h>
10#include <time.h> 10#include <time.h>
11#include <sys/stat.h> 11#include <sys/stat.h>
12 12
13#define LKC_DIRECT_LINK 13#define LKC_DIRECT_LINK
14#include "lkc.h" 14#include "lkc.h"
15 15
16static void conf(struct menu *menu); 16static void conf(struct menu *menu);
17static void check_conf(struct menu *menu); 17static void check_conf(struct menu *menu);
18 18
19enum { 19enum {
20 ask_all, 20 ask_all,
21 ask_new, 21 ask_new,
22 ask_silent, 22 ask_silent,
23 set_default, 23 set_default,
24 set_yes, 24 set_yes,
25 set_mod, 25 set_mod,
26 set_no, 26 set_no,
27 set_random 27 set_random
28} input_mode = ask_all; 28} input_mode = ask_all;
29 29
30static int indent = 1; 30static int indent = 1;
31static int valid_stdin = 1; 31static int valid_stdin = 1;
32static int conf_cnt; 32static int conf_cnt;
33static char line[128]; 33static char line[128];
34static struct menu *rootEntry; 34static struct menu *rootEntry;
35 35
36static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; 36static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
37 37
38#if 0
39static void printc(int ch)
40{
41 static int sep = 0;
42
43 if (!sep) {
44 putchar('[');
45 sep = 1;
46 } else if (ch)
47 putchar('/');
48 if (!ch) {
49 putchar(']');
50 putchar(' ');
51 sep = 0;
52 } else
53 putchar(ch);
54}
55#endif
56
57static void printo(const char *o)
58{
59 static int sep = 0;
60
61 if (!sep) {
62 putchar('(');
63 sep = 1;
64 } else if (o) {
65 putchar(',');
66 putchar(' ');
67 }
68 if (!o) {
69 putchar(')');
70 putchar(' ');
71 sep = 0;
72 } else
73 printf("%s", o);
74}
75
76static void strip(char *str) 38static void strip(char *str)
77{ 39{
78 char *p = str; 40 char *p = str;
79 int l; 41 int l;
80 42
81 while ((isspace(*p))) 43 while ((isspace(*p)))
82 p++; 44 p++;
83 l = strlen(p); 45 l = strlen(p);
84 if (p != str) 46 if (p != str)
85 memmove(str, p, l + 1); 47 memmove(str, p, l + 1);
86 if (!l) 48 if (!l)
87 return; 49 return;
88 p = str + l - 1; 50 p = str + l - 1;
89 while ((isspace(*p))) 51 while ((isspace(*p)))
90 *p-- = 0; 52 *p-- = 0;
91} 53}
92 54
55static void check_stdin(void)
56{
57 if (!valid_stdin && input_mode == ask_silent) {
58 printf("aborted!\n\n");
59 printf("Console input/output is redirected. ");
60 printf("Run 'make oldconfig' to update configuration.\n\n");
61 exit(1);
62 }
63}
64
93static void conf_askvalue(struct symbol *sym, const char *def) 65static void conf_askvalue(struct symbol *sym, const char *def)
94{ 66{
95 enum symbol_type type = sym_get_type(sym); 67 enum symbol_type type = sym_get_type(sym);
96 tristate val; 68 tristate val;
97 69
98 if (!sym_has_value(sym)) 70 if (!sym_has_value(sym))
99 printf("(NEW) "); 71 printf("(NEW) ");
100 72
101 line[0] = '\n'; 73 line[0] = '\n';
102 line[1] = 0; 74 line[1] = 0;
103 75
76 if (!sym_is_changable(sym)) {
77 printf("%s\n", def);
78 line[0] = '\n';
79 line[1] = 0;
80 return;
81 }
82
104 switch (input_mode) { 83 switch (input_mode) {
105 case ask_new: 84 case ask_new:
106 case ask_silent: 85 case ask_silent:
107 if (sym_has_value(sym)) { 86 if (sym_has_value(sym)) {
108 printf("%s\n", def); 87 printf("%s\n", def);
109 return; 88 return;
110 } 89 }
111 if (!valid_stdin && input_mode == ask_silent) { 90 check_stdin();
112 printf("aborted!\n\n");
113 printf("Console input/output is redirected. ");
114 printf("Run 'make oldconfig' to update configuration.\n\n");
115 exit(1);
116 }
117 case ask_all: 91 case ask_all:
118 fflush(stdout); 92 fflush(stdout);
119 fgets(line, 128, stdin); 93 fgets(line, 128, stdin);
120 return; 94 return;
121 case set_default: 95 case set_default:
122 printf("%s\n", def); 96 printf("%s\n", def);
123 return; 97 return;
124 default: 98 default:
125 break; 99 break;
126 } 100 }
127 101
128 switch (type) { 102 switch (type) {
129 case S_INT: 103 case S_INT:
130 case S_HEX: 104 case S_HEX:
131 case S_STRING: 105 case S_STRING:
132 printf("%s\n", def); 106 printf("%s\n", def);
133 return; 107 return;
134 default: 108 default:
135 ; 109 ;
136 } 110 }
137 switch (input_mode) { 111 switch (input_mode) {
138 case set_yes: 112 case set_yes:
139 if (sym_tristate_within_range(sym, yes)) { 113 if (sym_tristate_within_range(sym, yes)) {
140 line[0] = 'y'; 114 line[0] = 'y';
141 line[1] = '\n'; 115 line[1] = '\n';
142 line[2] = 0; 116 line[2] = 0;
143 break; 117 break;
144 } 118 }
145 case set_mod: 119 case set_mod:
146 if (type == S_TRISTATE) { 120 if (type == S_TRISTATE) {
147 if (sym_tristate_within_range(sym, mod)) { 121 if (sym_tristate_within_range(sym, mod)) {
148 line[0] = 'm'; 122 line[0] = 'm';
149 line[1] = '\n'; 123 line[1] = '\n';
150 line[2] = 0; 124 line[2] = 0;
151 break; 125 break;
152 } 126 }
153 } else { 127 } else {
154 if (sym_tristate_within_range(sym, yes)) { 128 if (sym_tristate_within_range(sym, yes)) {
155 line[0] = 'y'; 129 line[0] = 'y';
156 line[1] = '\n'; 130 line[1] = '\n';
157 line[2] = 0; 131 line[2] = 0;
158 break; 132 break;
159 } 133 }
160 } 134 }
161 case set_no: 135 case set_no:
162 if (sym_tristate_within_range(sym, no)) { 136 if (sym_tristate_within_range(sym, no)) {
163 line[0] = 'n'; 137 line[0] = 'n';
164 line[1] = '\n'; 138 line[1] = '\n';
165 line[2] = 0; 139 line[2] = 0;
166 break; 140 break;
167 } 141 }
168 case set_random: 142 case set_random:
169 do { 143 do {
170 val = (tristate)(random() % 3); 144 val = (tristate)(random() % 3);
171 } while (!sym_tristate_within_range(sym, val)); 145 } while (!sym_tristate_within_range(sym, val));
172 switch (val) { 146 switch (val) {
173 case no: line[0] = 'n'; break; 147 case no: line[0] = 'n'; break;
174 case mod: line[0] = 'm'; break; 148 case mod: line[0] = 'm'; break;
175 case yes: line[0] = 'y'; break; 149 case yes: line[0] = 'y'; break;
176 } 150 }
177 line[1] = '\n'; 151 line[1] = '\n';
178 line[2] = 0; 152 line[2] = 0;
179 break; 153 break;
180 default: 154 default:
181 break; 155 break;
182 } 156 }
183 printf("%s", line); 157 printf("%s", line);
184} 158}
185 159
186int conf_string(struct menu *menu) 160int conf_string(struct menu *menu)
187{ 161{
188 struct symbol *sym = menu->sym; 162 struct symbol *sym = menu->sym;
189 const char *def, *help; 163 const char *def, *help;
190 164
191 while (1) { 165 while (1) {
192 printf("%*s%s ", indent - 1, "", menu->prompt->text); 166 printf("%*s%s ", indent - 1, "", menu->prompt->text);
193 printf("(%s) ", sym->name); 167 printf("(%s) ", sym->name);
194 def = sym_get_string_value(sym); 168 def = sym_get_string_value(sym);
195 if (sym_get_string_value(sym)) 169 if (sym_get_string_value(sym))
196 printf("[%s] ", def); 170 printf("[%s] ", def);
197 conf_askvalue(sym, def); 171 conf_askvalue(sym, def);
198 switch (line[0]) { 172 switch (line[0]) {
199 case '\n': 173 case '\n':
200 break; 174 break;
201 case '?': 175 case '?':
202 /* print help */ 176 /* print help */
203 if (line[1] == 0) { 177 if (line[1] == 0) {
204 help = nohelp_text; 178 help = nohelp_text;
205 if (menu->sym->help) 179 if (menu->sym->help)
206 help = menu->sym->help; 180 help = menu->sym->help;
207 printf("\n%s\n", menu->sym->help); 181 printf("\n%s\n", menu->sym->help);
208 def = NULL; 182 def = NULL;
209 break; 183 break;
210 } 184 }
211 default: 185 default:
212 line[strlen(line)-1] = 0; 186 line[strlen(line)-1] = 0;
213 def = line; 187 def = line;
214 } 188 }
215 if (def && sym_set_string_value(sym, def)) 189 if (def && sym_set_string_value(sym, def))
216 return 0; 190 return 0;
217 } 191 }
218} 192}
219 193
220static int conf_sym(struct menu *menu) 194static int conf_sym(struct menu *menu)
221{ 195{
222 struct symbol *sym = menu->sym; 196 struct symbol *sym = menu->sym;
223 int type; 197 int type;
224 tristate oldval, newval; 198 tristate oldval, newval;
225 const char *help; 199 const char *help;
226 200
227 while (1) { 201 while (1) {
228 printf("%*s%s ", indent - 1, "", menu->prompt->text); 202 printf("%*s%s ", indent - 1, "", menu->prompt->text);
229 if (sym->name) 203 if (sym->name)
230 printf("(%s) ", sym->name); 204 printf("(%s) ", sym->name);
231 type = sym_get_type(sym); 205 type = sym_get_type(sym);
232 putchar('['); 206 putchar('[');
233 oldval = sym_get_tristate_value(sym); 207 oldval = sym_get_tristate_value(sym);
234 switch (oldval) { 208 switch (oldval) {
235 case no: 209 case no:
236 putchar('N'); 210 putchar('N');
237 break; 211 break;
238 case mod: 212 case mod:
239 putchar('M'); 213 putchar('M');
240 break; 214 break;
241 case yes: 215 case yes:
242 putchar('Y'); 216 putchar('Y');
243 break; 217 break;
244 } 218 }
245 if (oldval != no && sym_tristate_within_range(sym, no)) 219 if (oldval != no && sym_tristate_within_range(sym, no))
246 printf("/n"); 220 printf("/n");
247 if (oldval != mod && sym_tristate_within_range(sym, mod)) 221 if (oldval != mod && sym_tristate_within_range(sym, mod))
248 printf("/m"); 222 printf("/m");
249 if (oldval != yes && sym_tristate_within_range(sym, yes)) 223 if (oldval != yes && sym_tristate_within_range(sym, yes))
250 printf("/y"); 224 printf("/y");
251 if (sym->help) 225 if (sym->help)
252 printf("/?"); 226 printf("/?");
253 printf("] "); 227 printf("] ");
254 conf_askvalue(sym, sym_get_string_value(sym)); 228 conf_askvalue(sym, sym_get_string_value(sym));
255 strip(line); 229 strip(line);
256 230
257 switch (line[0]) { 231 switch (line[0]) {
258 case 'n': 232 case 'n':
259 case 'N': 233 case 'N':
260 newval = no; 234 newval = no;
261 if (!line[1] || !strcmp(&line[1], "o")) 235 if (!line[1] || !strcmp(&line[1], "o"))
262 break; 236 break;
263 continue; 237 continue;
264 case 'm': 238 case 'm':
265 case 'M': 239 case 'M':
266 newval = mod; 240 newval = mod;
267 if (!line[1]) 241 if (!line[1])
268 break; 242 break;
269 continue; 243 continue;
270 case 'y': 244 case 'y':
271 case 'Y': 245 case 'Y':
272 newval = yes; 246 newval = yes;
273 if (!line[1] || !strcmp(&line[1], "es")) 247 if (!line[1] || !strcmp(&line[1], "es"))
274 break; 248 break;
275 continue; 249 continue;
276 case 0: 250 case 0:
277 newval = oldval; 251 newval = oldval;
278 break; 252 break;
279 case '?': 253 case '?':
280 goto help; 254 goto help;
281 default: 255 default:
282 continue; 256 continue;
283 } 257 }
284 if (sym_set_tristate_value(sym, newval)) 258 if (sym_set_tristate_value(sym, newval))
285 return 0; 259 return 0;
286help: 260help:
287 help = nohelp_text; 261 help = nohelp_text;
288 if (sym->help) 262 if (sym->help)
289 help = sym->help; 263 help = sym->help;
290 printf("\n%s\n", help); 264 printf("\n%s\n", help);
291 } 265 }
292} 266}
293 267
294static int conf_choice(struct menu *menu) 268static int conf_choice(struct menu *menu)
295{ 269{
296 struct symbol *sym, *def_sym; 270 struct symbol *sym, *def_sym;
297 struct menu *cmenu, *def_menu; 271 struct menu *child;
298 const char *help; 272 int type;
299 int type, len;
300 bool is_new; 273 bool is_new;
301 274
302 sym = menu->sym; 275 sym = menu->sym;
303 type = sym_get_type(sym); 276 type = sym_get_type(sym);
304 is_new = !sym_has_value(sym); 277 is_new = !sym_has_value(sym);
305 if (sym_is_changable(sym)) { 278 if (sym_is_changable(sym)) {
306 conf_sym(menu); 279 conf_sym(menu);
307 sym_calc_value(sym); 280 sym_calc_value(sym);
308 switch (sym_get_tristate_value(sym)) { 281 switch (sym_get_tristate_value(sym)) {
309 case no: 282 case no:
310 return 1; 283 return 1;
311 case mod: 284 case mod:
312 return 0; 285 return 0;
313 case yes: 286 case yes:
314 break; 287 break;
315 } 288 }
316 } else { 289 } else {
317 sym->def = sym->curr; 290 switch (sym_get_tristate_value(sym)) {
318 if (S_TRI(sym->curr) == mod) { 291 case no:
292 return 1;
293 case mod:
319 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 294 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
320 return 0; 295 return 0;
296 case yes:
297 break;
321 } 298 }
322 } 299 }
323 300
324 while (1) { 301 while (1) {
325 printf("%*s%s ", indent - 1, "", menu_get_prompt(menu)); 302 int cnt, def;
303
304 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
326 def_sym = sym_get_choice_value(sym); 305 def_sym = sym_get_choice_value(sym);
327 def_menu = NULL; 306 cnt = def = 0;
328 for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { 307 line[0] = '0';
329 if (!menu_is_visible(cmenu)) 308 line[1] = 0;
309 for (child = menu->list; child; child = child->next) {
310 if (!menu_is_visible(child))
330 continue; 311 continue;
331 printo(menu_get_prompt(cmenu)); 312 if (!child->sym) {
332 if (cmenu->sym == def_sym) 313 printf("%*c %s\n", indent, '*', menu_get_prompt(child));
333 def_menu = cmenu; 314 continue;
334 } 315 }
335 printo(NULL); 316 cnt++;
336 if (def_menu) 317 if (child->sym == def_sym) {
337 printf("[%s] ", menu_get_prompt(def_menu)); 318 def = cnt;
338 else { 319 printf("%*c", indent, '>');
320 } else
321 printf("%*c", indent, ' ');
322 printf(" %d. %s", cnt, menu_get_prompt(child));
323 if (child->sym->name)
324 printf(" (%s)", child->sym->name);
325 if (!sym_has_value(child->sym))
326 printf(" (NEW)");
339 printf("\n"); 327 printf("\n");
340 return 1;
341 } 328 }
329 printf("%*schoice", indent - 1, "");
330 if (cnt == 1) {
331 printf("[1]: 1\n");
332 goto conf_childs;
333 }
334 printf("[1-%d", cnt);
335 if (sym->help)
336 printf("?");
337 printf("]: ");
342 switch (input_mode) { 338 switch (input_mode) {
343 case ask_new: 339 case ask_new:
344 case ask_silent: 340 case ask_silent:
341 if (!is_new) {
342 cnt = def;
343 printf("%d\n", cnt);
344 break;
345 }
346 check_stdin();
345 case ask_all: 347 case ask_all:
346 if (is_new) 348 fflush(stdout);
347 sym->flags |= SYMBOL_NEW; 349 fgets(line, 128, stdin);
348 conf_askvalue(sym, menu_get_prompt(def_menu));
349 strip(line); 350 strip(line);
351 if (line[0] == '?') {
352 printf("\n%s\n", menu->sym->help ?
353 menu->sym->help : nohelp_text);
354 continue;
355 }
356 if (!line[0])
357 cnt = def;
358 else if (isdigit(line[0]))
359 cnt = atoi(line);
360 else
361 continue;
362 break;
363 case set_random:
364 def = (random() % cnt) + 1;
365 case set_default:
366 case set_yes:
367 case set_mod:
368 case set_no:
369 cnt = def;
370 printf("%d\n", cnt);
350 break; 371 break;
351 default:
352 line[0] = 0;
353 printf("\n");
354 } 372 }
355 if (line[0] == '?' && !line[1]) { 373
356 help = nohelp_text; 374 conf_childs:
357 if (menu->sym->help) 375 for (child = menu->list; child; child = child->next) {
358 help = menu->sym->help; 376 if (!child->sym || !menu_is_visible(child))
359 printf("\n%s\n", help); 377 continue;
360 continue; 378 if (!--cnt)
379 break;
361 } 380 }
362 if (line[0]) { 381 if (!child)
363 len = strlen(line); 382 continue;
364 line[len] = 0; 383 if (line[strlen(line) - 1] == '?') {
365 384 printf("\n%s\n", child->sym->help ?
366 def_menu = NULL; 385 child->sym->help : nohelp_text);
367 for (cmenu = menu->list; cmenu; cmenu = cmenu->next) { 386 continue;
368 if (!cmenu->sym || !menu_is_visible(cmenu))
369 continue;
370 if (!strncasecmp(line, menu_get_prompt(cmenu), len)) {
371 def_menu = cmenu;
372 break;
373 }
374 }
375 } 387 }
376 if (def_menu) { 388 sym_set_choice_value(sym, child->sym);
377 sym_set_choice_value(sym, def_menu->sym); 389 if (child->list) {
378 if (def_menu->list) { 390 indent += 2;
379 indent += 2; 391 conf(child->list);
380 conf(def_menu->list); 392 indent -= 2;
381 indent -= 2;
382 }
383 return 1;
384 } 393 }
394 return 1;
385 } 395 }
386} 396}
387 397
388static void conf(struct menu *menu) 398static void conf(struct menu *menu)
389{ 399{
390 struct symbol *sym; 400 struct symbol *sym;
391 struct property *prop; 401 struct property *prop;
392 struct menu *child; 402 struct menu *child;
393 403
394 if (!menu_is_visible(menu)) 404 if (!menu_is_visible(menu))
395 return; 405 return;
396 406
397 sym = menu->sym; 407 sym = menu->sym;
398 prop = menu->prompt; 408 prop = menu->prompt;
399 if (prop) { 409 if (prop) {
400 const char *prompt; 410 const char *prompt;
401 411
402 switch (prop->type) { 412 switch (prop->type) {
403 case P_MENU: 413 case P_MENU:
404 if (input_mode == ask_silent && rootEntry != menu) { 414 if (input_mode == ask_silent && rootEntry != menu) {
405 check_conf(menu); 415 check_conf(menu);
406 return; 416 return;
407 } 417 }
408 case P_COMMENT: 418 case P_COMMENT:
409 prompt = menu_get_prompt(menu); 419 prompt = menu_get_prompt(menu);
410 if (prompt) 420 if (prompt)
411 printf("%*c\n%*c %s\n%*c\n", 421 printf("%*c\n%*c %s\n%*c\n",
412 indent, '*', 422 indent, '*',
413 indent, '*', prompt, 423 indent, '*', prompt,
414 indent, '*'); 424 indent, '*');
415 default: 425 default:
416 ; 426 ;
417 } 427 }
418 } 428 }
419 429
420 if (!sym) 430 if (!sym)
421 goto conf_childs; 431 goto conf_childs;
422 432
423 if (sym_is_choice(sym)) { 433 if (sym_is_choice(sym)) {
424 conf_choice(menu); 434 conf_choice(menu);
425 if (S_TRI(sym->curr) != mod) 435 if (sym->curr.tri != mod)
426 return; 436 return;
427 goto conf_childs; 437 goto conf_childs;
428 } 438 }
429 439
430 switch (sym->type) { 440 switch (sym->type) {
431 case S_INT: 441 case S_INT:
432 case S_HEX: 442 case S_HEX:
433 case S_STRING: 443 case S_STRING:
434 conf_string(menu); 444 conf_string(menu);
435 break; 445 break;
436 default: 446 default:
437 conf_sym(menu); 447 conf_sym(menu);
438 break; 448 break;
439 } 449 }
440 450
441conf_childs: 451conf_childs:
442 if (sym) 452 if (sym)
443 indent += 2; 453 indent += 2;
444 for (child = menu->list; child; child = child->next) 454 for (child = menu->list; child; child = child->next)
445 conf(child); 455 conf(child);
446 if (sym) 456 if (sym)
447 indent -= 2; 457 indent -= 2;
448} 458}
449 459
450static void check_conf(struct menu *menu) 460static void check_conf(struct menu *menu)
451{ 461{
452 struct symbol *sym; 462 struct symbol *sym;
453 struct menu *child; 463 struct menu *child;
454 464
455 if (!menu_is_visible(menu)) 465 if (!menu_is_visible(menu))
456 return; 466 return;
457 467
458 sym = menu->sym; 468 sym = menu->sym;
459 if (!sym) 469 if (sym) {
460 goto conf_childs; 470 if (sym_is_changable(sym) && !sym_has_value(sym)) {
461
462 if (sym_is_choice(sym)) {
463 if (!sym_has_value(sym)) {
464 if (!conf_cnt++) 471 if (!conf_cnt++)
465 printf("*\n* Restart config...\n*\n"); 472 printf("*\n* Restart config...\n*\n");
466 rootEntry = menu_get_parent_menu(menu); 473 rootEntry = menu_get_parent_menu(menu);
467 conf(rootEntry); 474 conf(rootEntry);
468 } 475 }
469 if (sym_get_tristate_value(sym) != mod) 476 if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
470 return; 477 return;
471 goto conf_childs;
472 } 478 }
473 479
474 if (!sym_has_value(sym)) {
475 if (!conf_cnt++)
476 printf("*\n* Restart config...\n*\n");
477 rootEntry = menu_get_parent_menu(menu);
478 conf(rootEntry);
479 }
480
481conf_childs:
482 for (child = menu->list; child; child = child->next) 480 for (child = menu->list; child; child = child->next)
483 check_conf(child); 481 check_conf(child);
484} 482}
485 483
486int main(int ac, char **av) 484int main(int ac, char **av)
487{ 485{
488 const char *name; 486 const char *name;
489 struct stat tmpstat; 487 struct stat tmpstat;
490 488
491 if (ac > 1 && av[1][0] == '-') { 489 if (ac > 1 && av[1][0] == '-') {
492 switch (av[1][1]) { 490 switch (av[1][1]) {
493 case 'o': 491 case 'o':
494 input_mode = ask_new; 492 input_mode = ask_new;
495 break; 493 break;
496 case 's': 494 case 's':
497 input_mode = ask_silent; 495 input_mode = ask_silent;
498 valid_stdin = isatty(0) && isatty(1) && isatty(2); 496 valid_stdin = isatty(0) && isatty(1) && isatty(2);
499 break; 497 break;
500 case 'd': 498 case 'd':
501 input_mode = set_default; 499 input_mode = set_default;
502 break; 500 break;
503 case 'n': 501 case 'n':
504 input_mode = set_no; 502 input_mode = set_no;
505 break; 503 break;
506 case 'm': 504 case 'm':
507 input_mode = set_mod; 505 input_mode = set_mod;
508 break; 506 break;
509 case 'y': 507 case 'y':
510 input_mode = set_yes; 508 input_mode = set_yes;
511 break; 509 break;
512 case 'r': 510 case 'r':
513 input_mode = set_random; 511 input_mode = set_random;
514 srandom(time(NULL)); 512 srandom(time(NULL));
515 break; 513 break;
516 case 'h': 514 case 'h':
517 case '?': 515 case '?':
518 printf("%s [-o|-s] config\n", av[0]); 516 printf("%s [-o|-s] config\n", av[0]);
519 exit(0); 517 exit(0);
520 } 518 }
521 name = av[2]; 519 name = av[2];
522 } else 520 } else
523 name = av[1]; 521 name = av[1];
524 conf_parse(name); 522 conf_parse(name);
525 //zconfdump(stdout); 523 //zconfdump(stdout);
526 switch (input_mode) { 524 switch (input_mode) {
527 case set_default: 525 case set_default:
528 name = conf_get_default_confname(); 526 name = conf_get_default_confname();
529 if (conf_read(name)) { 527 if (conf_read(name)) {
530 printf("***\n" 528 printf("***\n"
531 "*** Can't find default configuration \"%s\"!\n" 529 "*** Can't find default configuration \"%s\"!\n"
532 "***\n", name); 530 "***\n", name);
533 exit(1); 531 exit(1);
534 } 532 }
535 break; 533 break;
536 case ask_silent: 534 case ask_silent:
537 if (stat(".config", &tmpstat)) { 535 if (stat(".config", &tmpstat)) {
538 printf("***\n" 536 printf("***\n"
539 "*** You have not yet configured your kernel!\n" 537 "*** You have not yet configured!\n"
540 "***\n" 538 "***\n"
541 "*** Please run some configurator (e.g. \"make oldconfig\" or\n" 539 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
542 "*** \"make menuconfig\" or \"make xconfig\").\n" 540 "*** \"make menuconfig\" or \"make xconfig\").\n"
543 "***\n"); 541 "***\n");
544 exit(1); 542 exit(1);
545 } 543 }
546 case ask_all: 544 case ask_all:
547 case ask_new: 545 case ask_new:
548 conf_read(NULL); 546 conf_read(NULL);
549 break; 547 break;
550 default: 548 default:
551 break; 549 break;
552 } 550 }
553 551
554 if (input_mode != ask_silent) { 552 if (input_mode != ask_silent) {
555 rootEntry = &rootmenu; 553 rootEntry = &rootmenu;
556 conf(&rootmenu); 554 conf(&rootmenu);
557 if (input_mode == ask_all) { 555 if (input_mode == ask_all) {
558 input_mode = ask_silent; 556 input_mode = ask_silent;
559 valid_stdin = 1; 557 valid_stdin = 1;
560 } 558 }
561 } 559 }
562 do { 560 do {
563 conf_cnt = 0; 561 conf_cnt = 0;
564 check_conf(&rootmenu); 562 check_conf(&rootmenu);
565 } while (conf_cnt); 563 } while (conf_cnt);
566 conf_write(NULL); 564 conf_write(NULL);
567 return 0; 565 return 0;
568} 566}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 9bf7af9..f3796ce 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -1,378 +1,422 @@
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 <sys/stat.h>
7#include <ctype.h> 7#include <ctype.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";
17 17
18const char conf_defname[] = "arch/$ARCH/defconfig"; 18const char conf_defname[] = "arch/$ARCH/defconfig";
19 19
20const char *conf_confnames[] = { 20const char *conf_confnames[] = {
21 ".config", 21 ".config",
22 "/lib/modules/$UNAME_RELEASE/.config",
23 "/etc/kernel-config",
24 "/boot/config-$UNAME_RELEASE",
25 conf_defname, 22 conf_defname,
26 NULL, 23 NULL,
27}; 24};
28 25
29static char *conf_expand_value(const char *in) 26static char *conf_expand_value(const char *in)
30{ 27{
31 struct symbol *sym; 28 struct symbol *sym;
32 const char *src; 29 const char *src;
33 static char res_value[SYMBOL_MAXLENGTH]; 30 static char res_value[SYMBOL_MAXLENGTH];
34 char *dst, name[SYMBOL_MAXLENGTH]; 31 char *dst, name[SYMBOL_MAXLENGTH];
35 32
36 res_value[0] = 0; 33 res_value[0] = 0;
37 dst = name; 34 dst = name;
38 while ((src = strchr(in, '$'))) { 35 while ((src = strchr(in, '$'))) {
39 strncat(res_value, in, src - in); 36 strncat(res_value, in, src - in);
40 src++; 37 src++;
41 dst = name; 38 dst = name;
42 while (isalnum(*src) || *src == '_') 39 while (isalnum(*src) || *src == '_')
43 *dst++ = *src++; 40 *dst++ = *src++;
44 *dst = 0; 41 *dst = 0;
45 sym = sym_lookup(name, 0); 42 sym = sym_lookup(name, 0);
46 sym_calc_value(sym); 43 sym_calc_value(sym);
47 strcat(res_value, sym_get_string_value(sym)); 44 strcat(res_value, sym_get_string_value(sym));
48 in = src; 45 in = src;
49 } 46 }
50 strcat(res_value, in); 47 strcat(res_value, in);
51 48
52 return res_value; 49 return res_value;
53} 50}
54 51
55char *conf_get_default_confname(void) 52char *conf_get_default_confname(void)
56{ 53{
57 struct stat buf; 54 struct stat buf;
58 static char fullname[PATH_MAX+1]; 55 static char fullname[PATH_MAX+1];
59 char *env, *name; 56 char *env, *name;
60 57
61 name = conf_expand_value(conf_defname); 58 name = conf_expand_value(conf_defname);
62 env = getenv(SRCTREE); 59 env = getenv(SRCTREE);
63 if (env) { 60 if (env) {
64 sprintf(fullname, "%s/%s", env, name); 61 sprintf(fullname, "%s/%s", env, name);
65 if (!stat(fullname, &buf)) 62 if (!stat(fullname, &buf))
66 return fullname; 63 return fullname;
67 } 64 }
68 return name; 65 return name;
69} 66}
70 67
71int conf_read(const char *name) 68int conf_read(const char *name)
72{ 69{
73 FILE *in = NULL; 70 FILE *in = NULL;
74 char line[1024]; 71 char line[1024];
75 char *p, *p2; 72 char *p, *p2;
76 int lineno = 0; 73 int lineno = 0;
77 struct symbol *sym; 74 struct symbol *sym;
78 struct property *prop; 75 struct property *prop;
79 struct expr *e; 76 struct expr *e;
80 int i; 77 int i;
81 78
82 if (name) { 79 if (name) {
83 in = zconf_fopen(name); 80 in = zconf_fopen(name);
84 } else { 81 } else {
85 const char **names = conf_confnames; 82 const char **names = conf_confnames;
86 while ((name = *names++)) { 83 while ((name = *names++)) {
87 name = conf_expand_value(name); 84 name = conf_expand_value(name);
88 in = zconf_fopen(name); 85 in = zconf_fopen(name);
89 if (in) { 86 if (in) {
90 printf("#\n" 87 printf("#\n"
91 "# using defaults found in %s\n" 88 "# using defaults found in %s\n"
92 "#\n", name); 89 "#\n", name);
93 break; 90 break;
94 } 91 }
95 } 92 }
96 } 93 }
97 94
98 if (!in) 95 if (!in)
99 return 1; 96 return 1;
100 97
101 for_all_symbols(i, sym) { 98 for_all_symbols(i, sym) {
102 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; 99 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
103 sym->flags &= ~SYMBOL_VALID; 100 sym->flags &= ~SYMBOL_VALID;
104 switch (sym->type) { 101 switch (sym->type) {
105 case S_INT: 102 case S_INT:
106 case S_HEX: 103 case S_HEX:
107 case S_STRING: 104 case S_STRING:
108 if (S_VAL(sym->def)) 105 if (sym->user.val)
109 free(S_VAL(sym->def)); 106 free(sym->user.val);
110 default: 107 default:
111 S_VAL(sym->def) = NULL; 108 sym->user.val = NULL;
112 S_TRI(sym->def) = no; 109 sym->user.tri = no;
113 } 110 }
114 } 111 }
115 112
116 while (fgets(line, sizeof(line), in)) { 113 while (fgets(line, sizeof(line), in)) {
117 lineno++; 114 lineno++;
118 switch (line[0]) { 115 switch (line[0]) {
119 case '#': 116 case '#':
120 if (memcmp(line + 2, "CONFIG_", 7)) 117 if (memcmp(line + 2, "CONFIG_", 7))
121 continue; 118 continue;
122 p = strchr(line + 9, ' '); 119 p = strchr(line + 9, ' ');
123 if (!p) 120 if (!p)
124 continue; 121 continue;
125 *p++ = 0; 122 *p++ = 0;
126 if (strncmp(p, "is not set", 10)) 123 if (strncmp(p, "is not set", 10))
127 continue; 124 continue;
128 sym = sym_lookup(line + 9, 0); 125 sym = sym_lookup(line + 9, 0);
129 switch (sym->type) { 126 switch (sym->type) {
130 case S_BOOLEAN: 127 case S_BOOLEAN:
131 case S_TRISTATE: 128 case S_TRISTATE:
132 sym->def = symbol_no.curr; 129 sym->user = symbol_no.curr;
133 sym->flags &= ~SYMBOL_NEW; 130 sym->flags &= ~SYMBOL_NEW;
134 break; 131 break;
135 default: 132 default:
136 ; 133 ;
137 } 134 }
138 break; 135 break;
139 case 'C': 136 case 'C':
140 if (memcmp(line, "CONFIG_", 7)) 137 if (memcmp(line, "CONFIG_", 7))
141 continue; 138 continue;
142 p = strchr(line + 7, '='); 139 p = strchr(line + 7, '=');
143 if (!p) 140 if (!p)
144 continue; 141 continue;
145 *p++ = 0; 142 *p++ = 0;
146 p2 = strchr(p, '\n'); 143 p2 = strchr(p, '\n');
147 if (p2) 144 if (p2)
148 *p2 = 0; 145 *p2 = 0;
149 sym = sym_find(line + 7); 146 sym = sym_find(line + 7);
150 if (!sym) { 147 if (!sym) {
151 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7); 148 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
152 break; 149 break;
153 } 150 }
154 switch (sym->type) { 151 switch (sym->type) {
155 case S_TRISTATE: 152 case S_TRISTATE:
156 if (p[0] == 'm') { 153 if (p[0] == 'm') {
157 S_TRI(sym->def) = mod; 154 sym->user.tri = mod;
158 sym->flags &= ~SYMBOL_NEW; 155 sym->flags &= ~SYMBOL_NEW;
159 break; 156 break;
160 } 157 }
161 case S_BOOLEAN: 158 case S_BOOLEAN:
162 if (p[0] == 'y') { 159 if (p[0] == 'y') {
163 S_TRI(sym->def) = yes; 160 sym->user.tri = yes;
164 sym->flags &= ~SYMBOL_NEW; 161 sym->flags &= ~SYMBOL_NEW;
165 break; 162 break;
166 } 163 }
167 if (p[0] == 'n') { 164 if (p[0] == 'n') {
168 S_TRI(sym->def) = no; 165 sym->user.tri = no;
169 sym->flags &= ~SYMBOL_NEW; 166 sym->flags &= ~SYMBOL_NEW;
170 break; 167 break;
171 } 168 }
172 break; 169 break;
173 case S_STRING: 170 case S_STRING:
174 if (*p++ != '"') 171 if (*p++ != '"')
175 break; 172 break;
176 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 173 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
177 if (*p2 == '"') { 174 if (*p2 == '"') {
178 *p2 = 0; 175 *p2 = 0;
179 break; 176 break;
180 } 177 }
181 memmove(p2, p2 + 1, strlen(p2)); 178 memmove(p2, p2 + 1, strlen(p2));
182 } 179 }
183 if (!p2) { 180 if (!p2) {
184 fprintf(stderr, "%s:%d: invalid string found\n", name, lineno); 181 fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
185 exit(1); 182 exit(1);
186 } 183 }
187 case S_INT: 184 case S_INT:
188 case S_HEX: 185 case S_HEX:
189 if (sym_string_valid(sym, p)) { 186 if (sym_string_valid(sym, p)) {
190 S_VAL(sym->def) = strdup(p); 187 sym->user.val = strdup(p);
191 sym->flags &= ~SYMBOL_NEW; 188 sym->flags &= ~SYMBOL_NEW;
192 } else { 189 } else {
193 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name); 190 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
194 exit(1); 191 exit(1);
195 } 192 }
196 break; 193 break;
197 default: 194 default:
198 ; 195 ;
199 } 196 }
200 if (sym_is_choice_value(sym)) { 197 if (sym_is_choice_value(sym)) {
201 prop = sym_get_choice_prop(sym); 198 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
202 switch (S_TRI(sym->def)) { 199 switch (sym->user.tri) {
203 case mod: 200 case mod:
204 if (S_TRI(prop->def->def) == yes) 201 if (cs->user.tri == yes)
205 /* warn? */; 202 /* warn? */;
206 break; 203 break;
207 case yes: 204 case yes:
208 if (S_TRI(prop->def->def) != no) 205 if (cs->user.tri != no)
209 /* warn? */; 206 /* warn? */;
210 S_VAL(prop->def->def) = sym; 207 cs->user.val = sym;
211 break; 208 break;
212 case no: 209 case no:
213 break; 210 break;
214 } 211 }
215 S_TRI(prop->def->def) = S_TRI(sym->def); 212 cs->user.tri = sym->user.tri;
216 } 213 }
217 break; 214 break;
218 case '\n': 215 case '\n':
219 break; 216 break;
220 default: 217 default:
221 continue; 218 continue;
222 } 219 }
223 } 220 }
224 fclose(in); 221 fclose(in);
225 222
226 for_all_symbols(i, sym) { 223 for_all_symbols(i, sym) {
224 sym_calc_value(sym);
225 if (sym_has_value(sym)) {
226 if (sym->visible == no)
227 sym->flags |= SYMBOL_NEW;
228 switch (sym->type) {
229 case S_STRING:
230 case S_INT:
231 case S_HEX:
232 if (!sym_string_within_range(sym, sym->user.val))
233 sym->flags |= SYMBOL_NEW;
234 default:
235 break;
236 }
237 }
227 if (!sym_is_choice(sym)) 238 if (!sym_is_choice(sym))
228 continue; 239 continue;
229 prop = sym_get_choice_prop(sym); 240 prop = sym_get_choice_prop(sym);
230 sym->flags &= ~SYMBOL_NEW; 241 sym->flags &= ~SYMBOL_NEW;
231 for (e = prop->dep; e; e = e->left.expr) 242 for (e = prop->expr; e; e = e->left.expr)
232 sym->flags |= e->right.sym->flags & SYMBOL_NEW; 243 if (e->right.sym->visible != no)
244 sym->flags |= e->right.sym->flags & SYMBOL_NEW;
233 } 245 }
234 246
235 sym_change_count = 1; 247 sym_change_count = 1;
236 248
237 return 0; 249 return 0;
238} 250}
239 251
240int conf_write(const char *name) 252int conf_write(const char *name)
241{ 253{
242 FILE *out, *out_h; 254 FILE *out, *out_h;
243 struct symbol *sym; 255 struct symbol *sym;
244 struct menu *menu; 256 struct menu *menu;
245 char oldname[128]; 257 const char *basename;
258 char dirname[128], tmpname[128], newname[128];
246 int type, l; 259 int type, l;
247 const char *str; 260 const char *str;
248 261
249 out = fopen(".tmpconfig", "w"); 262 dirname[0] = 0;
263 if (name && name[0]) {
264 char *slash = strrchr(name, '/');
265 if (slash) {
266 int size = slash - name + 1;
267 memcpy(dirname, name, size);
268 dirname[size] = 0;
269 if (slash[1])
270 basename = slash + 1;
271 else
272 basename = conf_def_filename;
273 } else
274 basename = name;
275 } else
276 basename = conf_def_filename;
277
278 sprintf(newname, "%s.tmpconfig.%d", dirname, getpid());
279 out = fopen(newname, "w");
250 if (!out) 280 if (!out)
251 return 1; 281 return 1;
252 out_h = fopen(".tmpconfig.h", "w"); 282 out_h = NULL;
253 if (!out_h) 283 if (!name) {
254 return 1; 284 out_h = fopen(".tmpconfig.h", "w");
285 if (!out_h)
286 return 1;
287 }
255 fprintf(out, "#\n" 288 fprintf(out, "#\n"
256 "# Automatically generated make config: don't edit\n" 289 "# Automatically generated make config: don't edit\n"
257 "#\n"); 290 "#\n");
258 fprintf(out_h, "/*\n" 291 if (out_h)
259 " * Automatically generated C config: don't edit\n" 292 fprintf(out_h, "/*\n"
260 " */\n" 293 " * Automatically generated C config: don't edit\n"
261 "#define AUTOCONF_INCLUDED\n"); 294 " */\n"
295 "#define AUTOCONF_INCLUDED\n");
262 296
263 if (!sym_change_count) 297 if (!sym_change_count)
264 sym_clear_all_valid(); 298 sym_clear_all_valid();
265 299
266 menu = rootmenu.list; 300 menu = rootmenu.list;
267 while (menu) { 301 while (menu) {
268 sym = menu->sym; 302 sym = menu->sym;
269 if (!sym) { 303 if (!sym) {
270 if (!menu_is_visible(menu)) 304 if (!menu_is_visible(menu))
271 goto next; 305 goto next;
272 str = menu_get_prompt(menu); 306 str = menu_get_prompt(menu);
273 fprintf(out, "\n" 307 fprintf(out, "\n"
274 "#\n" 308 "#\n"
275 "# %s\n" 309 "# %s\n"
276 "#\n", str); 310 "#\n", str);
277 fprintf(out_h, "\n" 311 if (out_h)
278 "/*\n" 312 fprintf(out_h, "\n"
279 " * %s\n" 313 "/*\n"
280 " */\n", str); 314 " * %s\n"
315 " */\n", str);
281 } else if (!(sym->flags & SYMBOL_CHOICE)) { 316 } else if (!(sym->flags & SYMBOL_CHOICE)) {
282 sym_calc_value(sym); 317 sym_calc_value(sym);
283 if (!(sym->flags & SYMBOL_WRITE)) 318 if (!(sym->flags & SYMBOL_WRITE))
284 goto next; 319 goto next;
285 sym->flags &= ~SYMBOL_WRITE; 320 sym->flags &= ~SYMBOL_WRITE;
286 type = sym->type; 321 type = sym->type;
287 if (type == S_TRISTATE) { 322 if (type == S_TRISTATE) {
288 sym_calc_value(modules_sym); 323 sym_calc_value(modules_sym);
289 if (S_TRI(modules_sym->curr) == no) 324 if (modules_sym->curr.tri == no)
290 type = S_BOOLEAN; 325 type = S_BOOLEAN;
291 } 326 }
292 switch (type) { 327 switch (type) {
293 case S_BOOLEAN: 328 case S_BOOLEAN:
294 case S_TRISTATE: 329 case S_TRISTATE:
295 switch (sym_get_tristate_value(sym)) { 330 switch (sym_get_tristate_value(sym)) {
296 case no: 331 case no:
297 fprintf(out, "# CONFIG_%s is not set\n", sym->name); 332 fprintf(out, "# CONFIG_%s is not set\n", sym->name);
298 fprintf(out_h, "#undef CONFIG_%s\n", sym->name); 333 if (out_h)
334 fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
299 break; 335 break;
300 case mod: 336 case mod:
301 fprintf(out, "CONFIG_%s=m\n", sym->name); 337 fprintf(out, "CONFIG_%s=m\n", sym->name);
302 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 338 if (out_h)
339 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
303 break; 340 break;
304 case yes: 341 case yes:
305 fprintf(out, "CONFIG_%s=y\n", sym->name); 342 fprintf(out, "CONFIG_%s=y\n", sym->name);
306 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); 343 if (out_h)
344 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
307 break; 345 break;
308 } 346 }
309 break; 347 break;
310 case S_STRING: 348 case S_STRING:
311 // fix me 349 // fix me
312 str = sym_get_string_value(sym); 350 str = sym_get_string_value(sym);
313 fprintf(out, "CONFIG_%s=\"", sym->name); 351 fprintf(out, "CONFIG_%s=\"", sym->name);
314 fprintf(out_h, "#define CONFIG_%s \"", sym->name); 352 if (out_h)
353 fprintf(out_h, "#define CONFIG_%s \"", sym->name);
315 do { 354 do {
316 l = strcspn(str, "\"\\"); 355 l = strcspn(str, "\"\\");
317 if (l) { 356 if (l) {
318 fwrite(str, l, 1, out); 357 fwrite(str, l, 1, out);
319 fwrite(str, l, 1, out_h); 358 if (out_h)
359 fwrite(str, l, 1, out_h);
320 } 360 }
321 str += l; 361 str += l;
322 while (*str == '\\' || *str == '"') { 362 while (*str == '\\' || *str == '"') {
323 fprintf(out, "\\%c", *str); 363 fprintf(out, "\\%c", *str);
324 fprintf(out_h, "\\%c", *str); 364 if (out_h)
365 fprintf(out_h, "\\%c", *str);
325 str++; 366 str++;
326 } 367 }
327 } while (*str); 368 } while (*str);
328 fputs("\"\n", out); 369 fputs("\"\n", out);
329 fputs("\"\n", out_h); 370 if (out_h)
371 fputs("\"\n", out_h);
330 break; 372 break;
331 case S_HEX: 373 case S_HEX:
332 str = sym_get_string_value(sym); 374 str = sym_get_string_value(sym);
333 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 375 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
334 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 376 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
335 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); 377 if (out_h)
378 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
336 break; 379 break;
337 } 380 }
338 case S_INT: 381 case S_INT:
339 str = sym_get_string_value(sym); 382 str = sym_get_string_value(sym);
340 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 383 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
341 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); 384 if (out_h)
385 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
342 break; 386 break;
343 } 387 }
344 } 388 }
345 389
346 next: 390 next:
347 if (menu->list) { 391 if (menu->list) {
348 menu = menu->list; 392 menu = menu->list;
349 continue; 393 continue;
350 } 394 }
351 if (menu->next) 395 if (menu->next)
352 menu = menu->next; 396 menu = menu->next;
353 else while ((menu = menu->parent)) { 397 else while ((menu = menu->parent)) {
354 if (menu->next) { 398 if (menu->next) {
355 menu = menu->next; 399 menu = menu->next;
356 break; 400 break;
357 } 401 }
358 } 402 }
359 } 403 }
360 fclose(out); 404 fclose(out);
361 fclose(out_h); 405 if (out_h) {
362 406 fclose(out_h);
363 if (!name) {
364 rename(".tmpconfig.h", "include/linux/autoconf.h"); 407 rename(".tmpconfig.h", "include/linux/autoconf.h");
365 name = conf_def_filename; 408 }
366 file_write_dep(NULL); 409 if (!name || basename != conf_def_filename) {
367 } else 410 if (!name)
368 unlink(".tmpconfig.h"); 411 name = conf_def_filename;
369 412 sprintf(tmpname, "%s.old", name);
370 sprintf(oldname, "%s.old", name); 413 rename(name, tmpname);
371 rename(name, oldname); 414 }
372 if (rename(".tmpconfig", name)) 415 sprintf(tmpname, "%s%s", dirname, basename);
416 if (rename(newname, tmpname))
373 return 1; 417 return 1;
374 418
375 sym_change_count = 0; 419 sym_change_count = 0;
376 420
377 return 0; 421 return 0;
378} 422}
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index d1af2a5..3f15ae8 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1,1054 +1,1083 @@
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 <stdio.h> 6#include <stdio.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <string.h> 8#include <string.h>
9 9
10#define LKC_DIRECT_LINK 10#define LKC_DIRECT_LINK
11#include "lkc.h" 11#include "lkc.h"
12 12
13struct expr *expr_alloc_symbol(struct symbol *sym) 13struct expr *expr_alloc_symbol(struct symbol *sym)
14{ 14{
15 struct expr *e = malloc(sizeof(*e)); 15 struct expr *e = malloc(sizeof(*e));
16 memset(e, 0, sizeof(*e)); 16 memset(e, 0, sizeof(*e));
17 e->type = E_SYMBOL; 17 e->type = E_SYMBOL;
18 e->left.sym = sym; 18 e->left.sym = sym;
19 return e; 19 return e;
20} 20}
21 21
22struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) 22struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
23{ 23{
24 struct expr *e = malloc(sizeof(*e)); 24 struct expr *e = malloc(sizeof(*e));
25 memset(e, 0, sizeof(*e)); 25 memset(e, 0, sizeof(*e));
26 e->type = type; 26 e->type = type;
27 e->left.expr = ce; 27 e->left.expr = ce;
28 return e; 28 return e;
29} 29}
30 30
31struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) 31struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
32{ 32{
33 struct expr *e = malloc(sizeof(*e)); 33 struct expr *e = malloc(sizeof(*e));
34 memset(e, 0, sizeof(*e)); 34 memset(e, 0, sizeof(*e));
35 e->type = type; 35 e->type = type;
36 e->left.expr = e1; 36 e->left.expr = e1;
37 e->right.expr = e2; 37 e->right.expr = e2;
38 return e; 38 return e;
39} 39}
40 40
41struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) 41struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
42{ 42{
43 struct expr *e = malloc(sizeof(*e)); 43 struct expr *e = malloc(sizeof(*e));
44 memset(e, 0, sizeof(*e)); 44 memset(e, 0, sizeof(*e));
45 e->type = type; 45 e->type = type;
46 e->left.sym = s1; 46 e->left.sym = s1;
47 e->right.sym = s2; 47 e->right.sym = s2;
48 return e; 48 return e;
49} 49}
50 50
51struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) 51struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
52{ 52{
53 if (!e1) 53 if (!e1)
54 return e2; 54 return e2;
55 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; 55 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
56} 56}
57 57
58struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
59{
60 if (!e1)
61 return e2;
62 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
63}
64
58struct expr *expr_copy(struct expr *org) 65struct expr *expr_copy(struct expr *org)
59{ 66{
60 struct expr *e; 67 struct expr *e;
61 68
62 if (!org) 69 if (!org)
63 return NULL; 70 return NULL;
64 71
65 e = malloc(sizeof(*org)); 72 e = malloc(sizeof(*org));
66 memcpy(e, org, sizeof(*org)); 73 memcpy(e, org, sizeof(*org));
67 switch (org->type) { 74 switch (org->type) {
68 case E_SYMBOL: 75 case E_SYMBOL:
69 e->left = org->left; 76 e->left = org->left;
70 break; 77 break;
71 case E_NOT: 78 case E_NOT:
72 e->left.expr = expr_copy(org->left.expr); 79 e->left.expr = expr_copy(org->left.expr);
73 break; 80 break;
74 case E_EQUAL: 81 case E_EQUAL:
75 case E_UNEQUAL: 82 case E_UNEQUAL:
76 e->left.sym = org->left.sym; 83 e->left.sym = org->left.sym;
77 e->right.sym = org->right.sym; 84 e->right.sym = org->right.sym;
78 break; 85 break;
79 case E_AND: 86 case E_AND:
80 case E_OR: 87 case E_OR:
81 case E_CHOICE: 88 case E_CHOICE:
82 e->left.expr = expr_copy(org->left.expr); 89 e->left.expr = expr_copy(org->left.expr);
83 e->right.expr = expr_copy(org->right.expr); 90 e->right.expr = expr_copy(org->right.expr);
84 break; 91 break;
85 default: 92 default:
86 printf("can't copy type %d\n", e->type); 93 printf("can't copy type %d\n", e->type);
87 free(e); 94 free(e);
88 e = NULL; 95 e = NULL;
89 break; 96 break;
90 } 97 }
91 98
92 return e; 99 return e;
93} 100}
94 101
95void expr_free(struct expr *e) 102void expr_free(struct expr *e)
96{ 103{
97 if (!e) 104 if (!e)
98 return; 105 return;
99 106
100 switch (e->type) { 107 switch (e->type) {
101 case E_SYMBOL: 108 case E_SYMBOL:
102 break; 109 break;
103 case E_NOT: 110 case E_NOT:
104 expr_free(e->left.expr); 111 expr_free(e->left.expr);
105 return; 112 return;
106 case E_EQUAL: 113 case E_EQUAL:
107 case E_UNEQUAL: 114 case E_UNEQUAL:
108 break; 115 break;
109 case E_OR: 116 case E_OR:
110 case E_AND: 117 case E_AND:
111 expr_free(e->left.expr); 118 expr_free(e->left.expr);
112 expr_free(e->right.expr); 119 expr_free(e->right.expr);
113 break; 120 break;
114 default: 121 default:
115 printf("how to free type %d?\n", e->type); 122 printf("how to free type %d?\n", e->type);
116 break; 123 break;
117 } 124 }
118 free(e); 125 free(e);
119} 126}
120 127
121static int trans_count; 128static int trans_count;
122 129
123#define e1 (*ep1) 130#define e1 (*ep1)
124#define e2 (*ep2) 131#define e2 (*ep2)
125 132
126static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) 133static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
127{ 134{
128 if (e1->type == type) { 135 if (e1->type == type) {
129 __expr_eliminate_eq(type, &e1->left.expr, &e2); 136 __expr_eliminate_eq(type, &e1->left.expr, &e2);
130 __expr_eliminate_eq(type, &e1->right.expr, &e2); 137 __expr_eliminate_eq(type, &e1->right.expr, &e2);
131 return; 138 return;
132 } 139 }
133 if (e2->type == type) { 140 if (e2->type == type) {
134 __expr_eliminate_eq(type, &e1, &e2->left.expr); 141 __expr_eliminate_eq(type, &e1, &e2->left.expr);
135 __expr_eliminate_eq(type, &e1, &e2->right.expr); 142 __expr_eliminate_eq(type, &e1, &e2->right.expr);
136 return; 143 return;
137 } 144 }
138 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 145 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
139 e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO))) 146 e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO)))
140 return; 147 return;
141 if (!expr_eq(e1, e2)) 148 if (!expr_eq(e1, e2))
142 return; 149 return;
143 trans_count++; 150 trans_count++;
144 expr_free(e1); expr_free(e2); 151 expr_free(e1); expr_free(e2);
145 switch (type) { 152 switch (type) {
146 case E_OR: 153 case E_OR:
147 e1 = expr_alloc_symbol(&symbol_no); 154 e1 = expr_alloc_symbol(&symbol_no);
148 e2 = expr_alloc_symbol(&symbol_no); 155 e2 = expr_alloc_symbol(&symbol_no);
149 break; 156 break;
150 case E_AND: 157 case E_AND:
151 e1 = expr_alloc_symbol(&symbol_yes); 158 e1 = expr_alloc_symbol(&symbol_yes);
152 e2 = expr_alloc_symbol(&symbol_yes); 159 e2 = expr_alloc_symbol(&symbol_yes);
153 break; 160 break;
154 default: 161 default:
155 ; 162 ;
156 } 163 }
157} 164}
158 165
159void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) 166void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
160{ 167{
161 if (!e1 || !e2 || e1->type != e2->type) 168 if (!e1 || !e2)
162 return; 169 return;
163 __expr_eliminate_eq(e1->type, ep1, ep2); 170 switch (e1->type) {
171 case E_OR:
172 case E_AND:
173 __expr_eliminate_eq(e1->type, ep1, ep2);
174 default:
175 ;
176 }
177 if (e1->type != e2->type) switch (e2->type) {
178 case E_OR:
179 case E_AND:
180 __expr_eliminate_eq(e2->type, ep1, ep2);
181 default:
182 ;
183 }
164 e1 = expr_eliminate_yn(e1); 184 e1 = expr_eliminate_yn(e1);
165 e2 = expr_eliminate_yn(e2); 185 e2 = expr_eliminate_yn(e2);
166} 186}
167 187
168#undef e1 188#undef e1
169#undef e2 189#undef e2
170 190
171int expr_eq(struct expr *e1, struct expr *e2) 191int expr_eq(struct expr *e1, struct expr *e2)
172{ 192{
173 int res, old_count; 193 int res, old_count;
174 194
175 if (e1->type != e2->type) 195 if (e1->type != e2->type)
176 return 0; 196 return 0;
177 switch (e1->type) { 197 switch (e1->type) {
178 case E_EQUAL: 198 case E_EQUAL:
179 case E_UNEQUAL: 199 case E_UNEQUAL:
180 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; 200 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
181 case E_SYMBOL: 201 case E_SYMBOL:
182 return e1->left.sym == e2->left.sym; 202 return e1->left.sym == e2->left.sym;
183 case E_NOT: 203 case E_NOT:
184 return expr_eq(e1->left.expr, e2->left.expr); 204 return expr_eq(e1->left.expr, e2->left.expr);
185 case E_AND: 205 case E_AND:
186 case E_OR: 206 case E_OR:
187 e1 = expr_copy(e1); 207 e1 = expr_copy(e1);
188 e2 = expr_copy(e2); 208 e2 = expr_copy(e2);
189 old_count = trans_count; 209 old_count = trans_count;
190 expr_eliminate_eq(&e1, &e2); 210 expr_eliminate_eq(&e1, &e2);
191 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 211 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
192 e1->left.sym == e2->left.sym); 212 e1->left.sym == e2->left.sym);
193 expr_free(e1); 213 expr_free(e1);
194 expr_free(e2); 214 expr_free(e2);
195 trans_count = old_count; 215 trans_count = old_count;
196 return res; 216 return res;
197 case E_CHOICE: 217 case E_CHOICE:
218 case E_RANGE:
198 case E_NONE: 219 case E_NONE:
199 /* panic */; 220 /* panic */;
200 } 221 }
201 222
202 print_expr(0, e1, 0); 223 print_expr(0, e1, 0);
203 printf(" = "); 224 printf(" = ");
204 print_expr(0, e2, 0); 225 print_expr(0, e2, 0);
205 printf(" ?\n"); 226 printf(" ?\n");
206 227
207 return 0; 228 return 0;
208} 229}
209 230
210struct expr *expr_eliminate_yn(struct expr *e) 231struct expr *expr_eliminate_yn(struct expr *e)
211{ 232{
212 struct expr *tmp; 233 struct expr *tmp;
213 234
214 if (e) switch (e->type) { 235 if (e) switch (e->type) {
215 case E_AND: 236 case E_AND:
216 e->left.expr = expr_eliminate_yn(e->left.expr); 237 e->left.expr = expr_eliminate_yn(e->left.expr);
217 e->right.expr = expr_eliminate_yn(e->right.expr); 238 e->right.expr = expr_eliminate_yn(e->right.expr);
218 if (e->left.expr->type == E_SYMBOL) { 239 if (e->left.expr->type == E_SYMBOL) {
219 if (e->left.expr->left.sym == &symbol_no) { 240 if (e->left.expr->left.sym == &symbol_no) {
220 expr_free(e->left.expr); 241 expr_free(e->left.expr);
221 expr_free(e->right.expr); 242 expr_free(e->right.expr);
222 e->type = E_SYMBOL; 243 e->type = E_SYMBOL;
223 e->left.sym = &symbol_no; 244 e->left.sym = &symbol_no;
224 e->right.expr = NULL; 245 e->right.expr = NULL;
225 return e; 246 return e;
226 } else if (e->left.expr->left.sym == &symbol_yes) { 247 } else if (e->left.expr->left.sym == &symbol_yes) {
227 free(e->left.expr); 248 free(e->left.expr);
228 tmp = e->right.expr; 249 tmp = e->right.expr;
229 *e = *(e->right.expr); 250 *e = *(e->right.expr);
230 free(tmp); 251 free(tmp);
231 return e; 252 return e;
232 } 253 }
233 } 254 }
234 if (e->right.expr->type == E_SYMBOL) { 255 if (e->right.expr->type == E_SYMBOL) {
235 if (e->right.expr->left.sym == &symbol_no) { 256 if (e->right.expr->left.sym == &symbol_no) {
236 expr_free(e->left.expr); 257 expr_free(e->left.expr);
237 expr_free(e->right.expr); 258 expr_free(e->right.expr);
238 e->type = E_SYMBOL; 259 e->type = E_SYMBOL;
239 e->left.sym = &symbol_no; 260 e->left.sym = &symbol_no;
240 e->right.expr = NULL; 261 e->right.expr = NULL;
241 return e; 262 return e;
242 } else if (e->right.expr->left.sym == &symbol_yes) { 263 } else if (e->right.expr->left.sym == &symbol_yes) {
243 free(e->right.expr); 264 free(e->right.expr);
244 tmp = e->left.expr; 265 tmp = e->left.expr;
245 *e = *(e->left.expr); 266 *e = *(e->left.expr);
246 free(tmp); 267 free(tmp);
247 return e; 268 return e;
248 } 269 }
249 } 270 }
250 break; 271 break;
251 case E_OR: 272 case E_OR:
252 e->left.expr = expr_eliminate_yn(e->left.expr); 273 e->left.expr = expr_eliminate_yn(e->left.expr);
253 e->right.expr = expr_eliminate_yn(e->right.expr); 274 e->right.expr = expr_eliminate_yn(e->right.expr);
254 if (e->left.expr->type == E_SYMBOL) { 275 if (e->left.expr->type == E_SYMBOL) {
255 if (e->left.expr->left.sym == &symbol_no) { 276 if (e->left.expr->left.sym == &symbol_no) {
256 free(e->left.expr); 277 free(e->left.expr);
257 tmp = e->right.expr; 278 tmp = e->right.expr;
258 *e = *(e->right.expr); 279 *e = *(e->right.expr);
259 free(tmp); 280 free(tmp);
260 return e; 281 return e;
261 } else if (e->left.expr->left.sym == &symbol_yes) { 282 } else if (e->left.expr->left.sym == &symbol_yes) {
262 expr_free(e->left.expr); 283 expr_free(e->left.expr);
263 expr_free(e->right.expr); 284 expr_free(e->right.expr);
264 e->type = E_SYMBOL; 285 e->type = E_SYMBOL;
265 e->left.sym = &symbol_yes; 286 e->left.sym = &symbol_yes;
266 e->right.expr = NULL; 287 e->right.expr = NULL;
267 return e; 288 return e;
268 } 289 }
269 } 290 }
270 if (e->right.expr->type == E_SYMBOL) { 291 if (e->right.expr->type == E_SYMBOL) {
271 if (e->right.expr->left.sym == &symbol_no) { 292 if (e->right.expr->left.sym == &symbol_no) {
272 free(e->right.expr); 293 free(e->right.expr);
273 tmp = e->left.expr; 294 tmp = e->left.expr;
274 *e = *(e->left.expr); 295 *e = *(e->left.expr);
275 free(tmp); 296 free(tmp);
276 return e; 297 return e;
277 } else if (e->right.expr->left.sym == &symbol_yes) { 298 } else if (e->right.expr->left.sym == &symbol_yes) {
278 expr_free(e->left.expr); 299 expr_free(e->left.expr);
279 expr_free(e->right.expr); 300 expr_free(e->right.expr);
280 e->type = E_SYMBOL; 301 e->type = E_SYMBOL;
281 e->left.sym = &symbol_yes; 302 e->left.sym = &symbol_yes;
282 e->right.expr = NULL; 303 e->right.expr = NULL;
283 return e; 304 return e;
284 } 305 }
285 } 306 }
286 break; 307 break;
287 default: 308 default:
288 ; 309 ;
289 } 310 }
290 return e; 311 return e;
291} 312}
292 313
293/* 314/*
294 * bool FOO!=n => FOO 315 * bool FOO!=n => FOO
295 */ 316 */
296struct expr *expr_trans_bool(struct expr *e) 317struct expr *expr_trans_bool(struct expr *e)
297{ 318{
298 if (!e) 319 if (!e)
299 return NULL; 320 return NULL;
300 switch (e->type) { 321 switch (e->type) {
301 case E_AND: 322 case E_AND:
302 case E_OR: 323 case E_OR:
303 case E_NOT: 324 case E_NOT:
304 e->left.expr = expr_trans_bool(e->left.expr); 325 e->left.expr = expr_trans_bool(e->left.expr);
305 e->right.expr = expr_trans_bool(e->right.expr); 326 e->right.expr = expr_trans_bool(e->right.expr);
306 break; 327 break;
307 case E_UNEQUAL: 328 case E_UNEQUAL:
308 // FOO!=n -> FOO 329 // FOO!=n -> FOO
309 if (e->left.sym->type == S_TRISTATE) { 330 if (e->left.sym->type == S_TRISTATE) {
310 if (e->right.sym == &symbol_no) { 331 if (e->right.sym == &symbol_no) {
311 e->type = E_SYMBOL; 332 e->type = E_SYMBOL;
312 e->right.sym = NULL; 333 e->right.sym = NULL;
313 } 334 }
314 } 335 }
315 break; 336 break;
316 default: 337 default:
317 ; 338 ;
318 } 339 }
319 return e; 340 return e;
320} 341}
321 342
322/* 343/*
323 * e1 || e2 -> ? 344 * e1 || e2 -> ?
324 */ 345 */
325struct expr *expr_join_or(struct expr *e1, struct expr *e2) 346struct expr *expr_join_or(struct expr *e1, struct expr *e2)
326{ 347{
327 struct expr *tmp; 348 struct expr *tmp;
328 struct symbol *sym1, *sym2; 349 struct symbol *sym1, *sym2;
329 350
330 if (expr_eq(e1, e2)) 351 if (expr_eq(e1, e2))
331 return expr_copy(e1); 352 return expr_copy(e1);
332 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 353 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
333 return NULL; 354 return NULL;
334 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 355 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
335 return NULL; 356 return NULL;
336 if (e1->type == E_NOT) { 357 if (e1->type == E_NOT) {
337 tmp = e1->left.expr; 358 tmp = e1->left.expr;
338 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 359 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
339 return NULL; 360 return NULL;
340 sym1 = tmp->left.sym; 361 sym1 = tmp->left.sym;
341 } else 362 } else
342 sym1 = e1->left.sym; 363 sym1 = e1->left.sym;
343 if (e2->type == E_NOT) { 364 if (e2->type == E_NOT) {
344 if (e2->left.expr->type != E_SYMBOL) 365 if (e2->left.expr->type != E_SYMBOL)
345 return NULL; 366 return NULL;
346 sym2 = e2->left.expr->left.sym; 367 sym2 = e2->left.expr->left.sym;
347 } else 368 } else
348 sym2 = e2->left.sym; 369 sym2 = e2->left.sym;
349 if (sym1 != sym2) 370 if (sym1 != sym2)
350 return NULL; 371 return NULL;
351 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 372 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
352 return NULL; 373 return NULL;
353 if (sym1->type == S_TRISTATE) { 374 if (sym1->type == S_TRISTATE) {
354 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 375 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
355 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 376 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
356 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { 377 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
357 // (a='y') || (a='m') -> (a!='n') 378 // (a='y') || (a='m') -> (a!='n')
358 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); 379 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
359 } 380 }
360 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 381 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
361 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 382 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
362 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { 383 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
363 // (a='y') || (a='n') -> (a!='m') 384 // (a='y') || (a='n') -> (a!='m')
364 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); 385 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
365 } 386 }
366 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 387 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
367 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 388 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
368 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { 389 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
369 // (a='m') || (a='n') -> (a!='y') 390 // (a='m') || (a='n') -> (a!='y')
370 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); 391 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
371 } 392 }
372 } 393 }
373 if (sym1->type == S_BOOLEAN && sym1 == sym2) { 394 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
374 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || 395 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
375 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) 396 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
376 return expr_alloc_symbol(&symbol_yes); 397 return expr_alloc_symbol(&symbol_yes);
377 } 398 }
378 399
379 printf("optimize "); 400 printf("optimize ");
380 print_expr(0, e1, 0); 401 print_expr(0, e1, 0);
381 printf(" || "); 402 printf(" || ");
382 print_expr(0, e2, 0); 403 print_expr(0, e2, 0);
383 printf(" ?\n"); 404 printf(" ?\n");
384 return NULL; 405 return NULL;
385} 406}
386 407
387struct expr *expr_join_and(struct expr *e1, struct expr *e2) 408struct expr *expr_join_and(struct expr *e1, struct expr *e2)
388{ 409{
389 struct expr *tmp; 410 struct expr *tmp;
390 struct symbol *sym1, *sym2; 411 struct symbol *sym1, *sym2;
391 412
392 if (expr_eq(e1, e2)) 413 if (expr_eq(e1, e2))
393 return expr_copy(e1); 414 return expr_copy(e1);
394 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 415 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
395 return NULL; 416 return NULL;
396 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 417 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
397 return NULL; 418 return NULL;
398 if (e1->type == E_NOT) { 419 if (e1->type == E_NOT) {
399 tmp = e1->left.expr; 420 tmp = e1->left.expr;
400 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 421 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
401 return NULL; 422 return NULL;
402 sym1 = tmp->left.sym; 423 sym1 = tmp->left.sym;
403 } else 424 } else
404 sym1 = e1->left.sym; 425 sym1 = e1->left.sym;
405 if (e2->type == E_NOT) { 426 if (e2->type == E_NOT) {
406 if (e2->left.expr->type != E_SYMBOL) 427 if (e2->left.expr->type != E_SYMBOL)
407 return NULL; 428 return NULL;
408 sym2 = e2->left.expr->left.sym; 429 sym2 = e2->left.expr->left.sym;
409 } else 430 } else
410 sym2 = e2->left.sym; 431 sym2 = e2->left.sym;
411 if (sym1 != sym2) 432 if (sym1 != sym2)
412 return NULL; 433 return NULL;
413 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 434 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
414 return NULL; 435 return NULL;
415 436
416 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || 437 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
417 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) 438 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
418 // (a) && (a='y') -> (a='y') 439 // (a) && (a='y') -> (a='y')
419 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 440 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
420 441
421 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || 442 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
422 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) 443 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
423 // (a) && (a!='n') -> (a) 444 // (a) && (a!='n') -> (a)
424 return expr_alloc_symbol(sym1); 445 return expr_alloc_symbol(sym1);
425 446
426 if (sym1->type == S_TRISTATE) { 447 if (sym1->type == S_TRISTATE) {
427 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { 448 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
428 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 449 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
429 sym2 = e1->right.sym; 450 sym2 = e1->right.sym;
430 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 451 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
431 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 452 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
432 : expr_alloc_symbol(&symbol_no); 453 : expr_alloc_symbol(&symbol_no);
433 } 454 }
434 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { 455 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
435 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 456 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
436 sym2 = e2->right.sym; 457 sym2 = e2->right.sym;
437 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 458 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
438 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 459 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
439 : expr_alloc_symbol(&symbol_no); 460 : expr_alloc_symbol(&symbol_no);
440 } 461 }
441 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 462 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
442 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 463 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
443 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) 464 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
444 // (a!='y') && (a!='n') -> (a='m') 465 // (a!='y') && (a!='n') -> (a='m')
445 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); 466 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
446 467
447 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 468 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
448 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 469 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
449 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) 470 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
450 // (a!='y') && (a!='m') -> (a='n') 471 // (a!='y') && (a!='m') -> (a='n')
451 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); 472 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
452 473
453 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 474 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
454 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 475 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
455 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) 476 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
456 // (a!='m') && (a!='n') -> (a='m') 477 // (a!='m') && (a!='n') -> (a='m')
457 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 478 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
458 479
459 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || 480 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
460 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || 481 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
461 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || 482 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
462 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) 483 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
463 return NULL; 484 return NULL;
464 } 485 }
465 printf("optimize "); 486 printf("optimize ");
466 print_expr(0, e1, 0); 487 print_expr(0, e1, 0);
467 printf(" && "); 488 printf(" && ");
468 print_expr(0, e2, 0); 489 print_expr(0, e2, 0);
469 printf(" ?\n"); 490 printf(" ?\n");
470 return NULL; 491 return NULL;
471} 492}
472 493
473static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) 494static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
474{ 495{
475#define e1 (*ep1) 496#define e1 (*ep1)
476#define e2 (*ep2) 497#define e2 (*ep2)
477 struct expr *tmp; 498 struct expr *tmp;
478 499
479 if (e1->type == type) { 500 if (e1->type == type) {
480 expr_eliminate_dups1(type, &e1->left.expr, &e2); 501 expr_eliminate_dups1(type, &e1->left.expr, &e2);
481 expr_eliminate_dups1(type, &e1->right.expr, &e2); 502 expr_eliminate_dups1(type, &e1->right.expr, &e2);
482 return; 503 return;
483 } 504 }
484 if (e2->type == type) { 505 if (e2->type == type) {
485 expr_eliminate_dups1(type, &e1, &e2->left.expr); 506 expr_eliminate_dups1(type, &e1, &e2->left.expr);
486 expr_eliminate_dups1(type, &e1, &e2->right.expr); 507 expr_eliminate_dups1(type, &e1, &e2->right.expr);
487 return; 508 return;
488 } 509 }
489 if (e1 == e2) 510 if (e1 == e2)
490 return; 511 return;
491 512
492 switch (e1->type) { 513 switch (e1->type) {
493 case E_OR: case E_AND: 514 case E_OR: case E_AND:
494 expr_eliminate_dups1(e1->type, &e1, &e1); 515 expr_eliminate_dups1(e1->type, &e1, &e1);
495 default: 516 default:
496 ; 517 ;
497 } 518 }
498 519
499 switch (type) { 520 switch (type) {
500 case E_OR: 521 case E_OR:
501 tmp = expr_join_or(e1, e2); 522 tmp = expr_join_or(e1, e2);
502 if (tmp) { 523 if (tmp) {
503 expr_free(e1); expr_free(e2); 524 expr_free(e1); expr_free(e2);
504 e1 = expr_alloc_symbol(&symbol_no); 525 e1 = expr_alloc_symbol(&symbol_no);
505 e2 = tmp; 526 e2 = tmp;
506 trans_count++; 527 trans_count++;
507 } 528 }
508 break; 529 break;
509 case E_AND: 530 case E_AND:
510 tmp = expr_join_and(e1, e2); 531 tmp = expr_join_and(e1, e2);
511 if (tmp) { 532 if (tmp) {
512 expr_free(e1); expr_free(e2); 533 expr_free(e1); expr_free(e2);
513 e1 = expr_alloc_symbol(&symbol_yes); 534 e1 = expr_alloc_symbol(&symbol_yes);
514 e2 = tmp; 535 e2 = tmp;
515 trans_count++; 536 trans_count++;
516 } 537 }
517 break; 538 break;
518 default: 539 default:
519 ; 540 ;
520 } 541 }
521#undef e1 542#undef e1
522#undef e2 543#undef e2
523} 544}
524 545
525static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) 546static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
526{ 547{
527#define e1 (*ep1) 548#define e1 (*ep1)
528#define e2 (*ep2) 549#define e2 (*ep2)
529 struct expr *tmp, *tmp1, *tmp2; 550 struct expr *tmp, *tmp1, *tmp2;
530 551
531 if (e1->type == type) { 552 if (e1->type == type) {
532 expr_eliminate_dups2(type, &e1->left.expr, &e2); 553 expr_eliminate_dups2(type, &e1->left.expr, &e2);
533 expr_eliminate_dups2(type, &e1->right.expr, &e2); 554 expr_eliminate_dups2(type, &e1->right.expr, &e2);
534 return; 555 return;
535 } 556 }
536 if (e2->type == type) { 557 if (e2->type == type) {
537 expr_eliminate_dups2(type, &e1, &e2->left.expr); 558 expr_eliminate_dups2(type, &e1, &e2->left.expr);
538 expr_eliminate_dups2(type, &e1, &e2->right.expr); 559 expr_eliminate_dups2(type, &e1, &e2->right.expr);
539 } 560 }
540 if (e1 == e2) 561 if (e1 == e2)
541 return; 562 return;
542 563
543 switch (e1->type) { 564 switch (e1->type) {
544 case E_OR: 565 case E_OR:
545 expr_eliminate_dups2(e1->type, &e1, &e1); 566 expr_eliminate_dups2(e1->type, &e1, &e1);
546 // (FOO || BAR) && (!FOO && !BAR) -> n 567 // (FOO || BAR) && (!FOO && !BAR) -> n
547 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); 568 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
548 tmp2 = expr_copy(e2); 569 tmp2 = expr_copy(e2);
549 tmp = expr_extract_eq_and(&tmp1, &tmp2); 570 tmp = expr_extract_eq_and(&tmp1, &tmp2);
550 if (expr_is_yes(tmp1)) { 571 if (expr_is_yes(tmp1)) {
551 expr_free(e1); 572 expr_free(e1);
552 e1 = expr_alloc_symbol(&symbol_no); 573 e1 = expr_alloc_symbol(&symbol_no);
553 trans_count++; 574 trans_count++;
554 } 575 }
555 expr_free(tmp2); 576 expr_free(tmp2);
556 expr_free(tmp1); 577 expr_free(tmp1);
557 expr_free(tmp); 578 expr_free(tmp);
558 break; 579 break;
559 case E_AND: 580 case E_AND:
560 expr_eliminate_dups2(e1->type, &e1, &e1); 581 expr_eliminate_dups2(e1->type, &e1, &e1);
561 // (FOO && BAR) || (!FOO || !BAR) -> y 582 // (FOO && BAR) || (!FOO || !BAR) -> y
562 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); 583 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
563 tmp2 = expr_copy(e2); 584 tmp2 = expr_copy(e2);
564 tmp = expr_extract_eq_or(&tmp1, &tmp2); 585 tmp = expr_extract_eq_or(&tmp1, &tmp2);
565 if (expr_is_no(tmp1)) { 586 if (expr_is_no(tmp1)) {
566 expr_free(e1); 587 expr_free(e1);
567 e1 = expr_alloc_symbol(&symbol_yes); 588 e1 = expr_alloc_symbol(&symbol_yes);
568 trans_count++; 589 trans_count++;
569 } 590 }
570 expr_free(tmp2); 591 expr_free(tmp2);
571 expr_free(tmp1); 592 expr_free(tmp1);
572 expr_free(tmp); 593 expr_free(tmp);
573 break; 594 break;
574 default: 595 default:
575 ; 596 ;
576 } 597 }
577#undef e1 598#undef e1
578#undef e2 599#undef e2
579} 600}
580 601
581struct expr *expr_eliminate_dups(struct expr *e) 602struct expr *expr_eliminate_dups(struct expr *e)
582{ 603{
583 int oldcount; 604 int oldcount;
584 if (!e) 605 if (!e)
585 return e; 606 return e;
586 607
587 oldcount = trans_count; 608 oldcount = trans_count;
588 while (1) { 609 while (1) {
589 trans_count = 0; 610 trans_count = 0;
590 switch (e->type) { 611 switch (e->type) {
591 case E_OR: case E_AND: 612 case E_OR: case E_AND:
592 expr_eliminate_dups1(e->type, &e, &e); 613 expr_eliminate_dups1(e->type, &e, &e);
593 expr_eliminate_dups2(e->type, &e, &e); 614 expr_eliminate_dups2(e->type, &e, &e);
594 default: 615 default:
595 ; 616 ;
596 } 617 }
597 if (!trans_count) 618 if (!trans_count)
598 break; 619 break;
599 e = expr_eliminate_yn(e); 620 e = expr_eliminate_yn(e);
600 } 621 }
601 trans_count = oldcount; 622 trans_count = oldcount;
602 return e; 623 return e;
603} 624}
604 625
605struct expr *expr_transform(struct expr *e) 626struct expr *expr_transform(struct expr *e)
606{ 627{
607 struct expr *tmp; 628 struct expr *tmp;
608 629
609 if (!e) 630 if (!e)
610 return NULL; 631 return NULL;
611 switch (e->type) { 632 switch (e->type) {
612 case E_EQUAL: 633 case E_EQUAL:
613 case E_UNEQUAL: 634 case E_UNEQUAL:
614 case E_SYMBOL: 635 case E_SYMBOL:
615 case E_CHOICE: 636 case E_CHOICE:
616 break; 637 break;
617 default: 638 default:
618 e->left.expr = expr_transform(e->left.expr); 639 e->left.expr = expr_transform(e->left.expr);
619 e->right.expr = expr_transform(e->right.expr); 640 e->right.expr = expr_transform(e->right.expr);
620 } 641 }
621 642
622 switch (e->type) { 643 switch (e->type) {
623 case E_EQUAL: 644 case E_EQUAL:
624 if (e->left.sym->type != S_BOOLEAN) 645 if (e->left.sym->type != S_BOOLEAN)
625 break; 646 break;
626 if (e->right.sym == &symbol_no) { 647 if (e->right.sym == &symbol_no) {
627 e->type = E_NOT; 648 e->type = E_NOT;
628 e->left.expr = expr_alloc_symbol(e->left.sym); 649 e->left.expr = expr_alloc_symbol(e->left.sym);
629 e->right.sym = NULL; 650 e->right.sym = NULL;
630 break; 651 break;
631 } 652 }
632 if (e->right.sym == &symbol_mod) { 653 if (e->right.sym == &symbol_mod) {
633 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); 654 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
634 e->type = E_SYMBOL; 655 e->type = E_SYMBOL;
635 e->left.sym = &symbol_no; 656 e->left.sym = &symbol_no;
636 e->right.sym = NULL; 657 e->right.sym = NULL;
637 break; 658 break;
638 } 659 }
639 if (e->right.sym == &symbol_yes) { 660 if (e->right.sym == &symbol_yes) {
640 e->type = E_SYMBOL; 661 e->type = E_SYMBOL;
641 e->right.sym = NULL; 662 e->right.sym = NULL;
642 break; 663 break;
643 } 664 }
644 break; 665 break;
645 case E_UNEQUAL: 666 case E_UNEQUAL:
646 if (e->left.sym->type != S_BOOLEAN) 667 if (e->left.sym->type != S_BOOLEAN)
647 break; 668 break;
648 if (e->right.sym == &symbol_no) { 669 if (e->right.sym == &symbol_no) {
649 e->type = E_SYMBOL; 670 e->type = E_SYMBOL;
650 e->right.sym = NULL; 671 e->right.sym = NULL;
651 break; 672 break;
652 } 673 }
653 if (e->right.sym == &symbol_mod) { 674 if (e->right.sym == &symbol_mod) {
654 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); 675 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
655 e->type = E_SYMBOL; 676 e->type = E_SYMBOL;
656 e->left.sym = &symbol_yes; 677 e->left.sym = &symbol_yes;
657 e->right.sym = NULL; 678 e->right.sym = NULL;
658 break; 679 break;
659 } 680 }
660 if (e->right.sym == &symbol_yes) { 681 if (e->right.sym == &symbol_yes) {
661 e->type = E_NOT; 682 e->type = E_NOT;
662 e->left.expr = expr_alloc_symbol(e->left.sym); 683 e->left.expr = expr_alloc_symbol(e->left.sym);
663 e->right.sym = NULL; 684 e->right.sym = NULL;
664 break; 685 break;
665 } 686 }
666 break; 687 break;
667 case E_NOT: 688 case E_NOT:
668 switch (e->left.expr->type) { 689 switch (e->left.expr->type) {
669 case E_NOT: 690 case E_NOT:
670 // !!a -> a 691 // !!a -> a
671 tmp = e->left.expr->left.expr; 692 tmp = e->left.expr->left.expr;
672 free(e->left.expr); 693 free(e->left.expr);
673 free(e); 694 free(e);
674 e = tmp; 695 e = tmp;
675 e = expr_transform(e); 696 e = expr_transform(e);
676 break; 697 break;
677 case E_EQUAL: 698 case E_EQUAL:
678 case E_UNEQUAL: 699 case E_UNEQUAL:
679 // !a='x' -> a!='x' 700 // !a='x' -> a!='x'
680 tmp = e->left.expr; 701 tmp = e->left.expr;
681 free(e); 702 free(e);
682 e = tmp; 703 e = tmp;
683 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; 704 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
684 break; 705 break;
685 case E_OR: 706 case E_OR:
686 // !(a || b) -> !a && !b 707 // !(a || b) -> !a && !b
687 tmp = e->left.expr; 708 tmp = e->left.expr;
688 e->type = E_AND; 709 e->type = E_AND;
689 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 710 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
690 tmp->type = E_NOT; 711 tmp->type = E_NOT;
691 tmp->right.expr = NULL; 712 tmp->right.expr = NULL;
692 e = expr_transform(e); 713 e = expr_transform(e);
693 break; 714 break;
694 case E_AND: 715 case E_AND:
695 // !(a && b) -> !a || !b 716 // !(a && b) -> !a || !b
696 tmp = e->left.expr; 717 tmp = e->left.expr;
697 e->type = E_OR; 718 e->type = E_OR;
698 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 719 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
699 tmp->type = E_NOT; 720 tmp->type = E_NOT;
700 tmp->right.expr = NULL; 721 tmp->right.expr = NULL;
701 e = expr_transform(e); 722 e = expr_transform(e);
702 break; 723 break;
703 case E_SYMBOL: 724 case E_SYMBOL:
704 if (e->left.expr->left.sym == &symbol_yes) { 725 if (e->left.expr->left.sym == &symbol_yes) {
705 // !'y' -> 'n' 726 // !'y' -> 'n'
706 tmp = e->left.expr; 727 tmp = e->left.expr;
707 free(e); 728 free(e);
708 e = tmp; 729 e = tmp;
709 e->type = E_SYMBOL; 730 e->type = E_SYMBOL;
710 e->left.sym = &symbol_no; 731 e->left.sym = &symbol_no;
711 break; 732 break;
712 } 733 }
713 if (e->left.expr->left.sym == &symbol_mod) { 734 if (e->left.expr->left.sym == &symbol_mod) {
714 // !'m' -> 'm' 735 // !'m' -> 'm'
715 tmp = e->left.expr; 736 tmp = e->left.expr;
716 free(e); 737 free(e);
717 e = tmp; 738 e = tmp;
718 e->type = E_SYMBOL; 739 e->type = E_SYMBOL;
719 e->left.sym = &symbol_mod; 740 e->left.sym = &symbol_mod;
720 break; 741 break;
721 } 742 }
722 if (e->left.expr->left.sym == &symbol_no) { 743 if (e->left.expr->left.sym == &symbol_no) {
723 // !'n' -> 'y' 744 // !'n' -> 'y'
724 tmp = e->left.expr; 745 tmp = e->left.expr;
725 free(e); 746 free(e);
726 e = tmp; 747 e = tmp;
727 e->type = E_SYMBOL; 748 e->type = E_SYMBOL;
728 e->left.sym = &symbol_yes; 749 e->left.sym = &symbol_yes;
729 break; 750 break;
730 } 751 }
731 break; 752 break;
732 default: 753 default:
733 ; 754 ;
734 } 755 }
735 break; 756 break;
736 default: 757 default:
737 ; 758 ;
738 } 759 }
739 return e; 760 return e;
740} 761}
741 762
742int expr_contains_symbol(struct expr *dep, struct symbol *sym) 763int expr_contains_symbol(struct expr *dep, struct symbol *sym)
743{ 764{
744 if (!dep) 765 if (!dep)
745 return 0; 766 return 0;
746 767
747 switch (dep->type) { 768 switch (dep->type) {
748 case E_AND: 769 case E_AND:
749 case E_OR: 770 case E_OR:
750 return expr_contains_symbol(dep->left.expr, sym) || 771 return expr_contains_symbol(dep->left.expr, sym) ||
751 expr_contains_symbol(dep->right.expr, sym); 772 expr_contains_symbol(dep->right.expr, sym);
752 case E_SYMBOL: 773 case E_SYMBOL:
753 return dep->left.sym == sym; 774 return dep->left.sym == sym;
754 case E_EQUAL: 775 case E_EQUAL:
755 case E_UNEQUAL: 776 case E_UNEQUAL:
756 return dep->left.sym == sym || 777 return dep->left.sym == sym ||
757 dep->right.sym == sym; 778 dep->right.sym == sym;
758 case E_NOT: 779 case E_NOT:
759 return expr_contains_symbol(dep->left.expr, sym); 780 return expr_contains_symbol(dep->left.expr, sym);
760 default: 781 default:
761 ; 782 ;
762 } 783 }
763 return 0; 784 return 0;
764} 785}
765 786
766bool expr_depends_symbol(struct expr *dep, struct symbol *sym) 787bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
767{ 788{
768 if (!dep) 789 if (!dep)
769 return false; 790 return false;
770 791
771 switch (dep->type) { 792 switch (dep->type) {
772 case E_AND: 793 case E_AND:
773 return expr_depends_symbol(dep->left.expr, sym) || 794 return expr_depends_symbol(dep->left.expr, sym) ||
774 expr_depends_symbol(dep->right.expr, sym); 795 expr_depends_symbol(dep->right.expr, sym);
775 case E_SYMBOL: 796 case E_SYMBOL:
776 return dep->left.sym == sym; 797 return dep->left.sym == sym;
777 case E_EQUAL: 798 case E_EQUAL:
778 if (dep->left.sym == sym) { 799 if (dep->left.sym == sym) {
779 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) 800 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
780 return true; 801 return true;
781 } 802 }
782 break; 803 break;
783 case E_UNEQUAL: 804 case E_UNEQUAL:
784 if (dep->left.sym == sym) { 805 if (dep->left.sym == sym) {
785 if (dep->right.sym == &symbol_no) 806 if (dep->right.sym == &symbol_no)
786 return true; 807 return true;
787 } 808 }
788 break; 809 break;
789 default: 810 default:
790 ; 811 ;
791 } 812 }
792 return false; 813 return false;
793} 814}
794 815
795struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) 816struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
796{ 817{
797 struct expr *tmp = NULL; 818 struct expr *tmp = NULL;
798 expr_extract_eq(E_AND, &tmp, ep1, ep2); 819 expr_extract_eq(E_AND, &tmp, ep1, ep2);
799 if (tmp) { 820 if (tmp) {
800 *ep1 = expr_eliminate_yn(*ep1); 821 *ep1 = expr_eliminate_yn(*ep1);
801 *ep2 = expr_eliminate_yn(*ep2); 822 *ep2 = expr_eliminate_yn(*ep2);
802 } 823 }
803 return tmp; 824 return tmp;
804} 825}
805 826
806struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) 827struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
807{ 828{
808 struct expr *tmp = NULL; 829 struct expr *tmp = NULL;
809 expr_extract_eq(E_OR, &tmp, ep1, ep2); 830 expr_extract_eq(E_OR, &tmp, ep1, ep2);
810 if (tmp) { 831 if (tmp) {
811 *ep1 = expr_eliminate_yn(*ep1); 832 *ep1 = expr_eliminate_yn(*ep1);
812 *ep2 = expr_eliminate_yn(*ep2); 833 *ep2 = expr_eliminate_yn(*ep2);
813 } 834 }
814 return tmp; 835 return tmp;
815} 836}
816 837
817void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) 838void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
818{ 839{
819#define e1 (*ep1) 840#define e1 (*ep1)
820#define e2 (*ep2) 841#define e2 (*ep2)
821 if (e1->type == type) { 842 if (e1->type == type) {
822 expr_extract_eq(type, ep, &e1->left.expr, &e2); 843 expr_extract_eq(type, ep, &e1->left.expr, &e2);
823 expr_extract_eq(type, ep, &e1->right.expr, &e2); 844 expr_extract_eq(type, ep, &e1->right.expr, &e2);
824 return; 845 return;
825 } 846 }
826 if (e2->type == type) { 847 if (e2->type == type) {
827 expr_extract_eq(type, ep, ep1, &e2->left.expr); 848 expr_extract_eq(type, ep, ep1, &e2->left.expr);
828 expr_extract_eq(type, ep, ep1, &e2->right.expr); 849 expr_extract_eq(type, ep, ep1, &e2->right.expr);
829 return; 850 return;
830 } 851 }
831 if (expr_eq(e1, e2)) { 852 if (expr_eq(e1, e2)) {
832 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; 853 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
833 expr_free(e2); 854 expr_free(e2);
834 if (type == E_AND) { 855 if (type == E_AND) {
835 e1 = expr_alloc_symbol(&symbol_yes); 856 e1 = expr_alloc_symbol(&symbol_yes);
836 e2 = expr_alloc_symbol(&symbol_yes); 857 e2 = expr_alloc_symbol(&symbol_yes);
837 } else if (type == E_OR) { 858 } else if (type == E_OR) {
838 e1 = expr_alloc_symbol(&symbol_no); 859 e1 = expr_alloc_symbol(&symbol_no);
839 e2 = expr_alloc_symbol(&symbol_no); 860 e2 = expr_alloc_symbol(&symbol_no);
840 } 861 }
841 } 862 }
842#undef e1 863#undef e1
843#undef e2 864#undef e2
844} 865}
845 866
846struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) 867struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
847{ 868{
848 struct expr *e1, *e2; 869 struct expr *e1, *e2;
849 870
850 if (!e) { 871 if (!e) {
851 e = expr_alloc_symbol(sym); 872 e = expr_alloc_symbol(sym);
852 if (type == E_UNEQUAL) 873 if (type == E_UNEQUAL)
853 e = expr_alloc_one(E_NOT, e); 874 e = expr_alloc_one(E_NOT, e);
854 return e; 875 return e;
855 } 876 }
856 switch (e->type) { 877 switch (e->type) {
857 case E_AND: 878 case E_AND:
858 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 879 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
859 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 880 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
860 if (sym == &symbol_yes) 881 if (sym == &symbol_yes)
861 e = expr_alloc_two(E_AND, e1, e2); 882 e = expr_alloc_two(E_AND, e1, e2);
862 if (sym == &symbol_no) 883 if (sym == &symbol_no)
863 e = expr_alloc_two(E_OR, e1, e2); 884 e = expr_alloc_two(E_OR, e1, e2);
864 if (type == E_UNEQUAL) 885 if (type == E_UNEQUAL)
865 e = expr_alloc_one(E_NOT, e); 886 e = expr_alloc_one(E_NOT, e);
866 return e; 887 return e;
867 case E_OR: 888 case E_OR:
868 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 889 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
869 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 890 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
870 if (sym == &symbol_yes) 891 if (sym == &symbol_yes)
871 e = expr_alloc_two(E_OR, e1, e2); 892 e = expr_alloc_two(E_OR, e1, e2);
872 if (sym == &symbol_no) 893 if (sym == &symbol_no)
873 e = expr_alloc_two(E_AND, e1, e2); 894 e = expr_alloc_two(E_AND, e1, e2);
874 if (type == E_UNEQUAL) 895 if (type == E_UNEQUAL)
875 e = expr_alloc_one(E_NOT, e); 896 e = expr_alloc_one(E_NOT, e);
876 return e; 897 return e;
877 case E_NOT: 898 case E_NOT:
878 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); 899 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
879 case E_UNEQUAL: 900 case E_UNEQUAL:
880 case E_EQUAL: 901 case E_EQUAL:
881 if (type == E_EQUAL) { 902 if (type == E_EQUAL) {
882 if (sym == &symbol_yes) 903 if (sym == &symbol_yes)
883 return expr_copy(e); 904 return expr_copy(e);
884 if (sym == &symbol_mod) 905 if (sym == &symbol_mod)
885 return expr_alloc_symbol(&symbol_no); 906 return expr_alloc_symbol(&symbol_no);
886 if (sym == &symbol_no) 907 if (sym == &symbol_no)
887 return expr_alloc_one(E_NOT, expr_copy(e)); 908 return expr_alloc_one(E_NOT, expr_copy(e));
888 } else { 909 } else {
889 if (sym == &symbol_yes) 910 if (sym == &symbol_yes)
890 return expr_alloc_one(E_NOT, expr_copy(e)); 911 return expr_alloc_one(E_NOT, expr_copy(e));
891 if (sym == &symbol_mod) 912 if (sym == &symbol_mod)
892 return expr_alloc_symbol(&symbol_yes); 913 return expr_alloc_symbol(&symbol_yes);
893 if (sym == &symbol_no) 914 if (sym == &symbol_no)
894 return expr_copy(e); 915 return expr_copy(e);
895 } 916 }
896 break; 917 break;
897 case E_SYMBOL: 918 case E_SYMBOL:
898 return expr_alloc_comp(type, e->left.sym, sym); 919 return expr_alloc_comp(type, e->left.sym, sym);
899 case E_CHOICE: 920 case E_CHOICE:
921 case E_RANGE:
900 case E_NONE: 922 case E_NONE:
901 /* panic */; 923 /* panic */;
902 } 924 }
903 return NULL; 925 return NULL;
904} 926}
905 927
906tristate expr_calc_value(struct expr *e) 928tristate expr_calc_value(struct expr *e)
907{ 929{
908 tristate val1, val2; 930 tristate val1, val2;
909 const char *str1, *str2; 931 const char *str1, *str2;
910 932
911 if (!e) 933 if (!e)
912 return yes; 934 return yes;
913 935
914 switch (e->type) { 936 switch (e->type) {
915 case E_SYMBOL: 937 case E_SYMBOL:
916 sym_calc_value(e->left.sym); 938 sym_calc_value(e->left.sym);
917 return S_TRI(e->left.sym->curr); 939 return e->left.sym->curr.tri;
918 case E_AND: 940 case E_AND:
919 val1 = expr_calc_value(e->left.expr); 941 val1 = expr_calc_value(e->left.expr);
920 val2 = expr_calc_value(e->right.expr); 942 val2 = expr_calc_value(e->right.expr);
921 return E_AND(val1, val2); 943 return E_AND(val1, val2);
922 case E_OR: 944 case E_OR:
923 val1 = expr_calc_value(e->left.expr); 945 val1 = expr_calc_value(e->left.expr);
924 val2 = expr_calc_value(e->right.expr); 946 val2 = expr_calc_value(e->right.expr);
925 return E_OR(val1, val2); 947 return E_OR(val1, val2);
926 case E_NOT: 948 case E_NOT:
927 val1 = expr_calc_value(e->left.expr); 949 val1 = expr_calc_value(e->left.expr);
928 return E_NOT(val1); 950 return E_NOT(val1);
929 case E_EQUAL: 951 case E_EQUAL:
930 sym_calc_value(e->left.sym); 952 sym_calc_value(e->left.sym);
931 sym_calc_value(e->right.sym); 953 sym_calc_value(e->right.sym);
932 str1 = sym_get_string_value(e->left.sym); 954 str1 = sym_get_string_value(e->left.sym);
933 str2 = sym_get_string_value(e->right.sym); 955 str2 = sym_get_string_value(e->right.sym);
934 return !strcmp(str1, str2) ? yes : no; 956 return !strcmp(str1, str2) ? yes : no;
935 case E_UNEQUAL: 957 case E_UNEQUAL:
936 sym_calc_value(e->left.sym); 958 sym_calc_value(e->left.sym);
937 sym_calc_value(e->right.sym); 959 sym_calc_value(e->right.sym);
938 str1 = sym_get_string_value(e->left.sym); 960 str1 = sym_get_string_value(e->left.sym);
939 str2 = sym_get_string_value(e->right.sym); 961 str2 = sym_get_string_value(e->right.sym);
940 return !strcmp(str1, str2) ? no : yes; 962 return !strcmp(str1, str2) ? no : yes;
941 default: 963 default:
942 printf("expr_calc_value: %d?\n", e->type); 964 printf("expr_calc_value: %d?\n", e->type);
943 return no; 965 return no;
944 } 966 }
945} 967}
946 968
947int expr_compare_type(enum expr_type t1, enum expr_type t2) 969int expr_compare_type(enum expr_type t1, enum expr_type t2)
948{ 970{
949#if 0 971#if 0
950 return 1; 972 return 1;
951#else 973#else
952 if (t1 == t2) 974 if (t1 == t2)
953 return 0; 975 return 0;
954 switch (t1) { 976 switch (t1) {
955 case E_EQUAL: 977 case E_EQUAL:
956 case E_UNEQUAL: 978 case E_UNEQUAL:
957 if (t2 == E_NOT) 979 if (t2 == E_NOT)
958 return 1; 980 return 1;
959 case E_NOT: 981 case E_NOT:
960 if (t2 == E_AND) 982 if (t2 == E_AND)
961 return 1; 983 return 1;
962 case E_AND: 984 case E_AND:
963 if (t2 == E_OR) 985 if (t2 == E_OR)
964 return 1; 986 return 1;
965 case E_OR: 987 case E_OR:
966 if (t2 == E_CHOICE) 988 if (t2 == E_CHOICE)
967 return 1; 989 return 1;
968 case E_CHOICE: 990 case E_CHOICE:
969 if (t2 == 0) 991 if (t2 == 0)
970 return 1; 992 return 1;
971 default: 993 default:
972 return -1; 994 return -1;
973 } 995 }
974 printf("[%dgt%d?]", t1, t2); 996 printf("[%dgt%d?]", t1, t2);
975 return 0; 997 return 0;
976#endif 998#endif
977} 999}
978 1000
979void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken) 1001void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)
980{ 1002{
981 if (!e) { 1003 if (!e) {
982 fn(data, "y"); 1004 fn(data, "y");
983 return; 1005 return;
984 } 1006 }
985 1007
986 if (expr_compare_type(prevtoken, e->type) > 0) 1008 if (expr_compare_type(prevtoken, e->type) > 0)
987 fn(data, "("); 1009 fn(data, "(");
988 switch (e->type) { 1010 switch (e->type) {
989 case E_SYMBOL: 1011 case E_SYMBOL:
990 if (e->left.sym->name) 1012 if (e->left.sym->name)
991 fn(data, e->left.sym->name); 1013 fn(data, e->left.sym->name);
992 else 1014 else
993 fn(data, "<choice>"); 1015 fn(data, "<choice>");
994 break; 1016 break;
995 case E_NOT: 1017 case E_NOT:
996 fn(data, "!"); 1018 fn(data, "!");
997 expr_print(e->left.expr, fn, data, E_NOT); 1019 expr_print(e->left.expr, fn, data, E_NOT);
998 break; 1020 break;
999 case E_EQUAL: 1021 case E_EQUAL:
1000 fn(data, e->left.sym->name); 1022 fn(data, e->left.sym->name);
1001 fn(data, "="); 1023 fn(data, "=");
1002 fn(data, e->right.sym->name); 1024 fn(data, e->right.sym->name);
1003 break; 1025 break;
1004 case E_UNEQUAL: 1026 case E_UNEQUAL:
1005 fn(data, e->left.sym->name); 1027 fn(data, e->left.sym->name);
1006 fn(data, "!="); 1028 fn(data, "!=");
1007 fn(data, e->right.sym->name); 1029 fn(data, e->right.sym->name);
1008 break; 1030 break;
1009 case E_OR: 1031 case E_OR:
1010 expr_print(e->left.expr, fn, data, E_OR); 1032 expr_print(e->left.expr, fn, data, E_OR);
1011 fn(data, " || "); 1033 fn(data, " || ");
1012 expr_print(e->right.expr, fn, data, E_OR); 1034 expr_print(e->right.expr, fn, data, E_OR);
1013 break; 1035 break;
1014 case E_AND: 1036 case E_AND:
1015 expr_print(e->left.expr, fn, data, E_AND); 1037 expr_print(e->left.expr, fn, data, E_AND);
1016 fn(data, " && "); 1038 fn(data, " && ");
1017 expr_print(e->right.expr, fn, data, E_AND); 1039 expr_print(e->right.expr, fn, data, E_AND);
1018 break; 1040 break;
1019 case E_CHOICE: 1041 case E_CHOICE:
1042 fn(data, e->right.sym->name);
1020 if (e->left.expr) { 1043 if (e->left.expr) {
1021 expr_print(e->left.expr, fn, data, E_CHOICE);
1022 fn(data, " ^ "); 1044 fn(data, " ^ ");
1045 expr_print(e->left.expr, fn, data, E_CHOICE);
1023 } 1046 }
1047 break;
1048 case E_RANGE:
1049 fn(data, "[");
1050 fn(data, e->left.sym->name);
1051 fn(data, " ");
1024 fn(data, e->right.sym->name); 1052 fn(data, e->right.sym->name);
1053 fn(data, "]");
1025 break; 1054 break;
1026 default: 1055 default:
1027 { 1056 {
1028 char buf[32]; 1057 char buf[32];
1029 sprintf(buf, "<unknown type %d>", e->type); 1058 sprintf(buf, "<unknown type %d>", e->type);
1030 fn(data, buf); 1059 fn(data, buf);
1031 break; 1060 break;
1032 } 1061 }
1033 } 1062 }
1034 if (expr_compare_type(prevtoken, e->type) > 0) 1063 if (expr_compare_type(prevtoken, e->type) > 0)
1035 fn(data, ")"); 1064 fn(data, ")");
1036} 1065}
1037 1066
1038static void expr_print_file_helper(void *data, const char *str) 1067static void expr_print_file_helper(void *data, const char *str)
1039{ 1068{
1040 fwrite(str, strlen(str), 1, data); 1069 fwrite(str, strlen(str), 1, data);
1041} 1070}
1042 1071
1043void expr_fprint(struct expr *e, FILE *out) 1072void expr_fprint(struct expr *e, FILE *out)
1044{ 1073{
1045 expr_print(e, expr_print_file_helper, out, E_NONE); 1074 expr_print(e, expr_print_file_helper, out, E_NONE);
1046} 1075}
1047 1076
1048void print_expr(int mask, struct expr *e, int prevtoken) 1077void print_expr(int mask, struct expr *e, int prevtoken)
1049{ 1078{
1050 if (!(cdebug & mask)) 1079 if (!(cdebug & mask))
1051 return; 1080 return;
1052 expr_fprint(e, stdout); 1081 expr_fprint(e, stdout);
1053} 1082}
1054 1083
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 896a296..cc616f1 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -1,245 +1,194 @@
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 EXPR_H 6#ifndef EXPR_H
7#define EXPR_H 7#define EXPR_H
8 8
9#ifdef __cplusplus 9#ifdef __cplusplus
10extern "C" { 10extern "C" {
11#endif 11#endif
12 12
13#include <stdio.h> 13#include <stdio.h>
14#ifndef __cplusplus 14#ifndef __cplusplus
15#include <stdbool.h> 15#include <stdbool.h>
16#endif 16#endif
17 17
18struct file { 18struct file {
19 struct file *next; 19 struct file *next;
20 struct file *parent; 20 struct file *parent;
21#ifdef CML1
22 struct statement *stmt;
23 struct statement *last_stmt;
24#endif
25 char *name; 21 char *name;
26 int lineno; 22 int lineno;
27 int flags; 23 int flags;
28}; 24};
29 25
30 #define FILE_BUSY 0x0001 26 #define FILE_BUSY 0x0001
31 #define FILE_SCANNED 0x0002 27 #define FILE_SCANNED 0x0002
32 #define FILE_PRINTED 0x0004 28 #define FILE_PRINTED 0x0004
33 29
34typedef enum tristate { 30typedef enum tristate {
35 no, mod, yes 31 no, mod, yes
36} tristate; 32} tristate;
37 33
38enum expr_type { 34enum expr_type {
39 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL 35 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
40}; 36};
41 37
42union expr_data { 38union expr_data {
43 struct expr *expr; 39 struct expr *expr;
44 struct symbol *sym; 40 struct symbol *sym;
45}; 41};
46 42
47struct expr { 43struct expr {
48#ifdef CML1
49 int token;
50#else
51 enum expr_type type; 44 enum expr_type type;
52#endif
53 union expr_data left, right; 45 union expr_data left, right;
54}; 46};
55 47
56 #define E_TRI(ev)((ev).tri)
57 #define E_EXPR(ev)((ev).expr)
58 #define E_CALC(ev)(E_TRI(ev) = expr_calc_value(E_EXPR(ev)))
59
60 #define E_OR(dep1, dep2)(((dep1)>(dep2))?(dep1):(dep2)) 48 #define E_OR(dep1, dep2)(((dep1)>(dep2))?(dep1):(dep2))
61 #define E_AND(dep1, dep2)(((dep1)<(dep2))?(dep1):(dep2)) 49 #define E_AND(dep1, dep2)(((dep1)<(dep2))?(dep1):(dep2))
62 #define E_NOT(dep) (2-(dep)) 50 #define E_NOT(dep) (2-(dep))
63 51
64struct expr_value { 52struct expr_value {
65 struct expr *expr; 53 struct expr *expr;
66 tristate tri; 54 tristate tri;
67}; 55};
68 56
69 #define S_VAL(sv)((sv).value)
70 #define S_TRI(sv)((sv).tri)
71 #define S_EQ(sv1, sv2)(S_VAL(sv1) == S_VAL(sv2) || !strcmp(S_VAL(sv1), S_VAL(sv2)))
72
73struct symbol_value { 57struct symbol_value {
74 void *value; 58 void *val;
75 tristate tri; 59 tristate tri;
76}; 60};
77 61
78enum symbol_type { 62enum symbol_type {
79 S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER 63 S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
80}; 64};
81 65
82struct symbol { 66struct symbol {
83 struct symbol *next; 67 struct symbol *next;
84 char *name; 68 char *name;
85 char *help; 69 char *help;
86#ifdef CML1
87 int type;
88#else
89 enum symbol_type type; 70 enum symbol_type type;
90#endif 71 struct symbol_value curr, user;
91 struct symbol_value curr, def;
92 tristate visible; 72 tristate visible;
93 int flags; 73 int flags;
94 struct property *prop; 74 struct property *prop;
95 struct expr *dep, *dep2; 75 struct expr *dep, *dep2;
96 struct menu *menu; 76 struct expr_value rev_dep;
97}; 77};
98 78
99#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) 79#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
100 80
101#ifdef CML1
102 #define SYMBOL_UNKNOWN S_UNKNOWN
103 #define SYMBOL_BOOLEAN S_BOOLEAN
104 #define SYMBOL_TRISTATE S_TRISTATE
105 #define SYMBOL_INT S_INT
106 #define SYMBOL_HEX S_HEX
107 #define SYMBOL_STRING S_STRING
108 #define SYMBOL_OTHER S_OTHER
109#endif
110
111 #define SYMBOL_YES 0x0001 81 #define SYMBOL_YES 0x0001
112 #define SYMBOL_MOD 0x0002 82 #define SYMBOL_MOD 0x0002
113 #define SYMBOL_NO 0x0004 83 #define SYMBOL_NO 0x0004
114 #define SYMBOL_CONST 0x0007 84 #define SYMBOL_CONST 0x0007
115 #define SYMBOL_CHECK 0x0008 85 #define SYMBOL_CHECK 0x0008
116 #define SYMBOL_CHOICE 0x0010 86 #define SYMBOL_CHOICE 0x0010
117 #define SYMBOL_CHOICEVAL0x0020 87 #define SYMBOL_CHOICEVAL0x0020
118 #define SYMBOL_PRINTED 0x0040 88 #define SYMBOL_PRINTED 0x0040
119 #define SYMBOL_VALID 0x0080 89 #define SYMBOL_VALID 0x0080
120 #define SYMBOL_OPTIONAL 0x0100 90 #define SYMBOL_OPTIONAL 0x0100
121 #define SYMBOL_WRITE 0x0200 91 #define SYMBOL_WRITE 0x0200
122 #define SYMBOL_CHANGED 0x0400 92 #define SYMBOL_CHANGED 0x0400
123 #define SYMBOL_NEW 0x0800 93 #define SYMBOL_NEW 0x0800
124 #define SYMBOL_AUTO 0x1000 94 #define SYMBOL_AUTO 0x1000
95 #define SYMBOL_CHECKED 0x2000
96 #define SYMBOL_CHECK_DONE0x4000
97 #define SYMBOL_WARNED 0x8000
125 98
126 #define SYMBOL_MAXLENGTH256 99 #define SYMBOL_MAXLENGTH256
127 #define SYMBOL_HASHSIZE 257 100 #define SYMBOL_HASHSIZE 257
128 #define SYMBOL_HASHMASK 0xff 101 #define SYMBOL_HASHMASK 0xff
129 102
130enum prop_type { 103enum prop_type {
131 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_ROOTMENU, P_DEFAULT, P_CHOICE 104 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
132}; 105};
133 106
134struct property { 107struct property {
135 struct property *next; 108 struct property *next;
136 struct symbol *sym; 109 struct symbol *sym;
137#ifdef CML1
138 int token;
139#else
140 enum prop_type type; 110 enum prop_type type;
141#endif
142 const char *text; 111 const char *text;
143 struct symbol *def;
144 struct expr_value visible; 112 struct expr_value visible;
145 struct expr *dep; 113 struct expr *expr;
146 struct expr *dep2;
147 struct menu *menu; 114 struct menu *menu;
148 struct file *file; 115 struct file *file;
149 int lineno; 116 int lineno;
150#ifdef CML1
151 struct property *next_pos;
152#endif
153}; 117};
154 118
155#define for_all_properties(sym, st, tok) \ 119#define for_all_properties(sym, st, tok) \
156 for (st = sym->prop; st; st = st->next) \ 120 for (st = sym->prop; st; st = st->next) \
157 if (st->type == (tok)) 121 if (st->type == (tok))
158#define for_all_prompts(sym, st) for_all_properties(sym, st, P_PROMPT)
159#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) 122#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
160#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) 123#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
124#define for_all_prompts(sym, st) \
125 for (st = sym->prop; st; st = st->next) \
126 if (st->text)
161 127
162struct menu { 128struct menu {
163 struct menu *next; 129 struct menu *next;
164 struct menu *parent; 130 struct menu *parent;
165 struct menu *list; 131 struct menu *list;
166 struct symbol *sym; 132 struct symbol *sym;
167 struct property *prompt; 133 struct property *prompt;
168 struct expr *dep; 134 struct expr *dep;
169 unsigned int flags; 135 unsigned int flags;
170 //char *help; 136 //char *help;
171 struct file *file; 137 struct file *file;
172 int lineno; 138 int lineno;
173 void *data; 139 void *data;
174}; 140};
175 141
176 #define MENU_CHANGED 0x0001 142 #define MENU_CHANGED 0x0001
143 #define MENU_ROOT 0x0002
177 144
178#ifndef SWIG 145#ifndef SWIG
179 146
180extern struct file *file_list; 147extern struct file *file_list;
181extern struct file *current_file; 148extern struct file *current_file;
182struct file *lookup_file(const char *name); 149struct file *lookup_file(const char *name);
183 150
184extern struct symbol symbol_yes, symbol_no, symbol_mod; 151extern struct symbol symbol_yes, symbol_no, symbol_mod;
185extern struct symbol *modules_sym; 152extern struct symbol *modules_sym;
186extern int cdebug; 153extern int cdebug;
187extern int print_type;
188struct expr *expr_alloc_symbol(struct symbol *sym); 154struct expr *expr_alloc_symbol(struct symbol *sym);
189#ifdef CML1
190struct expr *expr_alloc_one(int token, struct expr *ce);
191struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2);
192struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2);
193#else
194struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); 155struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
195struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); 156struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
196struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); 157struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
197#endif
198struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); 158struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
159struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
199struct expr *expr_copy(struct expr *org); 160struct expr *expr_copy(struct expr *org);
200void expr_free(struct expr *e); 161void expr_free(struct expr *e);
201int expr_eq(struct expr *e1, struct expr *e2); 162int expr_eq(struct expr *e1, struct expr *e2);
202void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); 163void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
203tristate expr_calc_value(struct expr *e); 164tristate expr_calc_value(struct expr *e);
204struct expr *expr_eliminate_yn(struct expr *e); 165struct expr *expr_eliminate_yn(struct expr *e);
205struct expr *expr_trans_bool(struct expr *e); 166struct expr *expr_trans_bool(struct expr *e);
206struct expr *expr_eliminate_dups(struct expr *e); 167struct expr *expr_eliminate_dups(struct expr *e);
207struct expr *expr_transform(struct expr *e); 168struct expr *expr_transform(struct expr *e);
208int expr_contains_symbol(struct expr *dep, struct symbol *sym); 169int expr_contains_symbol(struct expr *dep, struct symbol *sym);
209bool expr_depends_symbol(struct expr *dep, struct symbol *sym); 170bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
210struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); 171struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
211struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); 172struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
212void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); 173void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
213struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); 174struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
214 175
215void expr_fprint(struct expr *e, FILE *out); 176void expr_fprint(struct expr *e, FILE *out);
216void print_expr(int mask, struct expr *e, int prevtoken); 177void print_expr(int mask, struct expr *e, int prevtoken);
217 178
218#ifdef CML1
219static inline int expr_is_yes(struct expr *e)
220{
221 return !e || (e->token == WORD && e->left.sym == &symbol_yes);
222}
223
224static inline int expr_is_no(struct expr *e)
225{
226 return e && (e->token == WORD && e->left.sym == &symbol_no);
227}
228#else
229static inline int expr_is_yes(struct expr *e) 179static inline int expr_is_yes(struct expr *e)
230{ 180{
231 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); 181 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
232} 182}
233 183
234static inline int expr_is_no(struct expr *e) 184static inline int expr_is_no(struct expr *e)
235{ 185{
236 return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); 186 return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
237} 187}
238#endif 188#endif
239#endif
240 189
241#ifdef __cplusplus 190#ifdef __cplusplus
242} 191}
243#endif 192#endif
244 193
245#endif /* EXPR_H */ 194#endif /* EXPR_H */
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
new file mode 100644
index 0000000..3227180
--- a/dev/null
+++ b/scripts/kconfig/gconf.c
@@ -0,0 +1,1618 @@
1/* Hey EMACS -*- linux-c -*- */
2/*
3 *
4 * Copyright (C) 2002-2003 Romain Lievin <roms@lpg.ticalc.org>
5 * Released under the terms of the GNU GPL v2.0.
6 *
7 */
8
9#ifdef HAVE_CONFIG_H
10# include <config.h>
11#endif
12
13#include "lkc.h"
14#include "images.c"
15
16#include <glade/glade.h>
17#include <gtk/gtk.h>
18#include <glib.h>
19#include <gdk/gdkkeysyms.h>
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24#include <time.h>
25#include <stdlib.h>
26
27//#define DEBUG
28
29enum {
30 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
31};
32
33static gint view_mode = SPLIT_VIEW;
34static gboolean show_name = TRUE;
35static gboolean show_range = TRUE;
36static gboolean show_value = TRUE;
37static gboolean show_all = FALSE;
38static gboolean show_debug = FALSE;
39static gboolean resizeable = FALSE;
40
41static gboolean config_changed = FALSE;
42
43static char nohelp_text[] =
44 "Sorry, no help available for this option yet.\n";
45
46GtkWidget *main_wnd = NULL;
47 GtkWidget *tree1_w = NULL;// left frame
48 GtkWidget *tree2_w = NULL;// right frame
49GtkWidget *text_w = NULL;
50GtkWidget *hpaned = NULL;
51GtkWidget *vpaned = NULL;
52GtkWidget *back_btn = NULL;
53
54GtkTextTag *tag1, *tag2;
55GdkColor color;
56
57GtkTreeStore *tree1, *tree2, *tree;
58GtkTreeModel *model1, *model2;
59static GtkTreeIter *parents[256] = { 0 };
60static gint indent;
61
62static struct menu *current;
63
64enum {
65 COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
66 COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF,
67 COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD,
68 COL_NUMBER
69};
70
71static void display_list(void);
72static void display_tree(struct menu *menu);
73static void display_tree_part(void);
74static void update_tree(struct menu *src, GtkTreeIter * dst);
75static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
76static gchar **fill_row(struct menu *menu);
77
78
79/* Helping/Debugging Functions */
80
81
82const char *dbg_print_stype(int val)
83{
84 static char buf[256];
85
86 bzero(buf, 256);
87
88 if (val == S_UNKNOWN)
89 strcpy(buf, "unknown");
90 if (val == S_BOOLEAN)
91 strcpy(buf, "boolean");
92 if (val == S_TRISTATE)
93 strcpy(buf, "tristate");
94 if (val == S_INT)
95 strcpy(buf, "int");
96 if (val == S_HEX)
97 strcpy(buf, "hex");
98 if (val == S_STRING)
99 strcpy(buf, "string");
100 if (val == S_OTHER)
101 strcpy(buf, "other");
102
103#ifdef DEBUG
104 printf("%s", buf);
105#endif
106
107 return buf;
108}
109
110const char *dbg_print_flags(int val)
111{
112 static char buf[256] = { 0 };
113
114 bzero(buf, 256);
115
116 if (val & SYMBOL_YES)
117 strcat(buf, "yes/");
118 if (val & SYMBOL_MOD)
119 strcat(buf, "mod/");
120 if (val & SYMBOL_NO)
121 strcat(buf, "no/");
122 if (val & SYMBOL_CONST)
123 strcat(buf, "const/");
124 if (val & SYMBOL_CHECK)
125 strcat(buf, "check/");
126 if (val & SYMBOL_CHOICE)
127 strcat(buf, "choice/");
128 if (val & SYMBOL_CHOICEVAL)
129 strcat(buf, "choiceval/");
130 if (val & SYMBOL_PRINTED)
131 strcat(buf, "printed/");
132 if (val & SYMBOL_VALID)
133 strcat(buf, "valid/");
134 if (val & SYMBOL_OPTIONAL)
135 strcat(buf, "optional/");
136 if (val & SYMBOL_WRITE)
137 strcat(buf, "write/");
138 if (val & SYMBOL_CHANGED)
139 strcat(buf, "changed/");
140 if (val & SYMBOL_NEW)
141 strcat(buf, "new/");
142 if (val & SYMBOL_AUTO)
143 strcat(buf, "auto/");
144
145 buf[strlen(buf) - 1] = '\0';
146#ifdef DEBUG
147 printf("%s", buf);
148#endif
149
150 return buf;
151}
152
153const char *dbg_print_ptype(int val)
154{
155 static char buf[256];
156
157 bzero(buf, 256);
158
159 if (val == P_UNKNOWN)
160 strcpy(buf, "unknown");
161 if (val == P_PROMPT)
162 strcpy(buf, "prompt");
163 if (val == P_COMMENT)
164 strcpy(buf, "comment");
165 if (val == P_MENU)
166 strcpy(buf, "menu");
167 if (val == P_DEFAULT)
168 strcpy(buf, "default");
169 if (val == P_CHOICE)
170 strcpy(buf, "choice");
171
172#ifdef DEBUG
173 printf("%s", buf);
174#endif
175
176 return buf;
177}
178
179
180/* Main Window Initialization */
181
182
183void init_main_window(const gchar * glade_file)
184{
185 GladeXML *xml;
186 GtkWidget *widget;
187 GtkTextBuffer *txtbuf;
188 char title[256];
189 GdkPixmap *pixmap;
190 GdkBitmap *mask;
191 GtkStyle *style;
192
193 xml = glade_xml_new(glade_file, "window1", NULL);
194 if (!xml)
195 g_error("GUI loading failed !\n");
196 glade_xml_signal_autoconnect(xml);
197
198 main_wnd = glade_xml_get_widget(xml, "window1");
199 hpaned = glade_xml_get_widget(xml, "hpaned1");
200 vpaned = glade_xml_get_widget(xml, "vpaned1");
201 tree1_w = glade_xml_get_widget(xml, "treeview1");
202 tree2_w = glade_xml_get_widget(xml, "treeview2");
203 text_w = glade_xml_get_widget(xml, "textview3");
204
205 back_btn = glade_xml_get_widget(xml, "button1");
206 gtk_widget_set_sensitive(back_btn, FALSE);
207
208 widget = glade_xml_get_widget(xml, "show_name1");
209 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
210 show_name);
211
212 widget = glade_xml_get_widget(xml, "show_range1");
213 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
214 show_range);
215
216 widget = glade_xml_get_widget(xml, "show_data1");
217 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
218 show_value);
219
220 style = gtk_widget_get_style(main_wnd);
221 widget = glade_xml_get_widget(xml, "toolbar1");
222
223 pixmap = gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
224 &style->bg[GTK_STATE_NORMAL],
225 (gchar **) xpm_single_view);
226 gtk_image_set_from_pixmap(GTK_IMAGE
227 (((GtkToolbarChild
228 *) (g_list_nth(GTK_TOOLBAR(widget)->
229 children,
230 5)->data))->icon),
231 pixmap, mask);
232 pixmap =
233 gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
234 &style->bg[GTK_STATE_NORMAL],
235 (gchar **) xpm_split_view);
236 gtk_image_set_from_pixmap(GTK_IMAGE
237 (((GtkToolbarChild
238 *) (g_list_nth(GTK_TOOLBAR(widget)->
239 children,
240 6)->data))->icon),
241 pixmap, mask);
242 pixmap =
243 gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
244 &style->bg[GTK_STATE_NORMAL],
245 (gchar **) xpm_tree_view);
246 gtk_image_set_from_pixmap(GTK_IMAGE
247 (((GtkToolbarChild
248 *) (g_list_nth(GTK_TOOLBAR(widget)->
249 children,
250 7)->data))->icon),
251 pixmap, mask);
252
253 switch (view_mode) {
254 case SINGLE_VIEW:
255 widget = glade_xml_get_widget(xml, "button4");
256 gtk_button_clicked(GTK_BUTTON(widget));
257 break;
258 case SPLIT_VIEW:
259 widget = glade_xml_get_widget(xml, "button5");
260 gtk_button_clicked(GTK_BUTTON(widget));
261 break;
262 case FULL_VIEW:
263 widget = glade_xml_get_widget(xml, "button6");
264 gtk_button_clicked(GTK_BUTTON(widget));
265 break;
266 }
267
268 txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
269 tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
270 "foreground", "red",
271 "weight", PANGO_WEIGHT_BOLD,
272 NULL);
273 tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
274 /*"style", PANGO_STYLE_OBLIQUE, */
275 NULL);
276
277 sprintf(title, "Build Configuration")
278 gtk_window_set_title(GTK_WINDOW(main_wnd), title);
279
280 gtk_widget_show(main_wnd);
281}
282
283void init_tree_model(void)
284{
285 gint i;
286
287 tree = tree2 = gtk_tree_store_new(COL_NUMBER,
288 G_TYPE_STRING, G_TYPE_STRING,
289 G_TYPE_STRING, G_TYPE_STRING,
290 G_TYPE_STRING, G_TYPE_STRING,
291 G_TYPE_POINTER, GDK_TYPE_COLOR,
292 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
293 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
294 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
295 G_TYPE_BOOLEAN);
296 model2 = GTK_TREE_MODEL(tree2);
297
298 for (parents[0] = NULL, i = 1; i < 256; i++)
299 parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
300
301 tree1 = gtk_tree_store_new(COL_NUMBER,
302 G_TYPE_STRING, G_TYPE_STRING,
303 G_TYPE_STRING, G_TYPE_STRING,
304 G_TYPE_STRING, G_TYPE_STRING,
305 G_TYPE_POINTER, GDK_TYPE_COLOR,
306 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
307 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
308 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
309 G_TYPE_BOOLEAN);
310 model1 = GTK_TREE_MODEL(tree1);
311}
312
313void init_left_tree(void)
314{
315 GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
316 GtkCellRenderer *renderer;
317 GtkTreeSelection *sel;
318
319 gtk_tree_view_set_model(view, model1);
320 gtk_tree_view_set_headers_visible(view, TRUE);
321 gtk_tree_view_set_rules_hint(view, FALSE);
322
323 renderer = gtk_cell_renderer_text_new();
324 gtk_tree_view_insert_column_with_attributes(view, -1,
325 "Options", renderer,
326 "text", COL_OPTION,
327 "foreground-gdk",
328 COL_COLOR, NULL);
329
330 sel = gtk_tree_view_get_selection(view);
331 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
332 gtk_widget_realize(tree1_w);
333}
334
335static void renderer_edited(GtkCellRendererText * cell,
336 const gchar * path_string,
337 const gchar * new_text, gpointer user_data);
338static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle,
339 gchar * arg1, gpointer user_data);
340
341void init_right_tree(void)
342{
343 GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
344 GtkCellRenderer *renderer;
345 GtkTreeSelection *sel;
346 GtkTreeViewColumn *column;
347 gint i;
348
349 gtk_tree_view_set_model(view, model2);
350 gtk_tree_view_set_headers_visible(view, TRUE);
351 gtk_tree_view_set_rules_hint(view, FALSE);
352
353 column = gtk_tree_view_column_new();
354 gtk_tree_view_append_column(view, column);
355 gtk_tree_view_column_set_title(column, "Options");
356
357 renderer = gtk_cell_renderer_pixbuf_new();
358 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
359 renderer, FALSE);
360 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
361 renderer,
362 "pixbuf", COL_PIXBUF,
363 "visible", COL_PIXVIS, NULL);
364 renderer = gtk_cell_renderer_toggle_new();
365 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
366 renderer, FALSE);
367 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
368 renderer,
369 "active", COL_BTNACT,
370 "inconsistent", COL_BTNINC,
371 "visible", COL_BTNVIS,
372 "radio", COL_BTNRAD, NULL);
373 /*g_signal_connect(G_OBJECT(renderer), "toggled",
374 G_CALLBACK(renderer_toggled), NULL); */
375 renderer = gtk_cell_renderer_text_new();
376 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
377 renderer, FALSE);
378 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
379 renderer,
380 "text", COL_OPTION,
381 "foreground-gdk",
382 COL_COLOR, NULL);
383
384 renderer = gtk_cell_renderer_text_new();
385 gtk_tree_view_insert_column_with_attributes(view, -1,
386 "Name", renderer,
387 "text", COL_NAME,
388 "foreground-gdk",
389 COL_COLOR, NULL);
390 renderer = gtk_cell_renderer_text_new();
391 gtk_tree_view_insert_column_with_attributes(view, -1,
392 "N", renderer,
393 "text", COL_NO,
394 "foreground-gdk",
395 COL_COLOR, NULL);
396 renderer = gtk_cell_renderer_text_new();
397 gtk_tree_view_insert_column_with_attributes(view, -1,
398 "M", renderer,
399 "text", COL_MOD,
400 "foreground-gdk",
401 COL_COLOR, NULL);
402 renderer = gtk_cell_renderer_text_new();
403 gtk_tree_view_insert_column_with_attributes(view, -1,
404 "Y", renderer,
405 "text", COL_YES,
406 "foreground-gdk",
407 COL_COLOR, NULL);
408 renderer = gtk_cell_renderer_text_new();
409 gtk_tree_view_insert_column_with_attributes(view, -1,
410 "Value", renderer,
411 "text", COL_VALUE,
412 "editable",
413 COL_EDIT,
414 "foreground-gdk",
415 COL_COLOR, NULL);
416 g_signal_connect(G_OBJECT(renderer), "edited",
417 G_CALLBACK(renderer_edited), NULL);
418
419 column = gtk_tree_view_get_column(view, COL_NAME);
420 gtk_tree_view_column_set_visible(column, show_name);
421 column = gtk_tree_view_get_column(view, COL_NO);
422 gtk_tree_view_column_set_visible(column, show_range);
423 column = gtk_tree_view_get_column(view, COL_MOD);
424 gtk_tree_view_column_set_visible(column, show_range);
425 column = gtk_tree_view_get_column(view, COL_YES);
426 gtk_tree_view_column_set_visible(column, show_range);
427 column = gtk_tree_view_get_column(view, COL_VALUE);
428 gtk_tree_view_column_set_visible(column, show_value);
429
430 if (resizeable) {
431 for (i = 0; i < COL_VALUE; i++) {
432 column = gtk_tree_view_get_column(view, i);
433 gtk_tree_view_column_set_resizable(column, TRUE);
434 }
435 }
436
437 sel = gtk_tree_view_get_selection(view);
438 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
439}
440
441
442/* Utility Functions */
443
444
445static void text_insert_help(struct menu *menu)
446{
447 GtkTextBuffer *buffer;
448 GtkTextIter start, end;
449 const char *prompt = menu_get_prompt(menu);
450 gchar *name;
451 const char *help = nohelp_text;
452
453 if (!menu->sym)
454 help = "";
455 else if (menu->sym->help)
456 help = menu->sym->help;
457
458 if (menu->sym && menu->sym->name)
459 name = g_strdup_printf(menu->sym->name);
460 else
461 name = g_strdup("");
462
463 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
464 gtk_text_buffer_get_bounds(buffer, &start, &end);
465 gtk_text_buffer_delete(buffer, &start, &end);
466 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
467
468 gtk_text_buffer_get_end_iter(buffer, &end);
469 gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
470 NULL);
471 gtk_text_buffer_insert_at_cursor(buffer, " ", 1);
472 gtk_text_buffer_get_end_iter(buffer, &end);
473 gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1,
474 NULL);
475 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
476 gtk_text_buffer_get_end_iter(buffer, &end);
477 gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2,
478 NULL);
479}
480
481
482static void text_insert_msg(const char *title, const char *message)
483{
484 GtkTextBuffer *buffer;
485 GtkTextIter start, end;
486 const char *msg = message;
487
488 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
489 gtk_text_buffer_get_bounds(buffer, &start, &end);
490 gtk_text_buffer_delete(buffer, &start, &end);
491 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
492
493 gtk_text_buffer_get_end_iter(buffer, &end);
494 gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
495 NULL);
496 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
497 gtk_text_buffer_get_end_iter(buffer, &end);
498 gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
499 NULL);
500}
501
502
503/* Main Windows Callbacks */
504
505void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data);
506gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
507 gpointer user_data)
508{
509 GtkWidget *dialog, *label;
510 gint result;
511
512 if (config_changed == FALSE)
513 return FALSE;
514
515 dialog = gtk_dialog_new_with_buttons("Warning !",
516 GTK_WINDOW(main_wnd),
517 (GtkDialogFlags)
518 (GTK_DIALOG_MODAL |
519 GTK_DIALOG_DESTROY_WITH_PARENT),
520 GTK_STOCK_OK,
521 GTK_RESPONSE_YES,
522 GTK_STOCK_NO,
523 GTK_RESPONSE_NO,
524 GTK_STOCK_CANCEL,
525 GTK_RESPONSE_CANCEL, NULL);
526 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
527 GTK_RESPONSE_CANCEL);
528
529 label = gtk_label_new("\nSave configuration ?\n");
530 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
531 gtk_widget_show(label);
532
533 result = gtk_dialog_run(GTK_DIALOG(dialog));
534 switch (result) {
535 case GTK_RESPONSE_YES:
536 on_save1_activate(NULL, NULL);
537 return FALSE;
538 case GTK_RESPONSE_NO:
539 return FALSE;
540 case GTK_RESPONSE_CANCEL:
541 case GTK_RESPONSE_DELETE_EVENT:
542 default:
543 gtk_widget_destroy(dialog);
544 return TRUE;
545 }
546
547 return FALSE;
548}
549
550
551void on_window1_destroy(GtkObject * object, gpointer user_data)
552{
553 gtk_main_quit();
554}
555
556
557void
558on_window1_size_request(GtkWidget * widget,
559 GtkRequisition * requisition, gpointer user_data)
560{
561 static gint old_h = 0;
562 gint w, h;
563
564 if (widget->window == NULL)
565 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
566 else
567 gdk_window_get_size(widget->window, &w, &h);
568
569 if (h == old_h)
570 return;
571 old_h = h;
572
573 gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
574}
575
576
577/* Menu & Toolbar Callbacks */
578
579
580static void
581load_filename(GtkFileSelection * file_selector, gpointer user_data)
582{
583 const gchar *fn;
584
585 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
586 (user_data));
587
588 if (conf_read(fn))
589 text_insert_msg("Error", "Unable to load configuration !");
590 else
591 display_tree(&rootmenu);
592}
593
594void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
595{
596 GtkWidget *fs;
597
598 fs = gtk_file_selection_new("Load file...");
599 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
600 "clicked",
601 G_CALLBACK(load_filename), (gpointer) fs);
602 g_signal_connect_swapped(GTK_OBJECT
603 (GTK_FILE_SELECTION(fs)->ok_button),
604 "clicked", G_CALLBACK(gtk_widget_destroy),
605 (gpointer) fs);
606 g_signal_connect_swapped(GTK_OBJECT
607 (GTK_FILE_SELECTION(fs)->cancel_button),
608 "clicked", G_CALLBACK(gtk_widget_destroy),
609 (gpointer) fs);
610 gtk_widget_show(fs);
611}
612
613
614void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
615{
616 if (conf_write(NULL))
617 text_insert_msg("Error", "Unable to save configuration !");
618
619 config_changed = FALSE;
620}
621
622
623static void
624store_filename(GtkFileSelection * file_selector, gpointer user_data)
625{
626 const gchar *fn;
627
628 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
629 (user_data));
630
631 if (conf_write(fn))
632 text_insert_msg("Error", "Unable to save configuration !");
633
634 gtk_widget_destroy(GTK_WIDGET(user_data));
635}
636
637void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
638{
639 GtkWidget *fs;
640
641 fs = gtk_file_selection_new("Save file as...");
642 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
643 "clicked",
644 G_CALLBACK(store_filename), (gpointer) fs);
645 g_signal_connect_swapped(GTK_OBJECT
646 (GTK_FILE_SELECTION(fs)->ok_button),
647 "clicked", G_CALLBACK(gtk_widget_destroy),
648 (gpointer) fs);
649 g_signal_connect_swapped(GTK_OBJECT
650 (GTK_FILE_SELECTION(fs)->cancel_button),
651 "clicked", G_CALLBACK(gtk_widget_destroy),
652 (gpointer) fs);
653 gtk_widget_show(fs);
654}
655
656
657void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
658{
659 if (!on_window1_delete_event(NULL, NULL, NULL))
660 gtk_widget_destroy(GTK_WIDGET(main_wnd));
661}
662
663
664void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
665{
666 GtkTreeViewColumn *col;
667
668 show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
669 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
670 if (col)
671 gtk_tree_view_column_set_visible(col, show_name);
672}
673
674
675void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
676{
677 GtkTreeViewColumn *col;
678
679 show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
680 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
681 if (col)
682 gtk_tree_view_column_set_visible(col, show_range);
683 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD);
684 if (col)
685 gtk_tree_view_column_set_visible(col, show_range);
686 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES);
687 if (col)
688 gtk_tree_view_column_set_visible(col, show_range);
689
690}
691
692
693void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
694{
695 GtkTreeViewColumn *col;
696
697 show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
698 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
699 if (col)
700 gtk_tree_view_column_set_visible(col, show_value);
701}
702
703
704void
705on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
706{
707 show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
708
709 gtk_tree_store_clear(tree2);
710 display_tree(&rootmenu);// instead of update_tree for speed reasons
711}
712
713
714void
715on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
716{
717 show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
718 update_tree(&rootmenu, NULL);
719}
720
721
722void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
723{
724 GtkWidget *dialog;
725 const gchar *intro_text =
726 "Welcome to gkc, the GTK+ graphical configuration tool\n"
727 "for Linux.\n"
728 "For each option, a blank box indicates the feature is disabled, a\n"
729 "check indicates it is enabled, and a dot indicates that it is to\n"
730 "be compiled as a module. Clicking on the box will cycle through the three states.\n"
731 "\n"
732 "If you do not see an option (e.g., a device driver) that you\n"
733 "believe should be present, try turning on Show All Options\n"
734 "under the Options menu.\n"
735 "Although there is no cross reference yet to help you figure out\n"
736 "what other options must be enabled to support the option you\n"
737 "are interested in, you can still view the help of a grayed-out\n"
738 "option.\n"
739 "\n"
740 "Toggling Show Debug Info under the Options menu will show \n"
741 "the dependencies, which you can then match by examining other options.";
742
743 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
744 GTK_DIALOG_DESTROY_WITH_PARENT,
745 GTK_MESSAGE_INFO,
746 GTK_BUTTONS_CLOSE, intro_text);
747 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
748 G_CALLBACK(gtk_widget_destroy),
749 GTK_OBJECT(dialog));
750 gtk_widget_show_all(dialog);
751}
752
753
754void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
755{
756 GtkWidget *dialog;
757 const gchar *about_text =
758 "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
759 "Based on the source code from Roman Zippel.\n";
760
761 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
762 GTK_DIALOG_DESTROY_WITH_PARENT,
763 GTK_MESSAGE_INFO,
764 GTK_BUTTONS_CLOSE, about_text);
765 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
766 G_CALLBACK(gtk_widget_destroy),
767 GTK_OBJECT(dialog));
768 gtk_widget_show_all(dialog);
769}
770
771
772void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
773{
774 GtkWidget *dialog;
775 const gchar *license_text =
776 "gkc is released under the terms of the GNU GPL v2.\n"
777 "For more information, please see the source code or\n"
778 "visit http://www.fsf.org/licenses/licenses.html\n";
779
780 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
781 GTK_DIALOG_DESTROY_WITH_PARENT,
782 GTK_MESSAGE_INFO,
783 GTK_BUTTONS_CLOSE, license_text);
784 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
785 G_CALLBACK(gtk_widget_destroy),
786 GTK_OBJECT(dialog));
787 gtk_widget_show_all(dialog);
788}
789
790
791void on_back_pressed(GtkButton * button, gpointer user_data)
792{
793 enum prop_type ptype;
794
795 current = current->parent;
796 ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
797 if (ptype != P_MENU)
798 current = current->parent;
799 display_tree_part();
800
801 if (current == &rootmenu)
802 gtk_widget_set_sensitive(back_btn, FALSE);
803}
804
805
806void on_load_pressed(GtkButton * button, gpointer user_data)
807{
808 on_load1_activate(NULL, user_data);
809}
810
811
812void on_save_pressed(GtkButton * button, gpointer user_data)
813{
814 on_save1_activate(NULL, user_data);
815}
816
817
818void on_single_clicked(GtkButton * button, gpointer user_data)
819{
820 view_mode = SINGLE_VIEW;
821 gtk_paned_set_position(GTK_PANED(hpaned), 0);
822 gtk_widget_hide(tree1_w);
823 current = &rootmenu;
824 display_tree_part();
825}
826
827
828void on_split_clicked(GtkButton * button, gpointer user_data)
829{
830 gint w, h;
831 view_mode = SPLIT_VIEW;
832 gtk_widget_show(tree1_w);
833 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
834 gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
835 if (tree2)
836 gtk_tree_store_clear(tree2);
837 display_list();
838}
839
840
841void on_full_clicked(GtkButton * button, gpointer user_data)
842{
843 view_mode = FULL_VIEW;
844 gtk_paned_set_position(GTK_PANED(hpaned), 0);
845 gtk_widget_hide(tree1_w);
846 if (tree2)
847 gtk_tree_store_clear(tree2);
848 display_tree(&rootmenu);
849 gtk_widget_set_sensitive(back_btn, FALSE);
850}
851
852
853void on_collapse_pressed(GtkButton * button, gpointer user_data)
854{
855 gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
856}
857
858
859void on_expand_pressed(GtkButton * button, gpointer user_data)
860{
861 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
862}
863
864
865/* CTree Callbacks */
866
867/* Change hex/int/string value in the cell */
868static void renderer_edited(GtkCellRendererText * cell,
869 const gchar * path_string,
870 const gchar * new_text, gpointer user_data)
871{
872 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
873 GtkTreeIter iter;
874 const char *old_def, *new_def;
875 struct menu *menu;
876 struct symbol *sym;
877
878 if (!gtk_tree_model_get_iter(model2, &iter, path))
879 return;
880
881 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
882 sym = menu->sym;
883
884 gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
885 new_def = new_text;
886
887 sym_set_string_value(sym, new_def);
888
889 config_changed = TRUE;
890 update_tree(&rootmenu, NULL);
891
892 gtk_tree_path_free(path);
893}
894
895/* Change the value of a symbol and update the tree */
896static void change_sym_value(struct menu *menu, gint col)
897{
898 struct symbol *sym = menu->sym;
899 tristate oldval, newval;
900
901 if (!sym)
902 return;
903
904 if (col == COL_NO)
905 newval = no;
906 else if (col == COL_MOD)
907 newval = mod;
908 else if (col == COL_YES)
909 newval = yes;
910 else
911 return;
912
913 switch (sym_get_type(sym)) {
914 case S_BOOLEAN:
915 case S_TRISTATE:
916 oldval = sym_get_tristate_value(sym);
917 if (!sym_tristate_within_range(sym, newval))
918 newval = yes;
919 sym_set_tristate_value(sym, newval);
920 config_changed = TRUE;
921 if (view_mode == FULL_VIEW)
922 update_tree(&rootmenu, NULL);
923 else if (view_mode == SPLIT_VIEW) {
924 update_tree(current, NULL);
925 display_list();
926 }
927 else if (view_mode == SINGLE_VIEW)
928 display_tree_part();//fixme: keep exp/coll
929 break;
930 case S_INT:
931 case S_HEX:
932 case S_STRING:
933 default:
934 break;
935 }
936}
937
938static void toggle_sym_value(struct menu *menu)
939{
940 const tristate next_val[3] = { no, mod, yes };
941 tristate newval;
942
943 if (!menu->sym)
944 return;
945
946 newval = next_val[(sym_get_tristate_value(menu->sym) + 1) % 3];
947 if (!sym_tristate_within_range(menu->sym, newval))
948 newval = yes;
949 sym_set_tristate_value(menu->sym, newval);
950 if (view_mode == FULL_VIEW)
951 update_tree(&rootmenu, NULL);
952 else if (view_mode == SPLIT_VIEW) {
953 update_tree(current, NULL);
954 display_list();
955 }
956 else if (view_mode == SINGLE_VIEW)
957 display_tree_part();//fixme: keep exp/coll
958}
959
960static void renderer_toggled(GtkCellRendererToggle * cell,
961 gchar * path_string, gpointer user_data)
962{
963 GtkTreePath *path, *sel_path = NULL;
964 GtkTreeIter iter, sel_iter;
965 GtkTreeSelection *sel;
966 struct menu *menu;
967
968 path = gtk_tree_path_new_from_string(path_string);
969 if (!gtk_tree_model_get_iter(model2, &iter, path))
970 return;
971
972 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w));
973 if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter))
974 sel_path = gtk_tree_model_get_path(model2, &sel_iter);
975 if (!sel_path)
976 goto out1;
977 if (gtk_tree_path_compare(path, sel_path))
978 goto out2;
979
980 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
981 toggle_sym_value(menu);
982
983 out2:
984 gtk_tree_path_free(sel_path);
985 out1:
986 gtk_tree_path_free(path);
987}
988
989static gint column2index(GtkTreeViewColumn * column)
990{
991 gint i;
992
993 for (i = 0; i < COL_NUMBER; i++) {
994 GtkTreeViewColumn *col;
995
996 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i);
997 if (col == column)
998 return i;
999 }
1000
1001 return -1;
1002}
1003
1004
1005//#define GTK_BUG_FIXED // uncomment it for GTK+ >= 2.1.4 (2.2)
1006
1007/* User click: update choice (full) or goes down (single) */
1008gboolean
1009on_treeview2_button_press_event(GtkWidget * widget,
1010 GdkEventButton * event, gpointer user_data)
1011{
1012 GtkTreeView *view = GTK_TREE_VIEW(widget);
1013 GtkTreePath *path;
1014 GtkTreeViewColumn *column;
1015 GtkTreeIter iter;
1016 struct menu *menu;
1017 gint col;
1018
1019#ifdef GTK_BUG_FIXED
1020 gint tx = (gint) event->x;
1021 gint ty = (gint) event->y;
1022 gint cx, cy;
1023
1024 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1025 &cy);
1026#else
1027 gtk_tree_view_get_cursor(view, &path, &column);
1028#endif
1029 if (path == NULL)
1030 return FALSE;
1031
1032 gtk_tree_model_get_iter(model2, &iter, path);
1033 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1034
1035 col = column2index(column);
1036 if (event->type == GDK_2BUTTON_PRESS) {
1037 enum prop_type ptype;
1038 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1039
1040 if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
1041 // goes down into menu
1042 current = menu;
1043 display_tree_part();
1044 gtk_widget_set_sensitive(back_btn, TRUE);
1045 } else if ((col == COL_OPTION)) {
1046 toggle_sym_value(menu);
1047 gtk_tree_view_expand_row(view, path, TRUE);
1048 }
1049 } else {
1050 if (col == COL_VALUE) {
1051 toggle_sym_value(menu);
1052 gtk_tree_view_expand_row(view, path, TRUE);
1053 } else if (col == COL_NO || col == COL_MOD
1054 || col == COL_YES) {
1055 change_sym_value(menu, col);
1056 gtk_tree_view_expand_row(view, path, TRUE);
1057 }
1058 }
1059
1060 return FALSE;
1061}
1062
1063/* Key pressed: update choice */
1064gboolean
1065on_treeview2_key_press_event(GtkWidget * widget,
1066 GdkEventKey * event, gpointer user_data)
1067{
1068 GtkTreeView *view = GTK_TREE_VIEW(widget);
1069 GtkTreePath *path;
1070 GtkTreeViewColumn *column;
1071 GtkTreeIter iter;
1072 struct menu *menu;
1073 gint col;
1074
1075 gtk_tree_view_get_cursor(view, &path, &column);
1076 if (path == NULL)
1077 return FALSE;
1078
1079 if (event->keyval == GDK_space) {
1080 if (gtk_tree_view_row_expanded(view, path))
1081 gtk_tree_view_collapse_row(view, path);
1082 else
1083 gtk_tree_view_expand_row(view, path, FALSE);
1084 return TRUE;
1085 }
1086 if (event->keyval == GDK_KP_Enter) {
1087 }
1088 if (widget == tree1_w)
1089 return FALSE;
1090
1091 gtk_tree_model_get_iter(model2, &iter, path);
1092 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1093
1094 if (!strcasecmp(event->string, "n"))
1095 col = COL_NO;
1096 else if (!strcasecmp(event->string, "m"))
1097 col = COL_MOD;
1098 else if (!strcasecmp(event->string, "y"))
1099 col = COL_YES;
1100 else
1101 col = -1;
1102 change_sym_value(menu, col);
1103
1104 return FALSE;
1105}
1106
1107
1108/* Row selection changed: update help */
1109void
1110on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
1111{
1112 GtkTreeSelection *selection;
1113 GtkTreeIter iter;
1114 struct menu *menu;
1115
1116 selection = gtk_tree_view_get_selection(treeview);
1117 if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
1118 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1119 text_insert_help(menu);
1120 }
1121}
1122
1123
1124/* User click: display sub-tree in the right frame. */
1125gboolean
1126on_treeview1_button_press_event(GtkWidget * widget,
1127 GdkEventButton * event, gpointer user_data)
1128{
1129 GtkTreeView *view = GTK_TREE_VIEW(widget);
1130 GtkTreePath *path;
1131 GtkTreeViewColumn *column;
1132 GtkTreeIter iter;
1133 struct menu *menu;
1134
1135 gint tx = (gint) event->x;
1136 gint ty = (gint) event->y;
1137 gint cx, cy;
1138
1139 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1140 &cy);
1141 if (path == NULL)
1142 return FALSE;
1143
1144 gtk_tree_model_get_iter(model1, &iter, path);
1145 gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
1146
1147 if (event->type == GDK_2BUTTON_PRESS) {
1148 toggle_sym_value(menu);
1149 current = menu;
1150 display_tree_part();
1151 } else {
1152 current = menu;
1153 display_tree_part();
1154 }
1155
1156 gtk_widget_realize(tree2_w);
1157 gtk_tree_view_set_cursor(view, path, NULL, FALSE);
1158 gtk_widget_grab_focus(GTK_TREE_VIEW(tree2_w));
1159
1160 return FALSE;
1161}
1162
1163
1164/* Conf management */
1165
1166
1167/* Fill a row of strings */
1168static gchar **fill_row(struct menu *menu)
1169{
1170 static gchar *row[COL_NUMBER] = { 0 };
1171 struct symbol *sym = menu->sym;
1172 const char *def;
1173 int stype;
1174 tristate val;
1175 enum prop_type ptype;
1176 int i;
1177
1178 for (i = COL_OPTION; i <= COL_COLOR; i++)
1179 g_free(row[i]);
1180 bzero(row, sizeof(row));
1181
1182 row[COL_OPTION] =
1183 g_strdup_printf("%s %s", menu_get_prompt(menu),
1184 sym ? (sym->
1185 flags & SYMBOL_NEW ? "(NEW)" : "") :
1186 "");
1187
1188 if (show_all && !menu_is_visible(menu))
1189 row[COL_COLOR] = g_strdup("DarkGray");
1190 else
1191 row[COL_COLOR] = g_strdup("Black");
1192
1193 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1194 switch (ptype) {
1195 case P_MENU:
1196 row[COL_PIXBUF] = (gchar *) xpm_menu;
1197 if (view_mode != FULL_VIEW)
1198 row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
1199 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1200 break;
1201 case P_COMMENT:
1202 row[COL_PIXBUF] = (gchar *) xpm_void;
1203 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1204 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1205 break;
1206 default:
1207 row[COL_PIXBUF] = (gchar *) xpm_void;
1208 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1209 row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1210 break;
1211 }
1212
1213 if (!sym)
1214 return row;
1215 row[COL_NAME] = g_strdup(sym->name);
1216
1217 sym_calc_value(sym);
1218 sym->flags &= ~SYMBOL_CHANGED;
1219
1220 if (sym_is_choice(sym)) {// parse childs for getting final value
1221 struct menu *child;
1222 struct symbol *def_sym = sym_get_choice_value(sym);
1223 struct menu *def_menu = NULL;
1224
1225 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1226
1227 for (child = menu->list; child; child = child->next) {
1228 if (menu_is_visible(child)
1229 && child->sym == def_sym)
1230 def_menu = child;
1231 }
1232
1233 if (def_menu)
1234 row[COL_VALUE] =
1235 g_strdup(menu_get_prompt(def_menu));
1236 }
1237 if(sym->flags & SYMBOL_CHOICEVAL)
1238 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
1239
1240 stype = sym_get_type(sym);
1241 switch (stype) {
1242 case S_BOOLEAN:
1243 if (sym_is_choice(sym))
1244 break;
1245 case S_TRISTATE:
1246 val = sym_get_tristate_value(sym);
1247 switch (val) {
1248 case no:
1249 row[COL_NO] = g_strdup("N");
1250 row[COL_VALUE] = g_strdup("N");
1251 row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
1252 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1253 break;
1254 case mod:
1255 row[COL_MOD] = g_strdup("M");
1256 row[COL_VALUE] = g_strdup("M");
1257 row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
1258 break;
1259 case yes:
1260 row[COL_YES] = g_strdup("Y");
1261 row[COL_VALUE] = g_strdup("Y");
1262 row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
1263 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1264 break;
1265 }
1266
1267 if (val != no && sym_tristate_within_range(sym, no))
1268 row[COL_NO] = g_strdup("_");
1269 if (val != mod && sym_tristate_within_range(sym, mod))
1270 row[COL_MOD] = g_strdup("_");
1271 if (val != yes && sym_tristate_within_range(sym, yes))
1272 row[COL_YES] = g_strdup("_");
1273 break;
1274 case S_INT:
1275 case S_HEX:
1276 case S_STRING:
1277 def = sym_get_string_value(sym);
1278 row[COL_VALUE] = g_strdup(def);
1279 row[COL_EDIT] = GINT_TO_POINTER(TRUE);
1280 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1281 break;
1282 }
1283
1284 return row;
1285}
1286
1287
1288/* Set the node content with a row of strings */
1289static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
1290{
1291 GdkColor color;
1292 gboolean success;
1293 GdkPixbuf *pix;
1294
1295 pix = gdk_pixbuf_new_from_xpm_data((const char **)
1296 row[COL_PIXBUF]);
1297
1298 gdk_color_parse(row[COL_COLOR], &color);
1299 gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
1300 FALSE, FALSE, &success);
1301
1302 gtk_tree_store_set(tree, node,
1303 COL_OPTION, row[COL_OPTION],
1304 COL_NAME, row[COL_NAME],
1305 COL_NO, row[COL_NO],
1306 COL_MOD, row[COL_MOD],
1307 COL_YES, row[COL_YES],
1308 COL_VALUE, row[COL_VALUE],
1309 COL_MENU, (gpointer) menu,
1310 COL_COLOR, &color,
1311 COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
1312 COL_PIXBUF, pix,
1313 COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
1314 COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
1315 COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
1316 COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
1317 COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
1318 -1);
1319
1320 g_object_unref(pix);
1321}
1322
1323
1324/* Add a node to the tree */
1325static void place_node(struct menu *menu, char **row)
1326{
1327 GtkTreeIter *parent = parents[indent - 1];
1328 GtkTreeIter *node = parents[indent];
1329
1330 gtk_tree_store_append(tree, node, parent);
1331 set_node(node, menu, row);
1332}
1333
1334
1335/* Find a node in the GTK+ tree */
1336static GtkTreeIter found;
1337
1338/*
1339 * Find a menu in the GtkTree starting at parent.
1340 */
1341GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
1342 struct menu *tofind)
1343{
1344 GtkTreeIter iter;
1345 GtkTreeIter *child = &iter;
1346 gboolean valid;
1347 GtkTreeIter *ret;
1348
1349 valid = gtk_tree_model_iter_children(model2, child, parent);
1350 while (valid) {
1351 struct menu *menu;
1352
1353 gtk_tree_model_get(model2, child, 6, &menu, -1);
1354
1355 if (menu == tofind) {
1356 memcpy(&found, child, sizeof(GtkTreeIter));
1357 return &found;
1358 }
1359
1360 ret = gtktree_iter_find_node(child, tofind);
1361 if (ret)
1362 return ret;
1363
1364 valid = gtk_tree_model_iter_next(model2, child);
1365 }
1366
1367 return NULL;
1368}
1369
1370
1371/*
1372 * Update the tree by adding/removing entries
1373 * Does not change other nodes
1374 */
1375static void update_tree(struct menu *src, GtkTreeIter * dst)
1376{
1377 struct menu *child1;
1378 GtkTreeIter iter, tmp;
1379 GtkTreeIter *child2 = &iter;
1380 gboolean valid;
1381 GtkTreeIter *sibling;
1382 struct symbol *sym;
1383 struct property *prop;
1384 struct menu *menu1, *menu2;
1385 static GtkTreePath *path = NULL;
1386
1387 if (src == &rootmenu)
1388 indent = 1;
1389
1390 valid = gtk_tree_model_iter_children(model2, child2, dst);
1391 for (child1 = src->list; child1; child1 = child1->next) {
1392
1393 prop = child1->prompt;
1394 sym = child1->sym;
1395
1396 reparse:
1397 menu1 = child1;
1398 if (valid)
1399 gtk_tree_model_get(model2, child2, COL_MENU,
1400 &menu2, -1);
1401 else
1402 menu2 = NULL;// force adding of a first child
1403
1404#ifdef DEBUG
1405 printf("%*c%s | %s\n", indent, ' ',
1406 menu1 ? menu_get_prompt(menu1) : "nil",
1407 menu2 ? menu_get_prompt(menu2) : "nil");
1408#endif
1409
1410 if (!menu_is_visible(child1) && !show_all) {// remove node
1411 if (gtktree_iter_find_node(dst, menu1) != NULL) {
1412 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1413 valid = gtk_tree_model_iter_next(model2,
1414 child2);
1415 gtk_tree_store_remove(tree2, &tmp);
1416 if (!valid)
1417 return;// next parent
1418 else
1419 goto reparse;// next child
1420 } else
1421 continue;
1422 }
1423
1424 if (menu1 != menu2) {
1425 if (gtktree_iter_find_node(dst, menu1) == NULL) {// add node
1426 if (!valid && !menu2)
1427 sibling = NULL;
1428 else
1429 sibling = child2;
1430 gtk_tree_store_insert_before(tree2,
1431 child2,
1432 dst, sibling);
1433 set_node(child2, menu1, fill_row(menu1));
1434 if (menu2 == NULL)
1435 valid = TRUE;
1436 } else {// remove node
1437 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1438 valid = gtk_tree_model_iter_next(model2,
1439 child2);
1440 gtk_tree_store_remove(tree2, &tmp);
1441 if (!valid)
1442 return;// next parent
1443 else
1444 goto reparse;// next child
1445 }
1446 } else if (sym && (sym->flags & SYMBOL_CHANGED)) {
1447 set_node(child2, menu1, fill_row(menu1));
1448 }
1449
1450 indent++;
1451 update_tree(child1, child2);
1452 indent--;
1453
1454 valid = gtk_tree_model_iter_next(model2, child2);
1455 }
1456}
1457
1458
1459/* Display the whole tree (single/split/full view) */
1460static void display_tree(struct menu *menu)
1461{
1462 struct symbol *sym;
1463 struct property *prop;
1464 struct menu *child;
1465 enum prop_type ptype;
1466
1467 if (menu == &rootmenu) {
1468 indent = 1;
1469 current = &rootmenu;
1470 }
1471
1472 for (child = menu->list; child; child = child->next) {
1473 prop = child->prompt;
1474 sym = child->sym;
1475 ptype = prop ? prop->type : P_UNKNOWN;
1476
1477 if (sym)
1478 sym->flags &= ~SYMBOL_CHANGED;
1479
1480 if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) &&
1481 (tree == tree1))
1482 continue;
1483
1484 if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) &&
1485 (tree == tree2))
1486 continue;
1487
1488 if (menu_is_visible(child) || show_all)
1489 place_node(child, fill_row(child));
1490#ifdef DEBUG
1491 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1492 dbg_print_ptype(ptype);
1493 printf(" | ");
1494 if (sym) {
1495 dbg_print_stype(sym->type);
1496 printf(" | ");
1497 dbg_print_flags(sym->flags);
1498 printf("\n");
1499 } else
1500 printf("\n");
1501#endif
1502 if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
1503 && (tree == tree2))
1504 continue;
1505
1506 if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) ||
1507 (view_mode == FULL_VIEW)
1508 || (view_mode == SPLIT_VIEW)) {
1509 indent++;
1510 display_tree(child);
1511 indent--;
1512 }
1513 }
1514}
1515
1516/* Display a part of the tree starting at current node (single/split view) */
1517static void display_tree_part(void)
1518{
1519 if (tree2)
1520 gtk_tree_store_clear(tree2);
1521 display_tree(current);
1522 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
1523}
1524
1525/* Display the list in the left frame (split view) */
1526static void display_list(void)
1527{
1528 if (tree1)
1529 gtk_tree_store_clear(tree1);
1530
1531 tree = tree1;
1532 display_tree(current = &rootmenu);
1533 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
1534 tree = tree2;
1535}
1536
1537static void fixup_rootmenu(struct menu *menu)
1538{
1539 struct menu *child;
1540
1541 if (!menu->prompt || menu->prompt->type != P_MENU)
1542 return;
1543 menu->flags |= MENU_ROOT;
1544 for (child = menu->list; child; child = child->next)
1545 fixup_rootmenu(child);
1546}
1547
1548
1549/* Main */
1550
1551
1552int main(int ac, char *av[])
1553{
1554 const char *name;
1555 gchar *cur_dir, *exe_path;
1556 gchar *glade_file;
1557
1558#ifndef LKC_DIRECT_LINK
1559 kconfig_load();
1560#endif
1561
1562 /* GTK stuffs */
1563 gtk_set_locale();
1564 gtk_init(&ac, &av);
1565 glade_init();
1566
1567 //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
1568 //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");
1569
1570 /* Determine GUI path */
1571 cur_dir = g_get_current_dir();
1572 exe_path = g_strdup(av[0]);
1573 exe_path[0] = '/';
1574 glade_file = g_strconcat(cur_dir, exe_path, ".glade", NULL);
1575 g_free(cur_dir);
1576 g_free(exe_path);
1577
1578 /* Load the interface and connect signals */
1579 init_main_window(glade_file);
1580 init_tree_model();
1581 init_left_tree();
1582 init_right_tree();
1583
1584 /* Conf stuffs */
1585 if (ac > 1 && av[1][0] == '-') {
1586 switch (av[1][1]) {
1587 case 'a':
1588 //showAll = 1;
1589 break;
1590 case 'h':
1591 case '?':
1592 printf("%s <config>\n", av[0]);
1593 exit(0);
1594 }
1595 name = av[2];
1596 } else
1597 name = av[1];
1598
1599 conf_parse(name);
1600 fixup_rootmenu(&rootmenu);
1601 conf_read(NULL);
1602
1603 switch (view_mode) {
1604 case SINGLE_VIEW:
1605 display_tree_part();
1606 break;
1607 case SPLIT_VIEW:
1608 display_list();
1609 break;
1610 case FULL_VIEW:
1611 display_tree(&rootmenu);
1612 break;
1613 }
1614
1615 gtk_main();
1616
1617 return 0;
1618}
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
new file mode 100644
index 0000000..1e1736d
--- a/dev/null
+++ b/scripts/kconfig/gconf.glade
@@ -0,0 +1,543 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
2<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
3
4<glade-interface>
5
6<widget class="GtkWindow" id="window1">
7 <property name="visible">True</property>
8 <property name="title" translatable="yes">Gtk Kernel Configurator</property>
9 <property name="type">GTK_WINDOW_TOPLEVEL</property>
10 <property name="window_position">GTK_WIN_POS_NONE</property>
11 <property name="modal">False</property>
12 <property name="default_width">640</property>
13 <property name="default_height">480</property>
14 <property name="resizable">True</property>
15 <property name="destroy_with_parent">False</property>
16 <signal name="destroy" handler="on_window1_destroy" object="window1"/>
17 <signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/>
18 <signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/>
19
20 <child>
21 <widget class="GtkVBox" id="vbox1">
22 <property name="visible">True</property>
23 <property name="homogeneous">False</property>
24 <property name="spacing">0</property>
25
26 <child>
27 <widget class="GtkMenuBar" id="menubar1">
28 <property name="visible">True</property>
29
30 <child>
31 <widget class="GtkMenuItem" id="file1">
32 <property name="visible">True</property>
33 <property name="label" translatable="yes">_File</property>
34 <property name="use_underline">True</property>
35
36 <child>
37 <widget class="GtkMenu" id="file1_menu">
38
39 <child>
40 <widget class="GtkImageMenuItem" id="load1">
41 <property name="visible">True</property>
42 <property name="tooltip" translatable="yes">Load a config file</property>
43 <property name="label" translatable="yes">_Load</property>
44 <property name="use_underline">True</property>
45 <signal name="activate" handler="on_load1_activate"/>
46 <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/>
47
48 <child internal-child="image">
49 <widget class="GtkImage" id="image27">
50 <property name="visible">True</property>
51 <property name="stock">gtk-open</property>
52 <property name="icon_size">1</property>
53 <property name="xalign">0.5</property>
54 <property name="yalign">0.5</property>
55 <property name="xpad">0</property>
56 <property name="ypad">0</property>
57 </widget>
58 </child>
59 </widget>
60 </child>
61
62 <child>
63 <widget class="GtkImageMenuItem" id="save1">
64 <property name="visible">True</property>
65 <property name="tooltip" translatable="yes">Save the config in .config</property>
66 <property name="label" translatable="yes">_Save</property>
67 <property name="use_underline">True</property>
68 <signal name="activate" handler="on_save1_activate"/>
69 <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
70
71 <child internal-child="image">
72 <widget class="GtkImage" id="image28">
73 <property name="visible">True</property>
74 <property name="stock">gtk-save</property>
75 <property name="icon_size">1</property>
76 <property name="xalign">0.5</property>
77 <property name="yalign">0.5</property>
78 <property name="xpad">0</property>
79 <property name="ypad">0</property>
80 </widget>
81 </child>
82 </widget>
83 </child>
84
85 <child>
86 <widget class="GtkImageMenuItem" id="save_as1">
87 <property name="visible">True</property>
88 <property name="tooltip" translatable="yes">Save the config in a file</property>
89 <property name="label" translatable="yes">Save _as</property>
90 <property name="use_underline">True</property>
91 <signal name="activate" handler="on_save_as1_activate"/>
92
93 <child internal-child="image">
94 <widget class="GtkImage" id="image29">
95 <property name="visible">True</property>
96 <property name="stock">gtk-save-as</property>
97 <property name="icon_size">1</property>
98 <property name="xalign">0.5</property>
99 <property name="yalign">0.5</property>
100 <property name="xpad">0</property>
101 <property name="ypad">0</property>
102 </widget>
103 </child>
104 </widget>
105 </child>
106
107 <child>
108 <widget class="GtkMenuItem" id="separator1">
109 <property name="visible">True</property>
110 </widget>
111 </child>
112
113 <child>
114 <widget class="GtkImageMenuItem" id="quit1">
115 <property name="visible">True</property>
116 <property name="label" translatable="yes">_Quit</property>
117 <property name="use_underline">True</property>
118 <signal name="activate" handler="on_quit1_activate"/>
119 <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
120
121 <child internal-child="image">
122 <widget class="GtkImage" id="image30">
123 <property name="visible">True</property>
124 <property name="stock">gtk-quit</property>
125 <property name="icon_size">1</property>
126 <property name="xalign">0.5</property>
127 <property name="yalign">0.5</property>
128 <property name="xpad">0</property>
129 <property name="ypad">0</property>
130 </widget>
131 </child>
132 </widget>
133 </child>
134 </widget>
135 </child>
136 </widget>
137 </child>
138
139 <child>
140 <widget class="GtkMenuItem" id="options1">
141 <property name="visible">True</property>
142 <property name="label" translatable="yes">_Options</property>
143 <property name="use_underline">True</property>
144
145 <child>
146 <widget class="GtkMenu" id="options1_menu">
147
148 <child>
149 <widget class="GtkCheckMenuItem" id="show_name1">
150 <property name="visible">True</property>
151 <property name="tooltip" translatable="yes">Show name</property>
152 <property name="label" translatable="yes">Show _name</property>
153 <property name="use_underline">True</property>
154 <property name="active">False</property>
155 <signal name="activate" handler="on_show_name1_activate"/>
156 </widget>
157 </child>
158
159 <child>
160 <widget class="GtkCheckMenuItem" id="show_range1">
161 <property name="visible">True</property>
162 <property name="tooltip" translatable="yes">Show range (Y/M/N)</property>
163 <property name="label" translatable="yes">Show _range</property>
164 <property name="use_underline">True</property>
165 <property name="active">False</property>
166 <signal name="activate" handler="on_show_range1_activate"/>
167 </widget>
168 </child>
169
170 <child>
171 <widget class="GtkCheckMenuItem" id="show_data1">
172 <property name="visible">True</property>
173 <property name="tooltip" translatable="yes">Show value of the option</property>
174 <property name="label" translatable="yes">Show _data</property>
175 <property name="use_underline">True</property>
176 <property name="active">False</property>
177 <signal name="activate" handler="on_show_data1_activate"/>
178 </widget>
179 </child>
180
181 <child>
182 <widget class="GtkMenuItem" id="separator2">
183 <property name="visible">True</property>
184 </widget>
185 </child>
186
187 <child>
188 <widget class="GtkCheckMenuItem" id="show_all_options1">
189 <property name="visible">True</property>
190 <property name="tooltip" translatable="yes">Show all options</property>
191 <property name="label" translatable="yes">Show all _options</property>
192 <property name="use_underline">True</property>
193 <property name="active">False</property>
194 <signal name="activate" handler="on_show_all_options1_activate"/>
195 </widget>
196 </child>
197
198 <child>
199 <widget class="GtkCheckMenuItem" id="show_debug_info1">
200 <property name="visible">True</property>
201 <property name="tooltip" translatable="yes">Show masked options</property>
202 <property name="label" translatable="yes">Show _debug info</property>
203 <property name="use_underline">True</property>
204 <property name="active">False</property>
205 <signal name="activate" handler="on_show_debug_info1_activate"/>
206 </widget>
207 </child>
208 </widget>
209 </child>
210 </widget>
211 </child>
212
213 <child>
214 <widget class="GtkMenuItem" id="help1">
215 <property name="visible">True</property>
216 <property name="label" translatable="yes">_Help</property>
217 <property name="use_underline">True</property>
218
219 <child>
220 <widget class="GtkMenu" id="help1_menu">
221
222 <child>
223 <widget class="GtkImageMenuItem" id="introduction1">
224 <property name="visible">True</property>
225 <property name="label" translatable="yes">_Introduction</property>
226 <property name="use_underline">True</property>
227 <signal name="activate" handler="on_introduction1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
228 <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/>
229
230 <child internal-child="image">
231 <widget class="GtkImage" id="image31">
232 <property name="visible">True</property>
233 <property name="stock">gtk-dialog-question</property>
234 <property name="icon_size">1</property>
235 <property name="xalign">0.5</property>
236 <property name="yalign">0.5</property>
237 <property name="xpad">0</property>
238 <property name="ypad">0</property>
239 </widget>
240 </child>
241 </widget>
242 </child>
243
244 <child>
245 <widget class="GtkImageMenuItem" id="about1">
246 <property name="visible">True</property>
247 <property name="label" translatable="yes">_About</property>
248 <property name="use_underline">True</property>
249 <signal name="activate" handler="on_about1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
250 <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
251
252 <child internal-child="image">
253 <widget class="GtkImage" id="image32">
254 <property name="visible">True</property>
255 <property name="stock">gtk-properties</property>
256 <property name="icon_size">1</property>
257 <property name="xalign">0.5</property>
258 <property name="yalign">0.5</property>
259 <property name="xpad">0</property>
260 <property name="ypad">0</property>
261 </widget>
262 </child>
263 </widget>
264 </child>
265
266 <child>
267 <widget class="GtkImageMenuItem" id="license1">
268 <property name="visible">True</property>
269 <property name="label" translatable="yes">_License</property>
270 <property name="use_underline">True</property>
271 <signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
272
273 <child internal-child="image">
274 <widget class="GtkImage" id="image33">
275 <property name="visible">True</property>
276 <property name="stock">gtk-justify-fill</property>
277 <property name="icon_size">1</property>
278 <property name="xalign">0.5</property>
279 <property name="yalign">0.5</property>
280 <property name="xpad">0</property>
281 <property name="ypad">0</property>
282 </widget>
283 </child>
284 </widget>
285 </child>
286 </widget>
287 </child>
288 </widget>
289 </child>
290 </widget>
291 <packing>
292 <property name="padding">0</property>
293 <property name="expand">False</property>
294 <property name="fill">False</property>
295 </packing>
296 </child>
297
298 <child>
299 <widget class="GtkHandleBox" id="handlebox1">
300 <property name="visible">True</property>
301 <property name="shadow_type">GTK_SHADOW_OUT</property>
302 <property name="handle_position">GTK_POS_LEFT</property>
303 <property name="snap_edge">GTK_POS_TOP</property>
304
305 <child>
306 <widget class="GtkToolbar" id="toolbar1">
307 <property name="visible">True</property>
308 <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
309 <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
310 <property name="tooltips">True</property>
311
312 <child>
313 <widget class="button" id="button1">
314 <property name="visible">True</property>
315 <property name="tooltip" translatable="yes">Goes up of one level (single view)</property>
316 <property name="label" translatable="yes">Back</property>
317 <property name="use_underline">True</property>
318 <property name="stock_pixmap">gtk-undo</property>
319 <signal name="pressed" handler="on_back_pressed"/>
320 </widget>
321 </child>
322
323 <child>
324 <widget class="GtkVSeparator" id="vseparator1">
325 <property name="visible">True</property>
326 </widget>
327 </child>
328
329 <child>
330 <widget class="button" id="button2">
331 <property name="visible">True</property>
332 <property name="tooltip" translatable="yes">Load a config file</property>
333 <property name="label" translatable="yes">Load</property>
334 <property name="use_underline">True</property>
335 <property name="stock_pixmap">gtk-open</property>
336 <signal name="pressed" handler="on_load_pressed"/>
337 </widget>
338 </child>
339
340 <child>
341 <widget class="button" id="button3">
342 <property name="visible">True</property>
343 <property name="tooltip" translatable="yes">Save a config file</property>
344 <property name="label" translatable="yes">Save</property>
345 <property name="use_underline">True</property>
346 <property name="stock_pixmap">gtk-save</property>
347 <signal name="pressed" handler="on_save_pressed"/>
348 </widget>
349 </child>
350
351 <child>
352 <widget class="GtkVSeparator" id="vseparator2">
353 <property name="visible">True</property>
354 </widget>
355 </child>
356
357 <child>
358 <widget class="button" id="button4">
359 <property name="visible">True</property>
360 <property name="tooltip" translatable="yes">Single view</property>
361 <property name="label" translatable="yes">Single</property>
362 <property name="use_underline">True</property>
363 <property name="stock_pixmap">gtk-missing-image</property>
364 <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/>
365 </widget>
366 </child>
367
368 <child>
369 <widget class="button" id="button5">
370 <property name="visible">True</property>
371 <property name="tooltip" translatable="yes">Split view</property>
372 <property name="label" translatable="yes">Split</property>
373 <property name="use_underline">True</property>
374 <property name="stock_pixmap">gtk-missing-image</property>
375 <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/>
376 </widget>
377 </child>
378
379 <child>
380 <widget class="button" id="button6">
381 <property name="visible">True</property>
382 <property name="tooltip" translatable="yes">Full view</property>
383 <property name="label" translatable="yes">Full</property>
384 <property name="use_underline">True</property>
385 <property name="stock_pixmap">gtk-missing-image</property>
386 <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/>
387 </widget>
388 </child>
389
390 <child>
391 <widget class="GtkVSeparator" id="vseparator3">
392 <property name="visible">True</property>
393 </widget>
394 </child>
395
396 <child>
397 <widget class="button" id="button7">
398 <property name="visible">True</property>
399 <property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property>
400 <property name="label" translatable="yes">Collapse</property>
401 <property name="use_underline">True</property>
402 <signal name="pressed" handler="on_collapse_pressed"/>
403 </widget>
404 </child>
405
406 <child>
407 <widget class="button" id="button8">
408 <property name="visible">True</property>
409 <property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property>
410 <property name="label" translatable="yes">Expand</property>
411 <property name="use_underline">True</property>
412 <signal name="pressed" handler="on_expand_pressed"/>
413 </widget>
414 </child>
415 </widget>
416 </child>
417 </widget>
418 <packing>
419 <property name="padding">0</property>
420 <property name="expand">False</property>
421 <property name="fill">False</property>
422 </packing>
423 </child>
424
425 <child>
426 <widget class="GtkHPaned" id="hpaned1">
427 <property name="width_request">1</property>
428 <property name="visible">True</property>
429 <property name="can_focus">True</property>
430 <property name="position">0</property>
431
432 <child>
433 <widget class="GtkScrolledWindow" id="scrolledwindow1">
434 <property name="visible">True</property>
435 <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
436 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
437 <property name="shadow_type">GTK_SHADOW_IN</property>
438 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
439
440 <child>
441 <widget class="GtkTreeView" id="treeview1">
442 <property name="visible">True</property>
443 <property name="can_focus">True</property>
444 <property name="headers_visible">True</property>
445 <property name="rules_hint">False</property>
446 <property name="reorderable">False</property>
447 <property name="enable_search">True</property>
448 <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:58:22 GMT"/>
449 <signal name="button_press_event" handler="on_treeview1_button_press_event" last_modification_time="Sun, 12 Jan 2003 16:03:52 GMT"/>
450 <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 16:11:44 GMT"/>
451 </widget>
452 </child>
453 </widget>
454 <packing>
455 <property name="shrink">True</property>
456 <property name="resize">False</property>
457 </packing>
458 </child>
459
460 <child>
461 <widget class="GtkVPaned" id="vpaned1">
462 <property name="visible">True</property>
463 <property name="can_focus">True</property>
464 <property name="position">0</property>
465
466 <child>
467 <widget class="GtkScrolledWindow" id="scrolledwindow2">
468 <property name="visible">True</property>
469 <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
470 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
471 <property name="shadow_type">GTK_SHADOW_IN</property>
472 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
473
474 <child>
475 <widget class="GtkTreeView" id="treeview2">
476 <property name="visible">True</property>
477 <property name="can_focus">True</property>
478 <property name="has_focus">True</property>
479 <property name="headers_visible">True</property>
480 <property name="rules_hint">False</property>
481 <property name="reorderable">False</property>
482 <property name="enable_search">True</property>
483 <signal name="cursor_changed" handler="on_treeview2_cursor_changed" last_modification_time="Sun, 12 Jan 2003 15:57:55 GMT"/>
484 <signal name="button_press_event" handler="on_treeview2_button_press_event" last_modification_time="Sun, 12 Jan 2003 15:57:58 GMT"/>
485 <signal name="key_press_event" handler="on_treeview2_key_press_event" last_modification_time="Sun, 12 Jan 2003 15:58:01 GMT"/>
486 </widget>
487 </child>
488 </widget>
489 <packing>
490 <property name="shrink">True</property>
491 <property name="resize">False</property>
492 </packing>
493 </child>
494
495 <child>
496 <widget class="GtkScrolledWindow" id="scrolledwindow3">
497 <property name="visible">True</property>
498 <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
499 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
500 <property name="shadow_type">GTK_SHADOW_IN</property>
501 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
502
503 <child>
504 <widget class="GtkTextView" id="textview3">
505 <property name="visible">True</property>
506 <property name="can_focus">True</property>
507 <property name="editable">False</property>
508 <property name="justification">GTK_JUSTIFY_LEFT</property>
509 <property name="wrap_mode">GTK_WRAP_WORD</property>
510 <property name="cursor_visible">True</property>
511 <property name="pixels_above_lines">0</property>
512 <property name="pixels_below_lines">0</property>
513 <property name="pixels_inside_wrap">0</property>
514 <property name="left_margin">0</property>
515 <property name="right_margin">0</property>
516 <property name="indent">0</property>
517 <property name="text" translatable="yes">Sorry, no help available for this option yet.</property>
518 </widget>
519 </child>
520 </widget>
521 <packing>
522 <property name="shrink">True</property>
523 <property name="resize">True</property>
524 </packing>
525 </child>
526 </widget>
527 <packing>
528 <property name="shrink">True</property>
529 <property name="resize">True</property>
530 </packing>
531 </child>
532 </widget>
533 <packing>
534 <property name="padding">0</property>
535 <property name="expand">True</property>
536 <property name="fill">True</property>
537 </packing>
538 </child>
539 </widget>
540 </child>
541</widget>
542
543</glade-interface>
diff --git a/scripts/kconfig/images.c b/scripts/kconfig/images.c
index 65a5d67..d4f84bd 100644
--- a/scripts/kconfig/images.c
+++ b/scripts/kconfig/images.c
@@ -1,292 +1,326 @@
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
6static const char *xpm_load[] = { 6static const char *xpm_load[] = {
7"22 22 5 1", 7"22 22 5 1",
8". c None", 8". c None",
9"# c #000000", 9"# c #000000",
10"c c #838100", 10"c c #838100",
11"a c #ffff00", 11"a c #ffff00",
12"b c #ffffff", 12"b c #ffffff",
13"......................", 13"......................",
14"......................", 14"......................",
15"......................", 15"......................",
16"............####....#.", 16"............####....#.",
17"...........#....##.##.", 17"...........#....##.##.",
18"..................###.", 18"..................###.",
19".................####.", 19".................####.",
20".####...........#####.", 20".####...........#####.",
21"#abab##########.......", 21"#abab##########.......",
22"#babababababab#.......", 22"#babababababab#.......",
23"#ababababababa#.......", 23"#ababababababa#.......",
24"#babababababab#.......", 24"#babababababab#.......",
25"#ababab###############", 25"#ababab###############",
26"#babab##cccccccccccc##", 26"#babab##cccccccccccc##",
27"#abab##cccccccccccc##.", 27"#abab##cccccccccccc##.",
28"#bab##cccccccccccc##..", 28"#bab##cccccccccccc##..",
29"#ab##cccccccccccc##...", 29"#ab##cccccccccccc##...",
30"#b##cccccccccccc##....", 30"#b##cccccccccccc##....",
31"###cccccccccccc##.....", 31"###cccccccccccc##.....",
32"##cccccccccccc##......", 32"##cccccccccccc##......",
33"###############.......", 33"###############.......",
34"......................"}; 34"......................"};
35 35
36static const char *xpm_save[] = { 36static const char *xpm_save[] = {
37"22 22 5 1", 37"22 22 5 1",
38". c None", 38". c None",
39"# c #000000", 39"# c #000000",
40"a c #838100", 40"a c #838100",
41"b c #c5c2c5", 41"b c #c5c2c5",
42"c c #cdb6d5", 42"c c #cdb6d5",
43"......................", 43"......................",
44".####################.", 44".####################.",
45".#aa#bbbbbbbbbbbb#bb#.", 45".#aa#bbbbbbbbbbbb#bb#.",
46".#aa#bbbbbbbbbbbb#bb#.", 46".#aa#bbbbbbbbbbbb#bb#.",
47".#aa#bbbbbbbbbcbb####.", 47".#aa#bbbbbbbbbcbb####.",
48".#aa#bbbccbbbbbbb#aa#.", 48".#aa#bbbccbbbbbbb#aa#.",
49".#aa#bbbccbbbbbbb#aa#.", 49".#aa#bbbccbbbbbbb#aa#.",
50".#aa#bbbbbbbbbbbb#aa#.", 50".#aa#bbbbbbbbbbbb#aa#.",
51".#aa#bbbbbbbbbbbb#aa#.", 51".#aa#bbbbbbbbbbbb#aa#.",
52".#aa#bbbbbbbbbbbb#aa#.", 52".#aa#bbbbbbbbbbbb#aa#.",
53".#aa#bbbbbbbbbbbb#aa#.", 53".#aa#bbbbbbbbbbbb#aa#.",
54".#aaa############aaa#.", 54".#aaa############aaa#.",
55".#aaaaaaaaaaaaaaaaaa#.", 55".#aaaaaaaaaaaaaaaaaa#.",
56".#aaaaaaaaaaaaaaaaaa#.", 56".#aaaaaaaaaaaaaaaaaa#.",
57".#aaa#############aa#.", 57".#aaa#############aa#.",
58".#aaa#########bbb#aa#.", 58".#aaa#########bbb#aa#.",
59".#aaa#########bbb#aa#.", 59".#aaa#########bbb#aa#.",
60".#aaa#########bbb#aa#.", 60".#aaa#########bbb#aa#.",
61".#aaa#########bbb#aa#.", 61".#aaa#########bbb#aa#.",
62".#aaa#########bbb#aa#.", 62".#aaa#########bbb#aa#.",
63"..##################..", 63"..##################..",
64"......................"}; 64"......................"};
65 65
66static const char *xpm_back[] = { 66static const char *xpm_back[] = {
67"22 22 3 1", 67"22 22 3 1",
68". c None", 68". c None",
69"# c #000083", 69"# c #000083",
70"a c #838183", 70"a c #838183",
71"......................", 71"......................",
72"......................", 72"......................",
73"......................", 73"......................",
74"......................", 74"......................",
75"......................", 75"......................",
76"...........######a....", 76"...........######a....",
77"..#......##########...", 77"..#......##########...",
78"..##...####......##a..", 78"..##...####......##a..",
79"..###.###.........##..", 79"..###.###.........##..",
80"..######..........##..", 80"..######..........##..",
81"..#####...........##..", 81"..#####...........##..",
82"..######..........##..", 82"..######..........##..",
83"..#######.........##..", 83"..#######.........##..",
84"..########.......##a..", 84"..########.......##a..",
85"...............a###...", 85"...............a###...",
86"...............###....", 86"...............###....",
87"......................", 87"......................",
88"......................", 88"......................",
89"......................", 89"......................",
90"......................", 90"......................",
91"......................", 91"......................",
92"......................"}; 92"......................"};
93 93
94static const char *xpm_tree_view[] = { 94static const char *xpm_tree_view[] = {
95"22 22 2 1", 95"22 22 2 1",
96". c None", 96". c None",
97"# c #000000", 97"# c #000000",
98"......................", 98"......................",
99"......................", 99"......................",
100"......#...............", 100"......#...............",
101"......#...............", 101"......#...............",
102"......#...............", 102"......#...............",
103"......#...............", 103"......#...............",
104"......#...............", 104"......#...............",
105"......########........", 105"......########........",
106"......#...............", 106"......#...............",
107"......#...............", 107"......#...............",
108"......#...............", 108"......#...............",
109"......#...............", 109"......#...............",
110"......#...............", 110"......#...............",
111"......########........", 111"......########........",
112"......#...............", 112"......#...............",
113"......#...............", 113"......#...............",
114"......#...............", 114"......#...............",
115"......#...............", 115"......#...............",
116"......#...............", 116"......#...............",
117"......########........", 117"......########........",
118"......................", 118"......................",
119"......................"}; 119"......................"};
120 120
121static const char *xpm_single_view[] = { 121static const char *xpm_single_view[] = {
122"22 22 2 1", 122"22 22 2 1",
123". c None", 123". c None",
124"# c #000000", 124"# c #000000",
125"......................", 125"......................",
126"......................", 126"......................",
127"..........#...........", 127"..........#...........",
128"..........#...........", 128"..........#...........",
129"..........#...........", 129"..........#...........",
130"..........#...........", 130"..........#...........",
131"..........#...........", 131"..........#...........",
132"..........#...........", 132"..........#...........",
133"..........#...........", 133"..........#...........",
134"..........#...........", 134"..........#...........",
135"..........#...........", 135"..........#...........",
136"..........#...........", 136"..........#...........",
137"..........#...........", 137"..........#...........",
138"..........#...........", 138"..........#...........",
139"..........#...........", 139"..........#...........",
140"..........#...........", 140"..........#...........",
141"..........#...........", 141"..........#...........",
142"..........#...........", 142"..........#...........",
143"..........#...........", 143"..........#...........",
144"..........#...........", 144"..........#...........",
145"......................", 145"......................",
146"......................"}; 146"......................"};
147 147
148static const char *xpm_split_view[] = { 148static const char *xpm_split_view[] = {
149"22 22 2 1", 149"22 22 2 1",
150". c None", 150". c None",
151"# c #000000", 151"# c #000000",
152"......................", 152"......................",
153"......................", 153"......................",
154"......#......#........", 154"......#......#........",
155"......#......#........", 155"......#......#........",
156"......#......#........", 156"......#......#........",
157"......#......#........", 157"......#......#........",
158"......#......#........", 158"......#......#........",
159"......#......#........", 159"......#......#........",
160"......#......#........", 160"......#......#........",
161"......#......#........", 161"......#......#........",
162"......#......#........", 162"......#......#........",
163"......#......#........", 163"......#......#........",
164"......#......#........", 164"......#......#........",
165"......#......#........", 165"......#......#........",
166"......#......#........", 166"......#......#........",
167"......#......#........", 167"......#......#........",
168"......#......#........", 168"......#......#........",
169"......#......#........", 169"......#......#........",
170"......#......#........", 170"......#......#........",
171"......#......#........", 171"......#......#........",
172"......................", 172"......................",
173"......................"}; 173"......................"};
174 174
175static const char *xpm_symbol_no[] = { 175static const char *xpm_symbol_no[] = {
176"12 12 2 1", 176"12 12 2 1",
177" c white", 177" c white",
178". c black", 178". c black",
179" ", 179" ",
180" .......... ", 180" .......... ",
181" . . ", 181" . . ",
182" . . ", 182" . . ",
183" . . ", 183" . . ",
184" . . ", 184" . . ",
185" . . ", 185" . . ",
186" . . ", 186" . . ",
187" . . ", 187" . . ",
188" . . ", 188" . . ",
189" .......... ", 189" .......... ",
190" "}; 190" "};
191 191
192static const char *xpm_symbol_mod[] = { 192static const char *xpm_symbol_mod[] = {
193"12 12 2 1", 193"12 12 2 1",
194" c white", 194" c white",
195". c black", 195". c black",
196" ", 196" ",
197" .......... ", 197" .......... ",
198" . . ", 198" . . ",
199" . . ", 199" . . ",
200" . .. . ", 200" . .. . ",
201" . .... . ", 201" . .... . ",
202" . .... . ", 202" . .... . ",
203" . .. . ", 203" . .. . ",
204" . . ", 204" . . ",
205" . . ", 205" . . ",
206" .......... ", 206" .......... ",
207" "}; 207" "};
208 208
209static const char *xpm_symbol_yes[] = { 209static const char *xpm_symbol_yes[] = {
210"12 12 2 1", 210"12 12 2 1",
211" c white", 211" c white",
212". c black", 212". c black",
213" ", 213" ",
214" .......... ", 214" .......... ",
215" . . ", 215" . . ",
216" . . ", 216" . . ",
217" . . . ", 217" . . . ",
218" . .. . ", 218" . .. . ",
219" . . .. . ", 219" . . .. . ",
220" . .... . ", 220" . .... . ",
221" . .. . ", 221" . .. . ",
222" . . ", 222" . . ",
223" .......... ", 223" .......... ",
224" "}; 224" "};
225 225
226static const char *xpm_choice_no[] = { 226static const char *xpm_choice_no[] = {
227"12 12 2 1", 227"12 12 2 1",
228" c white", 228" c white",
229". c black", 229". c black",
230" ", 230" ",
231" .... ", 231" .... ",
232" .. .. ", 232" .. .. ",
233" . . ", 233" . . ",
234" . . ", 234" . . ",
235" . . ", 235" . . ",
236" . . ", 236" . . ",
237" . . ", 237" . . ",
238" . . ", 238" . . ",
239" .. .. ", 239" .. .. ",
240" .... ", 240" .... ",
241" "}; 241" "};
242 242
243static const char *xpm_choice_yes[] = { 243static const char *xpm_choice_yes[] = {
244"12 12 2 1", 244"12 12 2 1",
245" c white", 245" c white",
246". c black", 246". c black",
247" ", 247" ",
248" .... ", 248" .... ",
249" .. .. ", 249" .. .. ",
250" . . ", 250" . . ",
251" . .. . ", 251" . .. . ",
252" . .... . ", 252" . .... . ",
253" . .... . ", 253" . .... . ",
254" . .. . ", 254" . .. . ",
255" . . ", 255" . . ",
256" .. .. ", 256" .. .. ",
257" .... ", 257" .... ",
258" "}; 258" "};
259 259
260static const char *xpm_menu[] = { 260static const char *xpm_menu[] = {
261"12 12 2 1", 261"12 12 2 1",
262" c white", 262" c white",
263". c black", 263". c black",
264" ", 264" ",
265" .......... ", 265" .......... ",
266" . . ", 266" . . ",
267" . .. . ", 267" . .. . ",
268" . .... . ", 268" . .... . ",
269" . ...... . ", 269" . ...... . ",
270" . ...... . ", 270" . ...... . ",
271" . .... . ", 271" . .... . ",
272" . .. . ", 272" . .. . ",
273" . . ", 273" . . ",
274" .......... ", 274" .......... ",
275" "}; 275" "};
276 276
277static const char *xpm_menu_inv[] = { 277static const char *xpm_menu_inv[] = {
278"12 12 2 1", 278"12 12 2 1",
279" c white", 279" c white",
280". c black", 280". c black",
281" ", 281" ",
282" .......... ", 282" .......... ",
283" .......... ", 283" .......... ",
284" .. ...... ", 284" .. ...... ",
285" .. .... ", 285" .. .... ",
286" .. .. ", 286" .. .. ",
287" .. .. ", 287" .. .. ",
288" .. .... ", 288" .. .... ",
289" .. ...... ", 289" .. ...... ",
290" .......... ", 290" .......... ",
291" .......... ", 291" .......... ",
292" "}; 292" "};
293
294static const char *xpm_menuback[] = {
295"12 12 2 1",
296" c white",
297". c black",
298" ",
299" .......... ",
300" . . ",
301" . .. . ",
302" . .... . ",
303" . ...... . ",
304" . ...... . ",
305" . .... . ",
306" . .. . ",
307" . . ",
308" .......... ",
309" "};
310
311static const char *xpm_void[] = {
312"12 12 2 1",
313" c white",
314". c black",
315" ",
316" ",
317" ",
318" ",
319" ",
320" ",
321" ",
322" ",
323" ",
324" ",
325" ",
326" "};
diff --git a/scripts/kconfig/lkc-language.txt b/scripts/kconfig/lkc-language.txt
index a3037ff..40f8583 100644
--- a/scripts/kconfig/lkc-language.txt
+++ b/scripts/kconfig/lkc-language.txt
@@ -1,255 +1,279 @@
1Introduction 1Introduction
2------------ 2------------
3 3
4The configuration database is collection of configuration options 4The configuration database is collection of configuration options
5organized in a tree structure: 5organized in a tree structure:
6 6
7 +- Code maturity level options 7 +- Code maturity level options
8 | +- Prompt for development and/or incomplete code/drivers 8 | +- Prompt for development and/or incomplete code/drivers
9 +- General setup 9 +- General setup
10 | +- Networking support 10 | +- Networking support
11 | +- System V IPC 11 | +- System V IPC
12 | +- BSD Process Accounting 12 | +- BSD Process Accounting
13 | +- Sysctl support 13 | +- Sysctl support
14 +- Loadable module support 14 +- Loadable module support
15 | +- Enable loadable module support 15 | +- Enable loadable module support
16 | +- Set version information on all module symbols 16 | +- Set version information on all module symbols
17 | +- Kernel module loader 17 | +- Kernel module loader
18 +- ... 18 +- ...
19 19
20Every entry has its own dependencies. These dependencies are used 20Every entry has its own dependencies. These dependencies are used
21to determine the visible of an entry. Any child entry is only 21to determine the visibility of an entry. Any child entry is only
22visible if its parent entry is also visible. 22visible if its parent entry is also visible.
23 23
24Menu entries 24Menu entries
25------------ 25------------
26 26
27Most entries define a config option, all other entries help to organize 27Most entries define a config option, all other entries help to organize
28them. A single configuration option is defined like this: 28them. A single configuration option is defined like this:
29 29
30config MODVERSIONS 30config MODVERSIONS
31 bool "Set version information on all module symbols" 31 bool "Set version information on all module symbols"
32 depends MODULES 32 depends MODULES
33 help 33 help
34 Usually, modules have to be recompiled whenever you switch to a new 34 Usually, modules have to be recompiled whenever you switch to a new
35 kernel. ... 35 kernel. ...
36 36
37Every line starts with a key word and can be followed by multiple 37Every line starts with a key word and can be followed by multiple
38arguments. "config" starts a new config entry. The following lines 38arguments. "config" starts a new config entry. The following lines
39define attributes for this config option. Attributes can be the type of 39define attributes for this config option. Attributes can be the type of
40the config option, input prompt, dependencies, help text and default 40the config option, input prompt, dependencies, help text and default
41values. A config option can be defined multiple times with the same 41values. A config option can be defined multiple times with the same
42name, but every definition can have only a single input prompt and the 42name, but every definition can have only a single input prompt and the
43type must not conflict. 43type must not conflict.
44 44
45Menu attributes 45Menu attributes
46--------------- 46---------------
47 47
48A menu entry can have a number of attributes. Not all of them are 48A menu entry can have a number of attributes. Not all of them are
49applicable everywhere (see syntax). 49applicable everywhere (see syntax).
50 50
51- type definition: "bool"/"tristate"/"string"/"hex"/"integer" 51- type definition: "bool"/"tristate"/"string"/"hex"/"integer"
52 Every config option must have a type. There are only two basic types: 52 Every config option must have a type. There are only two basic types:
53 tristate and string, the other types base on these two. The type 53 tristate and string, the other types are based on these two. The type
54 definition optionally accepts an input prompt, so these two examples 54 definition optionally accepts an input prompt, so these two examples
55 are equivalent: 55 are equivalent:
56 56
57 bool "Networking support" 57 bool "Networking support"
58 and 58 and
59 bool 59 bool
60 prompt "Networking support" 60 prompt "Networking support"
61 61
62- input prompt: "prompt" <prompt> ["if" <expr>] 62- input prompt: "prompt" <prompt> ["if" <expr>]
63 Every menu entry can have at most one prompt, which is used to display 63 Every menu entry can have at most one prompt, which is used to display
64 to the user. Optionally dependencies only for this prompt can be added 64 to the user. Optionally dependencies only for this prompt can be added
65 with "if". 65 with "if".
66 66
67- default value: "default" <symbol> ["if" <expr>] 67- default value: "default" <expr> ["if" <expr>]
68 A config option can have any number of default values. If multiple 68 A config option can have any number of default values. If multiple
69 default values are visible, only the first defined one is active. 69 default values are visible, only the first defined one is active.
70 Default values are not limited to the menu entry, where they are 70 Default values are not limited to the menu entry, where they are
71 defined, this means the default can be defined somewhere else or be 71 defined, this means the default can be defined somewhere else or be
72 overriden by an earlier definition. 72 overridden by an earlier definition.
73 The default value is only assigned to the config symbol if no other 73 The default value is only assigned to the config symbol if no other
74 value was set by the user (via the input prompt above). If an input 74 value was set by the user (via the input prompt above). If an input
75 prompt is visible the default value is presented to the user and can 75 prompt is visible the default value is presented to the user and can
76 be overridden by him. 76 be overridden by him.
77 Optionally dependencies only for this default value can be added with 77 Optionally dependencies only for this default value can be added with
78 "if". 78 "if".
79 79
80- dependencies: "depends on"/"requires" <expr> 80- dependencies: "depends on"/"requires" <expr>
81 This defines a dependency for this menu entry. If multiple 81 This defines a dependency for this menu entry. If multiple
82 dependencies are defined they are connected with '&&'. Dependencies 82 dependencies are defined they are connected with '&&'. Dependencies
83 are applied to all other options within this menu entry (which also 83 are applied to all other options within this menu entry (which also
84 accept "if" expression), so these two examples are equivalent: 84 accept an "if" expression), so these two examples are equivalent:
85 85
86 bool "foo" if BAR 86 bool "foo" if BAR
87 default y if BAR 87 default y if BAR
88 and 88 and
89 depends on BAR 89 depends on BAR
90 bool "foo" 90 bool "foo"
91 default y 91 default y
92 92
93- reverse dependencies: "select" <symbol> ["if" <expr>]
94 While normal dependencies reduce the upper limit of a symbol (see
95 below), reverse dependencies can be used to force a lower limit of
96 another symbol. The value of the current menu symbol is used as the
97 minimal value <symbol> can be set to. If <symbol> is selected multiple
98 times, the limit is set to the largest selection.
99 Reverse dependencies can only be used with boolean or tristate
100 symbols.
101
102- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
103 This allows to limit the range of possible input values for integer
104 and hex symbols. The user can only input a value which is larger than
105 or equal to the first symbol and smaller than or equal to the second
106 symbol.
107
93- help text: "help" 108- help text: "help"
94 This defines a help text. The end of the help text is determined by 109 This defines a help text. The end of the help text is determined by
95 the level indentation, this means it ends at the first line which has 110 the indentation level, this means it ends at the first line which has
96 a smaller indentation than the first line of the help text. 111 a smaller indentation than the first line of the help text.
97 112
98 113
99Menu dependencies 114Menu dependencies
100----------------- 115-----------------
101 116
102Dependencies define the visibility of a menu entry and can also reduce 117Dependencies define the visibility of a menu entry and can also reduce
103the input range of tristate symbols. The tristate logic used in the 118the input range of tristate symbols. The tristate logic used in the
104expressions uses one more state than normal boolean logic to express the 119expressions uses one more state than normal boolean logic to express the
105module state. Dependency expressions have the following syntax: 120module state. Dependency expressions have the following syntax:
106 121
107<expr> ::= <symbol> (1) 122<expr> ::= <symbol> (1)
108 <symbol> '=' <symbol> (2) 123 <symbol> '=' <symbol> (2)
109 <symbol> '!=' <symbol> (3) 124 <symbol> '!=' <symbol> (3)
110 '(' <expr> ')' (4) 125 '(' <expr> ')' (4)
111 '!' <expr> (5) 126 '!' <expr> (5)
112 <expr> '||' <expr> (6) 127 <expr> '||' <expr> (6)
113 <expr> '&&' <expr> (7) 128 <expr> '&&' <expr> (7)
114 129
115Expressions are listed in decreasing order of precedence. 130Expressions are listed in decreasing order of precedence.
116 131
117(1) Convert the symbol into an expression. Boolean and tristate symbols 132(1) Convert the symbol into an expression. Boolean and tristate symbols
118 are simply converted into the respective expression values. All 133 are simply converted into the respective expression values. All
119 other symbol types result in 'n'. 134 other symbol types result in 'n'.
120(2) If the values of both symbols are equal, it returns 'y', 135(2) If the values of both symbols are equal, it returns 'y',
121 otherwise 'n'. 136 otherwise 'n'.
122(3) If the values of both symbols are equal, it returns 'n', 137(3) If the values of both symbols are equal, it returns 'n',
123 otherwise 'y'. 138 otherwise 'y'.
124(4) Returns the value of the expression. Used to override precedence. 139(4) Returns the value of the expression. Used to override precedence.
125(5) Returns the result of (2-/expr/). 140(5) Returns the result of (2-/expr/).
126(6) Returns the result of min(/expr/, /expr/). 141(6) Returns the result of max(/expr/, /expr/).
127(7) Returns the result of max(/expr/, /expr/). 142(7) Returns the result of min(/expr/, /expr/).
128 143
129An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 144An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
130respectively for calculations). A menu entry becomes visible when it's 145respectively for calculations). A menu entry becomes visible when it's
131expression evaluates to 'm' or 'y'. 146expression evaluates to 'm' or 'y'.
132 147
133There are two type of symbols: constant and nonconstant symbols. 148There are two types of symbols: constant and nonconstant symbols.
134Nonconstant symbols are the most common ones and are defined with the 149Nonconstant symbols are the most common ones and are defined with the
135'config' statement. Nonconstant symbols consist entirely of alphanumeric 150'config' statement. Nonconstant symbols consist entirely of alphanumeric
136characters or underscores. 151characters or underscores.
137Constant symbols are only part of expressions. Constant symbols are 152Constant symbols are only part of expressions. Constant symbols are
138always surrounded by single or double quotes. Within the quote any 153always surrounded by single or double quotes. Within the quote any
139other character is allowed and the quotes can be escaped using '\'. 154other character is allowed and the quotes can be escaped using '\'.
140 155
141Menu structure 156Menu structure
142-------------- 157--------------
143 158
144The position of a menu entry in the tree is determined in two ways. First 159The position of a menu entry in the tree is determined in two ways. First
145it can be specified explicitely: 160it can be specified explicitly:
146 161
147menu "Network device support" 162menu "Network device support"
148 depends NET 163 depends NET
149 164
150config NETDEVICES 165config NETDEVICES
151 ... 166 ...
152 167
153endmenu 168endmenu
154 169
155All entries within the "menu" ... "endmenu" block become a submenu of 170All entries within the "menu" ... "endmenu" block become a submenu of
156"Network device support". All subentries inherit the dependencies from 171"Network device support". All subentries inherit the dependencies from
157the menu entry, e.g. this means the dependency "NET" is added to the 172the menu entry, e.g. this means the dependency "NET" is added to the
158dependency list of the config option NETDEVICES. 173dependency list of the config option NETDEVICES.
159 174
160The other way to generate the menu structure is done by analyzing the 175The other way to generate the menu structure is done by analyzing the
161dependencies. If a menu entry somehow depends on the previous entry, it 176dependencies. If a menu entry somehow depends on the previous entry, it
162can be made a submenu of it. First the the previous (parent) symbol must 177can be made a submenu of it. First, the previous (parent) symbol must
163be part of the dependency list and then one of these two condititions 178be part of the dependency list and then one of these two conditions
164must be true: 179must be true:
165- the child entry must become invisible, if the parent is set to 'n' 180- the child entry must become invisible, if the parent is set to 'n'
166- the child entry must only be visible, if the parent is visible 181- the child entry must only be visible, if the parent is visible
167 182
168config MODULES 183config MODULES
169 bool "Enable loadable module support" 184 bool "Enable loadable module support"
170 185
171config MODVERSIONS 186config MODVERSIONS
172 bool "Set version information on all module symbols" 187 bool "Set version information on all module symbols"
173 depends MODULES 188 depends MODULES
174 189
175comment "module support disabled" 190comment "module support disabled"
176 depends !MODULES 191 depends !MODULES
177 192
178MODVERSIONS directly depends on MODULES, this means it's only visible if 193MODVERSIONS directly depends on MODULES, this means it's only visible if
179MODULES is different from 'n'. The comment on the other hand is always 194MODULES is different from 'n'. The comment on the other hand is always
180visible when MODULES it's visible (the (empty) dependency of MODULES is 195visible when MODULES is visible (the (empty) dependency of MODULES is
181also part of the comment dependencies). 196also part of the comment dependencies).
182 197
183 198
184Kconfig syntax 199Kconfig syntax
185-------------- 200--------------
186 201
187The configuration file describes a series of menu entries, where every 202The configuration file describes a series of menu entries, where every
188line starts with a keyword (except help texts). The following keywords 203line starts with a keyword (except help texts). The following keywords
189end a menu entry: 204end a menu entry:
190- config 205- config
206- menuconfig
191- choice/endchoice 207- choice/endchoice
192- comment 208- comment
193- menu/endmenu 209- menu/endmenu
194- if/endif 210- if/endif
195- source 211- source
196The first four also start the definition of a menu entry. 212The first five also start the definition of a menu entry.
197 213
198config: 214config:
199 215
200 "config" <symbol> 216 "config" <symbol>
201 <config options> 217 <config options>
202 218
203This defines a config symbol <symbol> and accepts any of above 219This defines a config symbol <symbol> and accepts any of above
204attributes as options. 220attributes as options.
205 221
222menuconfig:
223 "menuconfig" <symbol>
224 <config options>
225
226This is similiar to the simple config entry above, but it also gives a
227hint to front ends, that all suboptions should be displayed as a
228separate list of options.
229
206choices: 230choices:
207 231
208 "choice" 232 "choice"
209 <choice options> 233 <choice options>
210 <choice block> 234 <choice block>
211 "endchoice" 235 "endchoice"
212 236
213This defines a choice group and accepts any of above attributes as 237This defines a choice group and accepts any of above attributes as
214options. A choice can only be of type bool or tristate, while a boolean 238options. A choice can only be of type bool or tristate, while a boolean
215choice only allows a single config entry to be selected, a tristate 239choice only allows a single config entry to be selected, a tristate
216choice also allows any number of config entries to be set to 'm'. This 240choice also allows any number of config entries to be set to 'm'. This
217can be used if multiple drivers for a single hardware exists and only a 241can be used if multiple drivers for a single hardware exists and only a
218single driver can be compiled/loaded into the kernel, but all drivers 242single driver can be compiled/loaded into the kernel, but all drivers
219can be compiled as modules. 243can be compiled as modules.
220A choice accepts another option "optional", which allows to set the 244A choice accepts another option "optional", which allows to set the
221choice to 'n' and no entry needs to be selected. 245choice to 'n' and no entry needs to be selected.
222 246
223comment: 247comment:
224 248
225 "comment" <prompt> 249 "comment" <prompt>
226 <comment options> 250 <comment options>
227 251
228This defines a comment which is displayed to the user during the 252This defines a comment which is displayed to the user during the
229configuration process and is also echoed to the output files. The only 253configuration process and is also echoed to the output files. The only
230possible options are dependencies. 254possible options are dependencies.
231 255
232menu: 256menu:
233 257
234 "menu" <prompt> 258 "menu" <prompt>
235 <menu options> 259 <menu options>
236 <menu block> 260 <menu block>
237 "endmenu" 261 "endmenu"
238 262
239This defines a menu block, see "Menu structure" above for more 263This defines a menu block, see "Menu structure" above for more
240information. The only possible options are dependencies. 264information. The only possible options are dependencies.
241 265
242if: 266if:
243 267
244 "if" <expr> 268 "if" <expr>
245 <if block> 269 <if block>
246 "endif" 270 "endif"
247 271
248This defines an if block. The dependency expression <expr> is appended 272This defines an if block. The dependency expression <expr> is appended
249to all enclosed menu entries. 273to all enclosed menu entries.
250 274
251source: 275source:
252 276
253 "source" <prompt> 277 "source" <prompt>
254 278
255This reads the specified configuration file. This file is always parsed. 279This reads the specified configuration file. This file is always parsed.
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index cdd04a9..dd040f7 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -1,109 +1,113 @@
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
24#define SRCTREE "srctree" 24#define SRCTREE "srctree"
25 25
26int zconfparse(void); 26int zconfparse(void);
27void zconfdump(FILE *out); 27void zconfdump(FILE *out);
28 28
29extern int zconfdebug; 29extern int zconfdebug;
30void zconf_starthelp(void); 30void zconf_starthelp(void);
31FILE *zconf_fopen(const char *name); 31FILE *zconf_fopen(const char *name);
32void zconf_initscan(const char *name); 32void zconf_initscan(const char *name);
33void zconf_nextfile(const char *name); 33void zconf_nextfile(const char *name);
34int zconf_lineno(void); 34int zconf_lineno(void);
35char *zconf_curname(void); 35char *zconf_curname(void);
36 36
37/* confdata.c */ 37/* confdata.c */
38extern const char conf_def_filename[]; 38extern const char conf_def_filename[];
39extern char conf_filename[]; 39extern char conf_filename[];
40 40
41char *conf_get_default_confname(void); 41char *conf_get_default_confname(void);
42 42
43/* kconfig_load.c */ 43/* kconfig_load.c */
44void kconfig_load(void); 44void kconfig_load(void);
45 45
46/* menu.c */ 46/* menu.c */
47void menu_init(void); 47void menu_init(void);
48void menu_add_menu(void); 48void menu_add_menu(void);
49void menu_end_menu(void); 49void menu_end_menu(void);
50void menu_add_entry(struct symbol *sym); 50void menu_add_entry(struct symbol *sym);
51void menu_end_entry(void); 51void menu_end_entry(void);
52struct property *create_prop(enum prop_type type);
53void menu_add_dep(struct expr *dep); 52void menu_add_dep(struct expr *dep);
54struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep); 53struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
54void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
55void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
56void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
55void menu_finalize(struct menu *parent); 57void menu_finalize(struct menu *parent);
56void menu_set_type(int type); 58void menu_set_type(int type);
57struct file *file_lookup(const char *name); 59struct file *file_lookup(const char *name);
58int file_write_dep(const char *name); 60int file_write_dep(const char *name);
59 61
60extern struct menu *current_entry; 62extern struct menu *current_entry;
61extern struct menu *current_menu; 63extern struct menu *current_menu;
62 64
63/* symbol.c */ 65/* symbol.c */
64void sym_init(void); 66void sym_init(void);
65void sym_clear_all_valid(void); 67void sym_clear_all_valid(void);
66void sym_set_changed(struct symbol *sym); 68void sym_set_changed(struct symbol *sym);
69struct symbol *sym_check_deps(struct symbol *sym);
70struct property *prop_alloc(enum prop_type type, struct symbol *sym);
71struct symbol *prop_get_symbol(struct property *prop);
67 72
68static inline tristate sym_get_tristate_value(struct symbol *sym) 73static inline tristate sym_get_tristate_value(struct symbol *sym)
69{ 74{
70 return S_TRI(sym->curr); 75 return sym->curr.tri;
71} 76}
72 77
73 78
74static inline struct symbol *sym_get_choice_value(struct symbol *sym) 79static inline struct symbol *sym_get_choice_value(struct symbol *sym)
75{ 80{
76 return (struct symbol *)S_VAL(sym->curr); 81 return (struct symbol *)sym->curr.val;
77} 82}
78 83
79static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) 84static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
80{ 85{
81 return sym_set_tristate_value(chval, yes); 86 return sym_set_tristate_value(chval, yes);
82} 87}
83 88
84static inline bool sym_is_choice(struct symbol *sym) 89static inline bool sym_is_choice(struct symbol *sym)
85{ 90{
86 return sym->flags & SYMBOL_CHOICE ? true : false; 91 return sym->flags & SYMBOL_CHOICE ? true : false;
87} 92}
88 93
89static inline bool sym_is_choice_value(struct symbol *sym) 94static inline bool sym_is_choice_value(struct symbol *sym)
90{ 95{
91 return sym->flags & SYMBOL_CHOICEVAL ? true : false; 96 return sym->flags & SYMBOL_CHOICEVAL ? true : false;
92} 97}
93 98
94static inline bool sym_is_optional(struct symbol *sym) 99static inline bool sym_is_optional(struct symbol *sym)
95{ 100{
96 return sym->flags & SYMBOL_OPTIONAL ? true : false; 101 return sym->flags & SYMBOL_OPTIONAL ? true : false;
97} 102}
98 103
99static inline bool sym_has_value(struct symbol *sym) 104static inline bool sym_has_value(struct symbol *sym)
100{ 105{
101 //return S_VAL(sym->def) != NULL;
102 return sym->flags & SYMBOL_NEW ? false : true; 106 return sym->flags & SYMBOL_NEW ? false : true;
103} 107}
104 108
105#ifdef __cplusplus 109#ifdef __cplusplus
106} 110}
107#endif 111#endif
108 112
109#endif /* LKC_H */ 113#endif /* LKC_H */
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 116d759..97c7917 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -1,38 +1,39 @@
1 1
2/* confdata.c */ 2/* confdata.c */
3P(conf_parse,void,(const char *name)); 3P(conf_parse,void,(const char *name));
4P(conf_read,int,(const char *name)); 4P(conf_read,int,(const char *name));
5P(conf_write,int,(const char *name)); 5P(conf_write,int,(const char *name));
6 6
7/* menu.c */ 7/* menu.c */
8P(rootmenu,struct menu,); 8P(rootmenu,struct menu,);
9 9
10P(menu_is_visible,bool,(struct menu *menu)); 10P(menu_is_visible,bool,(struct menu *menu));
11P(menu_get_prompt,const char *,(struct menu *menu)); 11P(menu_get_prompt,const char *,(struct menu *menu));
12P(menu_get_root_menu,struct menu *,(struct menu *menu)); 12P(menu_get_root_menu,struct menu *,(struct menu *menu));
13P(menu_get_parent_menu,struct menu *,(struct menu *menu)); 13P(menu_get_parent_menu,struct menu *,(struct menu *menu));
14 14
15/* symbol.c */ 15/* symbol.c */
16P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); 16P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
17P(sym_change_count,int,); 17P(sym_change_count,int,);
18 18
19P(sym_lookup,struct symbol *,(const char *name, int isconst)); 19P(sym_lookup,struct symbol *,(const char *name, int isconst));
20P(sym_find,struct symbol *,(const char *name)); 20P(sym_find,struct symbol *,(const char *name));
21P(sym_type_name,const char *,(int type)); 21P(sym_type_name,const char *,(enum symbol_type type));
22P(sym_calc_value,void,(struct symbol *sym)); 22P(sym_calc_value,void,(struct symbol *sym));
23P(sym_get_type,int,(struct symbol *sym)); 23P(sym_get_type,enum symbol_type,(struct symbol *sym));
24P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); 24P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
25P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); 25P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
26P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); 26P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
27P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); 27P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
28P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
28P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); 29P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
29P(sym_is_changable,bool,(struct symbol *sym)); 30P(sym_is_changable,bool,(struct symbol *sym));
30P(sym_get_choice_prop,struct property *,(struct symbol *sym)); 31P(sym_get_choice_prop,struct property *,(struct symbol *sym));
31P(sym_get_default_prop,struct property *,(struct symbol *sym)); 32P(sym_get_default_prop,struct property *,(struct symbol *sym));
32P(sym_get_string_value,const char *,(struct symbol *sym)); 33P(sym_get_string_value,const char *,(struct symbol *sym));
33 34
34P(prop_get_type_name,const char *,(enum prop_type type)); 35P(prop_get_type_name,const char *,(enum prop_type type));
35 36
36/* expr.c */ 37/* expr.c */
37P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); 38P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
38P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)); 39P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken));
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 6d82718..b9cf25f 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -1,780 +1,802 @@
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 * Introduced single menu mode (show all sub-menus in one large tree). 5 * Introduced single menu mode (show all sub-menus in one large tree).
6 * 2002-11-06 Petr Baudis <pasky@ucw.cz> 6 * 2002-11-06 Petr Baudis <pasky@ucw.cz>
7 */ 7 */
8 8
9#include <sys/ioctl.h> 9#include <sys/ioctl.h>
10#include <sys/wait.h> 10#include <sys/wait.h>
11#include <ctype.h> 11#include <ctype.h>
12#include <errno.h> 12#include <errno.h>
13#include <fcntl.h> 13#include <fcntl.h>
14#include <limits.h> 14#include <limits.h>
15#include <signal.h> 15#include <signal.h>
16#include <stdarg.h> 16#include <stdarg.h>
17#include <stdlib.h> 17#include <stdlib.h>
18#include <string.h> 18#include <string.h>
19#include <termios.h> 19#include <termios.h>
20#include <unistd.h> 20#include <unistd.h>
21 21
22#define LKC_DIRECT_LINK 22#define LKC_DIRECT_LINK
23#include "lkc.h" 23#include "lkc.h"
24 24
25static char menu_backtitle[128]; 25static char menu_backtitle[128];
26static const char menu_instructions[] = 26static const char menu_instructions[] =
27 "Arrow keys navigate the menu. " 27 "Arrow keys navigate the menu. "
28 "<Enter> selects submenus --->. " 28 "<Enter> selects submenus --->. "
29 "Highlighted letters are hotkeys. " 29 "Highlighted letters are hotkeys. "
30 "Pressing <Y> includes, <N> excludes, <M> modularizes features. " 30 "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
31 "Press <Esc><Esc> to exit, <?> for Help. " 31 "Press <Esc><Esc> to exit, <?> for Help. "
32 "Legend: [*] built-in [ ] excluded <M> module < > module capable", 32 "Legend: [*] built-in [ ] excluded <M> module < > module capable",
33radiolist_instructions[] = 33radiolist_instructions[] =
34 "Use the arrow keys to navigate this window or " 34 "Use the arrow keys to navigate this window or "
35 "press the hotkey of the item you wish to select " 35 "press the hotkey of the item you wish to select "
36 "followed by the <SPACE BAR>. " 36 "followed by the <SPACE BAR>. "
37 "Press <?> for additional information about this option.", 37 "Press <?> for additional information about this option.",
38inputbox_instructions_int[] = 38inputbox_instructions_int[] =
39 "Please enter a decimal value. " 39 "Please enter a decimal value. "
40 "Fractions will not be accepted. " 40 "Fractions will not be accepted. "
41 "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.",
42inputbox_instructions_hex[] = 42inputbox_instructions_hex[] =
43 "Please enter a hexadecimal value. " 43 "Please enter a hexadecimal value. "
44 "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.",
45inputbox_instructions_string[] = 45inputbox_instructions_string[] =
46 "Please enter a string value. " 46 "Please enter a string value. "
47 "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.",
48setmod_text[] = 48setmod_text[] =
49 "This feature depends on another which has been configured as a module.\n" 49 "This feature depends on another which has been configured as a module.\n"
50 "As a result, this feature will be built as a module.", 50 "As a result, this feature will be built as a module.",
51nohelp_text[] = 51nohelp_text[] =
52 "There is no help available for this kernel option.\n", 52 "There is no help available for this option.\n",
53load_config_text[] = 53load_config_text[] =
54 "Enter the name of the configuration file you wish to load. " 54 "Enter the name of the configuration file you wish to load. "
55 "Accept the name shown to restore the configuration you " 55 "Accept the name shown to restore the configuration you "
56 "last retrieved. Leave blank to abort.", 56 "last retrieved. Leave blank to abort.",
57load_config_help[] = 57load_config_help[] =
58 "\n" 58 "\n"
59 "For various reasons, one may wish to keep several different kernel\n" 59 "For various reasons, one may wish to keep several different \n"
60 "configurations available on a single machine.\n" 60 "configurations available on a single machine.\n"
61 "\n" 61 "\n"
62 "If you have saved a previous configuration in a file other than the\n" 62 "If you have saved a previous configuration in a file other than the\n"
63 "kernel's default, entering the name of the file here will allow you\n" 63 "default, entering the name of the file here will allow you\n"
64 "to modify that configuration.\n" 64 "to modify that configuration.\n"
65 "\n" 65 "\n"
66 "If you are uncertain, then you have probably never used alternate\n" 66 "If you are uncertain, then you have probably never used alternate\n"
67 "configuration files. You should therefor leave this blank to abort.\n", 67 "configuration files. You should therefor leave this blank to abort.\n",
68save_config_text[] = 68save_config_text[] =
69 "Enter a filename to which this configuration should be saved " 69 "Enter a filename to which this configuration should be saved "
70 "as an alternate. Leave blank to abort.", 70 "as an alternate. Leave blank to abort.",
71save_config_help[] = 71save_config_help[] =
72 "\n" 72 "\n"
73 "For various reasons, one may wish to keep different kernel\n" 73 "For various reasons, one may wish to keep different\n"
74 "configurations available on a single machine.\n" 74 "configurations available on a single machine.\n"
75 "\n" 75 "\n"
76 "Entering a file name here will allow you to later retrieve, modify\n" 76 "Entering a file name here will allow you to later retrieve, modify\n"
77 "and use the current configuration as an alternate to whatever\n" 77 "and use the current configuration as an alternate to whatever\n"
78 "configuration options you have selected at that time.\n" 78 "configuration options you have selected at that time.\n"
79 "\n" 79 "\n"
80 "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"
81 "leave this blank.\n" 81 "leave this blank.\n"
82; 82;
83 83
84static char buf[4096], *bufptr = buf; 84static char buf[4096], *bufptr = buf;
85static char input_buf[4096]; 85static char input_buf[4096];
86static char filename[PATH_MAX+1] = ".config"; 86static char filename[PATH_MAX+1] = ".config";
87static char *args[1024], **argptr = args; 87static char *args[1024], **argptr = args;
88static int indent = 0; 88static int indent = 0;
89static struct termios ios_org; 89static struct termios ios_org;
90static int rows, cols; 90static int rows, cols;
91static struct menu *current_menu; 91static struct menu *current_menu;
92static int child_count; 92static int child_count;
93static int do_resize; 93static int do_resize;
94static int single_menu_mode; 94static int single_menu_mode;
95 95
96static void conf(struct menu *menu); 96static void conf(struct menu *menu);
97static void conf_choice(struct menu *menu); 97static void conf_choice(struct menu *menu);
98static void conf_string(struct menu *menu); 98static void conf_string(struct menu *menu);
99static void conf_load(void); 99static void conf_load(void);
100static void conf_save(void); 100static void conf_save(void);
101static 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);
102static void show_helptext(const char *title, const char *text); 102static void show_helptext(const char *title, const char *text);
103static void show_help(struct menu *menu); 103static void show_help(struct menu *menu);
104static void show_readme(void); 104static void show_readme(void);
105 105
106static void cprint_init(void); 106static void cprint_init(void);
107static int cprint1(const char *fmt, ...); 107static int cprint1(const char *fmt, ...);
108static void cprint_done(void); 108static void cprint_done(void);
109static int cprint(const char *fmt, ...); 109static int cprint(const char *fmt, ...);
110 110
111static void init_wsize(void) 111static void init_wsize(void)
112{ 112{
113 struct winsize ws; 113 struct winsize ws;
114 char *env; 114 char *env;
115 115
116 if (ioctl(1, TIOCGWINSZ, &ws) == -1) { 116 if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
117 rows = 24; 117 rows = 24;
118 cols = 80; 118 cols = 80;
119 } else { 119 } else {
120 rows = ws.ws_row; 120 rows = ws.ws_row;
121 cols = ws.ws_col; 121 cols = ws.ws_col;
122 if (!rows) { 122 if (!rows) {
123 env = getenv("LINES"); 123 env = getenv("LINES");
124 if (env) 124 if (env)
125 rows = atoi(env); 125 rows = atoi(env);
126 if (!rows) 126 if (!rows)
127 rows = 24; 127 rows = 24;
128 } 128 }
129 if (!cols) { 129 if (!cols) {
130 env = getenv("COLUMNS"); 130 env = getenv("COLUMNS");
131 if (env) 131 if (env)
132 cols = atoi(env); 132 cols = atoi(env);
133 if (!cols) 133 if (!cols)
134 cols = 80; 134 cols = 80;
135 } 135 }
136 } 136 }
137 137
138 if (rows < 19 || cols < 80) { 138 if (rows < 19 || cols < 80) {
139 fprintf(stderr, "Your display is too small to run Menuconfig!\n"); 139 fprintf(stderr, "Your display is too small to run Menuconfig!\n");
140 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");
141 exit(1); 141 exit(1);
142 } 142 }
143 143
144 rows -= 4; 144 rows -= 4;
145 cols -= 5; 145 cols -= 5;
146} 146}
147 147
148static void cprint_init(void) 148static void cprint_init(void)
149{ 149{
150 char *env = getenv("LXDIALOG");
150 bufptr = buf; 151 bufptr = buf;
151 argptr = args; 152 argptr = args;
152 memset(args, 0, sizeof(args)); 153 memset(args, 0, sizeof(args));
153 indent = 0; 154 indent = 0;
154 child_count = 0; 155 child_count = 0;
155 cprint("./scripts/lxdialog/lxdialog"); 156 if(env != NULL) {
157 cprint(env);
158 } else {
159 cprint("./scripts/lxdialog/lxdialog");
160 }
156 cprint("--backtitle"); 161 cprint("--backtitle");
157 cprint(menu_backtitle); 162 cprint(menu_backtitle);
158} 163}
159 164
160static int cprint1(const char *fmt, ...) 165static int cprint1(const char *fmt, ...)
161{ 166{
162 va_list ap; 167 va_list ap;
163 int res; 168 int res;
164 169
165 if (!*argptr) 170 if (!*argptr)
166 *argptr = bufptr; 171 *argptr = bufptr;
167 va_start(ap, fmt); 172 va_start(ap, fmt);
168 res = vsprintf(bufptr, fmt, ap); 173 res = vsprintf(bufptr, fmt, ap);
169 va_end(ap); 174 va_end(ap);
170 bufptr += res; 175 bufptr += res;
171 176
172 return res; 177 return res;
173} 178}
174 179
175static void cprint_done(void) 180static void cprint_done(void)
176{ 181{
177 *bufptr++ = 0; 182 *bufptr++ = 0;
178 argptr++; 183 argptr++;
179} 184}
180 185
181static int cprint(const char *fmt, ...) 186static int cprint(const char *fmt, ...)
182{ 187{
183 va_list ap; 188 va_list ap;
184 int res; 189 int res;
185 190
186 *argptr++ = bufptr; 191 *argptr++ = bufptr;
187 va_start(ap, fmt); 192 va_start(ap, fmt);
188 res = vsprintf(bufptr, fmt, ap); 193 res = vsprintf(bufptr, fmt, ap);
189 va_end(ap); 194 va_end(ap);
190 bufptr += res; 195 bufptr += res;
191 *bufptr++ = 0; 196 *bufptr++ = 0;
192 197
193 return res; 198 return res;
194} 199}
195 200
196pid_t pid; 201pid_t pid;
197 202
198static void winch_handler(int sig) 203static void winch_handler(int sig)
199{ 204{
200 if (!do_resize) { 205 if (!do_resize) {
201 kill(pid, SIGINT); 206 kill(pid, SIGINT);
202 do_resize = 1; 207 do_resize = 1;
203 } 208 }
204} 209}
205 210
206static int exec_conf(void) 211static int exec_conf(void)
207{ 212{
208 int pipefd[2], stat, size; 213 int pipefd[2], stat, size;
209 struct sigaction sa; 214 struct sigaction sa;
210 sigset_t sset, osset; 215 sigset_t sset, osset;
211 216
212 sigemptyset(&sset); 217 sigemptyset(&sset);
213 sigaddset(&sset, SIGINT); 218 sigaddset(&sset, SIGINT);
214 sigprocmask(SIG_BLOCK, &sset, &osset); 219 sigprocmask(SIG_BLOCK, &sset, &osset);
215 220
216 signal(SIGINT, SIG_DFL); 221 signal(SIGINT, SIG_DFL);
217 222
218 sa.sa_handler = winch_handler; 223 sa.sa_handler = winch_handler;
219 sigemptyset(&sa.sa_mask); 224 sigemptyset(&sa.sa_mask);
220 sa.sa_flags = SA_RESTART; 225 sa.sa_flags = SA_RESTART;
221 sigaction(SIGWINCH, &sa, NULL); 226 sigaction(SIGWINCH, &sa, NULL);
222 227
223 *argptr++ = NULL; 228 *argptr++ = NULL;
224 229
225 pipe(pipefd); 230 pipe(pipefd);
226 pid = fork(); 231 pid = fork();
227 if (pid == 0) { 232 if (pid == 0) {
228 sigprocmask(SIG_SETMASK, &osset, NULL); 233 sigprocmask(SIG_SETMASK, &osset, NULL);
229 dup2(pipefd[1], 2); 234 dup2(pipefd[1], 2);
230 close(pipefd[0]); 235 close(pipefd[0]);
231 close(pipefd[1]); 236 close(pipefd[1]);
232 execv(args[0], args); 237 execv(args[0], args);
233 _exit(EXIT_FAILURE); 238 _exit(EXIT_FAILURE);
234 } 239 }
235 240
236 close(pipefd[1]); 241 close(pipefd[1]);
237 bufptr = input_buf; 242 bufptr = input_buf;
238 while (1) { 243 while (1) {
239 size = input_buf + sizeof(input_buf) - bufptr; 244 size = input_buf + sizeof(input_buf) - bufptr;
240 size = read(pipefd[0], bufptr, size); 245 size = read(pipefd[0], bufptr, size);
241 if (size <= 0) { 246 if (size <= 0) {
242 if (size < 0) { 247 if (size < 0) {
243 if (errno == EINTR || errno == EAGAIN) 248 if (errno == EINTR || errno == EAGAIN)
244 continue; 249 continue;
245 perror("read"); 250 perror("read");
246 } 251 }
247 break; 252 break;
248 } 253 }
249 bufptr += size; 254 bufptr += size;
250 } 255 }
251 *bufptr++ = 0; 256 *bufptr++ = 0;
252 close(pipefd[0]); 257 close(pipefd[0]);
253 waitpid(pid, &stat, 0); 258 waitpid(pid, &stat, 0);
254 259
255 if (do_resize) { 260 if (do_resize) {
256 init_wsize(); 261 init_wsize();
257 do_resize = 0; 262 do_resize = 0;
258 sigprocmask(SIG_SETMASK, &osset, NULL); 263 sigprocmask(SIG_SETMASK, &osset, NULL);
259 return -1; 264 return -1;
260 } 265 }
261 if (WIFSIGNALED(stat)) { 266 if (WIFSIGNALED(stat)) {
262 printf("\finterrupted(%d)\n", WTERMSIG(stat)); 267 printf("\finterrupted(%d)\n", WTERMSIG(stat));
263 exit(1); 268 exit(1);
264 } 269 }
265#if 0 270#if 0
266 printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf); 271 printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
267 sleep(1); 272 sleep(1);
268#endif 273#endif
269 sigpending(&sset); 274 sigpending(&sset);
270 if (sigismember(&sset, SIGINT)) { 275 if (sigismember(&sset, SIGINT)) {
271 printf("\finterrupted\n"); 276 printf("\finterrupted\n");
272 exit(1); 277 exit(1);
273 } 278 }
274 sigprocmask(SIG_SETMASK, &osset, NULL); 279 sigprocmask(SIG_SETMASK, &osset, NULL);
275 280
276 return WEXITSTATUS(stat); 281 return WEXITSTATUS(stat);
277} 282}
278 283
279static void build_conf(struct menu *menu) 284static void build_conf(struct menu *menu)
280{ 285{
281 struct symbol *sym; 286 struct symbol *sym;
282 struct property *prop; 287 struct property *prop;
283 struct menu *child; 288 struct menu *child;
284 int type, tmp, doint = 2; 289 int type, tmp, doint = 2;
285 tristate val; 290 tristate val;
286 char ch; 291 char ch;
287 292
288 if (!menu_is_visible(menu)) 293 if (!menu_is_visible(menu))
289 return; 294 return;
290 295
291 sym = menu->sym; 296 sym = menu->sym;
292 prop = menu->prompt; 297 prop = menu->prompt;
293 if (!sym) { 298 if (!sym) {
294 if (prop && menu != current_menu) { 299 if (prop && menu != current_menu) {
295 const char *prompt = menu_get_prompt(menu); 300 const char *prompt = menu_get_prompt(menu);
296 switch (prop->type) { 301 switch (prop->type) {
297 case P_MENU: 302 case P_MENU:
298 child_count++; 303 child_count++;
299 cprint("m%p", menu); 304 cprint("m%p", menu);
300 305
301 if (single_menu_mode) { 306 if (single_menu_mode) {
302 cprint1("%s%*c%s", 307 cprint1("%s%*c%s",
303 menu->data ? "-->" : "++>", 308 menu->data ? "-->" : "++>",
304 indent + 1, ' ', prompt); 309 indent + 1, ' ', prompt);
305 } else { 310 } else
306 if (menu->parent != &rootmenu) 311 cprint1(" %*c%s --->", indent + 1, ' ', prompt);
307 cprint1(" %*c", indent + 1, ' ');
308 cprint1("%s --->", prompt);
309 }
310 312
311 cprint_done(); 313 cprint_done();
312 if (single_menu_mode && menu->data) 314 if (single_menu_mode && menu->data)
313 goto conf_childs; 315 goto conf_childs;
314 return; 316 return;
315 default: 317 default:
316 if (prompt) { 318 if (prompt) {
317 child_count++; 319 child_count++;
318 cprint(":%p", menu); 320 cprint(":%p", menu);
319 cprint("---%*c%s", indent + 1, ' ', prompt); 321 cprint("---%*c%s", indent + 1, ' ', prompt);
320 } 322 }
321 } 323 }
322 } else 324 } else
323 doint = 0; 325 doint = 0;
324 goto conf_childs; 326 goto conf_childs;
325 } 327 }
326 328
327 type = sym_get_type(sym); 329 type = sym_get_type(sym);
328 if (sym_is_choice(sym)) { 330 if (sym_is_choice(sym)) {
329 struct symbol *def_sym = sym_get_choice_value(sym); 331 struct symbol *def_sym = sym_get_choice_value(sym);
330 struct menu *def_menu = NULL; 332 struct menu *def_menu = NULL;
331 333
332 child_count++; 334 child_count++;
333 for (child = menu->list; child; child = child->next) { 335 for (child = menu->list; child; child = child->next) {
334 if (menu_is_visible(child) && child->sym == def_sym) 336 if (menu_is_visible(child) && child->sym == def_sym)
335 def_menu = child; 337 def_menu = child;
336 } 338 }
337 339
338 val = sym_get_tristate_value(sym); 340 val = sym_get_tristate_value(sym);
339 if (sym_is_changable(sym)) { 341 if (sym_is_changable(sym)) {
340 cprint("t%p", menu); 342 cprint("t%p", menu);
341 switch (type) { 343 switch (type) {
342 case S_BOOLEAN: 344 case S_BOOLEAN:
343 cprint1("[%c]", val == no ? ' ' : '*'); 345 cprint1("[%c]", val == no ? ' ' : '*');
344 break; 346 break;
345 case S_TRISTATE: 347 case S_TRISTATE:
346 switch (val) { 348 switch (val) {
347 case yes: ch = '*'; break; 349 case yes: ch = '*'; break;
348 case mod: ch = 'M'; break; 350 case mod: ch = 'M'; break;
349 default: ch = ' '; break; 351 default: ch = ' '; break;
350 } 352 }
351 cprint1("<%c>", ch); 353 cprint1("<%c>", ch);
352 break; 354 break;
353 } 355 }
354 } else { 356 } else {
355 cprint("%c%p", def_menu ? 't' : ':', menu); 357 cprint("%c%p", def_menu ? 't' : ':', menu);
356 cprint1(" "); 358 cprint1(" ");
357 } 359 }
358 360
359 cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); 361 cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
360 if (val == yes) { 362 if (val == yes) {
361 if (def_menu) { 363 if (def_menu) {
362 cprint1(" (%s)", menu_get_prompt(def_menu)); 364 cprint1(" (%s)", menu_get_prompt(def_menu));
363 cprint1(" --->"); 365 cprint1(" --->");
364 cprint_done(); 366 cprint_done();
365 if (def_menu->list) { 367 if (def_menu->list) {
366 indent += 2; 368 indent += 2;
367 build_conf(def_menu); 369 build_conf(def_menu);
368 indent -= 2; 370 indent -= 2;
369 } 371 }
370 } else 372 } else
371 cprint_done(); 373 cprint_done();
372 return; 374 return;
373 } 375 }
374 cprint_done(); 376 cprint_done();
375 } else { 377 } else {
378 if (menu == current_menu) {
379 cprint(":%p", menu);
380 cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
381 goto conf_childs;
382 }
376 child_count++; 383 child_count++;
377 val = sym_get_tristate_value(sym); 384 val = sym_get_tristate_value(sym);
378 if (sym_is_choice_value(sym) && val == yes) { 385 if (sym_is_choice_value(sym) && val == yes) {
379 cprint(":%p", menu); 386 cprint(":%p", menu);
380 cprint1(" "); 387 cprint1(" ");
381 } else { 388 } else {
382 switch (type) { 389 switch (type) {
383 case S_BOOLEAN: 390 case S_BOOLEAN:
384 cprint("t%p", menu); 391 cprint("t%p", menu);
385 cprint1("[%c]", val == no ? ' ' : '*'); 392 if (sym_is_changable(sym))
393 cprint1("[%c]", val == no ? ' ' : '*');
394 else
395 cprint1("---");
386 break; 396 break;
387 case S_TRISTATE: 397 case S_TRISTATE:
388 cprint("t%p", menu); 398 cprint("t%p", menu);
389 switch (val) { 399 switch (val) {
390 case yes: ch = '*'; break; 400 case yes: ch = '*'; break;
391 case mod: ch = 'M'; break; 401 case mod: ch = 'M'; break;
392 default: ch = ' '; break; 402 default: ch = ' '; break;
393 } 403 }
394 cprint1("<%c>", ch); 404 if (sym_is_changable(sym))
405 cprint1("<%c>", ch);
406 else
407 cprint1("---");
395 break; 408 break;
396 default: 409 default:
397 cprint("s%p", menu); 410 cprint("s%p", menu);
398 tmp = cprint1("(%s)", sym_get_string_value(sym)); 411 tmp = cprint1("(%s)", sym_get_string_value(sym));
399 tmp = indent - tmp + 4; 412 tmp = indent - tmp + 4;
400 if (tmp < 0) 413 if (tmp < 0)
401 tmp = 0; 414 tmp = 0;
402 cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), 415 cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
403 sym_has_value(sym) ? "" : " (NEW)"); 416 (sym_has_value(sym) || !sym_is_changable(sym)) ?
417 "" : " (NEW)");
404 cprint_done(); 418 cprint_done();
405 goto conf_childs; 419 goto conf_childs;
406 } 420 }
407 } 421 }
408 cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), 422 cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
409 sym_has_value(sym) ? "" : " (NEW)"); 423 (sym_has_value(sym) || !sym_is_changable(sym)) ?
424 "" : " (NEW)");
425 if (menu->prompt->type == P_MENU) {
426 cprint1(" --->");
427 cprint_done();
428 return;
429 }
410 cprint_done(); 430 cprint_done();
411 } 431 }
412 432
413conf_childs: 433conf_childs:
414 indent += doint; 434 indent += doint;
415 for (child = menu->list; child; child = child->next) 435 for (child = menu->list; child; child = child->next)
416 build_conf(child); 436 build_conf(child);
417 indent -= doint; 437 indent -= doint;
418} 438}
419 439
420static void conf(struct menu *menu) 440static void conf(struct menu *menu)
421{ 441{
422 struct menu *submenu; 442 struct menu *submenu;
423 const char *prompt = menu_get_prompt(menu); 443 const char *prompt = menu_get_prompt(menu);
424 struct symbol *sym; 444 struct symbol *sym;
425 char active_entry[40]; 445 char active_entry[40];
426 int stat, type, i; 446 int stat, type, i;
427 447
428 unlink("lxdialog.scrltmp"); 448 unlink("lxdialog.scrltmp");
429 active_entry[0] = 0; 449 active_entry[0] = 0;
430 while (1) { 450 while (1) {
431 cprint_init(); 451 cprint_init();
432 cprint("--title"); 452 cprint("--title");
433 cprint("%s", prompt ? prompt : "Main Menu"); 453 cprint("%s", prompt ? prompt : "Main Menu");
434 cprint("--menu"); 454 cprint("--menu");
435 cprint(menu_instructions); 455 cprint(menu_instructions);
436 cprint("%d", rows); 456 cprint("%d", rows);
437 cprint("%d", cols); 457 cprint("%d", cols);
438 cprint("%d", rows - 10); 458 cprint("%d", rows - 10);
439 cprint("%s", active_entry); 459 cprint("%s", active_entry);
440 current_menu = menu; 460 current_menu = menu;
441 build_conf(menu); 461 build_conf(menu);
442 if (!child_count) 462 if (!child_count)
443 break; 463 break;
444 if (menu == &rootmenu) { 464 if (menu == &rootmenu) {
445 cprint(":"); 465 cprint(":");
446 cprint("--- "); 466 cprint("--- ");
447 cprint("L"); 467 cprint("L");
448 cprint("Load an Alternate Configuration File"); 468 cprint(" Load an Alternate Configuration File");
449 cprint("S"); 469 cprint("S");
450 cprint("Save Configuration to an Alternate File"); 470 cprint(" Save Configuration to an Alternate File");
451 } 471 }
452 stat = exec_conf(); 472 stat = exec_conf();
453 if (stat < 0) 473 if (stat < 0)
454 continue; 474 continue;
455 475
456 if (stat == 1 || stat == 255) 476 if (stat == 1 || stat == 255)
457 break; 477 break;
458 478
459 type = input_buf[0]; 479 type = input_buf[0];
460 if (!type) 480 if (!type)
461 continue; 481 continue;
462 482
463 for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++) 483 for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
464 ; 484 ;
465 if (i >= sizeof(active_entry)) 485 if (i >= sizeof(active_entry))
466 i = sizeof(active_entry) - 1; 486 i = sizeof(active_entry) - 1;
467 input_buf[i] = 0; 487 input_buf[i] = 0;
468 strcpy(active_entry, input_buf); 488 strcpy(active_entry, input_buf);
469 489
470 sym = NULL; 490 sym = NULL;
471 submenu = NULL; 491 submenu = NULL;
472 if (sscanf(input_buf + 1, "%p", &submenu) == 1) 492 if (sscanf(input_buf + 1, "%p", &submenu) == 1)
473 sym = submenu->sym; 493 sym = submenu->sym;
474 494
475 switch (stat) { 495 switch (stat) {
476 case 0: 496 case 0:
477 switch (type) { 497 switch (type) {
478 case 'm': 498 case 'm':
479 if (single_menu_mode) 499 if (single_menu_mode)
480 submenu->data = (void *) !submenu->data; 500 submenu->data = (void *) !submenu->data;
481 else 501 else
482 conf(submenu); 502 conf(submenu);
483 break; 503 break;
484 case 't': 504 case 't':
485 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) 505 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
486 conf_choice(submenu); 506 conf_choice(submenu);
507 else if (submenu->prompt->type == P_MENU)
508 conf(submenu);
487 break; 509 break;
488 case 's': 510 case 's':
489 conf_string(submenu); 511 conf_string(submenu);
490 break; 512 break;
491 case 'L': 513 case 'L':
492 conf_load(); 514 conf_load();
493 break; 515 break;
494 case 'S': 516 case 'S':
495 conf_save(); 517 conf_save();
496 break; 518 break;
497 } 519 }
498 break; 520 break;
499 case 2: 521 case 2:
500 if (sym) 522 if (sym)
501 show_help(submenu); 523 show_help(submenu);
502 else 524 else
503 show_readme(); 525 show_readme();
504 break; 526 break;
505 case 3: 527 case 3:
506 if (type == 't') { 528 if (type == 't') {
507 if (sym_set_tristate_value(sym, yes)) 529 if (sym_set_tristate_value(sym, yes))
508 break; 530 break;
509 if (sym_set_tristate_value(sym, mod)) 531 if (sym_set_tristate_value(sym, mod))
510 show_textbox(NULL, setmod_text, 6, 74); 532 show_textbox(NULL, setmod_text, 6, 74);
511 } 533 }
512 break; 534 break;
513 case 4: 535 case 4:
514 if (type == 't') 536 if (type == 't')
515 sym_set_tristate_value(sym, no); 537 sym_set_tristate_value(sym, no);
516 break; 538 break;
517 case 5: 539 case 5:
518 if (type == 't') 540 if (type == 't')
519 sym_set_tristate_value(sym, mod); 541 sym_set_tristate_value(sym, mod);
520 break; 542 break;
521 case 6: 543 case 6:
522 if (type == 't') 544 if (type == 't')
523 sym_toggle_tristate_value(sym); 545 sym_toggle_tristate_value(sym);
524 else if (type == 'm') 546 else if (type == 'm')
525 conf(submenu); 547 conf(submenu);
526 break; 548 break;
527 } 549 }
528 } 550 }
529} 551}
530 552
531static void show_textbox(const char *title, const char *text, int r, int c) 553static void show_textbox(const char *title, const char *text, int r, int c)
532{ 554{
533 int fd; 555 int fd;
534 556
535 fd = creat(".help.tmp", 0777); 557 fd = creat(".help.tmp", 0777);
536 write(fd, text, strlen(text)); 558 write(fd, text, strlen(text));
537 close(fd); 559 close(fd);
538 do { 560 do {
539 cprint_init(); 561 cprint_init();
540 if (title) { 562 if (title) {
541 cprint("--title"); 563 cprint("--title");
542 cprint("%s", title); 564 cprint("%s", title);
543 } 565 }
544 cprint("--textbox"); 566 cprint("--textbox");
545 cprint(".help.tmp"); 567 cprint(".help.tmp");
546 cprint("%d", r); 568 cprint("%d", r);
547 cprint("%d", c); 569 cprint("%d", c);
548 } while (exec_conf() < 0); 570 } while (exec_conf() < 0);
549 unlink(".help.tmp"); 571 unlink(".help.tmp");
550} 572}
551 573
552static void show_helptext(const char *title, const char *text) 574static void show_helptext(const char *title, const char *text)
553{ 575{
554 show_textbox(title, text, rows, cols); 576 show_textbox(title, text, rows, cols);
555} 577}
556 578
557static void show_help(struct menu *menu) 579static void show_help(struct menu *menu)
558{ 580{
559 const char *help; 581 const char *help;
560 char *helptext; 582 char *helptext;
561 struct symbol *sym = menu->sym; 583 struct symbol *sym = menu->sym;
562 584
563 help = sym->help; 585 help = sym->help;
564 if (!help) 586 if (!help)
565 help = nohelp_text; 587 help = nohelp_text;
566 if (sym->name) { 588 if (sym->name) {
567 helptext = malloc(strlen(sym->name) + strlen(help) + 16); 589 helptext = malloc(strlen(sym->name) + strlen(help) + 16);
568 sprintf(helptext, "CONFIG_%s:\n\n%s", sym->name, help); 590 sprintf(helptext, "CONFIG_%s:\n\n%s", sym->name, help);
569 show_helptext(menu_get_prompt(menu), helptext); 591 show_helptext(menu_get_prompt(menu), helptext);
570 free(helptext); 592 free(helptext);
571 } else 593 } else
572 show_helptext(menu_get_prompt(menu), help); 594 show_helptext(menu_get_prompt(menu), help);
573} 595}
574 596
575static void show_readme(void) 597static void show_readme(void)
576{ 598{
577 do { 599 do {
578 cprint_init(); 600 cprint_init();
579 cprint("--textbox"); 601 cprint("--textbox");
580 cprint("scripts/README.Menuconfig"); 602 cprint("scripts/README.Menuconfig");
581 cprint("%d", rows); 603 cprint("%d", rows);
582 cprint("%d", cols); 604 cprint("%d", cols);
583 } while (exec_conf() == -1); 605 } while (exec_conf() == -1);
584} 606}
585 607
586static void conf_choice(struct menu *menu) 608static void conf_choice(struct menu *menu)
587{ 609{
588 const char *prompt = menu_get_prompt(menu); 610 const char *prompt = menu_get_prompt(menu);
589 struct menu *child; 611 struct menu *child;
590 struct symbol *active; 612 struct symbol *active;
591 int stat; 613 int stat;
592 614
593 while (1) { 615 while (1) {
594 cprint_init(); 616 cprint_init();
595 cprint("--title"); 617 cprint("--title");
596 cprint("%s", prompt ? prompt : "Main Menu"); 618 cprint("%s", prompt ? prompt : "Main Menu");
597 cprint("--radiolist"); 619 cprint("--radiolist");
598 cprint(radiolist_instructions); 620 cprint(radiolist_instructions);
599 cprint("15"); 621 cprint("15");
600 cprint("70"); 622 cprint("70");
601 cprint("6"); 623 cprint("6");
602 624
603 current_menu = menu; 625 current_menu = menu;
604 active = sym_get_choice_value(menu->sym); 626 active = sym_get_choice_value(menu->sym);
605 for (child = menu->list; child; child = child->next) { 627 for (child = menu->list; child; child = child->next) {
606 if (!menu_is_visible(child)) 628 if (!menu_is_visible(child))
607 continue; 629 continue;
608 cprint("%p", child); 630 cprint("%p", child);
609 cprint("%s", menu_get_prompt(child)); 631 cprint("%s", menu_get_prompt(child));
610 cprint(child->sym == active ? "ON" : "OFF"); 632 cprint(child->sym == active ? "ON" : "OFF");
611 } 633 }
612 634
613 stat = exec_conf(); 635 stat = exec_conf();
614 switch (stat) { 636 switch (stat) {
615 case 0: 637 case 0:
616 if (sscanf(input_buf, "%p", &menu) != 1) 638 if (sscanf(input_buf, "%p", &menu) != 1)
617 break; 639 break;
618 sym_set_tristate_value(menu->sym, yes); 640 sym_set_tristate_value(menu->sym, yes);
619 return; 641 return;
620 case 1: 642 case 1:
621 show_help(menu); 643 show_help(menu);
622 break; 644 break;
623 case 255: 645 case 255:
624 return; 646 return;
625 } 647 }
626 } 648 }
627} 649}
628 650
629static void conf_string(struct menu *menu) 651static void conf_string(struct menu *menu)
630{ 652{
631 const char *prompt = menu_get_prompt(menu); 653 const char *prompt = menu_get_prompt(menu);
632 int stat; 654 int stat;
633 655
634 while (1) { 656 while (1) {
635 cprint_init(); 657 cprint_init();
636 cprint("--title"); 658 cprint("--title");
637 cprint("%s", prompt ? prompt : "Main Menu"); 659 cprint("%s", prompt ? prompt : "Main Menu");
638 cprint("--inputbox"); 660 cprint("--inputbox");
639 switch (sym_get_type(menu->sym)) { 661 switch (sym_get_type(menu->sym)) {
640 case S_INT: 662 case S_INT:
641 cprint(inputbox_instructions_int); 663 cprint(inputbox_instructions_int);
642 break; 664 break;
643 case S_HEX: 665 case S_HEX:
644 cprint(inputbox_instructions_hex); 666 cprint(inputbox_instructions_hex);
645 break; 667 break;
646 case S_STRING: 668 case S_STRING:
647 cprint(inputbox_instructions_string); 669 cprint(inputbox_instructions_string);
648 break; 670 break;
649 default: 671 default:
650 /* panic? */; 672 /* panic? */;
651 } 673 }
652 cprint("10"); 674 cprint("10");
653 cprint("75"); 675 cprint("75");
654 cprint("%s", sym_get_string_value(menu->sym)); 676 cprint("%s", sym_get_string_value(menu->sym));
655 stat = exec_conf(); 677 stat = exec_conf();
656 switch (stat) { 678 switch (stat) {
657 case 0: 679 case 0:
658 if (sym_set_string_value(menu->sym, input_buf)) 680 if (sym_set_string_value(menu->sym, input_buf))
659 return; 681 return;
660 show_textbox(NULL, "You have made an invalid entry.", 5, 43); 682 show_textbox(NULL, "You have made an invalid entry.", 5, 43);
661 break; 683 break;
662 case 1: 684 case 1:
663 show_help(menu); 685 show_help(menu);
664 break; 686 break;
665 case 255: 687 case 255:
666 return; 688 return;
667 } 689 }
668 } 690 }
669} 691}
670 692
671static void conf_load(void) 693static void conf_load(void)
672{ 694{
673 int stat; 695 int stat;
674 696
675 while (1) { 697 while (1) {
676 cprint_init(); 698 cprint_init();
677 cprint("--inputbox"); 699 cprint("--inputbox");
678 cprint(load_config_text); 700 cprint(load_config_text);
679 cprint("11"); 701 cprint("11");
680 cprint("55"); 702 cprint("55");
681 cprint("%s", filename); 703 cprint("%s", filename);
682 stat = exec_conf(); 704 stat = exec_conf();
683 switch(stat) { 705 switch(stat) {
684 case 0: 706 case 0:
685 if (!input_buf[0]) 707 if (!input_buf[0])
686 return; 708 return;
687 if (!conf_read(input_buf)) 709 if (!conf_read(input_buf))
688 return; 710 return;
689 show_textbox(NULL, "File does not exist!", 5, 38); 711 show_textbox(NULL, "File does not exist!", 5, 38);
690 break; 712 break;
691 case 1: 713 case 1:
692 show_helptext("Load Alternate Configuration", load_config_help); 714 show_helptext("Load Alternate Configuration", load_config_help);
693 break; 715 break;
694 case 255: 716 case 255:
695 return; 717 return;
696 } 718 }
697 } 719 }
698} 720}
699 721
700static void conf_save(void) 722static void conf_save(void)
701{ 723{
702 int stat; 724 int stat;
703 725
704 while (1) { 726 while (1) {
705 cprint_init(); 727 cprint_init();
706 cprint("--inputbox"); 728 cprint("--inputbox");
707 cprint(save_config_text); 729 cprint(save_config_text);
708 cprint("11"); 730 cprint("11");
709 cprint("55"); 731 cprint("55");
710 cprint("%s", filename); 732 cprint("%s", filename);
711 stat = exec_conf(); 733 stat = exec_conf();
712 switch(stat) { 734 switch(stat) {
713 case 0: 735 case 0:
714 if (!input_buf[0]) 736 if (!input_buf[0])
715 return; 737 return;
716 if (!conf_write(input_buf)) 738 if (!conf_write(input_buf))
717 return; 739 return;
718 show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); 740 show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
719 break; 741 break;
720 case 1: 742 case 1:
721 show_helptext("Save Alternate Configuration", save_config_help); 743 show_helptext("Save Alternate Configuration", save_config_help);
722 break; 744 break;
723 case 255: 745 case 255:
724 return; 746 return;
725 } 747 }
726 } 748 }
727} 749}
728 750
729static void conf_cleanup(void) 751static void conf_cleanup(void)
730{ 752{
731 tcsetattr(1, TCSAFLUSH, &ios_org); 753 tcsetattr(1, TCSAFLUSH, &ios_org);
732 unlink(".help.tmp"); 754 unlink(".help.tmp");
733 unlink("lxdialog.scrltmp"); 755 unlink("lxdialog.scrltmp");
734} 756}
735 757
736int main(int ac, char **av) 758int main(int ac, char **av)
737{ 759{
738 struct symbol *sym; 760 struct symbol *sym;
739 char *mode; 761 char *mode;
740 int stat; 762 int stat;
741 763
742 conf_parse(av[1]); 764 conf_parse(av[1]);
743 conf_read(NULL); 765 conf_read(NULL);
744 766
745 sym = sym_lookup("KERNELRELEASE", 0); 767 sym = sym_lookup("KERNELRELEASE", 0);
746 sym_calc_value(sym); 768 sym_calc_value(sym);
747 sprintf(menu_backtitle, "Opie %s Configuration", 769 sprintf(menu_backtitle, "Build Configuration");
748 sym_get_string_value(sym));
749 770
750 mode = getenv("MENUCONFIG_MODE"); 771 mode = getenv("MENUCONFIG_MODE");
751 if (mode) { 772 if (mode) {
752 if (!strcasecmp(mode, "single_menu")) 773 if (!strcasecmp(mode, "single_menu"))
753 single_menu_mode = 1; 774 single_menu_mode = 1;
754 } 775 }
755 776
756 tcgetattr(1, &ios_org); 777 tcgetattr(1, &ios_org);
757 atexit(conf_cleanup); 778 atexit(conf_cleanup);
758 init_wsize(); 779 init_wsize();
759 conf(&rootmenu); 780 conf(&rootmenu);
760 781
761 do { 782 do {
762 cprint_init(); 783 cprint_init();
763 cprint("--yesno"); 784 cprint("--yesno");
764 cprint("Do you wish to save your new configuration?"); 785 cprint("Do you wish to save your new configuration?");
765 cprint("5"); 786 cprint("5");
766 cprint("60"); 787 cprint("60");
767 stat = exec_conf(); 788 stat = exec_conf();
768 } while (stat < 0); 789 } while (stat < 0);
769 790
770 if (stat == 0) { 791 if (stat == 0) {
771 conf_write(NULL); 792 conf_write(NULL);
772 printf("\n\n" 793 printf("\n\n"
773 "*** End of Opie configuration.\n" 794 "*** End of configuration.\n"
774 "*** Check the top-level Makefile for additional configuration.\n" 795 "\n\n");
775 "*** Next, you may run 'make'.\n\n");
776 } else 796 } else
777 printf("\n\nYour Opie configuration changes were NOT saved.\n\n"); 797 printf("\n\n"
798 "Your configuration changes were NOT saved."
799 "\n\n");
778 800
779 return 0; 801 return 0;
780} 802}
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 24be0ec..1631767 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -1,309 +1,397 @@
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 <stdlib.h> 6#include <stdlib.h>
7#include <string.h> 7#include <string.h>
8 8
9#define LKC_DIRECT_LINK 9#define LKC_DIRECT_LINK
10#include "lkc.h" 10#include "lkc.h"
11 11
12struct menu rootmenu; 12struct menu rootmenu;
13struct menu *current_menu, *current_entry; 13struct menu *current_menu, *current_entry;
14static struct menu **last_entry_ptr; 14static struct menu **last_entry_ptr;
15 15
16struct file *file_list; 16struct file *file_list;
17struct file *current_file; 17struct file *current_file;
18 18
19void menu_init(void) 19void menu_init(void)
20{ 20{
21 current_entry = current_menu = &rootmenu; 21 current_entry = current_menu = &rootmenu;
22 last_entry_ptr = &rootmenu.list; 22 last_entry_ptr = &rootmenu.list;
23} 23}
24 24
25void menu_add_entry(struct symbol *sym) 25void menu_add_entry(struct symbol *sym)
26{ 26{
27 struct menu *menu; 27 struct menu *menu;
28 28
29 menu = malloc(sizeof(*menu)); 29 menu = malloc(sizeof(*menu));
30 memset(menu, 0, sizeof(*menu)); 30 memset(menu, 0, sizeof(*menu));
31 menu->sym = sym; 31 menu->sym = sym;
32 menu->parent = current_menu; 32 menu->parent = current_menu;
33 menu->file = current_file; 33 menu->file = current_file;
34 menu->lineno = zconf_lineno(); 34 menu->lineno = zconf_lineno();
35 35
36 *last_entry_ptr = menu; 36 *last_entry_ptr = menu;
37 last_entry_ptr = &menu->next; 37 last_entry_ptr = &menu->next;
38 current_entry = menu; 38 current_entry = menu;
39} 39}
40 40
41void menu_end_entry(void) 41void menu_end_entry(void)
42{ 42{
43} 43}
44 44
45void menu_add_menu(void) 45void menu_add_menu(void)
46{ 46{
47 current_menu = current_entry; 47 current_menu = current_entry;
48 last_entry_ptr = &current_entry->list; 48 last_entry_ptr = &current_entry->list;
49} 49}
50 50
51void menu_end_menu(void) 51void menu_end_menu(void)
52{ 52{
53 last_entry_ptr = &current_menu->next; 53 last_entry_ptr = &current_menu->next;
54 current_menu = current_menu->parent; 54 current_menu = current_menu->parent;
55} 55}
56 56
57struct expr *menu_check_dep(struct expr *e)
58{
59 if (!e)
60 return e;
61
62 switch (e->type) {
63 case E_NOT:
64 e->left.expr = menu_check_dep(e->left.expr);
65 break;
66 case E_OR:
67 case E_AND:
68 e->left.expr = menu_check_dep(e->left.expr);
69 e->right.expr = menu_check_dep(e->right.expr);
70 break;
71 case E_SYMBOL:
72 /* change 'm' into 'm' && MODULES */
73 if (e->left.sym == &symbol_mod)
74 return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
75 break;
76 default:
77 break;
78 }
79 return e;
80}
81
57void menu_add_dep(struct expr *dep) 82void menu_add_dep(struct expr *dep)
58{ 83{
59 current_entry->dep = expr_alloc_and(current_entry->dep, dep); 84 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
60} 85}
61 86
62void menu_set_type(int type) 87void menu_set_type(int type)
63{ 88{
64 struct symbol *sym = current_entry->sym; 89 struct symbol *sym = current_entry->sym;
65 90
66 if (sym->type == type) 91 if (sym->type == type)
67 return; 92 return;
68 if (sym->type == S_UNKNOWN) { 93 if (sym->type == S_UNKNOWN) {
69 sym->type = type; 94 sym->type = type;
70 return; 95 return;
71 } 96 }
72 fprintf(stderr, "%s:%d: type of '%s' redefined from '%s' to '%s'\n", 97 fprintf(stderr, "%s:%d:warning: type of '%s' redefined from '%s' to '%s'\n",
73 current_entry->file->name, current_entry->lineno, 98 current_entry->file->name, current_entry->lineno,
74 sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type)); 99 sym->name ? sym->name : "<choice>", sym_type_name(sym->type), sym_type_name(type));
75} 100}
76 101
77struct property *create_prop(enum prop_type type) 102struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
78{
79 struct property *prop;
80
81 prop = malloc(sizeof(*prop));
82 memset(prop, 0, sizeof(*prop));
83 prop->type = type;
84 prop->file = current_file;
85 prop->lineno = zconf_lineno();
86
87 return prop;
88}
89
90struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep)
91{ 103{
92 struct property *prop = create_prop(token); 104 struct property *prop = prop_alloc(type, current_entry->sym);
93 struct property **propp;
94 105
95 prop->sym = current_entry->sym;
96 prop->menu = current_entry; 106 prop->menu = current_entry;
97 prop->text = prompt; 107 prop->text = prompt;
98 prop->def = def; 108 prop->expr = expr;
99 E_EXPR(prop->visible) = dep; 109 prop->visible.expr = menu_check_dep(dep);
100 110
101 if (prompt) 111 if (prompt) {
112 if (current_entry->prompt)
113 fprintf(stderr, "%s:%d: prompt redefined\n",
114 current_entry->file->name, current_entry->lineno);
102 current_entry->prompt = prop; 115 current_entry->prompt = prop;
103
104 /* append property to the prop list of symbol */
105 if (prop->sym) {
106 for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
107 ;
108 *propp = prop;
109 } 116 }
110 117
111 return prop; 118 return prop;
112} 119}
113 120
114void menu_add_prompt(int token, char *prompt, struct expr *dep) 121void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
115{ 122{
116 current_entry->prompt = menu_add_prop(token, prompt, NULL, dep); 123 menu_add_prop(type, prompt, NULL, dep);
117} 124}
118 125
119void menu_add_default(int token, struct symbol *def, struct expr *dep) 126void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
120{ 127{
121 current_entry->prompt = menu_add_prop(token, NULL, def, dep); 128 menu_add_prop(type, NULL, expr, dep);
129}
130
131void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
132{
133 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
122} 134}
123 135
124void menu_finalize(struct menu *parent) 136void menu_finalize(struct menu *parent)
125{ 137{
126 struct menu *menu, *last_menu; 138 struct menu *menu, *last_menu;
127 struct symbol *sym; 139 struct symbol *sym;
128 struct property *prop; 140 struct property *prop;
129 struct expr *parentdep, *basedep, *dep, *dep2; 141 struct expr *parentdep, *basedep, *dep, *dep2, **ep;
130 142
131 sym = parent->sym; 143 sym = parent->sym;
132 if (parent->list) { 144 if (parent->list) {
133 if (sym && sym_is_choice(sym)) { 145 if (sym && sym_is_choice(sym)) {
134 /* find the first choice value and find out choice type */ 146 /* find the first choice value and find out choice type */
135 for (menu = parent->list; menu; menu = menu->next) { 147 for (menu = parent->list; menu; menu = menu->next) {
136 if (menu->sym) { 148 if (menu->sym) {
137 current_entry = parent; 149 current_entry = parent;
138 menu_set_type(menu->sym->type); 150 menu_set_type(menu->sym->type);
139 current_entry = menu; 151 current_entry = menu;
140 menu_set_type(sym->type); 152 menu_set_type(sym->type);
141 break; 153 break;
142 } 154 }
143 } 155 }
144 parentdep = expr_alloc_symbol(sym); 156 parentdep = expr_alloc_symbol(sym);
145 } else if (parent->prompt) 157 } else if (parent->prompt)
146 parentdep = E_EXPR(parent->prompt->visible); 158 parentdep = parent->prompt->visible.expr;
147 else 159 else
148 parentdep = parent->dep; 160 parentdep = parent->dep;
149 161
150 for (menu = parent->list; menu; menu = menu->next) { 162 for (menu = parent->list; menu; menu = menu->next) {
151 basedep = expr_transform(menu->dep); 163 basedep = expr_transform(menu->dep);
152 basedep = expr_alloc_and(expr_copy(parentdep), basedep); 164 basedep = expr_alloc_and(expr_copy(parentdep), basedep);
153 basedep = expr_eliminate_dups(basedep); 165 basedep = expr_eliminate_dups(basedep);
154 menu->dep = basedep; 166 menu->dep = basedep;
155 if (menu->sym) 167 if (menu->sym)
156 prop = menu->sym->prop; 168 prop = menu->sym->prop;
157 else 169 else
158 prop = menu->prompt; 170 prop = menu->prompt;
159 for (; prop; prop = prop->next) { 171 for (; prop; prop = prop->next) {
160 if (prop->menu != menu) 172 if (prop->menu != menu)
161 continue; 173 continue;
162 dep = expr_transform(E_EXPR(prop->visible)); 174 dep = expr_transform(prop->visible.expr);
163 dep = expr_alloc_and(expr_copy(basedep), dep); 175 dep = expr_alloc_and(expr_copy(basedep), dep);
164 dep = expr_eliminate_dups(dep); 176 dep = expr_eliminate_dups(dep);
165 if (menu->sym && menu->sym->type != S_TRISTATE) 177 if (menu->sym && menu->sym->type != S_TRISTATE)
166 dep = expr_trans_bool(dep); 178 dep = expr_trans_bool(dep);
167 E_EXPR(prop->visible) = dep; 179 prop->visible.expr = dep;
180 if (prop->type == P_SELECT) {
181 struct symbol *es = prop_get_symbol(prop);
182 es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
183 expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
184 }
168 } 185 }
169 } 186 }
170 for (menu = parent->list; menu; menu = menu->next) 187 for (menu = parent->list; menu; menu = menu->next)
171 menu_finalize(menu); 188 menu_finalize(menu);
172 } else if (sym && parent->prompt) { 189 } else if (sym) {
173 basedep = E_EXPR(parent->prompt->visible); 190 basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
174 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); 191 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
175 basedep = expr_eliminate_dups(expr_transform(basedep)); 192 basedep = expr_eliminate_dups(expr_transform(basedep));
176 last_menu = NULL; 193 last_menu = NULL;
177 for (menu = parent->next; menu; menu = menu->next) { 194 for (menu = parent->next; menu; menu = menu->next) {
178 dep = menu->prompt ? E_EXPR(menu->prompt->visible) : menu->dep; 195 dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
179 if (!expr_contains_symbol(dep, sym)) 196 if (!expr_contains_symbol(dep, sym))
180 break; 197 break;
181 if (expr_depends_symbol(dep, sym)) 198 if (expr_depends_symbol(dep, sym))
182 goto next; 199 goto next;
183 dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); 200 dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
184 dep = expr_eliminate_dups(expr_transform(dep)); 201 dep = expr_eliminate_dups(expr_transform(dep));
185 dep2 = expr_copy(basedep); 202 dep2 = expr_copy(basedep);
186 expr_eliminate_eq(&dep, &dep2); 203 expr_eliminate_eq(&dep, &dep2);
187 expr_free(dep); 204 expr_free(dep);
188 if (!expr_is_yes(dep2)) { 205 if (!expr_is_yes(dep2)) {
189 expr_free(dep2); 206 expr_free(dep2);
190 break; 207 break;
191 } 208 }
192 expr_free(dep2); 209 expr_free(dep2);
193 next: 210 next:
194 menu_finalize(menu); 211 menu_finalize(menu);
195 menu->parent = parent; 212 menu->parent = parent;
196 last_menu = menu; 213 last_menu = menu;
197 } 214 }
198 if (last_menu) { 215 if (last_menu) {
199 parent->list = parent->next; 216 parent->list = parent->next;
200 parent->next = last_menu->next; 217 parent->next = last_menu->next;
201 last_menu->next = NULL; 218 last_menu->next = NULL;
202 } 219 }
203 } 220 }
204 for (menu = parent->list; menu; menu = menu->next) { 221 for (menu = parent->list; menu; menu = menu->next) {
205 if (sym && sym_is_choice(sym) && menu->sym) { 222 if (sym && sym_is_choice(sym) && menu->sym) {
206 menu->sym->flags |= SYMBOL_CHOICEVAL; 223 menu->sym->flags |= SYMBOL_CHOICEVAL;
224 if (!menu->prompt)
225 fprintf(stderr, "%s:%d:warning: choice value must have a prompt\n",
226 menu->file->name, menu->lineno);
227 for (prop = menu->sym->prop; prop; prop = prop->next) {
228 if (prop->type == P_PROMPT && prop->menu != menu) {
229 fprintf(stderr, "%s:%d:warning: choice values currently only support a single prompt\n",
230 prop->file->name, prop->lineno);
231
232 }
233 if (prop->type == P_DEFAULT)
234 fprintf(stderr, "%s:%d:warning: defaults for choice values not supported\n",
235 prop->file->name, prop->lineno);
236 }
207 current_entry = menu; 237 current_entry = menu;
208 menu_set_type(sym->type); 238 menu_set_type(sym->type);
209 menu_add_prop(P_CHOICE, NULL, parent->sym, NULL); 239 menu_add_symbol(P_CHOICE, sym, NULL);
210 prop = sym_get_choice_prop(parent->sym); 240 prop = sym_get_choice_prop(sym);
211 //dep = expr_alloc_one(E_CHOICE, dep); 241 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
212 //dep->right.sym = menu->sym; 242 ;
213 prop->dep = expr_alloc_one(E_CHOICE, prop->dep); 243 *ep = expr_alloc_one(E_CHOICE, NULL);
214 prop->dep->right.sym = menu->sym; 244 (*ep)->right.sym = menu->sym;
215 } 245 }
216 if (menu->list && (!menu->prompt || !menu->prompt->text)) { 246 if (menu->list && (!menu->prompt || !menu->prompt->text)) {
217 for (last_menu = menu->list; ; last_menu = last_menu->next) { 247 for (last_menu = menu->list; ; last_menu = last_menu->next) {
218 last_menu->parent = parent; 248 last_menu->parent = parent;
219 if (!last_menu->next) 249 if (!last_menu->next)
220 break; 250 break;
221 } 251 }
222 last_menu->next = menu->next; 252 last_menu->next = menu->next;
223 menu->next = menu->list; 253 menu->next = menu->list;
224 menu->list = NULL; 254 menu->list = NULL;
225 } 255 }
226 } 256 }
257
258 if (sym && !(sym->flags & SYMBOL_WARNED)) {
259 struct symbol *sym2;
260 if (sym->type == S_UNKNOWN)
261 fprintf(stderr, "%s:%d:warning: config symbol defined without type\n",
262 parent->file->name, parent->lineno);
263
264 if (sym_is_choice(sym) && !parent->prompt)
265 fprintf(stderr, "%s:%d:warning: choice must have a prompt\n",
266 parent->file->name, parent->lineno);
267
268 for (prop = sym->prop; prop; prop = prop->next) {
269 switch (prop->type) {
270 case P_DEFAULT:
271 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
272 prop->expr->type != E_SYMBOL)
273 fprintf(stderr, "%s:%d:warning: default must be a single symbol\n",
274 prop->file->name, prop->lineno);
275 break;
276 case P_SELECT:
277 sym2 = prop_get_symbol(prop);
278 if ((sym->type != S_BOOLEAN && sym->type != S_TRISTATE) ||
279 (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE))
280 fprintf(stderr, "%s:%d:warning: enable is only allowed with boolean and tristate symbols\n",
281 prop->file->name, prop->lineno);
282 break;
283 case P_RANGE:
284 if (sym->type != S_INT && sym->type != S_HEX)
285 fprintf(stderr, "%s:%d:warning: range is only allowed for int or hex symbols\n",
286 prop->file->name, prop->lineno);
287 if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
288 !sym_string_valid(sym, prop->expr->right.sym->name))
289 fprintf(stderr, "%s:%d:warning: range is invalid\n",
290 prop->file->name, prop->lineno);
291 break;
292 default:
293 ;
294 }
295 }
296 sym->flags |= SYMBOL_WARNED;
297 }
298
299 if (sym && !sym_is_optional(sym) && parent->prompt) {
300 sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
301 expr_alloc_and(parent->prompt->visible.expr,
302 expr_alloc_symbol(&symbol_mod)));
303 }
227} 304}
228 305
229bool menu_is_visible(struct menu *menu) 306bool menu_is_visible(struct menu *menu)
230{ 307{
308 struct menu *child;
309 struct symbol *sym;
231 tristate visible; 310 tristate visible;
232 311
233 if (!menu->prompt) 312 if (!menu->prompt)
234 return false; 313 return false;
235 if (menu->sym) { 314 sym = menu->sym;
236 sym_calc_value(menu->sym); 315 if (sym) {
237 visible = E_TRI(menu->prompt->visible); 316 sym_calc_value(sym);
317 visible = menu->prompt->visible.tri;
238 } else 318 } else
239 visible = E_CALC(menu->prompt->visible); 319 visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
240 return visible != no; 320
321 if (visible != no)
322 return true;
323 if (!sym || sym_get_tristate_value(menu->sym) == no)
324 return false;
325
326 for (child = menu->list; child; child = child->next)
327 if (menu_is_visible(child))
328 return true;
329 return false;
241} 330}
242 331
243const char *menu_get_prompt(struct menu *menu) 332const char *menu_get_prompt(struct menu *menu)
244{ 333{
245 if (menu->prompt) 334 if (menu->prompt)
246 return menu->prompt->text; 335 return menu->prompt->text;
247 else if (menu->sym) 336 else if (menu->sym)
248 return menu->sym->name; 337 return menu->sym->name;
249 return NULL; 338 return NULL;
250} 339}
251 340
252struct menu *menu_get_root_menu(struct menu *menu) 341struct menu *menu_get_root_menu(struct menu *menu)
253{ 342{
254 return &rootmenu; 343 return &rootmenu;
255} 344}
256 345
257struct menu *menu_get_parent_menu(struct menu *menu) 346struct menu *menu_get_parent_menu(struct menu *menu)
258{ 347{
259 enum prop_type type; 348 enum prop_type type;
260 349
261 while (menu != &rootmenu) { 350 for (; menu != &rootmenu; menu = menu->parent) {
262 menu = menu->parent;
263 type = menu->prompt ? menu->prompt->type : 0; 351 type = menu->prompt ? menu->prompt->type : 0;
264 if (type == P_MENU || type == P_ROOTMENU) 352 if (type == P_MENU)
265 break; 353 break;
266 } 354 }
267 return menu; 355 return menu;
268} 356}
269 357
270struct file *file_lookup(const char *name) 358struct file *file_lookup(const char *name)
271{ 359{
272 struct file *file; 360 struct file *file;
273 361
274 for (file = file_list; file; file = file->next) { 362 for (file = file_list; file; file = file->next) {
275 if (!strcmp(name, file->name)) 363 if (!strcmp(name, file->name))
276 return file; 364 return file;
277 } 365 }
278 366
279 file = malloc(sizeof(*file)); 367 file = malloc(sizeof(*file));
280 memset(file, 0, sizeof(*file)); 368 memset(file, 0, sizeof(*file));
281 file->name = strdup(name); 369 file->name = strdup(name);
282 file->next = file_list; 370 file->next = file_list;
283 file_list = file; 371 file_list = file;
284 return file; 372 return file;
285} 373}
286 374
287int file_write_dep(const char *name) 375int file_write_dep(const char *name)
288{ 376{
289 struct file *file; 377 struct file *file;
290 FILE *out; 378 FILE *out;
291 379
292 if (!name) 380 if (!name)
293 name = ".config.cmd"; 381 name = ".config.cmd";
294 out = fopen("..config.tmp", "w"); 382 out = fopen("..config.tmp", "w");
295 if (!out) 383 if (!out)
296 return 1; 384 return 1;
297 fprintf(out, "deps_config := \\\n"); 385 fprintf(out, "deps_config := \\\n");
298 for (file = file_list; file; file = file->next) { 386 for (file = file_list; file; file = file->next) {
299 if (file->next) 387 if (file->next)
300 fprintf(out, "\t%s \\\n", file->name); 388 fprintf(out, "\t%s \\\n", file->name);
301 else 389 else
302 fprintf(out, "\t%s\n", file->name); 390 fprintf(out, "\t%s\n", file->name);
303 } 391 }
304 fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n"); 392 fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
305 fclose(out); 393 fclose(out);
306 rename("..config.tmp", name); 394 rename("..config.tmp", name);
307 return 0; 395 return 0;
308} 396}
309 397
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index bed541d..52419ad 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1,1203 +1,1304 @@
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 20#if QT_VERSION >= 300
21#include <qsettings.h> 21#include <qsettings.h>
22#endif 22#endif
23 23
24#include <stdlib.h> 24#include <stdlib.h>
25 25
26#include "lkc.h" 26#include "lkc.h"
27#include "qconf.h" 27#include "qconf.h"
28 28
29#include "qconf.moc" 29#include "qconf.moc"
30#include "images.c" 30#include "images.c"
31 31
32static QApplication *configApp; 32static QApplication *configApp;
33#if QT_VERSION >= 300 33#if QT_VERSION >= 300
34static QSettings *configSettings; 34static QSettings *configSettings;
35#endif 35#endif
36 36
37/* 37/*
38 * update all the children of a menu entry 38 * update all the children of a menu entry
39 * removes/adds the entries from the parent widget as necessary 39 * removes/adds the entries from the parent widget as necessary
40 * 40 *
41 * parent: either the menu list widget or a menu entry widget 41 * parent: either the menu list widget or a menu entry widget
42 * menu: entry to be updated 42 * menu: entry to be updated
43 */ 43 */
44template <class P> 44template <class P>
45static void updateMenuList(P* parent, struct menu* menu) 45void ConfigList::updateMenuList(P* parent, struct menu* menu)
46{ 46{
47 struct menu* child; 47 struct menu* child;
48 ConfigList* list = parent->listView();
49 ConfigItem* item; 48 ConfigItem* item;
50 ConfigItem* last; 49 ConfigItem* last;
51 bool visible; 50 bool visible;
52 bool showAll = list->showAll;
53 enum listMode mode = list->mode;
54 enum prop_type type; 51 enum prop_type type;
55 52
56 if (!menu) { 53 if (!menu) {
57 while ((item = parent->firstChild())) 54 while ((item = parent->firstChild()))
58 delete item; 55 delete item;
59 return; 56 return;
60 } 57 }
61 58
62 last = 0; 59 last = parent->firstChild();
60 if (last && !last->goParent)
61 last = 0;
63 for (child = menu->list; child; child = child->next) { 62 for (child = menu->list; child; child = child->next) {
64 item = last ? last->nextSibling() : parent->firstChild(); 63 item = last ? last->nextSibling() : parent->firstChild();
65 type = child->prompt ? child->prompt->type : P_UNKNOWN; 64 type = child->prompt ? child->prompt->type : P_UNKNOWN;
66 65
67 switch (mode) { 66 switch (mode) {
68 case menuMode: 67 case menuMode:
69 if (type != P_ROOTMENU) 68 if (!(child->flags & MENU_ROOT))
70 goto hide; 69 goto hide;
71 break; 70 break;
72 case symbolMode: 71 case symbolMode:
73 if (type == P_ROOTMENU) 72 if (child->flags & MENU_ROOT)
74 goto hide; 73 goto hide;
75 break; 74 break;
76 default: 75 default:
77 break; 76 break;
78 } 77 }
79 78
80 visible = menu_is_visible(child); 79 visible = menu_is_visible(child);
81 if (showAll || visible) { 80 if (showAll || visible) {
82 if (!item || item->menu != child) 81 if (!item || item->menu != child)
83 item = new ConfigItem(parent, last, child, visible); 82 item = new ConfigItem(parent, last, child, visible);
84 else { 83 else
85 item->visible = visible; 84 item->testUpdateMenu(visible);
86 if (item->updateNeeded()) {
87 ConfigItem* i = (ConfigItem*)child->data;
88 for (; i; i = i->nextItem) {
89 i->updateMenu();
90 }
91 } else if (list->updateAll)
92 item->updateMenu();
93 }
94 85
95 if (mode == fullMode || mode == menuMode || 86 if (mode == fullMode || mode == menuMode || type != P_MENU)
96 (type != P_MENU && type != P_ROOTMENU))
97 updateMenuList(item, child); 87 updateMenuList(item, child);
98 else 88 else
99 updateMenuList(item, 0); 89 updateMenuList(item, 0);
100 last = item; 90 last = item;
101 continue; 91 continue;
102 } 92 }
103 hide: 93 hide:
104 if (item && item->menu == child) { 94 if (item && item->menu == child) {
105 last = parent->firstChild(); 95 last = parent->firstChild();
106 if (last == item) 96 if (last == item)
107 last = 0; 97 last = 0;
108 else while (last->nextSibling() != item) 98 else while (last->nextSibling() != item)
109 last = last->nextSibling(); 99 last = last->nextSibling();
110 delete item; 100 delete item;
111 } 101 }
112 } 102 }
113} 103}
114 104
115#if QT_VERSION >= 300 105#if QT_VERSION >= 300
116/* 106/*
117 * set the new data 107 * set the new data
118 * TODO check the value 108 * TODO check the value
119 */ 109 */
120void ConfigItem::okRename(int col) 110void ConfigItem::okRename(int col)
121{ 111{
122 Parent::okRename(col); 112 Parent::okRename(col);
123 sym_set_string_value(menu->sym, text(dataColIdx).latin1()); 113 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
124} 114}
125#endif 115#endif
126 116
127/* 117/*
128 * update the displayed of a menu entry 118 * update the displayed of a menu entry
129 */ 119 */
130void ConfigItem::updateMenu(void) 120void ConfigItem::updateMenu(void)
131{ 121{
132 ConfigList* list; 122 ConfigList* list;
133 struct symbol* sym; 123 struct symbol* sym;
124 struct property *prop;
134 QString prompt; 125 QString prompt;
135 int type; 126 int type;
136 enum prop_type ptype;
137 tristate expr; 127 tristate expr;
138 128
139 list = listView(); 129 list = listView();
130 if (goParent) {
131 setPixmap(promptColIdx, list->menuBackPix);
132 prompt = "..";
133 goto set_prompt;
134 }
140 135
141 sym = menu->sym; 136 sym = menu->sym;
142 if (!sym) { 137 prop = menu->prompt;
143 setText(promptColIdx, menu_get_prompt(menu)); 138 prompt = menu_get_prompt(menu);
144 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 139
145 if ((ptype == P_ROOTMENU || ptype == P_MENU) && 140 if (prop) switch (prop->type) {
146 (list->mode == singleMode || list->mode == symbolMode)) 141 case P_MENU:
142 if (list->mode == singleMode || list->mode == symbolMode) {
143 /* a menuconfig entry is displayed differently
144 * depending whether it's at the view root or a child.
145 */
146 if (sym && list->rootEntry == menu)
147 break;
147 setPixmap(promptColIdx, list->menuPix); 148 setPixmap(promptColIdx, list->menuPix);
148 else 149 } else {
150 if (sym)
151 break;
149 setPixmap(promptColIdx, 0); 152 setPixmap(promptColIdx, 0);
150 return; 153 }
154 goto set_prompt;
155 case P_COMMENT:
156 setPixmap(promptColIdx, 0);
157 goto set_prompt;
158 default:
159 ;
151 } 160 }
161 if (!sym)
162 goto set_prompt;
152 163
153 setText(nameColIdx, sym->name); 164 setText(nameColIdx, sym->name);
154 165
155 type = sym_get_type(sym); 166 type = sym_get_type(sym);
156 switch (type) { 167 switch (type) {
157 case S_BOOLEAN: 168 case S_BOOLEAN:
158 case S_TRISTATE: 169 case S_TRISTATE:
159 char ch; 170 char ch;
160 171
161 prompt = menu_get_prompt(menu);
162 if (!sym_is_changable(sym) && !list->showAll) { 172 if (!sym_is_changable(sym) && !list->showAll) {
173 setPixmap(promptColIdx, 0);
163 setText(noColIdx, 0); 174 setText(noColIdx, 0);
164 setText(modColIdx, 0); 175 setText(modColIdx, 0);
165 setText(yesColIdx, 0); 176 setText(yesColIdx, 0);
166 break; 177 break;
167 } 178 }
168 expr = sym_get_tristate_value(sym); 179 expr = sym_get_tristate_value(sym);
169 switch (expr) { 180 switch (expr) {
170 case yes: 181 case yes:
171 if (sym_is_choice_value(sym) && type == S_BOOLEAN) 182 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
172 setPixmap(promptColIdx, list->choiceYesPix); 183 setPixmap(promptColIdx, list->choiceYesPix);
173 else 184 else
174 setPixmap(promptColIdx, list->symbolYesPix); 185 setPixmap(promptColIdx, list->symbolYesPix);
175 setText(yesColIdx, "Y"); 186 setText(yesColIdx, "Y");
176 ch = 'Y'; 187 ch = 'Y';
177 break; 188 break;
178 case mod: 189 case mod:
179 setPixmap(promptColIdx, list->symbolModPix); 190 setPixmap(promptColIdx, list->symbolModPix);
180 setText(modColIdx, "M"); 191 setText(modColIdx, "M");
181 ch = 'M'; 192 ch = 'M';
182 break; 193 break;
183 default: 194 default:
184 if (sym_is_choice_value(sym) && type == S_BOOLEAN) 195 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
185 setPixmap(promptColIdx, list->choiceNoPix); 196 setPixmap(promptColIdx, list->choiceNoPix);
186 else 197 else
187 setPixmap(promptColIdx, list->symbolNoPix); 198 setPixmap(promptColIdx, list->symbolNoPix);
188 setText(noColIdx, "N"); 199 setText(noColIdx, "N");
189 ch = 'N'; 200 ch = 'N';
190 break; 201 break;
191 } 202 }
192 if (expr != no) 203 if (expr != no)
193 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0); 204 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
194 if (expr != mod) 205 if (expr != mod)
195 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0); 206 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
196 if (expr != yes) 207 if (expr != yes)
197 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0); 208 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
198 209
199 setText(dataColIdx, QChar(ch)); 210 setText(dataColIdx, QChar(ch));
200 break; 211 break;
201 case S_INT: 212 case S_INT:
202 case S_HEX: 213 case S_HEX:
203 case S_STRING: 214 case S_STRING:
204 const char* data; 215 const char* data;
205 216
206 data = sym_get_string_value(sym); 217 data = sym_get_string_value(sym);
207#if QT_VERSION >= 300 218#if QT_VERSION >= 300
208 int i = list->mapIdx(dataColIdx); 219 int i = list->mapIdx(dataColIdx);
209 if (i >= 0) 220 if (i >= 0)
210 setRenameEnabled(i, TRUE); 221 setRenameEnabled(i, TRUE);
211#endif 222#endif
212 setText(dataColIdx, data); 223 setText(dataColIdx, data);
213 if (type == S_STRING) 224 if (type == S_STRING)
214 prompt.sprintf("%s: %s", menu_get_prompt(menu), data); 225 prompt.sprintf("%s: %s", prompt.latin1(), data);
215 else 226 else
216 prompt.sprintf("(%s) %s", data, menu_get_prompt(menu)); 227 prompt.sprintf("(%s) %s", data, prompt.latin1());
217 break; 228 break;
218 } 229 }
219 if (!sym_has_value(sym) && visible) 230 if (!sym_has_value(sym) && visible)
220 prompt += " (NEW)"; 231 prompt += " (NEW)";
232set_prompt:
221 setText(promptColIdx, prompt); 233 setText(promptColIdx, prompt);
222} 234}
223 235
224bool ConfigItem::updateNeeded(void) 236void ConfigItem::testUpdateMenu(bool v)
225{ 237{
226 struct symbol* sym = menu->sym; 238 ConfigItem* i;
227 if (sym) 239
228 sym_calc_value(sym); 240 visible = v;
241 if (!menu)
242 return;
243
244 sym_calc_value(menu->sym);
229 if (menu->flags & MENU_CHANGED) { 245 if (menu->flags & MENU_CHANGED) {
246 /* the menu entry changed, so update all list items */
230 menu->flags &= ~MENU_CHANGED; 247 menu->flags &= ~MENU_CHANGED;
231 return true; 248 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
232 } 249 i->updateMenu();
233 return false; 250 } else if (listView()->updateAll)
251 updateMenu();
234} 252}
235 253
236void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align) 254void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
237{ 255{
238 ConfigList* list = listView(); 256 ConfigList* list = listView();
239 257
240 if (visible) { 258 if (visible) {
241 if (isSelected() && !list->hasFocus() && list->mode == menuMode) 259 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
242 Parent::paintCell(p, list->inactivedColorGroup, column, width, align); 260 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
243 else 261 else
244 Parent::paintCell(p, cg, column, width, align); 262 Parent::paintCell(p, cg, column, width, align);
245 } else 263 } else
246 Parent::paintCell(p, list->disabledColorGroup, column, width, align); 264 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
247} 265}
248 266
249/* 267/*
250 * construct a menu entry 268 * construct a menu entry
251 */ 269 */
252void ConfigItem::init(void) 270void ConfigItem::init(void)
253{ 271{
254 ConfigList* list = listView(); 272 if (menu) {
255 nextItem = (ConfigItem*)menu->data; 273 ConfigList* list = listView();
256 menu->data = this; 274 nextItem = (ConfigItem*)menu->data;
275 menu->data = this;
257 276
258 if (list->mode != fullMode) 277 if (list->mode != fullMode)
259 setOpen(TRUE); 278 setOpen(TRUE);
260 if (menu->sym)
261 sym_calc_value(menu->sym); 279 sym_calc_value(menu->sym);
280 }
262 updateMenu(); 281 updateMenu();
263} 282}
264 283
265/* 284/*
266 * destruct a menu entry 285 * destruct a menu entry
267 */ 286 */
268ConfigItem::~ConfigItem(void) 287ConfigItem::~ConfigItem(void)
269{ 288{
270 ConfigItem** ip = &(ConfigItem*)menu->data; 289 if (menu) {
271 for (; *ip; ip = &(*ip)->nextItem) { 290 ConfigItem** ip = (ConfigItem**)&menu->data;
272 if (*ip == this) { 291 for (; *ip; ip = &(*ip)->nextItem) {
273 *ip = nextItem; 292 if (*ip == this) {
274 break; 293 *ip = nextItem;
294 break;
295 }
275 } 296 }
276 } 297 }
277} 298}
278 299
279void ConfigLineEdit::show(ConfigItem* i) 300void ConfigLineEdit::show(ConfigItem* i)
280{ 301{
281 item = i; 302 item = i;
282 if (sym_get_string_value(item->menu->sym)) 303 if (sym_get_string_value(item->menu->sym))
283 setText(sym_get_string_value(item->menu->sym)); 304 setText(sym_get_string_value(item->menu->sym));
284 else 305 else
285 setText(0); 306 setText(0);
286 Parent::show(); 307 Parent::show();
287 setFocus(); 308 setFocus();
288} 309}
289 310
290void ConfigLineEdit::keyPressEvent(QKeyEvent* e) 311void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
291{ 312{
292 switch (e->key()) { 313 switch (e->key()) {
293 case Key_Escape: 314 case Key_Escape:
294 break; 315 break;
295 case Key_Return: 316 case Key_Return:
296 case Key_Enter: 317 case Key_Enter:
297 sym_set_string_value(item->menu->sym, text().latin1()); 318 sym_set_string_value(item->menu->sym, text().latin1());
298 parent()->updateList(item); 319 parent()->updateList(item);
299 break; 320 break;
300 default: 321 default:
301 Parent::keyPressEvent(e); 322 Parent::keyPressEvent(e);
302 return; 323 return;
303 } 324 }
304 e->accept(); 325 e->accept();
305 parent()->list->setFocus(); 326 parent()->list->setFocus();
306 hide(); 327 hide();
307} 328}
308 329
309ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv) 330ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv)
310 : Parent(p), cview(cv), 331 : Parent(p), cview(cv),
311 updateAll(false), 332 updateAll(false),
312 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), 333 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
313 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), 334 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
335 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
314 showAll(false), showName(false), showRange(false), showData(false), 336 showAll(false), showName(false), showRange(false), showData(false),
315 rootEntry(0) 337 rootEntry(0)
316{ 338{
317 int i; 339 int i;
318 340
319 setSorting(-1); 341 setSorting(-1);
320 setRootIsDecorated(TRUE); 342 setRootIsDecorated(TRUE);
321 disabledColorGroup = palette().active(); 343 disabledColorGroup = palette().active();
322 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text()); 344 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
323 inactivedColorGroup = palette().active(); 345 inactivedColorGroup = palette().active();
324 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight()); 346 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
325 347
326 connect(this, SIGNAL(selectionChanged(void)), 348 connect(this, SIGNAL(selectionChanged(void)),
327 SLOT(updateSelection(void))); 349 SLOT(updateSelection(void)));
328 350
329 for (i = 0; i < colNr; i++) 351 for (i = 0; i < colNr; i++)
330 colMap[i] = colRevMap[i] = -1; 352 colMap[i] = colRevMap[i] = -1;
331 addColumn(promptColIdx, "Option"); 353 addColumn(promptColIdx, "Option");
332 354
333 reinit(); 355 reinit();
334} 356}
335 357
336void ConfigList::reinit(void) 358void ConfigList::reinit(void)
337{ 359{
338 removeColumn(dataColIdx); 360 removeColumn(dataColIdx);
339 removeColumn(yesColIdx); 361 removeColumn(yesColIdx);
340 removeColumn(modColIdx); 362 removeColumn(modColIdx);
341 removeColumn(noColIdx); 363 removeColumn(noColIdx);
342 removeColumn(nameColIdx); 364 removeColumn(nameColIdx);
343 365
344 if (showName) 366 if (showName)
345 addColumn(nameColIdx, "Name"); 367 addColumn(nameColIdx, "Name");
346 if (showRange) { 368 if (showRange) {
347 addColumn(noColIdx, "N"); 369 addColumn(noColIdx, "N");
348 addColumn(modColIdx, "M"); 370 addColumn(modColIdx, "M");
349 addColumn(yesColIdx, "Y"); 371 addColumn(yesColIdx, "Y");
350 } 372 }
351 if (showData) 373 if (showData)
352 addColumn(dataColIdx, "Value"); 374 addColumn(dataColIdx, "Value");
353 375
354 updateListAll(); 376 updateListAll();
355} 377}
356 378
357void ConfigList::updateSelection(void) 379void ConfigList::updateSelection(void)
358{ 380{
359 struct menu *menu; 381 struct menu *menu;
360 enum prop_type type; 382 enum prop_type type;
361 383
362 ConfigItem* item = (ConfigItem*)selectedItem(); 384 ConfigItem* item = (ConfigItem*)selectedItem();
363 if (!item) 385 if (!item)
364 return; 386 return;
365 387
366 cview->setHelp(item); 388 cview->setHelp(item);
367 389
368 menu = item->menu; 390 menu = item->menu;
391 if (!menu)
392 return;
369 type = menu->prompt ? menu->prompt->type : P_UNKNOWN; 393 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
370 if (mode == menuMode && (type == P_MENU || type == P_ROOTMENU)) 394 if (mode == menuMode && type == P_MENU)
371 emit menuSelected(menu); 395 emit menuSelected(menu);
372} 396}
373 397
374void ConfigList::updateList(ConfigItem* item) 398void ConfigList::updateList(ConfigItem* item)
375{ 399{
376 (void)item;// unused so far 400 ConfigItem* last = 0;
401
402 if (!rootEntry)
403 goto update;
404
405 if (rootEntry != &rootmenu && (mode == singleMode ||
406 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
407 item = firstChild();
408 if (!item)
409 item = new ConfigItem(this, 0, true);
410 last = item;
411 }
412 if (mode == singleMode && rootEntry->sym && rootEntry->prompt) {
413 item = last ? last->nextSibling() : firstChild();
414 if (!item)
415 item = new ConfigItem(this, last, rootEntry, true);
416
417 updateMenuList(item, rootEntry);
418 triggerUpdate();
419 return;
420 }
421update:
377 updateMenuList(this, rootEntry); 422 updateMenuList(this, rootEntry);
378 triggerUpdate(); 423 triggerUpdate();
379} 424}
380 425
381void ConfigList::setAllOpen(bool open) 426void ConfigList::setAllOpen(bool open)
382{ 427{
383 QListViewItemIterator it(this); 428 QListViewItemIterator it(this);
384 429
385 for (; it.current(); it++) 430 for (; it.current(); it++)
386 it.current()->setOpen(open); 431 it.current()->setOpen(open);
387} 432}
388 433
389void ConfigList::setValue(ConfigItem* item, tristate val) 434void ConfigList::setValue(ConfigItem* item, tristate val)
390{ 435{
391 struct symbol* sym; 436 struct symbol* sym;
392 int type; 437 int type;
393 tristate oldval; 438 tristate oldval;
394 439
395 sym = item->menu->sym; 440 sym = item->menu ? item->menu->sym : 0;
396 if (!sym) 441 if (!sym)
397 return; 442 return;
398 443
399 type = sym_get_type(sym); 444 type = sym_get_type(sym);
400 switch (type) { 445 switch (type) {
401 case S_BOOLEAN: 446 case S_BOOLEAN:
402 case S_TRISTATE: 447 case S_TRISTATE:
403 oldval = sym_get_tristate_value(sym); 448 oldval = sym_get_tristate_value(sym);
404 449
405 if (!sym_set_tristate_value(sym, val)) 450 if (!sym_set_tristate_value(sym, val))
406 return; 451 return;
407 if (oldval == no && item->menu->list) 452 if (oldval == no && item->menu->list)
408 item->setOpen(TRUE); 453 item->setOpen(TRUE);
409 parent()->updateList(item); 454 parent()->updateList(item);
410 break; 455 break;
411 } 456 }
412} 457}
413 458
414void ConfigList::changeValue(ConfigItem* item) 459void ConfigList::changeValue(ConfigItem* item)
415{ 460{
416 struct symbol* sym; 461 struct symbol* sym;
417 struct menu* menu; 462 struct menu* menu;
418 int type, oldexpr, newexpr; 463 int type, oldexpr, newexpr;
419 464
420 menu = item->menu; 465 menu = item->menu;
466 if (!menu)
467 return;
421 sym = menu->sym; 468 sym = menu->sym;
422 if (!sym) { 469 if (!sym) {
423 if (item->menu->list) 470 if (item->menu->list)
424 item->setOpen(!item->isOpen()); 471 item->setOpen(!item->isOpen());
425 return; 472 return;
426 } 473 }
427 474
428 type = sym_get_type(sym); 475 type = sym_get_type(sym);
429 switch (type) { 476 switch (type) {
430 case S_BOOLEAN: 477 case S_BOOLEAN:
431 case S_TRISTATE: 478 case S_TRISTATE:
432 oldexpr = sym_get_tristate_value(sym); 479 oldexpr = sym_get_tristate_value(sym);
433 newexpr = sym_toggle_tristate_value(sym); 480 newexpr = sym_toggle_tristate_value(sym);
434 if (item->menu->list) { 481 if (item->menu->list) {
435 if (oldexpr == newexpr) 482 if (oldexpr == newexpr)
436 item->setOpen(!item->isOpen()); 483 item->setOpen(!item->isOpen());
437 else if (oldexpr == no) 484 else if (oldexpr == no)
438 item->setOpen(TRUE); 485 item->setOpen(TRUE);
439 } 486 }
440 if (oldexpr != newexpr) 487 if (oldexpr != newexpr)
441 parent()->updateList(item); 488 parent()->updateList(item);
442 break; 489 break;
443 case S_INT: 490 case S_INT:
444 case S_HEX: 491 case S_HEX:
445 case S_STRING: 492 case S_STRING:
446#if QT_VERSION >= 300 493#if QT_VERSION >= 300
447 if (colMap[dataColIdx] >= 0) 494 if (colMap[dataColIdx] >= 0)
448 item->startRename(colMap[dataColIdx]); 495 item->startRename(colMap[dataColIdx]);
449 else 496 else
450#endif 497#endif
451 parent()->lineEdit->show(item); 498 parent()->lineEdit->show(item);
452 break; 499 break;
453 } 500 }
454} 501}
455 502
456void ConfigList::setRootMenu(struct menu *menu) 503void ConfigList::setRootMenu(struct menu *menu)
457{ 504{
458 enum prop_type type; 505 enum prop_type type;
459 506
460 if (rootEntry == menu) 507 if (rootEntry == menu)
461 return; 508 return;
462 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN; 509 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
463 if (type != P_MENU && type != P_ROOTMENU) 510 if (type != P_MENU)
464 return; 511 return;
465 updateMenuList(this, 0); 512 updateMenuList(this, 0);
466 rootEntry = menu; 513 rootEntry = menu;
467 updateListAll(); 514 updateListAll();
468 setSelected(currentItem(), hasFocus()); 515 setSelected(currentItem(), hasFocus());
469} 516}
470 517
471void ConfigList::setParentMenu(void) 518void ConfigList::setParentMenu(void)
472{ 519{
473 ConfigItem* item; 520 ConfigItem* item;
474 struct menu *oldroot, *newroot; 521 struct menu *oldroot;
475 522
476 oldroot = rootEntry; 523 oldroot = rootEntry;
477 newroot = menu_get_parent_menu(oldroot); 524 if (rootEntry == &rootmenu)
478 if (newroot == oldroot)
479 return; 525 return;
480 setRootMenu(newroot); 526 setRootMenu(menu_get_parent_menu(rootEntry->parent));
481 527
482 QListViewItemIterator it(this); 528 QListViewItemIterator it(this);
483 for (; (item = (ConfigItem*)it.current()); it++) { 529 for (; (item = (ConfigItem*)it.current()); it++) {
484 if (item->menu == oldroot) { 530 if (item->menu == oldroot) {
485 setCurrentItem(item); 531 setCurrentItem(item);
486 ensureItemVisible(item); 532 ensureItemVisible(item);
487 break; 533 break;
488 } 534 }
489 } 535 }
490} 536}
491 537
492void ConfigList::keyPressEvent(QKeyEvent* ev) 538void ConfigList::keyPressEvent(QKeyEvent* ev)
493{ 539{
494 QListViewItem* i = currentItem(); 540 QListViewItem* i = currentItem();
495 ConfigItem* item; 541 ConfigItem* item;
496 struct menu *menu; 542 struct menu *menu;
497 enum prop_type type; 543 enum prop_type type;
498 544
499 if (ev->key() == Key_Escape && mode != fullMode) { 545 if (ev->key() == Key_Escape && mode != fullMode) {
500 emit parentSelected(); 546 emit parentSelected();
501 ev->accept(); 547 ev->accept();
502 return; 548 return;
503 } 549 }
504 550
505 if (!i) { 551 if (!i) {
506 Parent::keyPressEvent(ev); 552 Parent::keyPressEvent(ev);
507 return; 553 return;
508 } 554 }
509 item = (ConfigItem*)i; 555 item = (ConfigItem*)i;
510 556
511 switch (ev->key()) { 557 switch (ev->key()) {
512 case Key_Return: 558 case Key_Return:
513 case Key_Enter: 559 case Key_Enter:
560 if (item->goParent) {
561 emit parentSelected();
562 break;
563 }
514 menu = item->menu; 564 menu = item->menu;
565 if (!menu)
566 break;
515 type = menu->prompt ? menu->prompt->type : P_UNKNOWN; 567 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
516 if ((type == P_MENU || type == P_ROOTMENU) && mode != fullMode) { 568 if (type == P_MENU && rootEntry != menu &&
569 mode != fullMode && mode != menuMode) {
517 emit menuSelected(menu); 570 emit menuSelected(menu);
518 break; 571 break;
519 } 572 }
520 case Key_Space: 573 case Key_Space:
521 changeValue(item); 574 changeValue(item);
522 break; 575 break;
523 case Key_N: 576 case Key_N:
524 setValue(item, no); 577 setValue(item, no);
525 break; 578 break;
526 case Key_M: 579 case Key_M:
527 setValue(item, mod); 580 setValue(item, mod);
528 break; 581 break;
529 case Key_Y: 582 case Key_Y:
530 setValue(item, yes); 583 setValue(item, yes);
531 break; 584 break;
532 default: 585 default:
533 Parent::keyPressEvent(ev); 586 Parent::keyPressEvent(ev);
534 return; 587 return;
535 } 588 }
536 ev->accept(); 589 ev->accept();
537} 590}
538 591
539void ConfigList::contentsMousePressEvent(QMouseEvent* e) 592void ConfigList::contentsMousePressEvent(QMouseEvent* e)
540{ 593{
541 //QPoint p(contentsToViewport(e->pos())); 594 //QPoint p(contentsToViewport(e->pos()));
542 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); 595 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
543 Parent::contentsMousePressEvent(e); 596 Parent::contentsMousePressEvent(e);
544} 597}
545 598
546void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) 599void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
547{ 600{
548 QPoint p(contentsToViewport(e->pos())); 601 QPoint p(contentsToViewport(e->pos()));
549 ConfigItem* item = (ConfigItem*)itemAt(p); 602 ConfigItem* item = (ConfigItem*)itemAt(p);
550 struct menu *menu; 603 struct menu *menu;
604 enum prop_type ptype;
551 const QPixmap* pm; 605 const QPixmap* pm;
552 int idx, x; 606 int idx, x;
553 607
554 if (!item) 608 if (!item)
555 goto skip; 609 goto skip;
556 610
557 menu = item->menu; 611 menu = item->menu;
558 x = header()->offset() + p.x(); 612 x = header()->offset() + p.x();
559 idx = colRevMap[header()->sectionAt(x)]; 613 idx = colRevMap[header()->sectionAt(x)];
560 switch (idx) { 614 switch (idx) {
561 case promptColIdx: 615 case promptColIdx:
562 pm = item->pixmap(promptColIdx); 616 pm = item->pixmap(promptColIdx);
563 if (pm) { 617 if (pm) {
564 int off = header()->sectionPos(0) + itemMargin() + 618 int off = header()->sectionPos(0) + itemMargin() +
565 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0)); 619 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
566 if (x >= off && x < off + pm->width()) { 620 if (x >= off && x < off + pm->width()) {
567 if (menu->sym) 621 if (item->goParent) {
568 changeValue(item); 622 emit parentSelected();
569 else 623 break;
624 } else if (!menu)
625 break;
626 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
627 if (ptype == P_MENU && rootEntry != menu &&
628 mode != fullMode && mode != menuMode)
570 emit menuSelected(menu); 629 emit menuSelected(menu);
630 else
631 changeValue(item);
571 } 632 }
572 } 633 }
573 break; 634 break;
574 case noColIdx: 635 case noColIdx:
575 setValue(item, no); 636 setValue(item, no);
576 break; 637 break;
577 case modColIdx: 638 case modColIdx:
578 setValue(item, mod); 639 setValue(item, mod);
579 break; 640 break;
580 case yesColIdx: 641 case yesColIdx:
581 setValue(item, yes); 642 setValue(item, yes);
582 break; 643 break;
583 case dataColIdx: 644 case dataColIdx:
584 changeValue(item); 645 changeValue(item);
585 break; 646 break;
586 } 647 }
587 648
588skip: 649skip:
589 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y()); 650 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
590 Parent::contentsMouseReleaseEvent(e); 651 Parent::contentsMouseReleaseEvent(e);
591} 652}
592 653
593void ConfigList::contentsMouseMoveEvent(QMouseEvent* e) 654void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
594{ 655{
595 //QPoint p(contentsToViewport(e->pos())); 656 //QPoint p(contentsToViewport(e->pos()));
596 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); 657 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
597 Parent::contentsMouseMoveEvent(e); 658 Parent::contentsMouseMoveEvent(e);
598} 659}
599 660
600void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) 661void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
601{ 662{
602 QPoint p(contentsToViewport(e->pos())); 663 QPoint p(contentsToViewport(e->pos()));
603 ConfigItem* item = (ConfigItem*)itemAt(p); 664 ConfigItem* item = (ConfigItem*)itemAt(p);
604 struct menu *menu; 665 struct menu *menu;
605 enum prop_type ptype; 666 enum prop_type ptype;
606 667
607 if (!item) 668 if (!item)
608 goto skip; 669 goto skip;
670 if (item->goParent) {
671 emit parentSelected();
672 goto skip;
673 }
609 menu = item->menu; 674 menu = item->menu;
675 if (!menu)
676 goto skip;
610 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 677 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
611 if ((ptype == P_ROOTMENU || ptype == P_MENU) && 678 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
612 (mode == singleMode || mode == symbolMode))
613 emit menuSelected(menu); 679 emit menuSelected(menu);
614 else if (menu->sym) 680 else if (menu->sym)
615 changeValue(item); 681 changeValue(item);
616 682
617skip: 683skip:
618 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y()); 684 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
619 Parent::contentsMouseDoubleClickEvent(e); 685 Parent::contentsMouseDoubleClickEvent(e);
620} 686}
621 687
622void ConfigList::focusInEvent(QFocusEvent *e) 688void ConfigList::focusInEvent(QFocusEvent *e)
623{ 689{
624 Parent::focusInEvent(e); 690 Parent::focusInEvent(e);
625 691
626 QListViewItem* item = currentItem(); 692 QListViewItem* item = currentItem();
627 if (!item) 693 if (!item)
628 return; 694 return;
629 695
630 setSelected(item, TRUE); 696 setSelected(item, TRUE);
631 emit gotFocus(); 697 emit gotFocus();
632} 698}
633 699
634ConfigView* ConfigView::viewList; 700ConfigView* ConfigView::viewList;
635 701
636ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview) 702ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview)
637 : Parent(parent) 703 : Parent(parent)
638{ 704{
639 list = new ConfigList(this, cview); 705 list = new ConfigList(this, cview);
640 lineEdit = new ConfigLineEdit(this); 706 lineEdit = new ConfigLineEdit(this);
641 lineEdit->hide(); 707 lineEdit->hide();
642 708
643 this->nextView = viewList; 709 this->nextView = viewList;
644 viewList = this; 710 viewList = this;
645} 711}
646 712
647ConfigView::~ConfigView(void) 713ConfigView::~ConfigView(void)
648{ 714{
649 ConfigView** vp; 715 ConfigView** vp;
650 716
651 for (vp = &viewList; *vp; vp = &(*vp)->nextView) { 717 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
652 if (*vp == this) { 718 if (*vp == this) {
653 *vp = nextView; 719 *vp = nextView;
654 break; 720 break;
655 } 721 }
656 } 722 }
657} 723}
658 724
659void ConfigView::updateList(ConfigItem* item) 725void ConfigView::updateList(ConfigItem* item)
660{ 726{
661 ConfigView* v; 727 ConfigView* v;
662 728
663 for (v = viewList; v; v = v->nextView) 729 for (v = viewList; v; v = v->nextView)
664 v->list->updateList(item); 730 v->list->updateList(item);
665} 731}
666 732
667void ConfigView::updateListAll(void) 733void ConfigView::updateListAll(void)
668{ 734{
669 ConfigView* v; 735 ConfigView* v;
670 736
671 for (v = viewList; v; v = v->nextView) 737 for (v = viewList; v; v = v->nextView)
672 v->list->updateListAll(); 738 v->list->updateListAll();
673} 739}
674 740
675/* 741/*
676 * Construct the complete config widget 742 * Construct the complete config widget
677 */ 743 */
678ConfigMainWindow::ConfigMainWindow(void) 744ConfigMainWindow::ConfigMainWindow(void)
679{ 745{
680 ConfigView* view;
681 QMenuBar* menu; 746 QMenuBar* menu;
682 QSplitter* split1; 747 QSplitter* split1;
683 QSplitter* split2; 748 QSplitter* split2;
684 bool ok; 749 bool ok;
685 int x, y, width, height; 750 int x, y, width, height;
686 751
687 QWidget *d = configApp->desktop(); 752 QWidget *d = configApp->desktop();
688 753
689#if QT_VERSION >= 300 754#if QT_VERSION >= 300
690 width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64); 755 width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64);
691 height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64); 756 height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64);
692 resize(width, height); 757 resize(width, height);
693 x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok); 758 x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok);
694 if (ok) 759 if (ok)
695 y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok); 760 y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok);
696 if (ok) 761 if (ok)
697 move(x, y); 762 move(x, y);
698#else 763#else
699 width = d->width() - 64; 764 width = d->width() - 64;
700 height = d->height() - 64; 765 height = d->height() - 64;
701 resize(width, height); 766 resize(width, height);
702#endif 767#endif
703 768
704 showDebug = false; 769 showDebug = false;
705 770
706 split1 = new QSplitter(this); 771 split1 = new QSplitter(this);
707 split1->setOrientation(QSplitter::Horizontal); 772 split1->setOrientation(QSplitter::Horizontal);
708 setCentralWidget(split1); 773 setCentralWidget(split1);
709 774
710 view = new ConfigView(split1, this); 775 menuView = new ConfigView(split1, this);
711 menuList = view->list; 776 menuList = menuView->list;
712 777
713 split2 = new QSplitter(split1); 778 split2 = new QSplitter(split1);
714 split2->setOrientation(QSplitter::Vertical); 779 split2->setOrientation(QSplitter::Vertical);
715 780
716 // create config tree 781 // create config tree
717 view = new ConfigView(split2, this); 782 configView = new ConfigView(split2, this);
718 configList = view->list; 783 configList = configView->list;
719 784
720 helpText = new QTextView(split2); 785 helpText = new QTextView(split2);
721 helpText->setTextFormat(Qt::RichText); 786 helpText->setTextFormat(Qt::RichText);
722 787
723 setTabOrder(configList, helpText); 788 setTabOrder(configList, helpText);
724 configList->setFocus(); 789 configList->setFocus();
725 790
726 menu = menuBar(); 791 menu = menuBar();
727 toolBar = new QToolBar("Tools", this); 792 toolBar = new QToolBar("Tools", this);
728 793
729 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this); 794 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
730 connect(backAction, SIGNAL(activated()), SLOT(goBack())); 795 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
731 backAction->setEnabled(FALSE); 796 backAction->setEnabled(FALSE);
732 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this); 797 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
733 connect(quitAction, SIGNAL(activated()), SLOT(close())); 798 connect(quitAction, SIGNAL(activated()), SLOT(close()));
734 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this); 799 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
735 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); 800 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
736 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this); 801 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
737 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); 802 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
738 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this); 803 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
739 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); 804 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
740 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this); 805 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
741 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); 806 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
742 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this); 807 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
743 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); 808 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
744 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this); 809 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
745 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); 810 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
746 811
747 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this); 812 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
748 showNameAction->setToggleAction(TRUE); 813 showNameAction->setToggleAction(TRUE);
749 showNameAction->setOn(configList->showName); 814 showNameAction->setOn(configList->showName);
750 connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool))); 815 connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool)));
751 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this); 816 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
752 showRangeAction->setToggleAction(TRUE); 817 showRangeAction->setToggleAction(TRUE);
753 showRangeAction->setOn(configList->showRange); 818 showRangeAction->setOn(configList->showRange);
754 connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool))); 819 connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool)));
755 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this); 820 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
756 showDataAction->setToggleAction(TRUE); 821 showDataAction->setToggleAction(TRUE);
757 showDataAction->setOn(configList->showData); 822 showDataAction->setOn(configList->showData);
758 connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool))); 823 connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool)));
759 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this); 824 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
760 showAllAction->setToggleAction(TRUE); 825 showAllAction->setToggleAction(TRUE);
761 showAllAction->setOn(configList->showAll); 826 showAllAction->setOn(configList->showAll);
762 connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool))); 827 connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool)));
763 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this); 828 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
764 showDebugAction->setToggleAction(TRUE); 829 showDebugAction->setToggleAction(TRUE);
765 showDebugAction->setOn(showDebug); 830 showDebugAction->setOn(showDebug);
766 connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); 831 connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
767 832
768 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this); 833 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
769 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); 834 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
770 QAction *showAboutAction = new QAction(NULL, "About", 0, this); 835 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
771 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout())); 836 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
772 837
773 // init tool bar 838 // init tool bar
774 backAction->addTo(toolBar); 839 backAction->addTo(toolBar);
775 toolBar->addSeparator(); 840 toolBar->addSeparator();
776 loadAction->addTo(toolBar); 841 loadAction->addTo(toolBar);
777 saveAction->addTo(toolBar); 842 saveAction->addTo(toolBar);
778 toolBar->addSeparator(); 843 toolBar->addSeparator();
779 singleViewAction->addTo(toolBar); 844 singleViewAction->addTo(toolBar);
780 splitViewAction->addTo(toolBar); 845 splitViewAction->addTo(toolBar);
781 fullViewAction->addTo(toolBar); 846 fullViewAction->addTo(toolBar);
782 847
783 // create config menu 848 // create config menu
784 QPopupMenu* config = new QPopupMenu(this); 849 QPopupMenu* config = new QPopupMenu(this);
785 menu->insertItem("&File", config); 850 menu->insertItem("&File", config);
786 loadAction->addTo(config); 851 loadAction->addTo(config);
787 saveAction->addTo(config); 852 saveAction->addTo(config);
788 saveAsAction->addTo(config); 853 saveAsAction->addTo(config);
789 config->insertSeparator(); 854 config->insertSeparator();
790 quitAction->addTo(config); 855 quitAction->addTo(config);
791 856
792 // create options menu 857 // create options menu
793 QPopupMenu* optionMenu = new QPopupMenu(this); 858 QPopupMenu* optionMenu = new QPopupMenu(this);
794 menu->insertItem("&Option", optionMenu); 859 menu->insertItem("&Option", optionMenu);
795 showNameAction->addTo(optionMenu); 860 showNameAction->addTo(optionMenu);
796 showRangeAction->addTo(optionMenu); 861 showRangeAction->addTo(optionMenu);
797 showDataAction->addTo(optionMenu); 862 showDataAction->addTo(optionMenu);
798 optionMenu->insertSeparator(); 863 optionMenu->insertSeparator();
799 showAllAction->addTo(optionMenu); 864 showAllAction->addTo(optionMenu);
800 showDebugAction->addTo(optionMenu); 865 showDebugAction->addTo(optionMenu);
801 866
802 // create help menu 867 // create help menu
803 QPopupMenu* helpMenu = new QPopupMenu(this); 868 QPopupMenu* helpMenu = new QPopupMenu(this);
804 menu->insertSeparator(); 869 menu->insertSeparator();
805 menu->insertItem("&Help", helpMenu); 870 menu->insertItem("&Help", helpMenu);
806 showIntroAction->addTo(helpMenu); 871 showIntroAction->addTo(helpMenu);
807 showAboutAction->addTo(helpMenu); 872 showAboutAction->addTo(helpMenu);
808 873
809 connect(configList, SIGNAL(menuSelected(struct menu *)), 874 connect(configList, SIGNAL(menuSelected(struct menu *)),
810 SLOT(changeMenu(struct menu *))); 875 SLOT(changeMenu(struct menu *)));
811 connect(configList, SIGNAL(parentSelected()), 876 connect(configList, SIGNAL(parentSelected()),
812 SLOT(goBack())); 877 SLOT(goBack()));
813 connect(menuList, SIGNAL(menuSelected(struct menu *)), 878 connect(menuList, SIGNAL(menuSelected(struct menu *)),
814 SLOT(changeMenu(struct menu *))); 879 SLOT(changeMenu(struct menu *)));
815 880
816 connect(configList, SIGNAL(gotFocus(void)), 881 connect(configList, SIGNAL(gotFocus(void)),
817 SLOT(listFocusChanged(void))); 882 SLOT(listFocusChanged(void)));
818 connect(menuList, SIGNAL(gotFocus(void)), 883 connect(menuList, SIGNAL(gotFocus(void)),
819 SLOT(listFocusChanged(void))); 884 SLOT(listFocusChanged(void)));
820 885
821 //showFullView();
822 showSplitView(); 886 showSplitView();
823} 887}
824 888
825static QString print_filter(const char *str) 889static QString print_filter(const char *str)
826{ 890{
827 QRegExp re("[<>&\"\\n]"); 891 QRegExp re("[<>&\"\\n]");
828 QString res = str; 892 QString res = str;
829 for (int i = 0; (i = res.find(re, i)) >= 0;) { 893 for (int i = 0; (i = res.find(re, i)) >= 0;) {
830 switch (res[i].latin1()) { 894 switch (res[i].latin1()) {
831 case '<': 895 case '<':
832 res.replace(i, 1, "&lt;"); 896 res.replace(i, 1, "&lt;");
833 i += 4; 897 i += 4;
834 break; 898 break;
835 case '>': 899 case '>':
836 res.replace(i, 1, "&gt;"); 900 res.replace(i, 1, "&gt;");
837 i += 4; 901 i += 4;
838 break; 902 break;
839 case '&': 903 case '&':
840 res.replace(i, 1, "&amp;"); 904 res.replace(i, 1, "&amp;");
841 i += 5; 905 i += 5;
842 break; 906 break;
843 case '"': 907 case '"':
844 res.replace(i, 1, "&quot;"); 908 res.replace(i, 1, "&quot;");
845 i += 6; 909 i += 6;
846 break; 910 break;
847 case '\n': 911 case '\n':
848 res.replace(i, 1, "<br>"); 912 res.replace(i, 1, "<br>");
849 i += 4; 913 i += 4;
850 break; 914 break;
851 } 915 }
852 } 916 }
853 return res; 917 return res;
854} 918}
855 919
856static void expr_print_help(void *data, const char *str) 920static void expr_print_help(void *data, const char *str)
857{ 921{
858 ((QString*)data)->append(print_filter(str)); 922 ((QString*)data)->append(print_filter(str));
859} 923}
860 924
861/* 925/*
862 * display a new help entry as soon as a new menu entry is selected 926 * display a new help entry as soon as a new menu entry is selected
863 */ 927 */
864void ConfigMainWindow::setHelp(QListViewItem* item) 928void ConfigMainWindow::setHelp(QListViewItem* item)
865{ 929{
866 struct symbol* sym; 930 struct symbol* sym;
867 struct menu* menu; 931 struct menu* menu = 0;
868 932
869 configList->parent()->lineEdit->hide(); 933 configList->parent()->lineEdit->hide();
870 if (item) { 934 if (item)
871 QString head, debug, help;
872 menu = ((ConfigItem*)item)->menu; 935 menu = ((ConfigItem*)item)->menu;
873 sym = menu->sym; 936 if (!menu) {
874 if (sym) { 937 helpText->setText(NULL);
875 if (menu->prompt) { 938 return;
876 head += "<big><b>"; 939 }
877 head += print_filter(menu->prompt->text); 940
878 head += "</b></big>"; 941 QString head, debug, help;
879 if (sym->name) { 942 menu = ((ConfigItem*)item)->menu;
880 head += " ("; 943 sym = menu->sym;
881 head += print_filter(sym->name); 944 if (sym) {
882 head += ")"; 945 if (menu->prompt) {
883 } 946 head += "<big><b>";
884 } else if (sym->name) { 947 head += print_filter(menu->prompt->text);
885 head += "<big><b>"; 948 head += "</b></big>";
949 if (sym->name) {
950 head += " (";
886 head += print_filter(sym->name); 951 head += print_filter(sym->name);
887 head += "</b></big>"; 952 head += ")";
888 } 953 }
889 head += "<br><br>"; 954 } else if (sym->name) {
890 955 head += "<big><b>";
891 if (showDebug) { 956 head += print_filter(sym->name);
892 debug += "type: "; 957 head += "</b></big>";
893 debug += print_filter(sym_type_name(sym->type)); 958 }
959 head += "<br><br>";
960
961 if (showDebug) {
962 debug += "type: ";
963 debug += print_filter(sym_type_name(sym->type));
964 if (sym_is_choice(sym))
965 debug += " (choice)";
966 debug += "<br>";
967 if (sym->rev_dep.expr) {
968 debug += "reverse dep: ";
969 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
894 debug += "<br>"; 970 debug += "<br>";
895 for (struct property *prop = sym->prop; prop; prop = prop->next) { 971 }
896 switch (prop->type) { 972 for (struct property *prop = sym->prop; prop; prop = prop->next) {
897 case P_PROMPT: 973 switch (prop->type) {
898 debug += "prompt: "; 974 case P_PROMPT:
899 debug += print_filter(prop->text); 975 case P_MENU:
900 debug += "<br>"; 976 debug += "prompt: ";
901 if (prop->visible.expr) { 977 debug += print_filter(prop->text);
902 debug += "&nbsp;&nbsp;dep: "; 978 debug += "<br>";
903 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); 979 break;
904 debug += "<br>"; 980 case P_DEFAULT:
905 } 981 debug += "default: ";
906 break; 982 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
907 case P_DEFAULT: 983 debug += "<br>";
908 debug += "default: "; 984 break;
909 if (sym_is_choice(sym)) 985 case P_CHOICE:
910 debug += print_filter(prop->def->name); 986 if (sym_is_choice(sym)) {
911 else { 987 debug += "choice: ";
912 sym_calc_value(prop->def); 988 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
913 debug += print_filter(sym_get_string_value(prop->def));
914 }
915 debug += "<br>";
916 if (prop->visible.expr) {
917 debug += "&nbsp;&nbsp;dep: ";
918 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
919 debug += "<br>";
920 }
921 break;
922 case P_CHOICE:
923 break;
924 default:
925 debug += "unknown property: ";
926 debug += prop_get_type_name(prop->type);
927 debug += "<br>"; 989 debug += "<br>";
928 } 990 }
991 break;
992 case P_SELECT:
993 debug += "select: ";
994 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
995 debug += "<br>";
996 break;
997 case P_RANGE:
998 debug += "range: ";
999 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1000 debug += "<br>";
1001 break;
1002 default:
1003 debug += "unknown property: ";
1004 debug += prop_get_type_name(prop->type);
1005 debug += "<br>";
929 } 1006 }
930 debug += "<br>"; 1007 if (prop->visible.expr) {
931 } 1008 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
932 1009 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
933 help = print_filter(sym->help);
934 } else if (menu->prompt) {
935 head += "<big><b>";
936 head += print_filter(menu->prompt->text);
937 head += "</b></big><br><br>";
938 if (showDebug) {
939 if (menu->prompt->visible.expr) {
940 debug += "&nbsp;&nbsp;dep: ";
941 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
942 debug += "<br>"; 1010 debug += "<br>";
943 } 1011 }
944 } 1012 }
1013 debug += "<br>";
1014 }
1015
1016 help = print_filter(sym->help);
1017 } else if (menu->prompt) {
1018 head += "<big><b>";
1019 head += print_filter(menu->prompt->text);
1020 head += "</b></big><br><br>";
1021 if (showDebug) {
1022 if (menu->prompt->visible.expr) {
1023 debug += "&nbsp;&nbsp;dep: ";
1024 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1025 debug += "<br><br>";
1026 }
945 } 1027 }
946 helpText->setText(head + debug + help);
947 return;
948 } 1028 }
949 helpText->setText(NULL); 1029 if (showDebug)
1030 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1031 helpText->setText(head + debug + help);
950} 1032}
951 1033
952void ConfigMainWindow::loadConfig(void) 1034void ConfigMainWindow::loadConfig(void)
953{ 1035{
954 QString s = QFileDialog::getOpenFileName(".config", NULL, this); 1036 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
955 if (s.isNull()) 1037 if (s.isNull())
956 return; 1038 return;
957 if (conf_read(s.latin1())) 1039 if (conf_read(s.latin1()))
958 QMessageBox::information(this, "qconf", "Unable to load configuration!"); 1040 QMessageBox::information(this, "qconf", "Unable to load configuration!");
959 ConfigView::updateListAll(); 1041 ConfigView::updateListAll();
960} 1042}
961 1043
962void ConfigMainWindow::saveConfig(void) 1044void ConfigMainWindow::saveConfig(void)
963{ 1045{
964 if (conf_write(NULL)) 1046 if (conf_write(NULL))
965 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1047 QMessageBox::information(this, "qconf", "Unable to save configuration!");
966} 1048}
967 1049
968void ConfigMainWindow::saveConfigAs(void) 1050void ConfigMainWindow::saveConfigAs(void)
969{ 1051{
970 QString s = QFileDialog::getSaveFileName(".config", NULL, this); 1052 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
971 if (s.isNull()) 1053 if (s.isNull())
972 return; 1054 return;
973 if (conf_write(s.latin1())) 1055 if (conf_write(s.latin1()))
974 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1056 QMessageBox::information(this, "qconf", "Unable to save configuration!");
975} 1057}
976 1058
977void ConfigMainWindow::changeMenu(struct menu *menu) 1059void ConfigMainWindow::changeMenu(struct menu *menu)
978{ 1060{
979 configList->setRootMenu(menu); 1061 configList->setRootMenu(menu);
980 backAction->setEnabled(TRUE); 1062 backAction->setEnabled(TRUE);
981} 1063}
982 1064
983void ConfigMainWindow::listFocusChanged(void) 1065void ConfigMainWindow::listFocusChanged(void)
984{ 1066{
985 if (menuList->hasFocus()) { 1067 if (menuList->hasFocus()) {
986 if (menuList->mode == menuMode) 1068 if (menuList->mode == menuMode)
987 configList->clearSelection(); 1069 configList->clearSelection();
988 setHelp(menuList->selectedItem()); 1070 setHelp(menuList->selectedItem());
989 } else if (configList->hasFocus()) { 1071 } else if (configList->hasFocus()) {
990 setHelp(configList->selectedItem()); 1072 setHelp(configList->selectedItem());
991 } 1073 }
992} 1074}
993 1075
994void ConfigMainWindow::goBack(void) 1076void ConfigMainWindow::goBack(void)
995{ 1077{
996 ConfigItem* item; 1078 ConfigItem* item;
997 1079
998 configList->setParentMenu(); 1080 configList->setParentMenu();
999 if (configList->rootEntry == &rootmenu) 1081 if (configList->rootEntry == &rootmenu)
1000 backAction->setEnabled(FALSE); 1082 backAction->setEnabled(FALSE);
1001 item = (ConfigItem*)menuList->selectedItem(); 1083 item = (ConfigItem*)menuList->selectedItem();
1002 while (item) { 1084 while (item) {
1003 if (item->menu == configList->rootEntry) { 1085 if (item->menu == configList->rootEntry) {
1004 menuList->setSelected(item, TRUE); 1086 menuList->setSelected(item, TRUE);
1005 break; 1087 break;
1006 } 1088 }
1007 item = (ConfigItem*)item->parent(); 1089 item = (ConfigItem*)item->parent();
1008 } 1090 }
1009} 1091}
1010 1092
1011void ConfigMainWindow::showSingleView(void) 1093void ConfigMainWindow::showSingleView(void)
1012{ 1094{
1013 menuList->hide(); 1095 menuView->hide();
1014 menuList->setRootMenu(0); 1096 menuList->setRootMenu(0);
1015 configList->mode = singleMode; 1097 configList->mode = singleMode;
1016 if (configList->rootEntry == &rootmenu) 1098 if (configList->rootEntry == &rootmenu)
1017 configList->updateListAll(); 1099 configList->updateListAll();
1018 else 1100 else
1019 configList->setRootMenu(&rootmenu); 1101 configList->setRootMenu(&rootmenu);
1020 configList->setAllOpen(TRUE); 1102 configList->setAllOpen(TRUE);
1021 configList->setFocus(); 1103 configList->setFocus();
1022} 1104}
1023 1105
1024void ConfigMainWindow::showSplitView(void) 1106void ConfigMainWindow::showSplitView(void)
1025{ 1107{
1026 configList->mode = symbolMode; 1108 configList->mode = symbolMode;
1027 if (configList->rootEntry == &rootmenu) 1109 if (configList->rootEntry == &rootmenu)
1028 configList->updateListAll(); 1110 configList->updateListAll();
1029 else 1111 else
1030 configList->setRootMenu(&rootmenu); 1112 configList->setRootMenu(&rootmenu);
1031 configList->setAllOpen(TRUE); 1113 configList->setAllOpen(TRUE);
1032 configApp->processEvents(); 1114 configApp->processEvents();
1033 menuList->mode = menuMode; 1115 menuList->mode = menuMode;
1034 menuList->setRootMenu(&rootmenu); 1116 menuList->setRootMenu(&rootmenu);
1035 menuList->show();
1036 menuList->setAllOpen(TRUE); 1117 menuList->setAllOpen(TRUE);
1118 menuView->show();
1037 menuList->setFocus(); 1119 menuList->setFocus();
1038} 1120}
1039 1121
1040void ConfigMainWindow::showFullView(void) 1122void ConfigMainWindow::showFullView(void)
1041{ 1123{
1042 menuList->hide(); 1124 menuView->hide();
1043 menuList->setRootMenu(0); 1125 menuList->setRootMenu(0);
1044 configList->mode = fullMode; 1126 configList->mode = fullMode;
1045 if (configList->rootEntry == &rootmenu) 1127 if (configList->rootEntry == &rootmenu)
1046 configList->updateListAll(); 1128 configList->updateListAll();
1047 else 1129 else
1048 configList->setRootMenu(&rootmenu); 1130 configList->setRootMenu(&rootmenu);
1049 configList->setAllOpen(FALSE); 1131 configList->setAllOpen(FALSE);
1050 configList->setFocus(); 1132 configList->setFocus();
1051} 1133}
1052 1134
1053void ConfigMainWindow::setShowAll(bool b) 1135void ConfigMainWindow::setShowAll(bool b)
1054{ 1136{
1055 if (configList->showAll == b) 1137 if (configList->showAll == b)
1056 return; 1138 return;
1057 configList->showAll = b; 1139 configList->showAll = b;
1058 configList->updateListAll(); 1140 configList->updateListAll();
1059 menuList->showAll = b; 1141 menuList->showAll = b;
1060 menuList->updateListAll(); 1142 menuList->updateListAll();
1061} 1143}
1062 1144
1063void ConfigMainWindow::setShowDebug(bool b) 1145void ConfigMainWindow::setShowDebug(bool b)
1064{ 1146{
1065 if (showDebug == b) 1147 if (showDebug == b)
1066 return; 1148 return;
1067 showDebug = b; 1149 showDebug = b;
1068} 1150}
1069 1151
1070void ConfigMainWindow::setShowName(bool b) 1152void ConfigMainWindow::setShowName(bool b)
1071{ 1153{
1072 if (configList->showName == b) 1154 if (configList->showName == b)
1073 return; 1155 return;
1074 configList->showName = b; 1156 configList->showName = b;
1075 configList->reinit(); 1157 configList->reinit();
1158 menuList->showName = b;
1159 menuList->reinit();
1076} 1160}
1077 1161
1078void ConfigMainWindow::setShowRange(bool b) 1162void ConfigMainWindow::setShowRange(bool b)
1079{ 1163{
1080 if (configList->showRange == b) 1164 if (configList->showRange == b)
1081 return; 1165 return;
1082 configList->showRange = b; 1166 configList->showRange = b;
1083 configList->reinit(); 1167 configList->reinit();
1168 menuList->showRange = b;
1169 menuList->reinit();
1084} 1170}
1085 1171
1086void ConfigMainWindow::setShowData(bool b) 1172void ConfigMainWindow::setShowData(bool b)
1087{ 1173{
1088 if (configList->showData == b) 1174 if (configList->showData == b)
1089 return; 1175 return;
1090 configList->showData = b; 1176 configList->showData = b;
1091 configList->reinit(); 1177 configList->reinit();
1178 menuList->showData = b;
1179 menuList->reinit();
1092} 1180}
1093 1181
1094/* 1182/*
1095 * ask for saving configuration before quitting 1183 * ask for saving configuration before quitting
1096 * TODO ask only when something changed 1184 * TODO ask only when something changed
1097 */ 1185 */
1098void ConfigMainWindow::closeEvent(QCloseEvent* e) 1186void ConfigMainWindow::closeEvent(QCloseEvent* e)
1099{ 1187{
1100 if (!sym_change_count) { 1188 if (!sym_change_count) {
1101 e->accept(); 1189 e->accept();
1102 return; 1190 return;
1103 } 1191 }
1104 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, 1192 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1105 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); 1193 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1106 mb.setButtonText(QMessageBox::Yes, "&Save Changes"); 1194 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1107 mb.setButtonText(QMessageBox::No, "&Discard Changes"); 1195 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1108 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit"); 1196 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1109 switch (mb.exec()) { 1197 switch (mb.exec()) {
1110 case QMessageBox::Yes: 1198 case QMessageBox::Yes:
1111 conf_write(NULL); 1199 conf_write(NULL);
1112 case QMessageBox::No: 1200 case QMessageBox::No:
1113 e->accept(); 1201 e->accept();
1114 break; 1202 break;
1115 case QMessageBox::Cancel: 1203 case QMessageBox::Cancel:
1116 e->ignore(); 1204 e->ignore();
1117 break; 1205 break;
1118 } 1206 }
1119} 1207}
1120 1208
1121void ConfigMainWindow::showIntro(void) 1209void ConfigMainWindow::showIntro(void)
1122{ 1210{
1123 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n" 1211 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" 1212 "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" 1213 "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" 1214 "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" 1215 "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" 1216 "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" 1217 "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" 1218 "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" 1219 "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" 1220 "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"; 1221 "which you can then match by examining other options.\n\n";
1134 1222
1135 QMessageBox::information(this, "qconf", str); 1223 QMessageBox::information(this, "qconf", str);
1136} 1224}
1137 1225
1138void ConfigMainWindow::showAbout(void) 1226void ConfigMainWindow::showAbout(void)
1139{ 1227{
1140 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n" 1228 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"; 1229 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1142 1230
1143 QMessageBox::information(this, "qconf", str); 1231 QMessageBox::information(this, "qconf", str);
1144} 1232}
1145 1233
1146void fixup_rootmenu(struct menu *menu) 1234void fixup_rootmenu(struct menu *menu)
1147{ 1235{
1148 struct menu *child; 1236 struct menu *child;
1237 static int menu_cnt = 0;
1149 1238
1150 if (!menu->prompt || menu->prompt->type != P_MENU) 1239 menu->flags |= MENU_ROOT;
1151 return; 1240 for (child = menu->list; child; child = child->next) {
1152 menu->prompt->type = P_ROOTMENU; 1241 if (child->prompt && child->prompt->type == P_MENU) {
1153 for (child = menu->list; child; child = child->next) 1242 menu_cnt++;
1154 fixup_rootmenu(child); 1243 fixup_rootmenu(child);
1244 menu_cnt--;
1245 } else if (!menu_cnt)
1246 fixup_rootmenu(child);
1247 }
1248}
1249
1250static const char *progname;
1251
1252static void usage(void)
1253{
1254 printf("%s <config>\n", progname);
1255 exit(0);
1155} 1256}
1156 1257
1157int main(int ac, char** av) 1258int main(int ac, char** av)
1158{ 1259{
1159 ConfigMainWindow* v; 1260 ConfigMainWindow* v;
1160 const char *name; 1261 const char *name;
1161 1262
1162#ifndef LKC_DIRECT_LINK 1263#ifndef LKC_DIRECT_LINK
1163 kconfig_load(); 1264 kconfig_load();
1164#endif 1265#endif
1165 1266
1267 progname = av[0];
1166 configApp = new QApplication(ac, av); 1268 configApp = new QApplication(ac, av);
1167#if QT_VERSION >= 300 1269#if QT_VERSION >= 300
1168 configSettings = new QSettings; 1270 configSettings = new QSettings;
1169#endif 1271#endif
1170 if (ac > 1 && av[1][0] == '-') { 1272 if (ac > 1 && av[1][0] == '-') {
1171 switch (av[1][1]) { 1273 switch (av[1][1]) {
1172 case 'a':
1173 //showAll = 1;
1174 break;
1175 case 'h': 1274 case 'h':
1176 case '?': 1275 case '?':
1177 printf("%s <config>\n", av[0]); 1276 usage();
1178 exit(0);
1179 } 1277 }
1180 name = av[2]; 1278 name = av[2];
1181 } else 1279 } else
1182 name = av[1]; 1280 name = av[1];
1281 if (!name)
1282 usage();
1283
1183 conf_parse(name); 1284 conf_parse(name);
1184 fixup_rootmenu(&rootmenu); 1285 fixup_rootmenu(&rootmenu);
1185 conf_read(NULL); 1286 conf_read(NULL);
1186 //zconfdump(stdout); 1287 //zconfdump(stdout);
1187 1288
1188 v = new ConfigMainWindow(); 1289 v = new ConfigMainWindow();
1189 1290
1190 //zconfdump(stdout); 1291 //zconfdump(stdout);
1191 v->show(); 1292 v->show();
1192 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); 1293 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1193 configApp->exec(); 1294 configApp->exec();
1194 1295
1195#if QT_VERSION >= 300 1296#if QT_VERSION >= 300
1196 configSettings->writeEntry("/kconfig/qconf/window x", v->pos().x()); 1297 configSettings->writeEntry("/kconfig/qconf/window x", v->pos().x());
1197 configSettings->writeEntry("/kconfig/qconf/window y", v->pos().y()); 1298 configSettings->writeEntry("/kconfig/qconf/window y", v->pos().y());
1198 configSettings->writeEntry("/kconfig/qconf/window width", v->size().width()); 1299 configSettings->writeEntry("/kconfig/qconf/window width", v->size().width());
1199 configSettings->writeEntry("/kconfig/qconf/window height", v->size().height()); 1300 configSettings->writeEntry("/kconfig/qconf/window height", v->size().height());
1200 delete configSettings; 1301 delete configSettings;
1201#endif 1302#endif
1202 return 0; 1303 return 0;
1203} 1304}
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 6f096b4..c548884 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -1,226 +1,238 @@
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 ConfigList; 8class ConfigList;
9class ConfigItem; 9class ConfigItem;
10class ConfigLineEdit; 10class ConfigLineEdit;
11class ConfigMainWindow; 11class ConfigMainWindow;
12 12
13class ConfigView : public QVBox { 13class ConfigView : public QVBox {
14 Q_OBJECT 14 Q_OBJECT
15 typedef class QVBox Parent; 15 typedef class QVBox Parent;
16public: 16public:
17 ConfigView(QWidget* parent, ConfigMainWindow* cview); 17 ConfigView(QWidget* parent, ConfigMainWindow* cview);
18 ~ConfigView(void); 18 ~ConfigView(void);
19 static void updateList(ConfigItem* item); 19 static void updateList(ConfigItem* item);
20 static void updateListAll(void); 20 static void updateListAll(void);
21 21
22public: 22public:
23 ConfigList* list; 23 ConfigList* list;
24 ConfigLineEdit* lineEdit; 24 ConfigLineEdit* lineEdit;
25 25
26 static ConfigView* viewList; 26 static ConfigView* viewList;
27 ConfigView* nextView; 27 ConfigView* nextView;
28}; 28};
29 29
30enum colIdx { 30enum colIdx {
31 promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr 31 promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
32}; 32};
33enum listMode { 33enum listMode {
34 singleMode, menuMode, symbolMode, fullMode 34 singleMode, menuMode, symbolMode, fullMode
35}; 35};
36 36
37class ConfigList : public QListView { 37class ConfigList : public QListView {
38 Q_OBJECT 38 Q_OBJECT
39 typedef class QListView Parent; 39 typedef class QListView Parent;
40public: 40public:
41 ConfigList(ConfigView* p, ConfigMainWindow* cview); 41 ConfigList(ConfigView* p, ConfigMainWindow* cview);
42 void reinit(void); 42 void reinit(void);
43 ConfigView* parent(void) const 43 ConfigView* parent(void) const
44 { 44 {
45 return (ConfigView*)Parent::parent(); 45 return (ConfigView*)Parent::parent();
46 } 46 }
47 47
48protected: 48protected:
49 ConfigMainWindow* cview; 49 ConfigMainWindow* cview;
50 50
51 void keyPressEvent(QKeyEvent *e); 51 void keyPressEvent(QKeyEvent *e);
52 void contentsMousePressEvent(QMouseEvent *e); 52 void contentsMousePressEvent(QMouseEvent *e);
53 void contentsMouseReleaseEvent(QMouseEvent *e); 53 void contentsMouseReleaseEvent(QMouseEvent *e);
54 void contentsMouseMoveEvent(QMouseEvent *e); 54 void contentsMouseMoveEvent(QMouseEvent *e);
55 void contentsMouseDoubleClickEvent(QMouseEvent *e); 55 void contentsMouseDoubleClickEvent(QMouseEvent *e);
56 void focusInEvent(QFocusEvent *e); 56 void focusInEvent(QFocusEvent *e);
57public slots: 57public slots:
58 void setRootMenu(struct menu *menu); 58 void setRootMenu(struct menu *menu);
59 59
60 void updateList(ConfigItem *item); 60 void updateList(ConfigItem *item);
61 void setValue(ConfigItem* item, tristate val); 61 void setValue(ConfigItem* item, tristate val);
62 void changeValue(ConfigItem* item); 62 void changeValue(ConfigItem* item);
63 void updateSelection(void); 63 void updateSelection(void);
64signals: 64signals:
65 void menuSelected(struct menu *menu); 65 void menuSelected(struct menu *menu);
66 void parentSelected(void); 66 void parentSelected(void);
67 void gotFocus(void); 67 void gotFocus(void);
68 68
69public: 69public:
70 void updateListAll(void) 70 void updateListAll(void)
71 { 71 {
72 updateAll = true; 72 updateAll = true;
73 updateList(NULL); 73 updateList(NULL);
74 updateAll = false; 74 updateAll = false;
75 } 75 }
76 ConfigList* listView() 76 ConfigList* listView()
77 { 77 {
78 return this; 78 return this;
79 } 79 }
80 ConfigItem* firstChild() const 80 ConfigItem* firstChild() const
81 { 81 {
82 return (ConfigItem *)Parent::firstChild(); 82 return (ConfigItem *)Parent::firstChild();
83 } 83 }
84 int mapIdx(colIdx idx) 84 int mapIdx(colIdx idx)
85 { 85 {
86 return colMap[idx]; 86 return colMap[idx];
87 } 87 }
88 void addColumn(colIdx idx, const QString& label) 88 void addColumn(colIdx idx, const QString& label)
89 { 89 {
90 colMap[idx] = Parent::addColumn(label); 90 colMap[idx] = Parent::addColumn(label);
91 colRevMap[colMap[idx]] = idx; 91 colRevMap[colMap[idx]] = idx;
92 } 92 }
93 void removeColumn(colIdx idx) 93 void removeColumn(colIdx idx)
94 { 94 {
95 int col = colMap[idx]; 95 int col = colMap[idx];
96 if (col >= 0) { 96 if (col >= 0) {
97 Parent::removeColumn(col); 97 Parent::removeColumn(col);
98 colRevMap[col] = colMap[idx] = -1; 98 colRevMap[col] = colMap[idx] = -1;
99 } 99 }
100 } 100 }
101 void setAllOpen(bool open); 101 void setAllOpen(bool open);
102 void setParentMenu(void); 102 void setParentMenu(void);
103 103
104 template <class P>
105 void ConfigList::updateMenuList(P*, struct menu*);
106
104 bool updateAll; 107 bool updateAll;
105 108
106 QPixmap symbolYesPix, symbolModPix, symbolNoPix; 109 QPixmap symbolYesPix, symbolModPix, symbolNoPix;
107 QPixmap choiceYesPix, choiceNoPix, menuPix, menuInvPix; 110 QPixmap choiceYesPix, choiceNoPix;
111 QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
108 112
109 bool showAll, showName, showRange, showData; 113 bool showAll, showName, showRange, showData;
110 enum listMode mode; 114 enum listMode mode;
111 struct menu *rootEntry; 115 struct menu *rootEntry;
112 QColorGroup disabledColorGroup; 116 QColorGroup disabledColorGroup;
113 QColorGroup inactivedColorGroup; 117 QColorGroup inactivedColorGroup;
114 118
115private: 119private:
116 int colMap[colNr]; 120 int colMap[colNr];
117 int colRevMap[colNr]; 121 int colRevMap[colNr];
118}; 122};
119 123
120class ConfigItem : public QListViewItem { 124class ConfigItem : public QListViewItem {
121 typedef class QListViewItem Parent; 125 typedef class QListViewItem Parent;
122public: 126public:
123 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) 127 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v)
124 : Parent(parent, after), menu(m), visible(v) 128 : Parent(parent, after), menu(m), visible(v), goParent(false)
125 { 129 {
126 init(); 130 init();
127 } 131 }
128 ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) 132 ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
129 : Parent(parent, after), menu(m), visible(v) 133 : Parent(parent, after), menu(m), visible(v), goParent(false)
134 {
135 init();
136 }
137 ConfigItem(QListView *parent, ConfigItem *after, bool v)
138 : Parent(parent, after), menu(0), visible(v), goParent(true)
130 { 139 {
131 init(); 140 init();
132 } 141 }
133 ~ConfigItem(void); 142 ~ConfigItem(void);
134 void init(void); 143 void init(void);
135#if QT_VERSION >= 300 144#if QT_VERSION >= 300
136 void okRename(int col); 145 void okRename(int col);
137#endif 146#endif
138 void updateMenu(void); 147 void updateMenu(void);
139 bool updateNeeded(void); 148 void testUpdateMenu(bool v);
140 ConfigList* listView() const 149 ConfigList* listView() const
141 { 150 {
142 return (ConfigList*)Parent::listView(); 151 return (ConfigList*)Parent::listView();
143 } 152 }
144 ConfigItem* firstChild() const 153 ConfigItem* firstChild() const
145 { 154 {
146 return (ConfigItem *)Parent::firstChild(); 155 return (ConfigItem *)Parent::firstChild();
147 } 156 }
148 ConfigItem* nextSibling() const 157 ConfigItem* nextSibling() const
149 { 158 {
150 return (ConfigItem *)Parent::nextSibling(); 159 return (ConfigItem *)Parent::nextSibling();
151 } 160 }
152 void setText(colIdx idx, const QString& text) 161 void setText(colIdx idx, const QString& text)
153 { 162 {
154 Parent::setText(listView()->mapIdx(idx), text); 163 Parent::setText(listView()->mapIdx(idx), text);
155 } 164 }
156 QString text(colIdx idx) const 165 QString text(colIdx idx) const
157 { 166 {
158 return Parent::text(listView()->mapIdx(idx)); 167 return Parent::text(listView()->mapIdx(idx));
159 } 168 }
160 void setPixmap(colIdx idx, const QPixmap& pm) 169 void setPixmap(colIdx idx, const QPixmap& pm)
161 { 170 {
162 Parent::setPixmap(listView()->mapIdx(idx), pm); 171 Parent::setPixmap(listView()->mapIdx(idx), pm);
163 } 172 }
164 const QPixmap* pixmap(colIdx idx) const 173 const QPixmap* pixmap(colIdx idx) const
165 { 174 {
166 return Parent::pixmap(listView()->mapIdx(idx)); 175 return Parent::pixmap(listView()->mapIdx(idx));
167 } 176 }
168 void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align); 177 void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
169 178
170 ConfigItem* nextItem; 179 ConfigItem* nextItem;
171 struct menu *menu; 180 struct menu *menu;
172 bool visible; 181 bool visible;
182 bool goParent;
173}; 183};
174 184
175class ConfigLineEdit : public QLineEdit { 185class ConfigLineEdit : public QLineEdit {
176 Q_OBJECT 186 Q_OBJECT
177 typedef class QLineEdit Parent; 187 typedef class QLineEdit Parent;
178public: 188public:
179 ConfigLineEdit(ConfigView* parent) 189 ConfigLineEdit(ConfigView* parent)
180 : Parent(parent) 190 : Parent(parent)
181 { } 191 { }
182 ConfigView* parent(void) const 192 ConfigView* parent(void) const
183 { 193 {
184 return (ConfigView*)Parent::parent(); 194 return (ConfigView*)Parent::parent();
185 } 195 }
186 void show(ConfigItem *i); 196 void show(ConfigItem *i);
187 void keyPressEvent(QKeyEvent *e); 197 void keyPressEvent(QKeyEvent *e);
188 198
189public: 199public:
190 ConfigItem *item; 200 ConfigItem *item;
191}; 201};
192 202
193class ConfigMainWindow : public QMainWindow { 203class ConfigMainWindow : public QMainWindow {
194 Q_OBJECT 204 Q_OBJECT
195public: 205public:
196 ConfigMainWindow(void); 206 ConfigMainWindow(void);
197public slots: 207public slots:
198 void setHelp(QListViewItem* item); 208 void setHelp(QListViewItem* item);
199 void changeMenu(struct menu *); 209 void changeMenu(struct menu *);
200 void listFocusChanged(void); 210 void listFocusChanged(void);
201 void goBack(void); 211 void goBack(void);
202 void loadConfig(void); 212 void loadConfig(void);
203 void saveConfig(void); 213 void saveConfig(void);
204 void saveConfigAs(void); 214 void saveConfigAs(void);
205 void showSingleView(void); 215 void showSingleView(void);
206 void showSplitView(void); 216 void showSplitView(void);
207 void showFullView(void); 217 void showFullView(void);
208 void setShowAll(bool); 218 void setShowAll(bool);
209 void setShowDebug(bool); 219 void setShowDebug(bool);
210 void setShowRange(bool); 220 void setShowRange(bool);
211 void setShowName(bool); 221 void setShowName(bool);
212 void setShowData(bool); 222 void setShowData(bool);
213 void showIntro(void); 223 void showIntro(void);
214 void showAbout(void); 224 void showAbout(void);
215 225
216protected: 226protected:
217 void closeEvent(QCloseEvent *e); 227 void closeEvent(QCloseEvent *e);
218 228
229 ConfigView *menuView;
219 ConfigList *menuList; 230 ConfigList *menuList;
231 ConfigView *configView;
220 ConfigList *configList; 232 ConfigList *configList;
221 QTextView *helpText; 233 QTextView *helpText;
222 QToolBar *toolBar; 234 QToolBar *toolBar;
223 QAction *backAction; 235 QAction *backAction;
224 236
225 bool showDebug; 237 bool showDebug;
226}; 238};
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 845d8a3..11318d9 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -1,629 +1,778 @@
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 <ctype.h> 6#include <ctype.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <string.h> 8#include <string.h>
9#include <sys/utsname.h> 9#include <sys/utsname.h>
10 10
11#define LKC_DIRECT_LINK 11#define LKC_DIRECT_LINK
12#include "lkc.h" 12#include "lkc.h"
13 13
14struct symbol symbol_yes = { 14struct symbol symbol_yes = {
15 name: "y", 15 name: "y",
16 curr: { "y", yes }, 16 curr: { "y", yes },
17 flags: SYMBOL_YES|SYMBOL_VALID, 17 flags: SYMBOL_YES|SYMBOL_VALID,
18}, symbol_mod = { 18}, symbol_mod = {
19 name: "m", 19 name: "m",
20 curr: { "m", mod }, 20 curr: { "m", mod },
21 flags: SYMBOL_MOD|SYMBOL_VALID, 21 flags: SYMBOL_MOD|SYMBOL_VALID,
22}, symbol_no = { 22}, symbol_no = {
23 name: "n", 23 name: "n",
24 curr: { "n", no }, 24 curr: { "n", no },
25 flags: SYMBOL_NO|SYMBOL_VALID, 25 flags: SYMBOL_NO|SYMBOL_VALID,
26}, symbol_empty = { 26}, symbol_empty = {
27 name: "", 27 name: "",
28 curr: { "", no }, 28 curr: { "", no },
29 flags: SYMBOL_VALID, 29 flags: SYMBOL_VALID,
30}; 30};
31 31
32int sym_change_count; 32int sym_change_count;
33struct symbol *modules_sym; 33struct symbol *modules_sym;
34 34
35void sym_add_default(struct symbol *sym, const char *def) 35void sym_add_default(struct symbol *sym, const char *def)
36{ 36{
37 struct property *prop = create_prop(P_DEFAULT); 37 struct property *prop = prop_alloc(P_DEFAULT, sym);
38 struct property **propp;
39
40 prop->sym = sym;
41 prop->def = sym_lookup(def, 1);
42 38
43 /* append property to the prop list of symbol */ 39 prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
44 if (prop->sym) {
45 for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next)
46 ;
47 *propp = prop;
48 }
49} 40}
50 41
51void sym_init(void) 42void sym_init(void)
52{ 43{
53 struct symbol *sym; 44 struct symbol *sym;
54 struct utsname uts; 45 struct utsname uts;
55 char *p; 46 char *p;
56 static bool inited = false; 47 static bool inited = false;
57 48
58 if (inited) 49 if (inited)
59 return; 50 return;
60 inited = true; 51 inited = true;
61 52
62 uname(&uts); 53 uname(&uts);
63 54
64 sym = sym_lookup("ARCH", 0); 55 sym = sym_lookup("ARCH", 0);
65 sym->type = S_STRING; 56 sym->type = S_STRING;
66 sym->flags |= SYMBOL_AUTO; 57 sym->flags |= SYMBOL_AUTO;
67 p = getenv("ARCH"); 58 p = getenv("ARCH");
68 if (p) 59 if (p)
69 sym_add_default(sym, p); 60 sym_add_default(sym, p);
70 61
71 sym = sym_lookup("KERNELRELEASE", 0); 62 sym = sym_lookup("KERNELRELEASE", 0);
72 sym->type = S_STRING; 63 sym->type = S_STRING;
73 sym->flags |= SYMBOL_AUTO; 64 sym->flags |= SYMBOL_AUTO;
74 p = getenv("KERNELRELEASE"); 65 p = getenv("KERNELRELEASE");
75 if (p) 66 if (p)
76 sym_add_default(sym, p); 67 sym_add_default(sym, p);
77 68
78 sym = sym_lookup("UNAME_RELEASE", 0); 69 sym = sym_lookup("UNAME_RELEASE", 0);
79 sym->type = S_STRING; 70 sym->type = S_STRING;
80 sym->flags |= SYMBOL_AUTO; 71 sym->flags |= SYMBOL_AUTO;
81 sym_add_default(sym, uts.release); 72 sym_add_default(sym, uts.release);
82} 73}
83 74
84int sym_get_type(struct symbol *sym) 75enum symbol_type sym_get_type(struct symbol *sym)
85{ 76{
86 int type = sym->type; 77 enum symbol_type type = sym->type;
78
87 if (type == S_TRISTATE) { 79 if (type == S_TRISTATE) {
88 if (sym_is_choice_value(sym) && sym->visible == yes) 80 if (sym_is_choice_value(sym) && sym->visible == yes)
89 type = S_BOOLEAN; 81 type = S_BOOLEAN;
90 else { 82 else {
91 sym_calc_value(modules_sym); 83 sym_calc_value(modules_sym);
92 if (S_TRI(modules_sym->curr) == no) 84 if (modules_sym->curr.tri == no)
93 type = S_BOOLEAN; 85 type = S_BOOLEAN;
94 } 86 }
95 } 87 }
96 return type; 88 return type;
97} 89}
98 90
99const char *sym_type_name(int type) 91const char *sym_type_name(enum symbol_type type)
100{ 92{
101 switch (type) { 93 switch (type) {
102 case S_BOOLEAN: 94 case S_BOOLEAN:
103 return "boolean"; 95 return "boolean";
104 case S_TRISTATE: 96 case S_TRISTATE:
105 return "tristate"; 97 return "tristate";
106 case S_INT: 98 case S_INT:
107 return "integer"; 99 return "integer";
108 case S_HEX: 100 case S_HEX:
109 return "hex"; 101 return "hex";
110 case S_STRING: 102 case S_STRING:
111 return "string"; 103 return "string";
112 case S_UNKNOWN: 104 case S_UNKNOWN:
113 return "unknown"; 105 return "unknown";
106 case S_OTHER:
107 break;
114 } 108 }
115 return "???"; 109 return "???";
116} 110}
117 111
118struct property *sym_get_choice_prop(struct symbol *sym) 112struct property *sym_get_choice_prop(struct symbol *sym)
119{ 113{
120 struct property *prop; 114 struct property *prop;
121 115
122 for_all_choices(sym, prop) 116 for_all_choices(sym, prop)
123 return prop; 117 return prop;
124 return NULL; 118 return NULL;
125} 119}
126 120
127struct property *sym_get_default_prop(struct symbol *sym) 121struct property *sym_get_default_prop(struct symbol *sym)
128{ 122{
129 struct property *prop; 123 struct property *prop;
130 tristate visible;
131 124
132 for_all_defaults(sym, prop) { 125 for_all_defaults(sym, prop) {
133 visible = E_CALC(prop->visible); 126 prop->visible.tri = expr_calc_value(prop->visible.expr);
134 if (visible != no) 127 if (prop->visible.tri != no)
135 return prop; 128 return prop;
136 } 129 }
137 return NULL; 130 return NULL;
138} 131}
139 132
140void sym_calc_visibility(struct symbol *sym) 133struct property *sym_get_range_prop(struct symbol *sym)
141{ 134{
142 struct property *prop; 135 struct property *prop;
143 tristate visible, oldvisible; 136
137 for_all_properties(sym, prop, P_RANGE) {
138 prop->visible.tri = expr_calc_value(prop->visible.expr);
139 if (prop->visible.tri != no)
140 return prop;
141 }
142 return NULL;
143}
144
145static void sym_calc_visibility(struct symbol *sym)
146{
147 struct property *prop;
148 tristate tri;
144 149
145 /* any prompt visible? */ 150 /* any prompt visible? */
146 oldvisible = sym->visible; 151 tri = no;
147 visible = no; 152 for_all_prompts(sym, prop) {
148 for_all_prompts(sym, prop) 153 prop->visible.tri = expr_calc_value(prop->visible.expr);
149 visible = E_OR(visible, E_CALC(prop->visible)); 154 tri = E_OR(tri, prop->visible.tri);
150 if (oldvisible != visible) { 155 }
151 sym->visible = visible; 156 if (sym->visible != tri) {
157 sym->visible = tri;
158 sym_set_changed(sym);
159 }
160 if (sym_is_choice_value(sym))
161 return;
162 tri = no;
163 if (sym->rev_dep.expr)
164 tri = expr_calc_value(sym->rev_dep.expr);
165 if (sym->rev_dep.tri != tri) {
166 sym->rev_dep.tri = tri;
152 sym_set_changed(sym); 167 sym_set_changed(sym);
153 } 168 }
154} 169}
155 170
171static struct symbol *sym_calc_choice(struct symbol *sym)
172{
173 struct symbol *def_sym;
174 struct property *prop;
175 struct expr *e;
176
177 /* is the user choice visible? */
178 def_sym = sym->user.val;
179 if (def_sym) {
180 sym_calc_visibility(def_sym);
181 if (def_sym->visible != no)
182 return def_sym;
183 }
184
185 /* any of the defaults visible? */
186 for_all_defaults(sym, prop) {
187 prop->visible.tri = expr_calc_value(prop->visible.expr);
188 if (prop->visible.tri == no)
189 continue;
190 def_sym = prop_get_symbol(prop);
191 sym_calc_visibility(def_sym);
192 if (def_sym->visible != no)
193 return def_sym;
194 }
195
196 /* just get the first visible value */
197 prop = sym_get_choice_prop(sym);
198 for (e = prop->expr; e; e = e->left.expr) {
199 def_sym = e->right.sym;
200 sym_calc_visibility(def_sym);
201 if (def_sym->visible != no)
202 return def_sym;
203 }
204
205 /* no choice? reset tristate value */
206 sym->curr.tri = no;
207 return NULL;
208}
209
156void sym_calc_value(struct symbol *sym) 210void sym_calc_value(struct symbol *sym)
157{ 211{
158 struct symbol_value newval, oldval; 212 struct symbol_value newval, oldval;
159 struct property *prop, *def_prop; 213 struct property *prop;
160 struct symbol *def_sym;
161 struct expr *e; 214 struct expr *e;
162 215
216 if (!sym)
217 return;
218
163 if (sym->flags & SYMBOL_VALID) 219 if (sym->flags & SYMBOL_VALID)
164 return; 220 return;
221 sym->flags |= SYMBOL_VALID;
165 222
166 oldval = sym->curr; 223 oldval = sym->curr;
167 224
168 switch (sym->type) { 225 switch (sym->type) {
169 case S_INT: 226 case S_INT:
170 case S_HEX: 227 case S_HEX:
171 case S_STRING: 228 case S_STRING:
172 newval = symbol_empty.curr; 229 newval = symbol_empty.curr;
173 break; 230 break;
174 case S_BOOLEAN: 231 case S_BOOLEAN:
175 case S_TRISTATE: 232 case S_TRISTATE:
176 newval = symbol_no.curr; 233 newval = symbol_no.curr;
177 break; 234 break;
178 default: 235 default:
179 S_VAL(newval) = sym->name; 236 sym->curr.val = sym->name;
180 S_TRI(newval) = no; 237 sym->curr.tri = no;
181 if (sym->flags & SYMBOL_CONST) { 238 return;
182 goto out;
183 }
184 //newval = symbol_empty.curr;
185 // generate warning somewhere here later
186 //S_TRI(newval) = yes;
187 goto out;
188 } 239 }
189 sym->flags |= SYMBOL_VALID;
190 if (!sym_is_choice_value(sym)) 240 if (!sym_is_choice_value(sym))
191 sym->flags &= ~SYMBOL_WRITE; 241 sym->flags &= ~SYMBOL_WRITE;
192 242
193 sym_calc_visibility(sym); 243 sym_calc_visibility(sym);
194 244
195 /* set default if recursively called */ 245 /* set default if recursively called */
196 sym->curr = newval; 246 sym->curr = newval;
197 247
198 if (sym->visible != no) { 248 switch (sym_get_type(sym)) {
199 sym->flags |= SYMBOL_WRITE; 249 case S_BOOLEAN:
200 if (!sym_has_value(sym)) { 250 case S_TRISTATE:
201 if (!sym_is_choice(sym)) {
202 prop = sym_get_default_prop(sym);
203 if (prop) {
204 sym_calc_value(prop->def);
205 newval = prop->def->curr;
206 }
207 } else
208 S_TRI(newval) = S_TRI(sym->def);
209 } else
210 newval = sym->def;
211
212 S_TRI(newval) = E_AND(S_TRI(newval), sym->visible);
213 /* if the symbol is visible and not optionial,
214 * possibly ignore old user choice. */
215 if (!sym_is_optional(sym) && S_TRI(newval) == no)
216 S_TRI(newval) = sym->visible;
217 if (sym_is_choice_value(sym) && sym->visible == yes) { 251 if (sym_is_choice_value(sym) && sym->visible == yes) {
218 prop = sym_get_choice_prop(sym); 252 prop = sym_get_choice_prop(sym);
219 S_TRI(newval) = (S_VAL(prop->def->curr) == sym) ? yes : no; 253 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
220 } 254 } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
221 } else {
222 prop = sym_get_default_prop(sym);
223 if (prop) {
224 sym->flags |= SYMBOL_WRITE; 255 sym->flags |= SYMBOL_WRITE;
225 sym_calc_value(prop->def); 256 if (sym_has_value(sym))
226 newval = prop->def->curr; 257 newval.tri = sym->user.tri;
258 else if (!sym_is_choice(sym)) {
259 prop = sym_get_default_prop(sym);
260 if (prop)
261 newval.tri = expr_calc_value(prop->expr);
262 }
263 newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
264 } else if (!sym_is_choice(sym)) {
265 prop = sym_get_default_prop(sym);
266 if (prop) {
267 sym->flags |= SYMBOL_WRITE;
268 newval.tri = expr_calc_value(prop->expr);
269 }
227 } 270 }
228 } 271 if (sym_get_type(sym) == S_BOOLEAN) {
229 272 if (newval.tri == mod)
230 switch (sym_get_type(sym)) { 273 newval.tri = yes;
231 case S_TRISTATE: 274 if (sym->visible == mod)
232 if (S_TRI(newval) != mod) 275 sym->visible = yes;
233 break; 276 if (sym->rev_dep.tri == mod)
234 sym_calc_value(modules_sym); 277 sym->rev_dep.tri = yes;
235 if (S_TRI(modules_sym->curr) == no)
236 S_TRI(newval) = yes;
237 break;
238 case S_BOOLEAN:
239 if (S_TRI(newval) == mod)
240 S_TRI(newval) = yes;
241 }
242
243out:
244 sym->curr = newval;
245
246 if (sym_is_choice(sym) && S_TRI(newval) == yes) {
247 def_sym = S_VAL(sym->def);
248 if (def_sym) {
249 sym_calc_visibility(def_sym);
250 if (def_sym->visible == no)
251 def_sym = NULL;
252 } 278 }
253 if (!def_sym) { 279 break;
254 for_all_defaults(sym, def_prop) { 280 case S_STRING:
255 if (E_CALC(def_prop->visible) == no) 281 case S_HEX:
256 continue; 282 case S_INT:
257 sym_calc_visibility(def_prop->def); 283 if (sym->visible != no) {
258 if (def_prop->def->visible != no) { 284 sym->flags |= SYMBOL_WRITE;
259 def_sym = def_prop->def; 285 if (sym_has_value(sym)) {
260 break; 286 newval.val = sym->user.val;
261 } 287 break;
262 } 288 }
263 } 289 }
264 290 prop = sym_get_default_prop(sym);
265 if (!def_sym) { 291 if (prop) {
266 prop = sym_get_choice_prop(sym); 292 struct symbol *ds = prop_get_symbol(prop);
267 for (e = prop->dep; e; e = e->left.expr) { 293 if (ds) {
268 sym_calc_visibility(e->right.sym); 294 sym->flags |= SYMBOL_WRITE;
269 if (e->right.sym->visible != no) { 295 sym_calc_value(ds);
270 def_sym = e->right.sym; 296 newval.val = ds->curr.val;
271 break;
272 }
273 } 297 }
274 } 298 }
275 299 break;
276 S_VAL(newval) = def_sym; 300 default:
301 ;
277 } 302 }
278 303
279 if (memcmp(&oldval, &newval, sizeof(newval)))
280 sym_set_changed(sym);
281 sym->curr = newval; 304 sym->curr = newval;
305 if (sym_is_choice(sym) && newval.tri == yes)
306 sym->curr.val = sym_calc_choice(sym);
307
308 if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
309 sym_set_changed(sym);
282 310
283 if (sym_is_choice(sym)) { 311 if (sym_is_choice(sym)) {
284 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); 312 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
285 prop = sym_get_choice_prop(sym); 313 prop = sym_get_choice_prop(sym);
286 for (e = prop->dep; e; e = e->left.expr) { 314 for (e = prop->expr; e; e = e->left.expr) {
287 e->right.sym->flags |= flags; 315 e->right.sym->flags |= flags;
288 if (flags & SYMBOL_CHANGED) 316 if (flags & SYMBOL_CHANGED)
289 sym_set_changed(e->right.sym); 317 sym_set_changed(e->right.sym);
290 } 318 }
291 } 319 }
292} 320}
293 321
294void sym_clear_all_valid(void) 322void sym_clear_all_valid(void)
295{ 323{
296 struct symbol *sym; 324 struct symbol *sym;
297 int i; 325 int i;
298 326
299 for_all_symbols(i, sym) 327 for_all_symbols(i, sym)
300 sym->flags &= ~SYMBOL_VALID; 328 sym->flags &= ~SYMBOL_VALID;
301 sym_change_count++; 329 sym_change_count++;
302} 330}
303 331
304void sym_set_changed(struct symbol *sym) 332void sym_set_changed(struct symbol *sym)
305{ 333{
306 struct property *prop; 334 struct property *prop;
307 335
308 sym->flags |= SYMBOL_CHANGED; 336 sym->flags |= SYMBOL_CHANGED;
309 for (prop = sym->prop; prop; prop = prop->next) { 337 for (prop = sym->prop; prop; prop = prop->next) {
310 if (prop->menu) 338 if (prop->menu)
311 prop->menu->flags |= MENU_CHANGED; 339 prop->menu->flags |= MENU_CHANGED;
312 } 340 }
313} 341}
314 342
315void sym_set_all_changed(void) 343void sym_set_all_changed(void)
316{ 344{
317 struct symbol *sym; 345 struct symbol *sym;
318 int i; 346 int i;
319 347
320 for_all_symbols(i, sym) 348 for_all_symbols(i, sym)
321 sym_set_changed(sym); 349 sym_set_changed(sym);
322} 350}
323 351
324bool sym_tristate_within_range(struct symbol *sym, tristate val) 352bool sym_tristate_within_range(struct symbol *sym, tristate val)
325{ 353{
326 int type = sym_get_type(sym); 354 int type = sym_get_type(sym);
327 355
328 if (sym->visible == no) 356 if (sym->visible == no)
329 return false; 357 return false;
330 358
331 if (type != S_BOOLEAN && type != S_TRISTATE) 359 if (type != S_BOOLEAN && type != S_TRISTATE)
332 return false; 360 return false;
333 361
334 switch (val) { 362 if (type == S_BOOLEAN && val == mod)
335 case no: 363 return false;
336 if (sym_is_choice_value(sym) && sym->visible == yes) 364 if (sym->visible <= sym->rev_dep.tri)
337 return false; 365 return false;
338 return sym_is_optional(sym); 366 if (sym_is_choice_value(sym) && sym->visible == yes)
339 case mod: 367 return val == yes;
340 if (sym_is_choice_value(sym) && sym->visible == yes) 368 return val >= sym->rev_dep.tri && val <= sym->visible;
341 return false;
342 return type == S_TRISTATE;
343 case yes:
344 return type == S_BOOLEAN || sym->visible == yes;
345 }
346 return false;
347} 369}
348 370
349bool sym_set_tristate_value(struct symbol *sym, tristate val) 371bool sym_set_tristate_value(struct symbol *sym, tristate val)
350{ 372{
351 tristate oldval = sym_get_tristate_value(sym); 373 tristate oldval = sym_get_tristate_value(sym);
352 374
353 if (oldval != val && !sym_tristate_within_range(sym, val)) 375 if (oldval != val && !sym_tristate_within_range(sym, val))
354 return false; 376 return false;
355 377
356 if (sym->flags & SYMBOL_NEW) { 378 if (sym->flags & SYMBOL_NEW) {
357 sym->flags &= ~SYMBOL_NEW; 379 sym->flags &= ~SYMBOL_NEW;
358 sym_set_changed(sym); 380 sym_set_changed(sym);
359 } 381 }
360 if (sym_is_choice_value(sym) && val == yes) { 382 if (sym_is_choice_value(sym) && val == yes) {
361 struct property *prop = sym_get_choice_prop(sym); 383 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
362 384
363 S_VAL(prop->def->def) = sym; 385 cs->user.val = sym;
364 prop->def->flags &= ~SYMBOL_NEW; 386 cs->flags &= ~SYMBOL_NEW;
365 } 387 }
366 388
367 S_TRI(sym->def) = val; 389 sym->user.tri = val;
368 if (oldval != val) { 390 if (oldval != val) {
369 sym_clear_all_valid(); 391 sym_clear_all_valid();
370 if (sym == modules_sym) 392 if (sym == modules_sym)
371 sym_set_all_changed(); 393 sym_set_all_changed();
372 } 394 }
373 395
374 return true; 396 return true;
375} 397}
376 398
377tristate sym_toggle_tristate_value(struct symbol *sym) 399tristate sym_toggle_tristate_value(struct symbol *sym)
378{ 400{
379 tristate oldval, newval; 401 tristate oldval, newval;
380 402
381 oldval = newval = sym_get_tristate_value(sym); 403 oldval = newval = sym_get_tristate_value(sym);
382 do { 404 do {
383 switch (newval) { 405 switch (newval) {
384 case no: 406 case no:
385 newval = mod; 407 newval = mod;
386 break; 408 break;
387 case mod: 409 case mod:
388 newval = yes; 410 newval = yes;
389 break; 411 break;
390 case yes: 412 case yes:
391 newval = no; 413 newval = no;
392 break; 414 break;
393 } 415 }
394 if (sym_set_tristate_value(sym, newval)) 416 if (sym_set_tristate_value(sym, newval))
395 break; 417 break;
396 } while (oldval != newval); 418 } while (oldval != newval);
397 return newval; 419 return newval;
398} 420}
399 421
400bool sym_string_valid(struct symbol *sym, const char *str) 422bool sym_string_valid(struct symbol *sym, const char *str)
401{ 423{
402 char ch; 424 char ch;
403 425
404 switch (sym->type) { 426 switch (sym->type) {
405 case S_STRING: 427 case S_STRING:
406 return true; 428 return true;
407 case S_INT: 429 case S_INT:
408 ch = *str++; 430 ch = *str++;
409 if (ch == '-') 431 if (ch == '-')
410 ch = *str++; 432 ch = *str++;
411 if (!isdigit(ch)) 433 if (!isdigit(ch))
412 return false; 434 return false;
413 if (ch == '0' && *str != 0) 435 if (ch == '0' && *str != 0)
414 return false; 436 return false;
415 while ((ch = *str++)) { 437 while ((ch = *str++)) {
416 if (!isdigit(ch)) 438 if (!isdigit(ch))
417 return false; 439 return false;
418 } 440 }
419 return true; 441 return true;
420 case S_HEX: 442 case S_HEX:
421 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) 443 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
422 str += 2; 444 str += 2;
423 ch = *str++; 445 ch = *str++;
424 do { 446 do {
425 if (!isxdigit(ch)) 447 if (!isxdigit(ch))
426 return false; 448 return false;
427 } while ((ch = *str++)); 449 } while ((ch = *str++));
428 return true; 450 return true;
429 case S_BOOLEAN: 451 case S_BOOLEAN:
430 case S_TRISTATE: 452 case S_TRISTATE:
431 switch (str[0]) { 453 switch (str[0]) {
432 case 'y': 454 case 'y': case 'Y':
433 case 'Y': 455 case 'm': case 'M':
456 case 'n': case 'N':
457 return true;
458 }
459 return false;
460 default:
461 return false;
462 }
463}
464
465bool sym_string_within_range(struct symbol *sym, const char *str)
466{
467 struct property *prop;
468 int val;
469
470 switch (sym->type) {
471 case S_STRING:
472 return sym_string_valid(sym, str);
473 case S_INT:
474 if (!sym_string_valid(sym, str))
475 return false;
476 prop = sym_get_range_prop(sym);
477 if (!prop)
478 return true;
479 val = strtol(str, NULL, 10);
480 return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
481 val <= strtol(prop->expr->right.sym->name, NULL, 10);
482 case S_HEX:
483 if (!sym_string_valid(sym, str))
484 return false;
485 prop = sym_get_range_prop(sym);
486 if (!prop)
487 return true;
488 val = strtol(str, NULL, 16);
489 return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
490 val <= strtol(prop->expr->right.sym->name, NULL, 16);
491 case S_BOOLEAN:
492 case S_TRISTATE:
493 switch (str[0]) {
494 case 'y': case 'Y':
434 return sym_tristate_within_range(sym, yes); 495 return sym_tristate_within_range(sym, yes);
435 case 'm': 496 case 'm': case 'M':
436 case 'M':
437 return sym_tristate_within_range(sym, mod); 497 return sym_tristate_within_range(sym, mod);
438 case 'n': 498 case 'n': case 'N':
439 case 'N':
440 return sym_tristate_within_range(sym, no); 499 return sym_tristate_within_range(sym, no);
441 } 500 }
442 return false; 501 return false;
443 default: 502 default:
444 return false; 503 return false;
445 } 504 }
446} 505}
447 506
448bool sym_set_string_value(struct symbol *sym, const char *newval) 507bool sym_set_string_value(struct symbol *sym, const char *newval)
449{ 508{
450 const char *oldval; 509 const char *oldval;
451 char *val; 510 char *val;
452 int size; 511 int size;
453 512
454 switch (sym->type) { 513 switch (sym->type) {
455 case S_BOOLEAN: 514 case S_BOOLEAN:
456 case S_TRISTATE: 515 case S_TRISTATE:
457 switch (newval[0]) { 516 switch (newval[0]) {
458 case 'y': 517 case 'y': case 'Y':
459 case 'Y':
460 return sym_set_tristate_value(sym, yes); 518 return sym_set_tristate_value(sym, yes);
461 case 'm': 519 case 'm': case 'M':
462 case 'M':
463 return sym_set_tristate_value(sym, mod); 520 return sym_set_tristate_value(sym, mod);
464 case 'n': 521 case 'n': case 'N':
465 case 'N':
466 return sym_set_tristate_value(sym, no); 522 return sym_set_tristate_value(sym, no);
467 } 523 }
468 return false; 524 return false;
469 default: 525 default:
470 ; 526 ;
471 } 527 }
472 528
473 if (!sym_string_valid(sym, newval)) 529 if (!sym_string_within_range(sym, newval))
474 return false; 530 return false;
475 531
476 if (sym->flags & SYMBOL_NEW) { 532 if (sym->flags & SYMBOL_NEW) {
477 sym->flags &= ~SYMBOL_NEW; 533 sym->flags &= ~SYMBOL_NEW;
478 sym_set_changed(sym); 534 sym_set_changed(sym);
479 } 535 }
480 536
481 oldval = S_VAL(sym->def); 537 oldval = sym->user.val;
482 size = strlen(newval) + 1; 538 size = strlen(newval) + 1;
483 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { 539 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
484 size += 2; 540 size += 2;
485 S_VAL(sym->def) = val = malloc(size); 541 sym->user.val = val = malloc(size);
486 *val++ = '0'; 542 *val++ = '0';
487 *val++ = 'x'; 543 *val++ = 'x';
488 } else if (!oldval || strcmp(oldval, newval)) 544 } else if (!oldval || strcmp(oldval, newval))
489 S_VAL(sym->def) = val = malloc(size); 545 sym->user.val = val = malloc(size);
490 else 546 else
491 return true; 547 return true;
492 548
493 strcpy(val, newval); 549 strcpy(val, newval);
494 free((void *)oldval); 550 free((void *)oldval);
495 sym_clear_all_valid(); 551 sym_clear_all_valid();
496 552
497 return true; 553 return true;
498} 554}
499 555
500const char *sym_get_string_value(struct symbol *sym) 556const char *sym_get_string_value(struct symbol *sym)
501{ 557{
502 tristate val; 558 tristate val;
503 559
504 switch (sym->type) { 560 switch (sym->type) {
505 case S_BOOLEAN: 561 case S_BOOLEAN:
506 case S_TRISTATE: 562 case S_TRISTATE:
507 val = sym_get_tristate_value(sym); 563 val = sym_get_tristate_value(sym);
508 switch (val) { 564 switch (val) {
509 case no: 565 case no:
510 return "n"; 566 return "n";
511 case mod: 567 case mod:
512 return "m"; 568 return "m";
513 case yes: 569 case yes:
514 return "y"; 570 return "y";
515 } 571 }
516 break; 572 break;
517 default: 573 default:
518 ; 574 ;
519 } 575 }
520 return (const char *)S_VAL(sym->curr); 576 return (const char *)sym->curr.val;
521} 577}
522 578
523bool sym_is_changable(struct symbol *sym) 579bool sym_is_changable(struct symbol *sym)
524{ 580{
525 if (sym->visible == no) 581 return sym->visible > sym->rev_dep.tri;
526 return false;
527 /* at least 'n' and 'y'/'m' is selectable */
528 if (sym_is_optional(sym))
529 return true;
530 /* no 'n', so 'y' and 'm' must be selectable */
531 if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes)
532 return true;
533 return false;
534} 582}
535 583
536struct symbol *sym_lookup(const char *name, int isconst) 584struct symbol *sym_lookup(const char *name, int isconst)
537{ 585{
538 struct symbol *symbol; 586 struct symbol *symbol;
539 const char *ptr; 587 const char *ptr;
540 char *new_name; 588 char *new_name;
541 int hash = 0; 589 int hash = 0;
542 590
543 if (name) { 591 if (name) {
544 if (name[0] && !name[1]) { 592 if (name[0] && !name[1]) {
545 switch (name[0]) { 593 switch (name[0]) {
546 case 'y': return &symbol_yes; 594 case 'y': return &symbol_yes;
547 case 'm': return &symbol_mod; 595 case 'm': return &symbol_mod;
548 case 'n': return &symbol_no; 596 case 'n': return &symbol_no;
549 } 597 }
550 } 598 }
551 for (ptr = name; *ptr; ptr++) 599 for (ptr = name; *ptr; ptr++)
552 hash += *ptr; 600 hash += *ptr;
553 hash &= 0xff; 601 hash &= 0xff;
554 602
555 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 603 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
556 if (!strcmp(symbol->name, name)) { 604 if (!strcmp(symbol->name, name)) {
557 if ((isconst && symbol->flags & SYMBOL_CONST) || 605 if ((isconst && symbol->flags & SYMBOL_CONST) ||
558 (!isconst && !(symbol->flags & SYMBOL_CONST))) 606 (!isconst && !(symbol->flags & SYMBOL_CONST)))
559 return symbol; 607 return symbol;
560 } 608 }
561 } 609 }
562 new_name = strdup(name); 610 new_name = strdup(name);
563 } else { 611 } else {
564 new_name = NULL; 612 new_name = NULL;
565 hash = 256; 613 hash = 256;
566 } 614 }
567 615
568 symbol = malloc(sizeof(*symbol)); 616 symbol = malloc(sizeof(*symbol));
569 memset(symbol, 0, sizeof(*symbol)); 617 memset(symbol, 0, sizeof(*symbol));
570 symbol->name = new_name; 618 symbol->name = new_name;
571 symbol->type = S_UNKNOWN; 619 symbol->type = S_UNKNOWN;
572 symbol->flags = SYMBOL_NEW; 620 symbol->flags = SYMBOL_NEW;
573 if (isconst) 621 if (isconst)
574 symbol->flags |= SYMBOL_CONST; 622 symbol->flags |= SYMBOL_CONST;
575 623
576 symbol->next = symbol_hash[hash]; 624 symbol->next = symbol_hash[hash];
577 symbol_hash[hash] = symbol; 625 symbol_hash[hash] = symbol;
578 626
579 return symbol; 627 return symbol;
580} 628}
581 629
582struct symbol *sym_find(const char *name) 630struct symbol *sym_find(const char *name)
583{ 631{
584 struct symbol *symbol = NULL; 632 struct symbol *symbol = NULL;
585 const char *ptr; 633 const char *ptr;
586 int hash = 0; 634 int hash = 0;
587 635
588 if (!name) 636 if (!name)
589 return NULL; 637 return NULL;
590 638
591 if (name[0] && !name[1]) { 639 if (name[0] && !name[1]) {
592 switch (name[0]) { 640 switch (name[0]) {
593 case 'y': return &symbol_yes; 641 case 'y': return &symbol_yes;
594 case 'm': return &symbol_mod; 642 case 'm': return &symbol_mod;
595 case 'n': return &symbol_no; 643 case 'n': return &symbol_no;
596 } 644 }
597 } 645 }
598 for (ptr = name; *ptr; ptr++) 646 for (ptr = name; *ptr; ptr++)
599 hash += *ptr; 647 hash += *ptr;
600 hash &= 0xff; 648 hash &= 0xff;
601 649
602 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 650 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
603 if (!strcmp(symbol->name, name) && 651 if (!strcmp(symbol->name, name) &&
604 !(symbol->flags & SYMBOL_CONST)) 652 !(symbol->flags & SYMBOL_CONST))
605 break; 653 break;
606 } 654 }
607 655
608 return symbol; 656 return symbol;
609} 657}
610 658
659struct symbol *sym_check_deps(struct symbol *sym);
660
661static struct symbol *sym_check_expr_deps(struct expr *e)
662{
663 struct symbol *sym;
664
665 if (!e)
666 return NULL;
667 switch (e->type) {
668 case E_OR:
669 case E_AND:
670 sym = sym_check_expr_deps(e->left.expr);
671 if (sym)
672 return sym;
673 return sym_check_expr_deps(e->right.expr);
674 case E_NOT:
675 return sym_check_expr_deps(e->left.expr);
676 case E_EQUAL:
677 case E_UNEQUAL:
678 sym = sym_check_deps(e->left.sym);
679 if (sym)
680 return sym;
681 return sym_check_deps(e->right.sym);
682 case E_SYMBOL:
683 return sym_check_deps(e->left.sym);
684 default:
685 break;
686 }
687 printf("Oops! How to check %d?\n", e->type);
688 return NULL;
689}
690
691struct symbol *sym_check_deps(struct symbol *sym)
692{
693 struct symbol *sym2;
694 struct property *prop;
695
696 if (sym->flags & SYMBOL_CHECK_DONE)
697 return NULL;
698 if (sym->flags & SYMBOL_CHECK) {
699 printf("Warning! Found recursive dependency: %s", sym->name);
700 return sym;
701 }
702
703 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
704 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
705 if (sym2)
706 goto out;
707
708 for (prop = sym->prop; prop; prop = prop->next) {
709 if (prop->type == P_CHOICE)
710 continue;
711 sym2 = sym_check_expr_deps(prop->visible.expr);
712 if (sym2)
713 goto out;
714 if (prop->type != P_DEFAULT || sym_is_choice(sym))
715 continue;
716 sym2 = sym_check_expr_deps(prop->expr);
717 if (sym2)
718 goto out;
719 }
720out:
721 if (sym2)
722 printf(" %s", sym->name);
723 sym->flags &= ~SYMBOL_CHECK;
724 return sym2;
725}
726
727struct property *prop_alloc(enum prop_type type, struct symbol *sym)
728{
729 struct property *prop;
730 struct property **propp;
731
732 prop = malloc(sizeof(*prop));
733 memset(prop, 0, sizeof(*prop));
734 prop->type = type;
735 prop->sym = sym;
736 prop->file = current_file;
737 prop->lineno = zconf_lineno();
738
739 /* append property to the prop list of symbol */
740 if (sym) {
741 for (propp = &sym->prop; *propp; propp = &(*propp)->next)
742 ;
743 *propp = prop;
744 }
745
746 return prop;
747}
748
749struct symbol *prop_get_symbol(struct property *prop)
750{
751 if (prop->expr && (prop->expr->type == E_SYMBOL ||
752 prop->expr->type == E_CHOICE))
753 return prop->expr->left.sym;
754 return NULL;
755}
756
611const char *prop_get_type_name(enum prop_type type) 757const char *prop_get_type_name(enum prop_type type)
612{ 758{
613 switch (type) { 759 switch (type) {
614 case P_PROMPT: 760 case P_PROMPT:
615 return "prompt"; 761 return "prompt";
616 case P_COMMENT: 762 case P_COMMENT:
617 return "comment"; 763 return "comment";
618 case P_MENU: 764 case P_MENU:
619 return "menu"; 765 return "menu";
620 case P_ROOTMENU:
621 return "rootmenu";
622 case P_DEFAULT: 766 case P_DEFAULT:
623 return "default"; 767 return "default";
624 case P_CHOICE: 768 case P_CHOICE:
625 return "choice"; 769 return "choice";
626 default: 770 case P_SELECT:
627 return "unknown"; 771 return "select";
772 case P_RANGE:
773 return "range";
774 case P_UNKNOWN:
775 break;
628 } 776 }
777 return "unknown";
629} 778}
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 1471630..55517b2 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -1,359 +1,366 @@
1%option backup nostdinit noyywrap never-interactive 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 <limits.h>
11#include <stdio.h> 11#include <stdio.h>
12#include <stdlib.h> 12#include <stdlib.h>
13#include <string.h> 13#include <string.h>
14#include <unistd.h> 14#include <unistd.h>
15 15
16#define LKC_DIRECT_LINK 16#define LKC_DIRECT_LINK
17#include "lkc.h" 17#include "lkc.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 BEGIN(COMMAND); 86 BEGIN(COMMAND);
87} 87}
88 88
89 89
90<COMMAND>{ 90<COMMAND>{
91 "mainmenu" BEGIN(PARAM); return T_MAINMENU; 91 "mainmenu" BEGIN(PARAM); return T_MAINMENU;
92 "menu" BEGIN(PARAM); return T_MENU; 92 "menu" BEGIN(PARAM); return T_MENU;
93 "endmenu" BEGIN(PARAM); return T_ENDMENU; 93 "endmenu" BEGIN(PARAM); return T_ENDMENU;
94 "source" BEGIN(PARAM); return T_SOURCE; 94 "source" BEGIN(PARAM); return T_SOURCE;
95 "choice" BEGIN(PARAM); return T_CHOICE; 95 "choice" BEGIN(PARAM); return T_CHOICE;
96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE; 96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
97 "comment" BEGIN(PARAM); return T_COMMENT; 97 "comment" BEGIN(PARAM); return T_COMMENT;
98 "config" BEGIN(PARAM); return T_CONFIG; 98 "config" BEGIN(PARAM); return T_CONFIG;
99 "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
99 "help" BEGIN(PARAM); return T_HELP; 100 "help" BEGIN(PARAM); return T_HELP;
100 "if" BEGIN(PARAM); return T_IF; 101 "if" BEGIN(PARAM); return T_IF;
101 "endif" BEGIN(PARAM); return T_ENDIF; 102 "endif" BEGIN(PARAM); return T_ENDIF;
102 "depends" BEGIN(PARAM); return T_DEPENDS; 103 "depends" BEGIN(PARAM); return T_DEPENDS;
103 "requires" BEGIN(PARAM); return T_REQUIRES; 104 "requires" BEGIN(PARAM); return T_REQUIRES;
104 "optional" BEGIN(PARAM); return T_OPTIONAL; 105 "optional" BEGIN(PARAM); return T_OPTIONAL;
105 "default" BEGIN(PARAM); return T_DEFAULT; 106 "default" BEGIN(PARAM); return T_DEFAULT;
106 "prompt" BEGIN(PARAM); return T_PROMPT; 107 "prompt" BEGIN(PARAM); return T_PROMPT;
107 "tristate" BEGIN(PARAM); return T_TRISTATE; 108 "tristate" BEGIN(PARAM); return T_TRISTATE;
109 "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
108 "bool" BEGIN(PARAM); return T_BOOLEAN; 110 "bool" BEGIN(PARAM); return T_BOOLEAN;
109 "boolean" BEGIN(PARAM); return T_BOOLEAN; 111 "boolean" BEGIN(PARAM); return T_BOOLEAN;
112 "def_bool" BEGIN(PARAM); return T_DEF_BOOLEAN;
113 "def_boolean" BEGIN(PARAM); return T_DEF_BOOLEAN;
110 "int" BEGIN(PARAM); return T_INT; 114 "int" BEGIN(PARAM); return T_INT;
111 "hex" BEGIN(PARAM); return T_HEX; 115 "hex" BEGIN(PARAM); return T_HEX;
112 "string" BEGIN(PARAM); return T_STRING; 116 "string" BEGIN(PARAM); return T_STRING;
117 "select" BEGIN(PARAM); return T_SELECT;
118 "enable" BEGIN(PARAM); return T_SELECT;
119 "range" BEGIN(PARAM); return T_RANGE;
113 {n}+{ 120 {n}+{
114 alloc_string(yytext, yyleng); 121 alloc_string(yytext, yyleng);
115 zconflval.string = text; 122 zconflval.string = text;
116 return T_WORD; 123 return T_WORD;
117 } 124 }
118 . 125 .
119 \ncurrent_file->lineno++; BEGIN(INITIAL); 126 \ncurrent_file->lineno++; BEGIN(INITIAL);
120} 127}
121 128
122<PARAM>{ 129<PARAM>{
123 "&&"return T_AND; 130 "&&"return T_AND;
124 "||"return T_OR; 131 "||"return T_OR;
125 "("return T_OPEN_PAREN; 132 "("return T_OPEN_PAREN;
126 ")"return T_CLOSE_PAREN; 133 ")"return T_CLOSE_PAREN;
127 "!"return T_NOT; 134 "!"return T_NOT;
128 "="return T_EQUAL; 135 "="return T_EQUAL;
129 "!="return T_UNEQUAL; 136 "!="return T_UNEQUAL;
130 "if"return T_IF; 137 "if"return T_IF;
131 "on"return T_ON; 138 "on"return T_ON;
132 \"|\'{ 139 \"|\'{
133 str = yytext[0]; 140 str = yytext[0];
134 new_string(); 141 new_string();
135 BEGIN(STRING); 142 BEGIN(STRING);
136 } 143 }
137 \nBEGIN(INITIAL); current_file->lineno++; return T_EOL; 144 \nBEGIN(INITIAL); current_file->lineno++; return T_EOL;
138 ---/* ignore */ 145 ---/* ignore */
139 ({n}|[-/.])+{ 146 ({n}|[-/.])+{
140 alloc_string(yytext, yyleng); 147 alloc_string(yytext, yyleng);
141 zconflval.string = text; 148 zconflval.string = text;
142 return T_WORD; 149 return T_WORD;
143 } 150 }
151 #.*/* comment */
144 \\\ncurrent_file->lineno++; 152 \\\ncurrent_file->lineno++;
145 . 153 .
146 <<EOF>> { 154 <<EOF>> {
147 BEGIN(INITIAL); 155 BEGIN(INITIAL);
148 } 156 }
149} 157}
150 158
151<STRING>{ 159<STRING>{
152 [^'"\\\n]+/\n{ 160 [^'"\\\n]+/\n{
153 append_string(yytext, yyleng); 161 append_string(yytext, yyleng);
154 zconflval.string = text; 162 zconflval.string = text;
155 return T_STRING; 163 return T_WORD_QUOTE;
156 } 164 }
157 [^'"\\\n]+{ 165 [^'"\\\n]+{
158 append_string(yytext, yyleng); 166 append_string(yytext, yyleng);
159 } 167 }
160 \\.?/\n{ 168 \\.?/\n{
161 append_string(yytext + 1, yyleng - 1); 169 append_string(yytext + 1, yyleng - 1);
162 zconflval.string = text; 170 zconflval.string = text;
163 return T_STRING; 171 return T_WORD_QUOTE;
164 } 172 }
165 \\.?{ 173 \\.?{
166 append_string(yytext + 1, yyleng - 1); 174 append_string(yytext + 1, yyleng - 1);
167 } 175 }
168 \'|\"{ 176 \'|\"{
169 if (str == yytext[0]) { 177 if (str == yytext[0]) {
170 BEGIN(PARAM); 178 BEGIN(PARAM);
171 zconflval.string = text; 179 zconflval.string = text;
172 return T_STRING; 180 return T_WORD_QUOTE;
173 } else 181 } else
174 append_string(yytext, 1); 182 append_string(yytext, 1);
175 } 183 }
176 \n{ 184 \n{
177 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); 185 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
178 current_file->lineno++; 186 current_file->lineno++;
179 BEGIN(INITIAL); 187 BEGIN(INITIAL);
180 return T_EOL; 188 return T_EOL;
181 } 189 }
182 <<EOF>>{ 190 <<EOF>>{
183 BEGIN(INITIAL); 191 BEGIN(INITIAL);
184 } 192 }
185} 193}
186 194
187<HELP>{ 195<HELP>{
188 [ \t]+{ 196 [ \t]+{
189 ts = 0; 197 ts = 0;
190 for (i = 0; i < yyleng; i++) { 198 for (i = 0; i < yyleng; i++) {
191 if (yytext[i] == '\t') 199 if (yytext[i] == '\t')
192 ts = (ts & ~7) + 8; 200 ts = (ts & ~7) + 8;
193 else 201 else
194 ts++; 202 ts++;
195 } 203 }
196 last_ts = ts; 204 last_ts = ts;
197 if (first_ts) { 205 if (first_ts) {
198 if (ts < first_ts) { 206 if (ts < first_ts) {
199 zconf_endhelp(); 207 zconf_endhelp();
200 return T_HELPTEXT; 208 return T_HELPTEXT;
201 } 209 }
202 ts -= first_ts; 210 ts -= first_ts;
203 while (ts > 8) { 211 while (ts > 8) {
204 append_string(" ", 8); 212 append_string(" ", 8);
205 ts -= 8; 213 ts -= 8;
206 } 214 }
207 append_string(" ", ts); 215 append_string(" ", ts);
208 } 216 }
209
210 } 217 }
211 \n/[^ \t\n] { 218 [ \t]*\n/[^ \t\n] {
212 current_file->lineno++; 219 current_file->lineno++;
213 zconf_endhelp(); 220 zconf_endhelp();
214 return T_HELPTEXT; 221 return T_HELPTEXT;
215 } 222 }
216 [ \t]*\n{ 223 [ \t]*\n{
217 current_file->lineno++; 224 current_file->lineno++;
218 append_string("\n", 1); 225 append_string("\n", 1);
219 } 226 }
220 [^ \t\n].* { 227 [^ \t\n].* {
221 append_string(yytext, yyleng); 228 append_string(yytext, yyleng);
222 if (!first_ts) 229 if (!first_ts)
223 first_ts = last_ts; 230 first_ts = last_ts;
224 } 231 }
225 <<EOF>>{ 232 <<EOF>>{
226 zconf_endhelp(); 233 zconf_endhelp();
227 return T_HELPTEXT; 234 return T_HELPTEXT;
228 } 235 }
229} 236}
230 237
231 <<EOF>>{ 238 <<EOF>>{
232 if (current_buf) { 239 if (current_buf) {
233 zconf_endfile(); 240 zconf_endfile();
234 return T_EOF; 241 return T_EOF;
235 } 242 }
236 fclose(yyin); 243 fclose(yyin);
237 yyterminate(); 244 yyterminate();
238} 245}
239 246
240%% 247%%
241void zconf_starthelp(void) 248void zconf_starthelp(void)
242{ 249{
243 new_string(); 250 new_string();
244 last_ts = first_ts = 0; 251 last_ts = first_ts = 0;
245 BEGIN(HELP); 252 BEGIN(HELP);
246} 253}
247 254
248static void zconf_endhelp(void) 255static void zconf_endhelp(void)
249{ 256{
250 zconflval.string = text; 257 zconflval.string = text;
251 BEGIN(INITIAL); 258 BEGIN(INITIAL);
252} 259}
253 260
254 261
255/* 262/*
256 * Try to open specified file with following names: 263 * Try to open specified file with following names:
257 * ./name 264 * ./name
258 * $(srctree)/name 265 * $(srctree)/name
259 * The latter is used when srctree is separate from objtree 266 * The latter is used when srctree is separate from objtree
260 * when compiling the kernel. 267 * when compiling the kernel.
261 * Return NULL if file is not found. 268 * Return NULL if file is not found.
262 */ 269 */
263FILE *zconf_fopen(const char *name) 270FILE *zconf_fopen(const char *name)
264{ 271{
265 char *env, fullname[PATH_MAX+1]; 272 char *env, fullname[PATH_MAX+1];
266 FILE *f; 273 FILE *f;
267 274
268 f = fopen(name, "r"); 275 f = fopen(name, "r");
269 if (!f && name[0] != '/') { 276 if (!f && name[0] != '/') {
270 env = getenv(SRCTREE); 277 env = getenv(SRCTREE);
271 if (env) { 278 if (env) {
272 sprintf(fullname, "%s/%s", env, name); 279 sprintf(fullname, "%s/%s", env, name);
273 f = fopen(fullname, "r"); 280 f = fopen(fullname, "r");
274 } 281 }
275 } 282 }
276 return f; 283 return f;
277} 284}
278 285
279void zconf_initscan(const char *name) 286void zconf_initscan(const char *name)
280{ 287{
281 yyin = zconf_fopen(name); 288 yyin = zconf_fopen(name);
282 if (!yyin) { 289 if (!yyin) {
283 printf("can't find file %s\n", name); 290 printf("can't find file %s\n", name);
284 exit(1); 291 exit(1);
285 } 292 }
286 293
287 current_buf = malloc(sizeof(*current_buf)); 294 current_buf = malloc(sizeof(*current_buf));
288 memset(current_buf, 0, sizeof(*current_buf)); 295 memset(current_buf, 0, sizeof(*current_buf));
289 296
290 current_file = file_lookup(name); 297 current_file = file_lookup(name);
291 current_file->lineno = 1; 298 current_file->lineno = 1;
292 current_file->flags = FILE_BUSY; 299 current_file->flags = FILE_BUSY;
293} 300}
294 301
295void zconf_nextfile(const char *name) 302void zconf_nextfile(const char *name)
296{ 303{
297 struct file *file = file_lookup(name); 304 struct file *file = file_lookup(name);
298 struct buffer *buf = malloc(sizeof(*buf)); 305 struct buffer *buf = malloc(sizeof(*buf));
299 memset(buf, 0, sizeof(*buf)); 306 memset(buf, 0, sizeof(*buf));
300 307
301 current_buf->state = YY_CURRENT_BUFFER; 308 current_buf->state = YY_CURRENT_BUFFER;
302 yyin = zconf_fopen(name); 309 yyin = zconf_fopen(name);
303 if (!yyin) { 310 if (!yyin) {
304 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); 311 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
305 exit(1); 312 exit(1);
306 } 313 }
307 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 314 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
308 buf->parent = current_buf; 315 buf->parent = current_buf;
309 current_buf = buf; 316 current_buf = buf;
310 317
311 if (file->flags & FILE_BUSY) { 318 if (file->flags & FILE_BUSY) {
312 printf("recursive scan (%s)?\n", name); 319 printf("recursive scan (%s)?\n", name);
313 exit(1); 320 exit(1);
314 } 321 }
315 if (file->flags & FILE_SCANNED) { 322 if (file->flags & FILE_SCANNED) {
316 printf("file %s already scanned?\n", name); 323 printf("file %s already scanned?\n", name);
317 exit(1); 324 exit(1);
318 } 325 }
319 file->flags |= FILE_BUSY; 326 file->flags |= FILE_BUSY;
320 file->lineno = 1; 327 file->lineno = 1;
321 file->parent = current_file; 328 file->parent = current_file;
322 current_file = file; 329 current_file = file;
323} 330}
324 331
325static struct buffer *zconf_endfile(void) 332static struct buffer *zconf_endfile(void)
326{ 333{
327 struct buffer *parent; 334 struct buffer *parent;
328 335
329 current_file->flags |= FILE_SCANNED; 336 current_file->flags |= FILE_SCANNED;
330 current_file->flags &= ~FILE_BUSY; 337 current_file->flags &= ~FILE_BUSY;
331 current_file = current_file->parent; 338 current_file = current_file->parent;
332 339
333 parent = current_buf->parent; 340 parent = current_buf->parent;
334 if (parent) { 341 if (parent) {
335 fclose(yyin); 342 fclose(yyin);
336 yy_delete_buffer(YY_CURRENT_BUFFER); 343 yy_delete_buffer(YY_CURRENT_BUFFER);
337 yy_switch_to_buffer(parent->state); 344 yy_switch_to_buffer(parent->state);
338 } 345 }
339 free(current_buf); 346 free(current_buf);
340 current_buf = parent; 347 current_buf = parent;
341 348
342 return parent; 349 return parent;
343} 350}
344 351
345int zconf_lineno(void) 352int zconf_lineno(void)
346{ 353{
347 if (current_buf) 354 if (current_buf)
348 return current_file->lineno; 355 return current_file->lineno - 1;
349 else 356 else
350 return 0; 357 return 0;
351} 358}
352 359
353char *zconf_curname(void) 360char *zconf_curname(void)
354{ 361{
355 if (current_buf) 362 if (current_buf)
356 return current_file->name; 363 return current_file->name;
357 else 364 else
358 return "<none>"; 365 return "<none>";
359} 366}
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 996b10a..2468068 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -1,649 +1,687 @@
1%{ 1%{
2/* 2/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 * Released under the terms of the GNU GPL v2.0. 4 * Released under the terms of the GNU GPL v2.0.
5 */ 5 */
6 6
7#include <ctype.h> 7#include <ctype.h>
8#include <stdarg.h> 8#include <stdarg.h>
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12#include <stdbool.h> 12#include <stdbool.h>
13 13
14#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) 14#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
15 15
16 #define PRINTD 0x0001 16 #define PRINTD 0x0001
17 #define DEBUG_PARSE0x0002 17 #define DEBUG_PARSE0x0002
18 18
19int cdebug = PRINTD; 19int cdebug = PRINTD;
20 20
21extern int zconflex(void); 21extern int zconflex(void);
22static void zconfprint(const char *err, ...); 22static void zconfprint(const char *err, ...);
23static void zconferror(const char *err); 23static void zconferror(const char *err);
24static bool zconf_endtoken(int token, int starttoken, int endtoken); 24static bool zconf_endtoken(int token, int starttoken, int endtoken);
25 25
26struct symbol *symbol_hash[257]; 26struct symbol *symbol_hash[257];
27 27
28#define YYERROR_VERBOSE 28#define YYERROR_VERBOSE
29%} 29%}
30%expect 36 30%expect 40
31 31
32%union 32%union
33{ 33{
34 int token; 34 int token;
35 char *string; 35 char *string;
36 struct symbol *symbol; 36 struct symbol *symbol;
37 struct expr *expr; 37 struct expr *expr;
38 struct menu *menu; 38 struct menu *menu;
39} 39}
40 40
41%token T_MAINMENU 41%token T_MAINMENU
42%token T_MENU 42%token T_MENU
43%token T_ENDMENU 43%token T_ENDMENU
44%token T_SOURCE 44%token T_SOURCE
45%token T_CHOICE 45%token T_CHOICE
46%token T_ENDCHOICE 46%token T_ENDCHOICE
47%token T_COMMENT 47%token T_COMMENT
48%token T_CONFIG 48%token T_CONFIG
49%token T_MENUCONFIG
49%token T_HELP 50%token T_HELP
50%token <string> T_HELPTEXT 51%token <string> T_HELPTEXT
51%token T_IF 52%token T_IF
52%token T_ENDIF 53%token T_ENDIF
53%token T_DEPENDS 54%token T_DEPENDS
54%token T_REQUIRES 55%token T_REQUIRES
55%token T_OPTIONAL 56%token T_OPTIONAL
56%token T_PROMPT 57%token T_PROMPT
57%token T_DEFAULT 58%token T_DEFAULT
58%token T_TRISTATE 59%token T_TRISTATE
60%token T_DEF_TRISTATE
59%token T_BOOLEAN 61%token T_BOOLEAN
62%token T_DEF_BOOLEAN
63%token T_STRING
60%token T_INT 64%token T_INT
61%token T_HEX 65%token T_HEX
62%token <string> T_WORD 66%token <string> T_WORD
63%token <string> T_STRING 67%token <string> T_WORD_QUOTE
64%token T_UNEQUAL 68%token T_UNEQUAL
65%token T_EOF 69%token T_EOF
66%token T_EOL 70%token T_EOL
67%token T_CLOSE_PAREN 71%token T_CLOSE_PAREN
68%token T_OPEN_PAREN 72%token T_OPEN_PAREN
69%token T_ON 73%token T_ON
74%token T_SELECT
75%token T_RANGE
70 76
71%left T_OR 77%left T_OR
72%left T_AND 78%left T_AND
73%left T_EQUAL T_UNEQUAL 79%left T_EQUAL T_UNEQUAL
74%nonassoc T_NOT 80%nonassoc T_NOT
75 81
76%type <string> prompt 82%type <string> prompt
77%type <string> source 83%type <string> source
78%type <symbol> symbol 84%type <symbol> symbol
79%type <expr> expr 85%type <expr> expr
80%type <expr> if_expr 86%type <expr> if_expr
81%type <token> end 87%type <token> end
82 88
83%{ 89%{
84#define LKC_DIRECT_LINK 90#define LKC_DIRECT_LINK
85#include "lkc.h" 91#include "lkc.h"
86%} 92%}
87%% 93%%
88 input: /* empty */ 94 input: /* empty */
89 | input block 95 | input block
90; 96;
91 97
92 block: common_block 98 block: common_block
93 | choice_stmt 99 | choice_stmt
94 | menu_stmt 100 | menu_stmt
95 | T_MAINMENU prompt nl_or_eof 101 | T_MAINMENU prompt nl_or_eof
96 | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); } 102 | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
97 | T_ENDIF { zconfprint("unexpected 'endif' statement"); } 103 | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
98 | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); } 104 | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
99 | error nl_or_eof{ zconfprint("syntax error"); yyerrok; } 105 | error nl_or_eof{ zconfprint("syntax error"); yyerrok; }
100; 106;
101 107
102common_block: 108common_block:
103 if_stmt 109 if_stmt
104 | comment_stmt 110 | comment_stmt
105 | config_stmt 111 | config_stmt
112 | menuconfig_stmt
106 | source_stmt 113 | source_stmt
107 | nl_or_eof 114 | nl_or_eof
108; 115;
109 116
110 117
111/* config entry */ 118/* config/menuconfig entry */
112 119
113config_entry_start: T_CONFIG T_WORD 120config_entry_start: T_CONFIG T_WORD T_EOL
114{ 121{
115 struct symbol *sym = sym_lookup($2, 0); 122 struct symbol *sym = sym_lookup($2, 0);
116 sym->flags |= SYMBOL_OPTIONAL; 123 sym->flags |= SYMBOL_OPTIONAL;
117 menu_add_entry(sym); 124 menu_add_entry(sym);
118 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); 125 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
119}; 126};
120 127
121config_stmt: config_entry_start T_EOL config_option_list 128config_stmt: config_entry_start config_option_list
122{ 129{
123 menu_end_entry(); 130 menu_end_entry();
124 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); 131 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
125}; 132};
126 133
134menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
135{
136 struct symbol *sym = sym_lookup($2, 0);
137 sym->flags |= SYMBOL_OPTIONAL;
138 menu_add_entry(sym);
139 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
140};
141
142menuconfig_stmt: menuconfig_entry_start config_option_list
143{
144 if (current_entry->prompt)
145 current_entry->prompt->type = P_MENU;
146 else
147 zconfprint("warning: menuconfig statement without prompt");
148 menu_end_entry();
149 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
150};
151
127config_option_list: 152config_option_list:
128 /* empty */ 153 /* empty */
129 | config_option_list config_option T_EOL 154 | config_option_list config_option
130 | config_option_list depends T_EOL 155 | config_option_list depends
131 | config_option_list help 156 | config_option_list help
132 | config_option_list T_EOL 157 | config_option_list T_EOL
133{ }; 158;
134 159
135config_option: T_TRISTATE prompt_stmt_opt 160config_option: T_TRISTATE prompt_stmt_opt T_EOL
136{ 161{
137 menu_set_type(S_TRISTATE); 162 menu_set_type(S_TRISTATE);
138 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno()); 163 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
139}; 164};
140 165
141config_option: T_BOOLEAN prompt_stmt_opt 166config_option: T_DEF_TRISTATE expr if_expr T_EOL
167{
168 menu_add_expr(P_DEFAULT, $2, $3);
169 menu_set_type(S_TRISTATE);
170 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
171};
172
173config_option: T_BOOLEAN prompt_stmt_opt T_EOL
142{ 174{
143 menu_set_type(S_BOOLEAN); 175 menu_set_type(S_BOOLEAN);
144 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno()); 176 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
145}; 177};
146 178
147config_option: T_INT prompt_stmt_opt 179config_option: T_DEF_BOOLEAN expr if_expr T_EOL
180{
181 menu_add_expr(P_DEFAULT, $2, $3);
182 menu_set_type(S_BOOLEAN);
183 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
184};
185
186config_option: T_INT prompt_stmt_opt T_EOL
148{ 187{
149 menu_set_type(S_INT); 188 menu_set_type(S_INT);
150 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno()); 189 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
151}; 190};
152 191
153config_option: T_HEX prompt_stmt_opt 192config_option: T_HEX prompt_stmt_opt T_EOL
154{ 193{
155 menu_set_type(S_HEX); 194 menu_set_type(S_HEX);
156 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno()); 195 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
157}; 196};
158 197
159config_option: T_STRING prompt_stmt_opt 198config_option: T_STRING prompt_stmt_opt T_EOL
160{ 199{
161 menu_set_type(S_STRING); 200 menu_set_type(S_STRING);
162 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno()); 201 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
163}; 202};
164 203
165config_option: T_PROMPT prompt if_expr 204config_option: T_PROMPT prompt if_expr T_EOL
166{ 205{
167 menu_add_prop(P_PROMPT, $2, NULL, $3); 206 menu_add_prompt(P_PROMPT, $2, $3);
168 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 207 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
169}; 208};
170 209
171config_option: T_DEFAULT symbol if_expr 210config_option: T_DEFAULT expr if_expr T_EOL
172{ 211{
173 menu_add_prop(P_DEFAULT, NULL, $2, $3); 212 menu_add_expr(P_DEFAULT, $2, $3);
174 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 213 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
175}; 214};
176 215
216config_option: T_SELECT T_WORD if_expr T_EOL
217{
218 menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
219 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
220};
221
222config_option: T_RANGE symbol symbol if_expr T_EOL
223{
224 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
225 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
226};
227
177/* choice entry */ 228/* choice entry */
178 229
179choice: T_CHOICE 230choice: T_CHOICE T_EOL
180{ 231{
181 struct symbol *sym = sym_lookup(NULL, 0); 232 struct symbol *sym = sym_lookup(NULL, 0);
182 sym->flags |= SYMBOL_CHOICE; 233 sym->flags |= SYMBOL_CHOICE;
183 menu_add_entry(sym); 234 menu_add_entry(sym);
184 menu_add_prop(P_CHOICE, NULL, NULL, NULL); 235 menu_add_expr(P_CHOICE, NULL, NULL);
185 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno()); 236 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
186}; 237};
187 238
188choice_entry: choice T_EOL choice_option_list 239choice_entry: choice choice_option_list
189{ 240{
190 menu_end_entry(); 241 menu_end_entry();
191 menu_add_menu(); 242 menu_add_menu();
192}; 243};
193 244
194choice_end: end 245choice_end: end
195{ 246{
196 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { 247 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
197 menu_end_menu(); 248 menu_end_menu();
198 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); 249 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
199 } 250 }
200}; 251};
201 252
202choice_stmt: 253choice_stmt:
203 choice_entry choice_block choice_end T_EOL 254 choice_entry choice_block choice_end
204 | choice_entry choice_block 255 | choice_entry choice_block
205{ 256{
206 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno); 257 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
207 zconfnerrs++; 258 zconfnerrs++;
208}; 259};
209 260
210choice_option_list: 261choice_option_list:
211 /* empty */ 262 /* empty */
212 | choice_option_list choice_option T_EOL 263 | choice_option_list choice_option
213 | choice_option_list depends T_EOL 264 | choice_option_list depends
214 | choice_option_list help 265 | choice_option_list help
215 | choice_option_list T_EOL 266 | choice_option_list T_EOL
216; 267;
217 268
218choice_option: T_PROMPT prompt if_expr 269choice_option: T_PROMPT prompt if_expr T_EOL
219{ 270{
220 menu_add_prop(P_PROMPT, $2, NULL, $3); 271 menu_add_prompt(P_PROMPT, $2, $3);
221 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); 272 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
222}; 273};
223 274
224choice_option: T_OPTIONAL 275choice_option: T_TRISTATE prompt_stmt_opt T_EOL
276{
277 menu_set_type(S_TRISTATE);
278 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
279};
280
281choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
282{
283 menu_set_type(S_BOOLEAN);
284 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
285};
286
287choice_option: T_OPTIONAL T_EOL
225{ 288{
226 current_entry->sym->flags |= SYMBOL_OPTIONAL; 289 current_entry->sym->flags |= SYMBOL_OPTIONAL;
227 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); 290 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
228}; 291};
229 292
230choice_option: T_DEFAULT symbol if_expr 293choice_option: T_DEFAULT T_WORD if_expr T_EOL
231{ 294{
232 menu_add_prop(P_DEFAULT, NULL, $2, $3); 295 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
233 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno()); 296 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
234}; 297};
235 298
236choice_block: 299choice_block:
237 /* empty */ 300 /* empty */
238 | choice_block common_block 301 | choice_block common_block
239; 302;
240 303
241/* if entry */ 304/* if entry */
242 305
243if: T_IF expr 306if: T_IF expr T_EOL
244{ 307{
245 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); 308 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
246 menu_add_entry(NULL); 309 menu_add_entry(NULL);
247 menu_add_dep($2); 310 menu_add_dep($2);
248 menu_end_entry(); 311 menu_end_entry();
249 menu_add_menu(); 312 menu_add_menu();
250}; 313};
251 314
252if_end: end 315if_end: end
253{ 316{
254 if (zconf_endtoken($1, T_IF, T_ENDIF)) { 317 if (zconf_endtoken($1, T_IF, T_ENDIF)) {
255 menu_end_menu(); 318 menu_end_menu();
256 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); 319 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
257 } 320 }
258}; 321};
259 322
260if_stmt: 323if_stmt:
261 if T_EOL if_block if_end T_EOL 324 if if_block if_end
262 | if T_EOL if_block 325 | if if_block
263{ 326{
264 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno); 327 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
265 zconfnerrs++; 328 zconfnerrs++;
266}; 329};
267 330
268if_block: 331if_block:
269 /* empty */ 332 /* empty */
270 | if_block common_block 333 | if_block common_block
271 | if_block menu_stmt 334 | if_block menu_stmt
272 | if_block choice_stmt 335 | if_block choice_stmt
273; 336;
274 337
275/* menu entry */ 338/* menu entry */
276 339
277menu: T_MENU prompt 340menu: T_MENU prompt T_EOL
278{ 341{
279 menu_add_entry(NULL); 342 menu_add_entry(NULL);
280 menu_add_prop(P_MENU, $2, NULL, NULL); 343 menu_add_prop(P_MENU, $2, NULL, NULL);
281 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); 344 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
282}; 345};
283 346
284menu_entry: menu T_EOL depends_list 347menu_entry: menu depends_list
285{ 348{
286 menu_end_entry(); 349 menu_end_entry();
287 menu_add_menu(); 350 menu_add_menu();
288}; 351};
289 352
290menu_end: end 353menu_end: end
291{ 354{
292 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { 355 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
293 menu_end_menu(); 356 menu_end_menu();
294 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); 357 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
295 } 358 }
296}; 359};
297 360
298menu_stmt: 361menu_stmt:
299 menu_entry menu_block menu_end T_EOL 362 menu_entry menu_block menu_end
300 | menu_entry menu_block 363 | menu_entry menu_block
301{ 364{
302 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno); 365 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
303 zconfnerrs++; 366 zconfnerrs++;
304}; 367};
305 368
306menu_block: 369menu_block:
307 /* empty */ 370 /* empty */
308 | menu_block common_block 371 | menu_block common_block
309 | menu_block menu_stmt 372 | menu_block menu_stmt
310 | menu_block choice_stmt 373 | menu_block choice_stmt
311 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; } 374 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
312; 375;
313 376
314source: T_SOURCE prompt 377source: T_SOURCE prompt T_EOL
315{ 378{
316 $$ = $2; 379 $$ = $2;
317 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); 380 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
318}; 381};
319 382
320source_stmt: source T_EOL 383source_stmt: source
321{ 384{
322 zconf_nextfile($1); 385 zconf_nextfile($1);
323}; 386};
324 387
325/* comment entry */ 388/* comment entry */
326 389
327comment: T_COMMENT prompt 390comment: T_COMMENT prompt T_EOL
328{ 391{
329 menu_add_entry(NULL); 392 menu_add_entry(NULL);
330 menu_add_prop(P_COMMENT, $2, NULL, NULL); 393 menu_add_prop(P_COMMENT, $2, NULL, NULL);
331 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); 394 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
332}; 395};
333 396
334comment_stmt: comment T_EOL depends_list 397comment_stmt: comment depends_list
335{ 398{
336 menu_end_entry(); 399 menu_end_entry();
337}; 400};
338 401
339/* help option */ 402/* help option */
340 403
341help_start: T_HELP T_EOL 404help_start: T_HELP T_EOL
342{ 405{
343 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); 406 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
344 zconf_starthelp(); 407 zconf_starthelp();
345}; 408};
346 409
347help: help_start T_HELPTEXT 410help: help_start T_HELPTEXT
348{ 411{
349 current_entry->sym->help = $2; 412 current_entry->sym->help = $2;
350}; 413};
351 414
352/* depends option */ 415/* depends option */
353 416
354 depends_list: /* empty */ 417 depends_list: /* empty */
355 | depends_list depends T_EOL 418 | depends_list depends
356 | depends_list T_EOL 419 | depends_list T_EOL
357{ }; 420;
358 421
359depends: T_DEPENDS T_ON expr 422depends: T_DEPENDS T_ON expr T_EOL
360{ 423{
361 menu_add_dep($3); 424 menu_add_dep($3);
362 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); 425 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
363} 426}
364 | T_DEPENDS expr 427 | T_DEPENDS expr T_EOL
365{ 428{
366 menu_add_dep($2); 429 menu_add_dep($2);
367 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); 430 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
368} 431}
369 | T_REQUIRES expr 432 | T_REQUIRES expr T_EOL
370{ 433{
371 menu_add_dep($2); 434 menu_add_dep($2);
372 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); 435 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
373}; 436};
374 437
375/* prompt statement */ 438/* prompt statement */
376 439
377prompt_stmt_opt: 440prompt_stmt_opt:
378 /* empty */ 441 /* empty */
379 | prompt 442 | prompt if_expr
380{
381 menu_add_prop(P_PROMPT, $1, NULL, NULL);
382}
383 | prompt T_IF expr
384{ 443{
385 menu_add_prop(P_PROMPT, $1, NULL, $3); 444 menu_add_prop(P_PROMPT, $1, NULL, $2);
386}; 445};
387 446
388 prompt: T_WORD 447 prompt: T_WORD
389 | T_STRING 448 | T_WORD_QUOTE
390; 449;
391 450
392 end: T_ENDMENU { $$ = T_ENDMENU; } 451 end: T_ENDMENU nl_or_eof{ $$ = T_ENDMENU; }
393 | T_ENDCHOICE { $$ = T_ENDCHOICE; } 452 | T_ENDCHOICE nl_or_eof{ $$ = T_ENDCHOICE; }
394 | T_ENDIF { $$ = T_ENDIF; } 453 | T_ENDIF nl_or_eof{ $$ = T_ENDIF; }
395; 454;
396 455
397nl_or_eof: 456nl_or_eof:
398 T_EOL | T_EOF; 457 T_EOL | T_EOF;
399 458
400 if_expr: /* empty */ { $$ = NULL; } 459 if_expr: /* empty */ { $$ = NULL; }
401 | T_IF expr { $$ = $2; } 460 | T_IF expr { $$ = $2; }
402; 461;
403 462
404 expr: symbol { $$ = expr_alloc_symbol($1); } 463 expr: symbol { $$ = expr_alloc_symbol($1); }
405 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } 464 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
406 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } 465 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
407 | T_OPEN_PAREN expr T_CLOSE_PAREN{ $$ = $2; } 466 | T_OPEN_PAREN expr T_CLOSE_PAREN{ $$ = $2; }
408 | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } 467 | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
409 | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } 468 | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
410 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } 469 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
411; 470;
412 471
413 symbol: T_WORD{ $$ = sym_lookup($1, 0); free($1); } 472 symbol: T_WORD{ $$ = sym_lookup($1, 0); free($1); }
414 | T_STRING{ $$ = sym_lookup($1, 1); free($1); } 473 | T_WORD_QUOTE{ $$ = sym_lookup($1, 1); free($1); }
415; 474;
416 475
417%% 476%%
418 477
419void conf_parse(const char *name) 478void conf_parse(const char *name)
420{ 479{
480 struct symbol *sym;
481 int i;
482
421 zconf_initscan(name); 483 zconf_initscan(name);
422 484
423 sym_init(); 485 sym_init();
424 menu_init(); 486 menu_init();
425 rootmenu.prompt = menu_add_prop(P_MENU, "Configuration", NULL, NULL); 487 modules_sym = sym_lookup("MODULES", 0);
488 rootmenu.prompt = menu_add_prop(P_MENU, "Build Configuration", NULL, NULL);
426 489
427 //zconfdebug = 1; 490 //zconfdebug = 1;
428 zconfparse(); 491 zconfparse();
429 if (zconfnerrs) 492 if (zconfnerrs)
430 exit(1); 493 exit(1);
431 menu_finalize(&rootmenu); 494 menu_finalize(&rootmenu);
432 495 for_all_symbols(i, sym) {
433 modules_sym = sym_lookup("MODULES", 0); 496 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
497 printf("\n");
498 else
499 sym->flags |= SYMBOL_CHECK_DONE;
500 }
434 501
435 sym_change_count = 1; 502 sym_change_count = 1;
436} 503}
437 504
438const char *zconf_tokenname(int token) 505const char *zconf_tokenname(int token)
439{ 506{
440 switch (token) { 507 switch (token) {
441 case T_MENU: return "menu"; 508 case T_MENU: return "menu";
442 case T_ENDMENU: return "endmenu"; 509 case T_ENDMENU: return "endmenu";
443 case T_CHOICE: return "choice"; 510 case T_CHOICE: return "choice";
444 case T_ENDCHOICE:return "endchoice"; 511 case T_ENDCHOICE:return "endchoice";
445 case T_IF: return "if"; 512 case T_IF: return "if";
446 case T_ENDIF: return "endif"; 513 case T_ENDIF: return "endif";
447 } 514 }
448 return "<token>"; 515 return "<token>";
449} 516}
450 517
451static bool zconf_endtoken(int token, int starttoken, int endtoken) 518static bool zconf_endtoken(int token, int starttoken, int endtoken)
452{ 519{
453 if (token != endtoken) { 520 if (token != endtoken) {
454 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken)); 521 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
455 zconfnerrs++; 522 zconfnerrs++;
456 return false; 523 return false;
457 } 524 }
458 if (current_menu->file != current_file) { 525 if (current_menu->file != current_file) {
459 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken)); 526 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
460 zconfprint("location of the '%s'", zconf_tokenname(starttoken)); 527 zconfprint("location of the '%s'", zconf_tokenname(starttoken));
461 zconfnerrs++; 528 zconfnerrs++;
462 return false; 529 return false;
463 } 530 }
464 return true; 531 return true;
465} 532}
466 533
467static void zconfprint(const char *err, ...) 534static void zconfprint(const char *err, ...)
468{ 535{
469 va_list ap; 536 va_list ap;
470 537
471 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); 538 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
472 va_start(ap, err); 539 va_start(ap, err);
473 vfprintf(stderr, err, ap); 540 vfprintf(stderr, err, ap);
474 va_end(ap); 541 va_end(ap);
475 fprintf(stderr, "\n"); 542 fprintf(stderr, "\n");
476} 543}
477 544
478static void zconferror(const char *err) 545static void zconferror(const char *err)
479{ 546{
480 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err); 547 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
481} 548}
482 549
483void print_quoted_string(FILE *out, const char *str) 550void print_quoted_string(FILE *out, const char *str)
484{ 551{
485 const char *p; 552 const char *p;
486 int len; 553 int len;
487 554
488 putc('"', out); 555 putc('"', out);
489 while ((p = strchr(str, '"'))) { 556 while ((p = strchr(str, '"'))) {
490 len = p - str; 557 len = p - str;
491 if (len) 558 if (len)
492 fprintf(out, "%.*s", len, str); 559 fprintf(out, "%.*s", len, str);
493 fputs("\\\"", out); 560 fputs("\\\"", out);
494 str = p + 1; 561 str = p + 1;
495 } 562 }
496 fputs(str, out); 563 fputs(str, out);
497 putc('"', out); 564 putc('"', out);
498} 565}
499 566
500void print_symbol(FILE *out, struct menu *menu) 567void print_symbol(FILE *out, struct menu *menu)
501{ 568{
502 struct symbol *sym = menu->sym; 569 struct symbol *sym = menu->sym;
503 struct property *prop; 570 struct property *prop;
504 571
505 //sym->flags |= SYMBOL_PRINTED;
506
507 if (sym_is_choice(sym)) 572 if (sym_is_choice(sym))
508 fprintf(out, "choice\n"); 573 fprintf(out, "choice\n");
509 else 574 else
510 fprintf(out, "config %s\n", sym->name); 575 fprintf(out, "config %s\n", sym->name);
511 switch (sym->type) { 576 switch (sym->type) {
512 case S_BOOLEAN: 577 case S_BOOLEAN:
513 fputs(" boolean\n", out); 578 fputs(" boolean\n", out);
514 break; 579 break;
515 case S_TRISTATE: 580 case S_TRISTATE:
516 fputs(" tristate\n", out); 581 fputs(" tristate\n", out);
517 break; 582 break;
518 case S_STRING: 583 case S_STRING:
519 fputs(" string\n", out); 584 fputs(" string\n", out);
520 break; 585 break;
521 case S_INT: 586 case S_INT:
522 fputs(" integer\n", out); 587 fputs(" integer\n", out);
523 break; 588 break;
524 case S_HEX: 589 case S_HEX:
525 fputs(" hex\n", out); 590 fputs(" hex\n", out);
526 break; 591 break;
527 default: 592 default:
528 fputs(" ???\n", out); 593 fputs(" ???\n", out);
529 break; 594 break;
530 } 595 }
531#if 0
532 if (!expr_is_yes(sym->dep)) {
533 fputs(" depends ", out);
534 expr_fprint(sym->dep, out);
535 fputc('\n', out);
536 }
537#endif
538 for (prop = sym->prop; prop; prop = prop->next) { 596 for (prop = sym->prop; prop; prop = prop->next) {
539 if (prop->menu != menu) 597 if (prop->menu != menu)
540 continue; 598 continue;
541 switch (prop->type) { 599 switch (prop->type) {
542 case P_PROMPT: 600 case P_PROMPT:
543 fputs(" prompt ", out); 601 fputs(" prompt ", out);
544 print_quoted_string(out, prop->text); 602 print_quoted_string(out, prop->text);
545 if (prop->def) { 603 if (!expr_is_yes(prop->visible.expr)) {
546 fputc(' ', out);
547 if (prop->def->flags & SYMBOL_CONST)
548 print_quoted_string(out, prop->def->name);
549 else
550 fputs(prop->def->name, out);
551 }
552 if (!expr_is_yes(E_EXPR(prop->visible))) {
553 fputs(" if ", out); 604 fputs(" if ", out);
554 expr_fprint(E_EXPR(prop->visible), out); 605 expr_fprint(prop->visible.expr, out);
555 } 606 }
556 fputc('\n', out); 607 fputc('\n', out);
557 break; 608 break;
558 case P_DEFAULT: 609 case P_DEFAULT:
559 fputs( " default ", out); 610 fputs( " default ", out);
560 print_quoted_string(out, prop->def->name); 611 expr_fprint(prop->expr, out);
561 if (!expr_is_yes(E_EXPR(prop->visible))) { 612 if (!expr_is_yes(prop->visible.expr)) {
562 fputs(" if ", out); 613 fputs(" if ", out);
563 expr_fprint(E_EXPR(prop->visible), out); 614 expr_fprint(prop->visible.expr, out);
564 } 615 }
565 fputc('\n', out); 616 fputc('\n', out);
566 break; 617 break;
567 case P_CHOICE: 618 case P_CHOICE:
568 fputs(" #choice value\n", out); 619 fputs(" #choice value\n", out);
569 break; 620 break;
570 default: 621 default:
571 fprintf(out, " unknown prop %d!\n", prop->type); 622 fprintf(out, " unknown prop %d!\n", prop->type);
572 break; 623 break;
573 } 624 }
574 } 625 }
575 if (sym->help) { 626 if (sym->help) {
576 int len = strlen(sym->help); 627 int len = strlen(sym->help);
577 while (sym->help[--len] == '\n') 628 while (sym->help[--len] == '\n')
578 sym->help[len] = 0; 629 sym->help[len] = 0;
579 fprintf(out, " help\n%s\n", sym->help); 630 fprintf(out, " help\n%s\n", sym->help);
580 } 631 }
581 fputc('\n', out); 632 fputc('\n', out);
582} 633}
583 634
584void zconfdump(FILE *out) 635void zconfdump(FILE *out)
585{ 636{
586 //struct file *file;
587 struct property *prop; 637 struct property *prop;
588 struct symbol *sym; 638 struct symbol *sym;
589 struct menu *menu; 639 struct menu *menu;
590 640
591 menu = rootmenu.list; 641 menu = rootmenu.list;
592 while (menu) { 642 while (menu) {
593 if ((sym = menu->sym)) 643 if ((sym = menu->sym))
594 print_symbol(out, menu); 644 print_symbol(out, menu);
595 else if ((prop = menu->prompt)) { 645 else if ((prop = menu->prompt)) {
596 switch (prop->type) { 646 switch (prop->type) {
597 //case T_MAINMENU:
598 //fputs("\nmainmenu ", out);
599 //print_quoted_string(out, prop->text);
600 //fputs("\n", out);
601 //break;
602 case P_COMMENT: 647 case P_COMMENT:
603 fputs("\ncomment ", out); 648 fputs("\ncomment ", out);
604 print_quoted_string(out, prop->text); 649 print_quoted_string(out, prop->text);
605 fputs("\n", out); 650 fputs("\n", out);
606 break; 651 break;
607 case P_MENU: 652 case P_MENU:
608 fputs("\nmenu ", out); 653 fputs("\nmenu ", out);
609 print_quoted_string(out, prop->text); 654 print_quoted_string(out, prop->text);
610 fputs("\n", out); 655 fputs("\n", out);
611 break; 656 break;
612 //case T_SOURCE:
613 //fputs("\nsource ", out);
614 //print_quoted_string(out, prop->text);
615 //fputs("\n", out);
616 //break;
617 //case T_IF:
618 //fputs("\nif\n", out);
619 default: 657 default:
620 ; 658 ;
621 } 659 }
622 if (!expr_is_yes(E_EXPR(prop->visible))) { 660 if (!expr_is_yes(prop->visible.expr)) {
623 fputs(" depends ", out); 661 fputs(" depends ", out);
624 expr_fprint(E_EXPR(prop->visible), out); 662 expr_fprint(prop->visible.expr, out);
625 fputc('\n', out); 663 fputc('\n', out);
626 } 664 }
627 fputs("\n", out); 665 fputs("\n", out);
628 } 666 }
629 667
630 if (menu->list) 668 if (menu->list)
631 menu = menu->list; 669 menu = menu->list;
632 else if (menu->next) 670 else if (menu->next)
633 menu = menu->next; 671 menu = menu->next;
634 else while ((menu = menu->parent)) { 672 else while ((menu = menu->parent)) {
635 if (menu->prompt && menu->prompt->type == P_MENU) 673 if (menu->prompt && menu->prompt->type == P_MENU)
636 fputs("\nendmenu\n", out); 674 fputs("\nendmenu\n", out);
637 if (menu->next) { 675 if (menu->next) {
638 menu = menu->next; 676 menu = menu->next;
639 break; 677 break;
640 } 678 }
641 } 679 }
642 } 680 }
643} 681}
644 682
645#include "lex.zconf.c" 683#include "lex.zconf.c"
646#include "confdata.c" 684#include "confdata.c"
647#include "expr.c" 685#include "expr.c"
648#include "symbol.c" 686#include "symbol.c"
649#include "menu.c" 687#include "menu.c"