author | kergoth <kergoth> | 2003-06-17 17:03:49 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2003-06-17 17:03:49 (UTC) |
commit | 16e53b2a2e94742f3b55ee73700bb264e36638d4 (patch) (unidiff) | |
tree | 4f2b65a635d25c1ce0cfeea7953623c2bf7d9534 | |
parent | 384b7f1a42f9f2f101dc8fe11c3625055d96f672 (diff) | |
download | opie-16e53b2a2e94742f3b55ee73700bb264e36638d4.zip opie-16e53b2a2e94742f3b55ee73700bb264e36638d4.tar.gz opie-16e53b2a2e94742f3b55ee73700bb264e36638d4.tar.bz2 |
Update LinuxKernelConf version to 1.4.
-rw-r--r-- | scripts/kconfig/Makefile | 51 | ||||
-rw-r--r-- | scripts/kconfig/Makefile.kernel | 52 | ||||
-rw-r--r-- | scripts/kconfig/conf.c | 222 | ||||
-rw-r--r-- | scripts/kconfig/confdata.c | 152 | ||||
-rw-r--r-- | scripts/kconfig/expr.c | 37 | ||||
-rw-r--r-- | scripts/kconfig/expr.h | 79 | ||||
-rw-r--r-- | scripts/kconfig/gconf.c | 1618 | ||||
-rw-r--r-- | scripts/kconfig/gconf.glade | 543 | ||||
-rw-r--r-- | scripts/kconfig/images.c | 34 | ||||
-rw-r--r-- | scripts/kconfig/lkc-language.txt | 52 | ||||
-rw-r--r-- | scripts/kconfig/lkc.h | 14 | ||||
-rw-r--r-- | scripts/kconfig/lkc_proto.h | 5 | ||||
-rw-r--r-- | scripts/kconfig/mconf.c | 66 | ||||
-rw-r--r-- | scripts/kconfig/menu.c | 194 | ||||
-rw-r--r-- | scripts/kconfig/qconf.cc | 405 | ||||
-rw-r--r-- | scripts/kconfig/qconf.h | 20 | ||||
-rw-r--r-- | scripts/kconfig/symbol.c | 465 | ||||
-rw-r--r-- | scripts/kconfig/zconf.l | 23 | ||||
-rw-r--r-- | scripts/kconfig/zconf.y | 230 |
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 @@ | |||
1 | VERSION=1.3 | 1 | VERSION=1.4 |
2 | CC=gcc | 2 | CC=gcc |
3 | CXX=g++ | 3 | CXX=g++ |
4 | CFLAGS=-O0 -Wall -g -fPIC | 4 | CFLAGS=-O0 -Wall -g -fPIC |
5 | CXXFLAGS=$(CFLAGS) -I$(HOSTQTDIR)/include | 5 | CXXFLAGS=$(CFLAGS) -I$(QTDIR)/include |
6 | LDFLAGS= | 6 | LDFLAGS= |
7 | LXXFLAGS=$(LDFLAGS) -L$(HOSTQTDIR)/lib -Wl,-rpath,$(HOSTQTDIR)/lib | 7 | LXXFLAGS=$(LDFLAGS) -L$(QTDIR)/lib -Wl,-rpath,$(QTDIR)/lib |
8 | LEX=flex | 8 | LEX=flex |
9 | LFLAGS=-L | 9 | LFLAGS=-L |
10 | YACC=bison | 10 | YACC=bison |
11 | YFLAGS=-l | 11 | YFLAGS=-l |
12 | #YFLAGS=-d -t -v -l | 12 | #YFLAGS=-t -v -l |
13 | ifndef HOSTQTDIR | 13 | ifndef QTDIR |
14 | HOSTQTDIR=/usr/share/qt | 14 | QTDIR=/usr/share/qt3 |
15 | endif | 15 | endif |
16 | MOC=$(wildcard $(HOSTQTDIR)/bin/moc) | 16 | MOC=$(wildcard $(QTDIR)/bin/moc) |
17 | GTKCFLAGS=`pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` | ||
18 | GTKLDFLAGS=`pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs` | ||
17 | 19 | ||
18 | parse_SRC=zconf.y | 20 | parse_SRC=zconf.y |
19 | conf_SRC=conf.c $(parse_SRC) | 21 | conf_SRC=conf.c $(parse_SRC) |
20 | mconf_SRC=mconf.c $(parse_SRC) | 22 | mconf_SRC=mconf.c $(parse_SRC) |
21 | qconf_SRC=qconf.cc | 23 | qconf_SRC=qconf.cc |
24 | gconf_SRC=gconf.c kconfig_load.c | ||
22 | HDR=expr.h lkc.h lkc_proto.h qconf.h | 25 | HDR=expr.h lkc.h lkc_proto.h qconf.h |
23 | OTHER=README lkc-language.txt Makefile.kernel \ | 26 | OTHER=README lkc-language.txt Makefile.kernel \ |
24 | kconfig.i extconf.rb example | 27 | kconfig.i extconf.rb example |
25 | INST=zconf.y zconf.l confdata.c expr.c symbol.c menu.c \ | 28 | INST=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) |
27 | INSTGEN=lex.zconf.c zconf.tab.c | 30 | INSTGEN=lex.zconf.c zconf.tab.c |
28 | 31 | ||
29 | #DEBUG=1 | 32 | #DEBUG=1 |
30 | ifdef DEBUG | 33 | ifdef DEBUG |
31 | CFLAGS+=-DLKC_DIRECT_LINK | 34 | CFLAGS+=-DLKC_DIRECT_LINK |
32 | qconf_SRC+=$(parse_SRC) | 35 | qconf_SRC+=$(parse_SRC) |
33 | else | 36 | else |
34 | qconf_SRC+=kconfig_load.c | 37 | qconf_SRC+=kconfig_load.c |
35 | endif | 38 | endif |
36 | 39 | ||
37 | SRC=$(conf_SRC) $(mconf_SRC) $(qconf_SRC) | 40 | SRC=$(conf_SRC) $(mconf_SRC) $(qconf_SRC) |
38 | CSRC=$(filter %.c, $(SRC)) | 41 | CSRC=$(filter %.c, $(SRC)) |
39 | YSRC=$(filter %.y, $(SRC)) | 42 | YSRC=$(filter %.y, $(SRC)) |
40 | LSRC=$(filter %.l, $(SRC)) | 43 | LSRC=$(filter %.l, $(SRC)) |
41 | 44 | ||
42 | parse_OBJ=$(filter %.o, \ | 45 | parse_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))))) |
47 | conf_OBJ=$(filter %.o, \ | 50 | conf_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))))) |
52 | mconf_OBJ=$(filter %.o, \ | 55 | mconf_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))))) |
57 | qconf_OBJ=$(filter %.o, \ | 60 | qconf_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)))))) |
66 | gconf_OBJ=$(filter %.o, \ | ||
67 | $(patsubst %.c,%.o, \ | ||
68 | $(patsubst %.y,%.tab.o, \ | ||
69 | $(patsubst %.l,lex.%.o, \ | ||
70 | $(gconf_SRC))))) | ||
63 | OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ) | 71 | OBJ=$(conf_OBJ) $(mconf_OBJ) $(qconf_OBJ) |
64 | 72 | ||
65 | ifeq ($(MOC),) | 73 | ifeq ($(MOC),) |
66 | all: conf mconf | 74 | all: conf mconf |
67 | else | 75 | else |
68 | all: conf mconf qconf libkconfig.so | 76 | all: conf mconf qconf libkconfig.so |
69 | endif | 77 | endif |
70 | 78 | ||
71 | lkc_deps := lkc.h lkc_proto.h lkc_defs.h expr.h | 79 | lkc_deps := lkc.h lkc_proto.h lkc_defs.h expr.h |
72 | 80 | ||
73 | zconf.tab.c: zconf.y | 81 | zconf.tab.c: zconf.y |
74 | zconf.tab.h: zconf.y | 82 | zconf.tab.h: zconf.y |
75 | lex.zconf.c: zconf.l | 83 | lex.zconf.c: zconf.l |
76 | zconf.tab.o: zconf.tab.c lex.zconf.c confdata.c expr.c symbol.c menu.c $(lkc_deps) | 84 | zconf.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) |
82 | kconfig_load.o: kconfig_load.c $(lkc_deps) | 90 | kconfig_load.o: kconfig_load.c $(lkc_deps) |
83 | conf.o: conf.c $(lkc_deps) | 91 | conf.o: conf.c $(lkc_deps) |
84 | mconf.o: mconf.c $(lkc_deps) | 92 | mconf.o: mconf.c $(lkc_deps) |
85 | qconf.moc: qconf.h | 93 | qconf.moc: qconf.h |
86 | qconf.o: qconf.cc qconf.moc images.c $(lkc_deps) | 94 | qconf.o: qconf.cc qconf.moc images.c $(lkc_deps) |
95 | gconf.o: gconf.c $(lkc_deps) | ||
87 | 96 | ||
88 | mconf: $(mconf_OBJ) | 97 | mconf: $(mconf_OBJ) |
89 | $(CC) $(LDFLAGS) $^ -o $@ | 98 | $(CC) $(LDFLAGS) $^ -o $@ |
90 | 99 | ||
91 | conf: $(conf_OBJ) | 100 | conf: $(conf_OBJ) |
92 | $(CC) $(LDFLAGS) $^ -o $@ | 101 | $(CC) $(LDFLAGS) $^ -o $@ |
93 | 102 | ||
94 | ifeq ($(MOC),) | 103 | ifeq ($(MOC),) |
95 | qconf: | 104 | qconf: |
96 | @echo Unable to find the QT installation. Please make sure that the | 105 | @echo Unable to find the QT installation. Please make sure that the |
97 | @echo QT development package is correctly installed and the HOSTQTDIR | 106 | @echo QT development package is correctly installed and the QTDIR |
98 | @echo environment variable is set to the correct location. | 107 | @echo environment variable is set to the correct location. |
99 | @false | 108 | @false |
100 | else | 109 | else |
101 | qconf: $(qconf_OBJ) | 110 | qconf: $(qconf_OBJ) |
102 | $(CXX) $(LXXFLAGS) $^ -lqt -o $@ | 111 | $(CXX) $(LXXFLAGS) $^ -lqt-mt -o $@ |
103 | endif | 112 | endif |
104 | 113 | ||
114 | gconf.o: gconf.c | ||
115 | $(CC) $(CFLAGS) $(GTKCFLAGS) -c $< -o $@ | ||
116 | |||
117 | gconf: $(gconf_OBJ) | ||
118 | $(CC) $(LDFLAGS) $(GTKLDFLAGS) $^ -o $@ | ||
119 | |||
105 | libkconfig.so: $(parse_OBJ) | 120 | libkconfig.so: $(parse_OBJ) |
106 | $(CC) -shared $^ -o $@ | 121 | $(CC) -shared $^ -o $@ |
107 | 122 | ||
108 | lkc_defs.h: lkc_proto.h | 123 | lkc_defs.h: lkc_proto.h |
109 | sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' | 124 | sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' |
110 | 125 | ||
111 | clean: | 126 | clean: |
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 | ||
115 | tgz: | 130 | tgz: |
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 | ||
125 | lex.%.c: %.l | 140 | lex.%.c: %.l |
126 | $(LEX) $(LFLAGS) -P$* $< | 141 | $(LEX) $(LFLAGS) -P$* $< |
127 | 142 | ||
128 | %.moc: %.h | 143 | %.moc: %.h |
129 | $(HOSTQTDIR)/bin/moc -i $< -o $@ | 144 | $(QTDIR)/bin/moc -i $< -o $@ |
130 | 145 | ||
131 | %.o: %.c | 146 | %.o: %.c |
132 | $(CC) $(CFLAGS) -c $< -o $@ | 147 | $(CC) $(CFLAGS) -c $< -o $@ |
133 | 148 | ||
134 | %.o: %.cc | 149 | %.o: %.cc |
135 | $(CXX) $(CXXFLAGS) -c $< -o $@ | 150 | $(CXX) $(CXXFLAGS) -c $< -o $@ |
136 | 151 | ||
137 | ifdef KERNELSRC | 152 | ifdef KERNELSRC |
138 | install: $(INSTGEN) | 153 | install: $(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 | ||
143 | diff: $(INSTGEN) | 159 | diff: $(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 | ||
147 | else | 164 | else |
148 | install: | 165 | install: |
149 | @echo "Please use KERNELSRC=<path/to/linux-kernel> to install" | 166 | @echo "Please use KERNELSRC=<path/to/linux-kernel> to install" |
150 | endif | 167 | endif |
151 | 168 | ||
152 | ruby: .ruby libkconfig.so .ruby/kconfig.so | 169 | ruby: .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 | ||
167 | PYTHON_INCLUDE=$(shell python -c "import sys; print '-I'+sys.prefix+'/include/python'+sys.version[:3]") | 184 | PYTHON_INCLUDE=$(shell python -c "import sys; print '-I'+sys.prefix+'/include/python'+sys.version[:3]") |
168 | 185 | ||
169 | python: .python .python/kconfig.py .python/_kconfig.so | 186 | python: .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 |
12 | libkconfig-objs := zconf.tab.o | 15 | libkconfig-objs := zconf.tab.o |
13 | 16 | ||
14 | host-progs:= conf mconf qconf | 17 | host-progs:= conf mconf qconf gconf |
15 | conf-objs:= conf.o libkconfig.so | 18 | conf-objs:= conf.o libkconfig.so |
16 | mconf-objs:= mconf.o libkconfig.so | 19 | mconf-objs:= mconf.o libkconfig.so |
17 | 20 | ||
18 | qconf-objs:= kconfig_load.o | 21 | ifeq ($(MAKECMDGOALS),$(obj)/qconf) |
19 | qconf-cxxobjs:= qconf.o | 22 | qconf-cxxobjs:= qconf.o |
23 | qconf-objs:= kconfig_load.o | ||
24 | endif | ||
20 | 25 | ||
21 | clean-files:= libkconfig.so lkc_defs.h qconf.moc .tmp_qtcheck \ | 26 | ifeq ($(MAKECMDGOALS),$(obj)/gconf) |
22 | zconf.tab.c zconf.tab.h lex.zconf.c | 27 | gconf-objs:= gconf.o kconfig_load.o |
28 | endif | ||
23 | 29 | ||
24 | include $(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 | ||
37 | ifeq ($(MAKECMDGOALS),$(obj)/qconf) | 47 | ifeq ($(MAKECMDGOALS),$(obj)/qconf) |
38 | MOC = $(QTDIR)/bin/moc | 48 | MOC = $(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 |
63 | endif | 73 | endif |
64 | 74 | ||
75 | $(obj)/gconf.o: $(obj)/.tmp_gtkcheck | ||
76 | |||
77 | ifeq ($(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 | ||
99 | endif | ||
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 | ||
84 | ifdef LKC_GENPARSER | 122 | ifdef 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 | ||
92 | lex.%.c: %.l | 130 | lex.%.c: %.l |
93 | flex -P$(notdir $*) -o$@ $< | 131 | flex -P$(notdir $*) -o$@ $< |
94 | 132 | ||
95 | endif | 133 | endif |
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 | ||
16 | static void conf(struct menu *menu); | 16 | static void conf(struct menu *menu); |
17 | static void check_conf(struct menu *menu); | 17 | static void check_conf(struct menu *menu); |
18 | 18 | ||
19 | enum { | 19 | enum { |
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 | ||
30 | static int indent = 1; | 30 | static int indent = 1; |
31 | static int valid_stdin = 1; | 31 | static int valid_stdin = 1; |
32 | static int conf_cnt; | 32 | static int conf_cnt; |
33 | static char line[128]; | 33 | static char line[128]; |
34 | static struct menu *rootEntry; | 34 | static struct menu *rootEntry; |
35 | 35 | ||
36 | static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; | 36 | static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; |
37 | 37 | ||
38 | #if 0 | ||
39 | static 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 | |||
57 | static 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 | |||
76 | static void strip(char *str) | 38 | static 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 | ||
55 | static 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 | |||
93 | static void conf_askvalue(struct symbol *sym, const char *def) | 65 | static 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 | ||
186 | int conf_string(struct menu *menu) | 160 | int 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 | ||
220 | static int conf_sym(struct menu *menu) | 194 | static 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; |
286 | help: | 260 | help: |
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 | ||
294 | static int conf_choice(struct menu *menu) | 268 | static 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 | ||
388 | static void conf(struct menu *menu) | 398 | static 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 | ||
441 | conf_childs: | 451 | conf_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 | ||
450 | static void check_conf(struct menu *menu) | 460 | static 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 | |||
481 | conf_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 | ||
486 | int main(int ac, char **av) | 484 | int 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 | ||
16 | const char conf_def_filename[] = ".config"; | 16 | const char conf_def_filename[] = ".config"; |
17 | 17 | ||
18 | const char conf_defname[] = "arch/$ARCH/defconfig"; | 18 | const char conf_defname[] = "arch/$ARCH/defconfig"; |
19 | 19 | ||
20 | const char *conf_confnames[] = { | 20 | const char *conf_confnames[] = { |
21 | ".config", | 21 | ".config", |
22 | "/lib/modules/$UNAME_RELEASE/.config", | ||
23 | "/etc/kernel-config", | ||
24 | "/boot/config-$UNAME_RELEASE", | ||
25 | conf_defname, | 22 | conf_defname, |
26 | NULL, | 23 | NULL, |
27 | }; | 24 | }; |
28 | 25 | ||
29 | static char *conf_expand_value(const char *in) | 26 | static 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 | ||
55 | char *conf_get_default_confname(void) | 52 | char *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 | ||
71 | int conf_read(const char *name) | 68 | int 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 | ||
240 | int conf_write(const char *name) | 252 | int 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,389 +1,410 @@ | |||
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 | ||
13 | struct expr *expr_alloc_symbol(struct symbol *sym) | 13 | struct 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 | ||
22 | struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) | 22 | struct 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 | ||
31 | struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) | 31 | struct 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 | ||
41 | struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) | 41 | struct 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 | ||
51 | struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) | 51 | struct 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 | ||
58 | struct 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 | |||
58 | struct expr *expr_copy(struct expr *org) | 65 | struct 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 | ||
95 | void expr_free(struct expr *e) | 102 | void 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 | ||
121 | static int trans_count; | 128 | static int trans_count; |
122 | 129 | ||
123 | #define e1 (*ep1) | 130 | #define e1 (*ep1) |
124 | #define e2 (*ep2) | 131 | #define e2 (*ep2) |
125 | 132 | ||
126 | static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) | 133 | static 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 | ||
159 | void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) | 166 | void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) |
160 | { | 167 | { |
161 | if (!e1 || !e2 || e1->type != e2->type) | 168 | if (!e1 || !e2) |
162 | return; | 169 | return; |
163 | __expr_eliminate_eq(e1->type, ep1, ep2); | 170 | switch (e1->type) { |
171 | case E_OR: | ||
172 | case E_AND: | ||
173 | __expr_eliminate_eq(e1->type, ep1, ep2); | ||
174 | default: | ||
175 | ; | ||
176 | } | ||
177 | if (e1->type != e2->type) switch (e2->type) { | ||
178 | case E_OR: | ||
179 | case E_AND: | ||
180 | __expr_eliminate_eq(e2->type, ep1, ep2); | ||
181 | default: | ||
182 | ; | ||
183 | } | ||
164 | e1 = expr_eliminate_yn(e1); | 184 | e1 = expr_eliminate_yn(e1); |
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 | ||
171 | int expr_eq(struct expr *e1, struct expr *e2) | 191 | int 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 | ||
210 | struct expr *expr_eliminate_yn(struct expr *e) | 231 | struct 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 | */ |
296 | struct expr *expr_trans_bool(struct expr *e) | 317 | struct 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 | */ |
325 | struct expr *expr_join_or(struct expr *e1, struct expr *e2) | 346 | struct 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 | ||
387 | struct expr *expr_join_and(struct expr *e1, struct expr *e2) | 408 | struct expr *expr_join_and(struct expr *e1, struct expr *e2) |
388 | { | 409 | { |
389 | struct expr *tmp; | 410 | struct expr *tmp; |
@@ -708,347 +729,355 @@ struct expr *expr_transform(struct expr *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 | ||
742 | int expr_contains_symbol(struct expr *dep, struct symbol *sym) | 763 | int 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 | ||
766 | bool expr_depends_symbol(struct expr *dep, struct symbol *sym) | 787 | bool 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 | ||
795 | struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) | 816 | struct 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 | ||
806 | struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) | 827 | struct 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 | ||
817 | void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) | 838 | void 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 | ||
846 | struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) | 867 | struct 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 | ||
906 | tristate expr_calc_value(struct expr *e) | 928 | tristate 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 | ||
947 | int expr_compare_type(enum expr_type t1, enum expr_type t2) | 969 | int 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 | ||
979 | void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken) | 1001 | void 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 | ||
1038 | static void expr_print_file_helper(void *data, const char *str) | 1067 | static 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 | ||
1043 | void expr_fprint(struct expr *e, FILE *out) | 1072 | void 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 | ||
1048 | void print_expr(int mask, struct expr *e, int prevtoken) | 1077 | void 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 |
10 | extern "C" { | 10 | extern "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 | ||
18 | struct file { | 18 | struct 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 | ||
34 | typedef enum tristate { | 30 | typedef enum tristate { |
35 | no, mod, yes | 31 | no, mod, yes |
36 | } tristate; | 32 | } tristate; |
37 | 33 | ||
38 | enum expr_type { | 34 | enum 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 | ||
42 | union expr_data { | 38 | union expr_data { |
43 | struct expr *expr; | 39 | struct expr *expr; |
44 | struct symbol *sym; | 40 | struct symbol *sym; |
45 | }; | 41 | }; |
46 | 42 | ||
47 | struct expr { | 43 | struct 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 | ||
64 | struct expr_value { | 52 | struct 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 | |||
73 | struct symbol_value { | 57 | struct symbol_value { |
74 | void *value; | 58 | void *val; |
75 | tristate tri; | 59 | tristate tri; |
76 | }; | 60 | }; |
77 | 61 | ||
78 | enum symbol_type { | 62 | enum 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 | ||
82 | struct symbol { | 66 | struct symbol { |
83 | struct symbol *next; | 67 | struct symbol *next; |
84 | char *name; | 68 | char *name; |
85 | char *help; | 69 | char *help; |
86 | #ifdef CML1 | ||
87 | int type; | ||
88 | #else | ||
89 | enum symbol_type type; | 70 | enum symbol_type type; |
90 | #endif | 71 | struct symbol_value curr, user; |
91 | struct symbol_value curr, def; | ||
92 | tristate visible; | 72 | tristate visible; |
93 | int flags; | 73 | int flags; |
94 | struct property *prop; | 74 | struct property *prop; |
95 | struct expr *dep, *dep2; | 75 | struct expr *dep, *dep2; |
96 | struct menu *menu; | 76 | struct expr_value rev_dep; |
97 | }; | 77 | }; |
98 | 78 | ||
99 | #define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) | 79 | #define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) |
100 | 80 | ||
101 | #ifdef CML1 | ||
102 | #define SYMBOL_UNKNOWN S_UNKNOWN | ||
103 | #define SYMBOL_BOOLEAN S_BOOLEAN | ||
104 | #define SYMBOL_TRISTATE S_TRISTATE | ||
105 | #define SYMBOL_INT S_INT | ||
106 | #define SYMBOL_HEX S_HEX | ||
107 | #define SYMBOL_STRING S_STRING | ||
108 | #define SYMBOL_OTHER S_OTHER | ||
109 | #endif | ||
110 | |||
111 | #define SYMBOL_YES 0x0001 | 81 | #define SYMBOL_YES 0x0001 |
112 | #define SYMBOL_MOD 0x0002 | 82 | #define SYMBOL_MOD 0x0002 |
113 | #define SYMBOL_NO 0x0004 | 83 | #define SYMBOL_NO 0x0004 |
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 | ||
130 | enum prop_type { | 103 | enum 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 | ||
134 | struct property { | 107 | struct 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 | ||
162 | struct menu { | 128 | struct 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 | ||
180 | extern struct file *file_list; | 147 | extern struct file *file_list; |
181 | extern struct file *current_file; | 148 | extern struct file *current_file; |
182 | struct file *lookup_file(const char *name); | 149 | struct file *lookup_file(const char *name); |
183 | 150 | ||
184 | extern struct symbol symbol_yes, symbol_no, symbol_mod; | 151 | extern struct symbol symbol_yes, symbol_no, symbol_mod; |
185 | extern struct symbol *modules_sym; | 152 | extern struct symbol *modules_sym; |
186 | extern int cdebug; | 153 | extern int cdebug; |
187 | extern int print_type; | ||
188 | struct expr *expr_alloc_symbol(struct symbol *sym); | 154 | struct expr *expr_alloc_symbol(struct symbol *sym); |
189 | #ifdef CML1 | ||
190 | struct expr *expr_alloc_one(int token, struct expr *ce); | ||
191 | struct expr *expr_alloc_two(int token, struct expr *e1, struct expr *e2); | ||
192 | struct expr *expr_alloc_comp(int token, struct symbol *s1, struct symbol *s2); | ||
193 | #else | ||
194 | struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); | 155 | struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); |
195 | struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); | 156 | struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); |
196 | struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); | 157 | struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); |
197 | #endif | ||
198 | struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); | 158 | struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); |
159 | struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); | ||
199 | struct expr *expr_copy(struct expr *org); | 160 | struct expr *expr_copy(struct expr *org); |
200 | void expr_free(struct expr *e); | 161 | void expr_free(struct expr *e); |
201 | int expr_eq(struct expr *e1, struct expr *e2); | 162 | int expr_eq(struct expr *e1, struct expr *e2); |
202 | void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); | 163 | void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); |
203 | tristate expr_calc_value(struct expr *e); | 164 | tristate expr_calc_value(struct expr *e); |
204 | struct expr *expr_eliminate_yn(struct expr *e); | 165 | struct expr *expr_eliminate_yn(struct expr *e); |
205 | struct expr *expr_trans_bool(struct expr *e); | 166 | struct expr *expr_trans_bool(struct expr *e); |
206 | struct expr *expr_eliminate_dups(struct expr *e); | 167 | struct expr *expr_eliminate_dups(struct expr *e); |
207 | struct expr *expr_transform(struct expr *e); | 168 | struct expr *expr_transform(struct expr *e); |
208 | int expr_contains_symbol(struct expr *dep, struct symbol *sym); | 169 | int expr_contains_symbol(struct expr *dep, struct symbol *sym); |
209 | bool expr_depends_symbol(struct expr *dep, struct symbol *sym); | 170 | bool expr_depends_symbol(struct expr *dep, struct symbol *sym); |
210 | struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); | 171 | struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); |
211 | struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); | 172 | struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); |
212 | void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); | 173 | void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); |
213 | struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); | 174 | struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); |
214 | 175 | ||
215 | void expr_fprint(struct expr *e, FILE *out); | 176 | void expr_fprint(struct expr *e, FILE *out); |
216 | void print_expr(int mask, struct expr *e, int prevtoken); | 177 | void print_expr(int mask, struct expr *e, int prevtoken); |
217 | 178 | ||
218 | #ifdef CML1 | ||
219 | static inline int expr_is_yes(struct expr *e) | ||
220 | { | ||
221 | return !e || (e->token == WORD && e->left.sym == &symbol_yes); | ||
222 | } | ||
223 | |||
224 | static inline int expr_is_no(struct expr *e) | ||
225 | { | ||
226 | return e && (e->token == WORD && e->left.sym == &symbol_no); | ||
227 | } | ||
228 | #else | ||
229 | static inline int expr_is_yes(struct expr *e) | 179 | static 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 | ||
234 | static inline int expr_is_no(struct expr *e) | 184 | static 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 | |||
29 | enum { | ||
30 | SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW | ||
31 | }; | ||
32 | |||
33 | static gint view_mode = SPLIT_VIEW; | ||
34 | static gboolean show_name = TRUE; | ||
35 | static gboolean show_range = TRUE; | ||
36 | static gboolean show_value = TRUE; | ||
37 | static gboolean show_all = FALSE; | ||
38 | static gboolean show_debug = FALSE; | ||
39 | static gboolean resizeable = FALSE; | ||
40 | |||
41 | static gboolean config_changed = FALSE; | ||
42 | |||
43 | static char nohelp_text[] = | ||
44 | "Sorry, no help available for this option yet.\n"; | ||
45 | |||
46 | GtkWidget *main_wnd = NULL; | ||
47 | GtkWidget *tree1_w = NULL;// left frame | ||
48 | GtkWidget *tree2_w = NULL;// right frame | ||
49 | GtkWidget *text_w = NULL; | ||
50 | GtkWidget *hpaned = NULL; | ||
51 | GtkWidget *vpaned = NULL; | ||
52 | GtkWidget *back_btn = NULL; | ||
53 | |||
54 | GtkTextTag *tag1, *tag2; | ||
55 | GdkColor color; | ||
56 | |||
57 | GtkTreeStore *tree1, *tree2, *tree; | ||
58 | GtkTreeModel *model1, *model2; | ||
59 | static GtkTreeIter *parents[256] = { 0 }; | ||
60 | static gint indent; | ||
61 | |||
62 | static struct menu *current; | ||
63 | |||
64 | enum { | ||
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 | |||
71 | static void display_list(void); | ||
72 | static void display_tree(struct menu *menu); | ||
73 | static void display_tree_part(void); | ||
74 | static void update_tree(struct menu *src, GtkTreeIter * dst); | ||
75 | static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row); | ||
76 | static gchar **fill_row(struct menu *menu); | ||
77 | |||
78 | |||
79 | /* Helping/Debugging Functions */ | ||
80 | |||
81 | |||
82 | const 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 | |||
110 | const 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 | |||
153 | const 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 | |||
183 | void 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 | |||
283 | void 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 | |||
313 | void 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 | |||
335 | static void renderer_edited(GtkCellRendererText * cell, | ||
336 | const gchar * path_string, | ||
337 | const gchar * new_text, gpointer user_data); | ||
338 | static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle, | ||
339 | gchar * arg1, gpointer user_data); | ||
340 | |||
341 | void 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 | |||
445 | static 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 | |||
482 | static 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 | |||
505 | void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data); | ||
506 | gboolean 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 | |||
551 | void on_window1_destroy(GtkObject * object, gpointer user_data) | ||
552 | { | ||
553 | gtk_main_quit(); | ||
554 | } | ||
555 | |||
556 | |||
557 | void | ||
558 | on_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 | |||
580 | static void | ||
581 | load_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 | |||
594 | void 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 | |||
614 | void 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 | |||
623 | static void | ||
624 | store_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 | |||
637 | void 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 | |||
657 | void 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 | |||
664 | void 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 | |||
675 | void 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 | |||
693 | void 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 | |||
704 | void | ||
705 | on_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 | |||
714 | void | ||
715 | on_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 | |||
722 | void 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 | |||
754 | void 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 | |||
772 | void 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 | |||
791 | void 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 | |||
806 | void on_load_pressed(GtkButton * button, gpointer user_data) | ||
807 | { | ||
808 | on_load1_activate(NULL, user_data); | ||
809 | } | ||
810 | |||
811 | |||
812 | void on_save_pressed(GtkButton * button, gpointer user_data) | ||
813 | { | ||
814 | on_save1_activate(NULL, user_data); | ||
815 | } | ||
816 | |||
817 | |||
818 | void 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 | |||
828 | void 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 | |||
841 | void 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 | |||
853 | void on_collapse_pressed(GtkButton * button, gpointer user_data) | ||
854 | { | ||
855 | gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); | ||
856 | } | ||
857 | |||
858 | |||
859 | void 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 */ | ||
868 | static 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 */ | ||
896 | static 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 | |||
938 | static 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 | |||
960 | static 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 | |||
989 | static 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) */ | ||
1008 | gboolean | ||
1009 | on_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 */ | ||
1064 | gboolean | ||
1065 | on_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 */ | ||
1109 | void | ||
1110 | on_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. */ | ||
1125 | gboolean | ||
1126 | on_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 */ | ||
1168 | static 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 */ | ||
1289 | static 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 */ | ||
1325 | static 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 */ | ||
1336 | static GtkTreeIter found; | ||
1337 | |||
1338 | /* | ||
1339 | * Find a menu in the GtkTree starting at parent. | ||
1340 | */ | ||
1341 | GtkTreeIter *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 | */ | ||
1375 | static 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) */ | ||
1460 | static 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) */ | ||
1517 | static 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) */ | ||
1526 | static 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 | |||
1537 | static 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 | |||
1552 | int 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 | |||
@@ -101,192 +101,226 @@ static const char *xpm_tree_view[] = { | |||
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 | ||
121 | static const char *xpm_single_view[] = { | 121 | static 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 | ||
148 | static const char *xpm_split_view[] = { | 148 | static 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 | ||
175 | static const char *xpm_symbol_no[] = { | 175 | static 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 | ||
192 | static const char *xpm_symbol_mod[] = { | 192 | static 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 | ||
209 | static const char *xpm_symbol_yes[] = { | 209 | static 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 | ||
226 | static const char *xpm_choice_no[] = { | 226 | static 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 | ||
243 | static const char *xpm_choice_yes[] = { | 243 | static 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 | ||
260 | static const char *xpm_menu[] = { | 260 | static 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 | ||
277 | static const char *xpm_menu_inv[] = { | 277 | static 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 | |||
294 | static 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 | |||
311 | static 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 @@ | |||
1 | Introduction | 1 | Introduction |
2 | ------------ | 2 | ------------ |
3 | 3 | ||
4 | The configuration database is collection of configuration options | 4 | The configuration database is collection of configuration options |
5 | organized in a tree structure: | 5 | organized 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 | ||
20 | Every entry has its own dependencies. These dependencies are used | 20 | Every entry has its own dependencies. These dependencies are used |
21 | to determine the visible of an entry. Any child entry is only | 21 | to determine the visibility of an entry. Any child entry is only |
22 | visible if its parent entry is also visible. | 22 | visible if its parent entry is also visible. |
23 | 23 | ||
24 | Menu entries | 24 | Menu entries |
25 | ------------ | 25 | ------------ |
26 | 26 | ||
27 | Most entries define a config option, all other entries help to organize | 27 | Most entries define a config option, all other entries help to organize |
28 | them. A single configuration option is defined like this: | 28 | them. A single configuration option is defined like this: |
29 | 29 | ||
30 | config MODVERSIONS | 30 | config 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 | ||
37 | Every line starts with a key word and can be followed by multiple | 37 | Every line starts with a key word and can be followed by multiple |
38 | arguments. "config" starts a new config entry. The following lines | 38 | arguments. "config" starts a new config entry. The following lines |
39 | define attributes for this config option. Attributes can be the type of | 39 | define attributes for this config option. Attributes can be the type of |
40 | the config option, input prompt, dependencies, help text and default | 40 | the config option, input prompt, dependencies, help text and default |
41 | values. A config option can be defined multiple times with the same | 41 | values. A config option can be defined multiple times with the same |
42 | name, but every definition can have only a single input prompt and the | 42 | name, but every definition can have only a single input prompt and the |
43 | type must not conflict. | 43 | type must not conflict. |
44 | 44 | ||
45 | Menu attributes | 45 | Menu attributes |
46 | --------------- | 46 | --------------- |
47 | 47 | ||
48 | A menu entry can have a number of attributes. Not all of them are | 48 | A menu entry can have a number of attributes. Not all of them are |
49 | applicable everywhere (see syntax). | 49 | applicable everywhere (see syntax). |
50 | 50 | ||
51 | - type definition: "bool"/"tristate"/"string"/"hex"/"integer" | 51 | - type definition: "bool"/"tristate"/"string"/"hex"/"integer" |
52 | Every config option must have a type. There are only two basic types: | 52 | Every config option must have a type. There are only two basic types: |
53 | tristate and string, the other types base on these two. The type | 53 | tristate and string, the other types are based on these two. The type |
54 | definition optionally accepts an input prompt, so these two examples | 54 | definition optionally accepts an input prompt, so these two examples |
55 | are equivalent: | 55 | are equivalent: |
56 | 56 | ||
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 | ||
99 | Menu dependencies | 114 | Menu dependencies |
100 | ----------------- | 115 | ----------------- |
101 | 116 | ||
102 | Dependencies define the visibility of a menu entry and can also reduce | 117 | Dependencies define the visibility of a menu entry and can also reduce |
103 | the input range of tristate symbols. The tristate logic used in the | 118 | the input range of tristate symbols. The tristate logic used in the |
104 | expressions uses one more state than normal boolean logic to express the | 119 | expressions uses one more state than normal boolean logic to express the |
105 | module state. Dependency expressions have the following syntax: | 120 | module 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 | ||
115 | Expressions are listed in decreasing order of precedence. | 130 | Expressions 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 | ||
129 | An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 | 144 | An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2 |
130 | respectively for calculations). A menu entry becomes visible when it's | 145 | respectively for calculations). A menu entry becomes visible when it's |
131 | expression evaluates to 'm' or 'y'. | 146 | expression evaluates to 'm' or 'y'. |
132 | 147 | ||
133 | There are two type of symbols: constant and nonconstant symbols. | 148 | There are two types of symbols: constant and nonconstant symbols. |
134 | Nonconstant symbols are the most common ones and are defined with the | 149 | Nonconstant 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 |
136 | characters or underscores. | 151 | characters or underscores. |
137 | Constant symbols are only part of expressions. Constant symbols are | 152 | Constant symbols are only part of expressions. Constant symbols are |
138 | always surrounded by single or double quotes. Within the quote any | 153 | always surrounded by single or double quotes. Within the quote any |
139 | other character is allowed and the quotes can be escaped using '\'. | 154 | other character is allowed and the quotes can be escaped using '\'. |
140 | 155 | ||
141 | Menu structure | 156 | Menu structure |
142 | -------------- | 157 | -------------- |
143 | 158 | ||
144 | The position of a menu entry in the tree is determined in two ways. First | 159 | The position of a menu entry in the tree is determined in two ways. First |
145 | it can be specified explicitely: | 160 | it can be specified explicitly: |
146 | 161 | ||
147 | menu "Network device support" | 162 | menu "Network device support" |
148 | depends NET | 163 | depends NET |
149 | 164 | ||
150 | config NETDEVICES | 165 | config NETDEVICES |
151 | ... | 166 | ... |
152 | 167 | ||
153 | endmenu | 168 | endmenu |
154 | 169 | ||
155 | All entries within the "menu" ... "endmenu" block become a submenu of | 170 | All 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 |
157 | the menu entry, e.g. this means the dependency "NET" is added to the | 172 | the menu entry, e.g. this means the dependency "NET" is added to the |
158 | dependency list of the config option NETDEVICES. | 173 | dependency list of the config option NETDEVICES. |
159 | 174 | ||
160 | The other way to generate the menu structure is done by analyzing the | 175 | The other way to generate the menu structure is done by analyzing the |
161 | dependencies. If a menu entry somehow depends on the previous entry, it | 176 | dependencies. If a menu entry somehow depends on the previous entry, it |
162 | can be made a submenu of it. First the the previous (parent) symbol must | 177 | can be made a submenu of it. First, the previous (parent) symbol must |
163 | be part of the dependency list and then one of these two condititions | 178 | be part of the dependency list and then one of these two conditions |
164 | must be true: | 179 | must 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 | ||
168 | config MODULES | 183 | config MODULES |
169 | bool "Enable loadable module support" | 184 | bool "Enable loadable module support" |
170 | 185 | ||
171 | config MODVERSIONS | 186 | config 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 | ||
175 | comment "module support disabled" | 190 | comment "module support disabled" |
176 | depends !MODULES | 191 | depends !MODULES |
177 | 192 | ||
178 | MODVERSIONS directly depends on MODULES, this means it's only visible if | 193 | MODVERSIONS directly depends on MODULES, this means it's only visible if |
179 | MODULES is different from 'n'. The comment on the other hand is always | 194 | MODULES is different from 'n'. The comment on the other hand is always |
180 | visible when MODULES it's visible (the (empty) dependency of MODULES is | 195 | visible when MODULES is visible (the (empty) dependency of MODULES is |
181 | also part of the comment dependencies). | 196 | also part of the comment dependencies). |
182 | 197 | ||
183 | 198 | ||
184 | Kconfig syntax | 199 | Kconfig syntax |
185 | -------------- | 200 | -------------- |
186 | 201 | ||
187 | The configuration file describes a series of menu entries, where every | 202 | The configuration file describes a series of menu entries, where every |
188 | line starts with a keyword (except help texts). The following keywords | 203 | line starts with a keyword (except help texts). The following keywords |
189 | end a menu entry: | 204 | end 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 |
196 | The first four also start the definition of a menu entry. | 212 | The first five also start the definition of a menu entry. |
197 | 213 | ||
198 | config: | 214 | config: |
199 | 215 | ||
200 | "config" <symbol> | 216 | "config" <symbol> |
201 | <config options> | 217 | <config options> |
202 | 218 | ||
203 | This defines a config symbol <symbol> and accepts any of above | 219 | This defines a config symbol <symbol> and accepts any of above |
204 | attributes as options. | 220 | attributes as options. |
205 | 221 | ||
222 | menuconfig: | ||
223 | "menuconfig" <symbol> | ||
224 | <config options> | ||
225 | |||
226 | This is similiar to the simple config entry above, but it also gives a | ||
227 | hint to front ends, that all suboptions should be displayed as a | ||
228 | separate list of options. | ||
229 | |||
206 | choices: | 230 | choices: |
207 | 231 | ||
208 | "choice" | 232 | "choice" |
209 | <choice options> | 233 | <choice options> |
210 | <choice block> | 234 | <choice block> |
211 | "endchoice" | 235 | "endchoice" |
212 | 236 | ||
213 | This defines a choice group and accepts any of above attributes as | 237 | This defines a choice group and accepts any of above attributes as |
214 | options. A choice can only be of type bool or tristate, while a boolean | 238 | options. A choice can only be of type bool or tristate, while a boolean |
215 | choice only allows a single config entry to be selected, a tristate | 239 | choice only allows a single config entry to be selected, a tristate |
216 | choice also allows any number of config entries to be set to 'm'. This | 240 | choice also allows any number of config entries to be set to 'm'. This |
217 | can be used if multiple drivers for a single hardware exists and only a | 241 | can be used if multiple drivers for a single hardware exists and only a |
218 | single driver can be compiled/loaded into the kernel, but all drivers | 242 | single driver can be compiled/loaded into the kernel, but all drivers |
219 | can be compiled as modules. | 243 | can be compiled as modules. |
220 | A choice accepts another option "optional", which allows to set the | 244 | A choice accepts another option "optional", which allows to set the |
221 | choice to 'n' and no entry needs to be selected. | 245 | choice to 'n' and no entry needs to be selected. |
222 | 246 | ||
223 | comment: | 247 | comment: |
224 | 248 | ||
225 | "comment" <prompt> | 249 | "comment" <prompt> |
226 | <comment options> | 250 | <comment options> |
227 | 251 | ||
228 | This defines a comment which is displayed to the user during the | 252 | This defines a comment which is displayed to the user during the |
229 | configuration process and is also echoed to the output files. The only | 253 | configuration process and is also echoed to the output files. The only |
230 | possible options are dependencies. | 254 | possible options are dependencies. |
231 | 255 | ||
232 | menu: | 256 | menu: |
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 | ||
239 | This defines a menu block, see "Menu structure" above for more | 263 | This defines a menu block, see "Menu structure" above for more |
240 | information. The only possible options are dependencies. | 264 | information. The only possible options are dependencies. |
241 | 265 | ||
242 | if: | 266 | if: |
243 | 267 | ||
244 | "if" <expr> | 268 | "if" <expr> |
245 | <if block> | 269 | <if block> |
246 | "endif" | 270 | "endif" |
247 | 271 | ||
248 | This defines an if block. The dependency expression <expr> is appended | 272 | This defines an if block. The dependency expression <expr> is appended |
249 | to all enclosed menu entries. | 273 | to all enclosed menu entries. |
250 | 274 | ||
251 | source: | 275 | source: |
252 | 276 | ||
253 | "source" <prompt> | 277 | "source" <prompt> |
254 | 278 | ||
255 | This reads the specified configuration file. This file is always parsed. | 279 | This 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 |
12 | extern "C" { | 12 | extern "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 | ||
26 | int zconfparse(void); | 26 | int zconfparse(void); |
27 | void zconfdump(FILE *out); | 27 | void zconfdump(FILE *out); |
28 | 28 | ||
29 | extern int zconfdebug; | 29 | extern int zconfdebug; |
30 | void zconf_starthelp(void); | 30 | void zconf_starthelp(void); |
31 | FILE *zconf_fopen(const char *name); | 31 | FILE *zconf_fopen(const char *name); |
32 | void zconf_initscan(const char *name); | 32 | void zconf_initscan(const char *name); |
33 | void zconf_nextfile(const char *name); | 33 | void zconf_nextfile(const char *name); |
34 | int zconf_lineno(void); | 34 | int zconf_lineno(void); |
35 | char *zconf_curname(void); | 35 | char *zconf_curname(void); |
36 | 36 | ||
37 | /* confdata.c */ | 37 | /* confdata.c */ |
38 | extern const char conf_def_filename[]; | 38 | extern const char conf_def_filename[]; |
39 | extern char conf_filename[]; | 39 | extern char conf_filename[]; |
40 | 40 | ||
41 | char *conf_get_default_confname(void); | 41 | char *conf_get_default_confname(void); |
42 | 42 | ||
43 | /* kconfig_load.c */ | 43 | /* kconfig_load.c */ |
44 | void kconfig_load(void); | 44 | void kconfig_load(void); |
45 | 45 | ||
46 | /* menu.c */ | 46 | /* menu.c */ |
47 | void menu_init(void); | 47 | void menu_init(void); |
48 | void menu_add_menu(void); | 48 | void menu_add_menu(void); |
49 | void menu_end_menu(void); | 49 | void menu_end_menu(void); |
50 | void menu_add_entry(struct symbol *sym); | 50 | void menu_add_entry(struct symbol *sym); |
51 | void menu_end_entry(void); | 51 | void menu_end_entry(void); |
52 | struct property *create_prop(enum prop_type type); | ||
53 | void menu_add_dep(struct expr *dep); | 52 | void menu_add_dep(struct expr *dep); |
54 | struct property *menu_add_prop(int token, char *prompt, struct symbol *def, struct expr *dep); | 53 | struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep); |
54 | void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); | ||
55 | void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); | ||
56 | void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); | ||
55 | void menu_finalize(struct menu *parent); | 57 | void menu_finalize(struct menu *parent); |
56 | void menu_set_type(int type); | 58 | void menu_set_type(int type); |
57 | struct file *file_lookup(const char *name); | 59 | struct file *file_lookup(const char *name); |
58 | int file_write_dep(const char *name); | 60 | int file_write_dep(const char *name); |
59 | 61 | ||
60 | extern struct menu *current_entry; | 62 | extern struct menu *current_entry; |
61 | extern struct menu *current_menu; | 63 | extern struct menu *current_menu; |
62 | 64 | ||
63 | /* symbol.c */ | 65 | /* symbol.c */ |
64 | void sym_init(void); | 66 | void sym_init(void); |
65 | void sym_clear_all_valid(void); | 67 | void sym_clear_all_valid(void); |
66 | void sym_set_changed(struct symbol *sym); | 68 | void sym_set_changed(struct symbol *sym); |
69 | struct symbol *sym_check_deps(struct symbol *sym); | ||
70 | struct property *prop_alloc(enum prop_type type, struct symbol *sym); | ||
71 | struct symbol *prop_get_symbol(struct property *prop); | ||
67 | 72 | ||
68 | static inline tristate sym_get_tristate_value(struct symbol *sym) | 73 | static inline tristate sym_get_tristate_value(struct symbol *sym) |
69 | { | 74 | { |
70 | return S_TRI(sym->curr); | 75 | return sym->curr.tri; |
71 | } | 76 | } |
72 | 77 | ||
73 | 78 | ||
74 | static inline struct symbol *sym_get_choice_value(struct symbol *sym) | 79 | static inline struct symbol *sym_get_choice_value(struct symbol *sym) |
75 | { | 80 | { |
76 | return (struct symbol *)S_VAL(sym->curr); | 81 | return (struct symbol *)sym->curr.val; |
77 | } | 82 | } |
78 | 83 | ||
79 | static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval) | 84 | static 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 | ||
84 | static inline bool sym_is_choice(struct symbol *sym) | 89 | static 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 | ||
89 | static inline bool sym_is_choice_value(struct symbol *sym) | 94 | static 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 | ||
94 | static inline bool sym_is_optional(struct symbol *sym) | 99 | static 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 | ||
99 | static inline bool sym_has_value(struct symbol *sym) | 104 | static inline bool sym_has_value(struct symbol *sym) |
100 | { | 105 | { |
101 | //return S_VAL(sym->def) != NULL; | ||
102 | return sym->flags & SYMBOL_NEW ? false : true; | 106 | return sym->flags & SYMBOL_NEW ? false : true; |
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 */ |
3 | P(conf_parse,void,(const char *name)); | 3 | P(conf_parse,void,(const char *name)); |
4 | P(conf_read,int,(const char *name)); | 4 | P(conf_read,int,(const char *name)); |
5 | P(conf_write,int,(const char *name)); | 5 | P(conf_write,int,(const char *name)); |
6 | 6 | ||
7 | /* menu.c */ | 7 | /* menu.c */ |
8 | P(rootmenu,struct menu,); | 8 | P(rootmenu,struct menu,); |
9 | 9 | ||
10 | P(menu_is_visible,bool,(struct menu *menu)); | 10 | P(menu_is_visible,bool,(struct menu *menu)); |
11 | P(menu_get_prompt,const char *,(struct menu *menu)); | 11 | P(menu_get_prompt,const char *,(struct menu *menu)); |
12 | P(menu_get_root_menu,struct menu *,(struct menu *menu)); | 12 | P(menu_get_root_menu,struct menu *,(struct menu *menu)); |
13 | P(menu_get_parent_menu,struct menu *,(struct menu *menu)); | 13 | P(menu_get_parent_menu,struct menu *,(struct menu *menu)); |
14 | 14 | ||
15 | /* symbol.c */ | 15 | /* symbol.c */ |
16 | P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); | 16 | P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); |
17 | P(sym_change_count,int,); | 17 | P(sym_change_count,int,); |
18 | 18 | ||
19 | P(sym_lookup,struct symbol *,(const char *name, int isconst)); | 19 | P(sym_lookup,struct symbol *,(const char *name, int isconst)); |
20 | P(sym_find,struct symbol *,(const char *name)); | 20 | P(sym_find,struct symbol *,(const char *name)); |
21 | P(sym_type_name,const char *,(int type)); | 21 | P(sym_type_name,const char *,(enum symbol_type type)); |
22 | P(sym_calc_value,void,(struct symbol *sym)); | 22 | P(sym_calc_value,void,(struct symbol *sym)); |
23 | P(sym_get_type,int,(struct symbol *sym)); | 23 | P(sym_get_type,enum symbol_type,(struct symbol *sym)); |
24 | P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); | 24 | P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri)); |
25 | P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); | 25 | P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri)); |
26 | P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); | 26 | P(sym_toggle_tristate_value,tristate,(struct symbol *sym)); |
27 | P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); | 27 | P(sym_string_valid,bool,(struct symbol *sym, const char *newval)); |
28 | P(sym_string_within_range,bool,(struct symbol *sym, const char *str)); | ||
28 | P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); | 29 | P(sym_set_string_value,bool,(struct symbol *sym, const char *newval)); |
29 | P(sym_is_changable,bool,(struct symbol *sym)); | 30 | P(sym_is_changable,bool,(struct symbol *sym)); |
30 | P(sym_get_choice_prop,struct property *,(struct symbol *sym)); | 31 | P(sym_get_choice_prop,struct property *,(struct symbol *sym)); |
31 | P(sym_get_default_prop,struct property *,(struct symbol *sym)); | 32 | P(sym_get_default_prop,struct property *,(struct symbol *sym)); |
32 | P(sym_get_string_value,const char *,(struct symbol *sym)); | 33 | P(sym_get_string_value,const char *,(struct symbol *sym)); |
33 | 34 | ||
34 | P(prop_get_type_name,const char *,(enum prop_type type)); | 35 | P(prop_get_type_name,const char *,(enum prop_type type)); |
35 | 36 | ||
36 | /* expr.c */ | 37 | /* expr.c */ |
37 | P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); | 38 | P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); |
38 | P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)); | 39 | P(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 | ||
25 | static char menu_backtitle[128]; | 25 | static char menu_backtitle[128]; |
26 | static const char menu_instructions[] = | 26 | static 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", |
33 | radiolist_instructions[] = | 33 | radiolist_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.", |
38 | inputbox_instructions_int[] = | 38 | inputbox_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.", |
42 | inputbox_instructions_hex[] = | 42 | inputbox_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.", |
45 | inputbox_instructions_string[] = | 45 | inputbox_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.", |
48 | setmod_text[] = | 48 | setmod_text[] = |
49 | "This feature depends on another which has been configured as a module.\n" | 49 | "This feature depends on another which has been configured as a module.\n" |
50 | "As a result, this feature will be built as a module.", | 50 | "As a result, this feature will be built as a module.", |
51 | nohelp_text[] = | 51 | nohelp_text[] = |
52 | "There is no help available for this kernel option.\n", | 52 | "There is no help available for this option.\n", |
53 | load_config_text[] = | 53 | load_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.", |
57 | load_config_help[] = | 57 | load_config_help[] = |
58 | "\n" | 58 | "\n" |
59 | "For various reasons, one may wish to keep several different kernel\n" | 59 | "For various reasons, one may wish to keep several different \n" |
60 | "configurations available on a single machine.\n" | 60 | "configurations available on a single machine.\n" |
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", |
68 | save_config_text[] = | 68 | save_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.", |
71 | save_config_help[] = | 71 | save_config_help[] = |
72 | "\n" | 72 | "\n" |
73 | "For various reasons, one may wish to keep different kernel\n" | 73 | "For various reasons, one may wish to keep different\n" |
74 | "configurations available on a single machine.\n" | 74 | "configurations available on a single machine.\n" |
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 | ||
84 | static char buf[4096], *bufptr = buf; | 84 | static char buf[4096], *bufptr = buf; |
85 | static char input_buf[4096]; | 85 | static char input_buf[4096]; |
86 | static char filename[PATH_MAX+1] = ".config"; | 86 | static char filename[PATH_MAX+1] = ".config"; |
87 | static char *args[1024], **argptr = args; | 87 | static char *args[1024], **argptr = args; |
88 | static int indent = 0; | 88 | static int indent = 0; |
89 | static struct termios ios_org; | 89 | static struct termios ios_org; |
90 | static int rows, cols; | 90 | static int rows, cols; |
91 | static struct menu *current_menu; | 91 | static struct menu *current_menu; |
92 | static int child_count; | 92 | static int child_count; |
93 | static int do_resize; | 93 | static int do_resize; |
94 | static int single_menu_mode; | 94 | static int single_menu_mode; |
95 | 95 | ||
96 | static void conf(struct menu *menu); | 96 | static void conf(struct menu *menu); |
97 | static void conf_choice(struct menu *menu); | 97 | static void conf_choice(struct menu *menu); |
98 | static void conf_string(struct menu *menu); | 98 | static void conf_string(struct menu *menu); |
99 | static void conf_load(void); | 99 | static void conf_load(void); |
100 | static void conf_save(void); | 100 | static void conf_save(void); |
101 | static void show_textbox(const char *title, const char *text, int r, int c); | 101 | static void show_textbox(const char *title, const char *text, int r, int c); |
102 | static void show_helptext(const char *title, const char *text); | 102 | static void show_helptext(const char *title, const char *text); |
103 | static void show_help(struct menu *menu); | 103 | static void show_help(struct menu *menu); |
104 | static void show_readme(void); | 104 | static void show_readme(void); |
105 | 105 | ||
106 | static void cprint_init(void); | 106 | static void cprint_init(void); |
107 | static int cprint1(const char *fmt, ...); | 107 | static int cprint1(const char *fmt, ...); |
108 | static void cprint_done(void); | 108 | static void cprint_done(void); |
109 | static int cprint(const char *fmt, ...); | 109 | static int cprint(const char *fmt, ...); |
110 | 110 | ||
111 | static void init_wsize(void) | 111 | static 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 | ||
148 | static void cprint_init(void) | 148 | static 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 | ||
160 | static int cprint1(const char *fmt, ...) | 165 | static 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 | ||
175 | static void cprint_done(void) | 180 | static void cprint_done(void) |
176 | { | 181 | { |
177 | *bufptr++ = 0; | 182 | *bufptr++ = 0; |
178 | argptr++; | 183 | argptr++; |
179 | } | 184 | } |
180 | 185 | ||
181 | static int cprint(const char *fmt, ...) | 186 | static 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 | ||
196 | pid_t pid; | 201 | pid_t pid; |
197 | 202 | ||
198 | static void winch_handler(int sig) | 203 | static 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 | ||
206 | static int exec_conf(void) | 211 | static 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 | ||
279 | static void build_conf(struct menu *menu) | 284 | static 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 | ||
413 | conf_childs: | 433 | conf_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 | ||
420 | static void conf(struct menu *menu) | 440 | static 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 | ||
531 | static void show_textbox(const char *title, const char *text, int r, int c) | 553 | static 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 | ||
552 | static void show_helptext(const char *title, const char *text) | 574 | static 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 | ||
557 | static void show_help(struct menu *menu) | 579 | static 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 | ||
575 | static void show_readme(void) | 597 | static 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 | ||
586 | static void conf_choice(struct menu *menu) | 608 | static 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 | ||
629 | static void conf_string(struct menu *menu) | 651 | static 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 | ||
671 | static void conf_load(void) | 693 | static 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 | ||
700 | static void conf_save(void) | 722 | static 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 | ||
729 | static void conf_cleanup(void) | 751 | static 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 | ||
736 | int main(int ac, char **av) | 758 | int 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 | ||
12 | struct menu rootmenu; | 12 | struct menu rootmenu; |
13 | struct menu *current_menu, *current_entry; | 13 | struct menu *current_menu, *current_entry; |
14 | static struct menu **last_entry_ptr; | 14 | static struct menu **last_entry_ptr; |
15 | 15 | ||
16 | struct file *file_list; | 16 | struct file *file_list; |
17 | struct file *current_file; | 17 | struct file *current_file; |
18 | 18 | ||
19 | void menu_init(void) | 19 | void 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 | ||
25 | void menu_add_entry(struct symbol *sym) | 25 | void 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 | ||
41 | void menu_end_entry(void) | 41 | void menu_end_entry(void) |
42 | { | 42 | { |
43 | } | 43 | } |
44 | 44 | ||
45 | void menu_add_menu(void) | 45 | void menu_add_menu(void) |
46 | { | 46 | { |
47 | current_menu = current_entry; | 47 | current_menu = current_entry; |
48 | last_entry_ptr = ¤t_entry->list; | 48 | last_entry_ptr = ¤t_entry->list; |
49 | } | 49 | } |
50 | 50 | ||
51 | void menu_end_menu(void) | 51 | void menu_end_menu(void) |
52 | { | 52 | { |
53 | last_entry_ptr = ¤t_menu->next; | 53 | last_entry_ptr = ¤t_menu->next; |
54 | current_menu = current_menu->parent; | 54 | current_menu = current_menu->parent; |
55 | } | 55 | } |
56 | 56 | ||
57 | struct 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 | |||
57 | void menu_add_dep(struct expr *dep) | 82 | void 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 | ||
62 | void menu_set_type(int type) | 87 | void 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 | ||
77 | struct property *create_prop(enum prop_type type) | 102 | struct 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 | |||
90 | struct 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 | ||
114 | void menu_add_prompt(int token, char *prompt, struct expr *dep) | 121 | void 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 | ||
119 | void menu_add_default(int token, struct symbol *def, struct expr *dep) | 126 | void 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 | |||
131 | void 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 | ||
124 | void menu_finalize(struct menu *parent) | 136 | void 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 | ||
229 | bool menu_is_visible(struct menu *menu) | 306 | bool 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 | ||
243 | const char *menu_get_prompt(struct menu *menu) | 332 | const 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 | ||
252 | struct menu *menu_get_root_menu(struct menu *menu) | 341 | struct menu *menu_get_root_menu(struct menu *menu) |
253 | { | 342 | { |
254 | return &rootmenu; | 343 | return &rootmenu; |
255 | } | 344 | } |
256 | 345 | ||
257 | struct menu *menu_get_parent_menu(struct menu *menu) | 346 | struct menu *menu_get_parent_menu(struct menu *menu) |
258 | { | 347 | { |
259 | enum prop_type type; | 348 | enum prop_type type; |
260 | 349 | ||
261 | while (menu != &rootmenu) { | 350 | for (; menu != &rootmenu; menu = menu->parent) { |
262 | menu = menu->parent; | ||
263 | type = menu->prompt ? menu->prompt->type : 0; | 351 | type = menu->prompt ? menu->prompt->type : 0; |
264 | if (type == P_MENU || type == P_ROOTMENU) | 352 | if (type == P_MENU) |
265 | break; | 353 | break; |
266 | } | 354 | } |
267 | return menu; | 355 | return menu; |
268 | } | 356 | } |
269 | 357 | ||
270 | struct file *file_lookup(const char *name) | 358 | struct 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 | ||
287 | int file_write_dep(const char *name) | 375 | int 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 | ||
32 | static QApplication *configApp; | 32 | static QApplication *configApp; |
33 | #if QT_VERSION >= 300 | 33 | #if QT_VERSION >= 300 |
34 | static QSettings *configSettings; | 34 | static 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 | */ |
44 | template <class P> | 44 | template <class P> |
45 | static void updateMenuList(P* parent, struct menu* menu) | 45 | void 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 | */ |
120 | void ConfigItem::okRename(int col) | 110 | void 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 | */ |
130 | void ConfigItem::updateMenu(void) | 120 | void ConfigItem::updateMenu(void) |
131 | { | 121 | { |
132 | ConfigList* list; | 122 | ConfigList* list; |
133 | struct symbol* sym; | 123 | struct symbol* sym; |
124 | struct property *prop; | ||
134 | QString prompt; | 125 | QString prompt; |
135 | int type; | 126 | int type; |
136 | enum prop_type ptype; | ||
137 | tristate expr; | 127 | tristate expr; |
138 | 128 | ||
139 | list = listView(); | 129 | list = listView(); |
130 | if (goParent) { | ||
131 | setPixmap(promptColIdx, list->menuBackPix); | ||
132 | prompt = ".."; | ||
133 | goto set_prompt; | ||
134 | } | ||
140 | 135 | ||
141 | sym = menu->sym; | 136 | sym = menu->sym; |
142 | if (!sym) { | 137 | prop = menu->prompt; |
143 | setText(promptColIdx, menu_get_prompt(menu)); | 138 | prompt = menu_get_prompt(menu); |
144 | ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; | 139 | |
145 | if ((ptype == P_ROOTMENU || ptype == P_MENU) && | 140 | if (prop) switch (prop->type) { |
146 | (list->mode == singleMode || list->mode == symbolMode)) | 141 | case P_MENU: |
142 | if (list->mode == singleMode || list->mode == symbolMode) { | ||
143 | /* a menuconfig entry is displayed differently | ||
144 | * depending whether it's at the view root or a child. | ||
145 | */ | ||
146 | if (sym && list->rootEntry == menu) | ||
147 | break; | ||
147 | setPixmap(promptColIdx, list->menuPix); | 148 | setPixmap(promptColIdx, list->menuPix); |
148 | else | 149 | } else { |
150 | if (sym) | ||
151 | break; | ||
149 | setPixmap(promptColIdx, 0); | 152 | setPixmap(promptColIdx, 0); |
150 | return; | 153 | } |
154 | goto set_prompt; | ||
155 | case P_COMMENT: | ||
156 | setPixmap(promptColIdx, 0); | ||
157 | goto set_prompt; | ||
158 | default: | ||
159 | ; | ||
151 | } | 160 | } |
161 | if (!sym) | ||
162 | goto set_prompt; | ||
152 | 163 | ||
153 | setText(nameColIdx, sym->name); | 164 | setText(nameColIdx, sym->name); |
154 | 165 | ||
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)"; |
232 | set_prompt: | ||
221 | setText(promptColIdx, prompt); | 233 | setText(promptColIdx, prompt); |
222 | } | 234 | } |
223 | 235 | ||
224 | bool ConfigItem::updateNeeded(void) | 236 | void 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 | ||
236 | void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align) | 254 | void 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 | */ |
252 | void ConfigItem::init(void) | 270 | void ConfigItem::init(void) |
253 | { | 271 | { |
254 | ConfigList* list = listView(); | 272 | if (menu) { |
255 | nextItem = (ConfigItem*)menu->data; | 273 | ConfigList* list = listView(); |
256 | menu->data = this; | 274 | nextItem = (ConfigItem*)menu->data; |
275 | menu->data = this; | ||
257 | 276 | ||
258 | if (list->mode != fullMode) | 277 | if (list->mode != fullMode) |
259 | setOpen(TRUE); | 278 | setOpen(TRUE); |
260 | if (menu->sym) | ||
261 | sym_calc_value(menu->sym); | 279 | sym_calc_value(menu->sym); |
280 | } | ||
262 | updateMenu(); | 281 | updateMenu(); |
263 | } | 282 | } |
264 | 283 | ||
265 | /* | 284 | /* |
266 | * destruct a menu entry | 285 | * destruct a menu entry |
267 | */ | 286 | */ |
268 | ConfigItem::~ConfigItem(void) | 287 | ConfigItem::~ConfigItem(void) |
269 | { | 288 | { |
270 | ConfigItem** ip = &(ConfigItem*)menu->data; | 289 | if (menu) { |
271 | for (; *ip; ip = &(*ip)->nextItem) { | 290 | ConfigItem** ip = (ConfigItem**)&menu->data; |
272 | if (*ip == this) { | 291 | for (; *ip; ip = &(*ip)->nextItem) { |
273 | *ip = nextItem; | 292 | if (*ip == this) { |
274 | break; | 293 | *ip = nextItem; |
294 | break; | ||
295 | } | ||
275 | } | 296 | } |
276 | } | 297 | } |
277 | } | 298 | } |
278 | 299 | ||
279 | void ConfigLineEdit::show(ConfigItem* i) | 300 | void 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 | ||
290 | void ConfigLineEdit::keyPressEvent(QKeyEvent* e) | 311 | void 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 | ||
309 | ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv) | 330 | ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv) |
310 | : Parent(p), cview(cv), | 331 | : Parent(p), cview(cv), |
311 | updateAll(false), | 332 | updateAll(false), |
312 | symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), | 333 | symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), |
313 | choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), | 334 | choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), |
335 | menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), | ||
314 | showAll(false), showName(false), showRange(false), showData(false), | 336 | showAll(false), showName(false), showRange(false), showData(false), |
315 | rootEntry(0) | 337 | rootEntry(0) |
316 | { | 338 | { |
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 | ||
336 | void ConfigList::reinit(void) | 358 | void 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 | ||
357 | void ConfigList::updateSelection(void) | 379 | void 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 | ||
374 | void ConfigList::updateList(ConfigItem* item) | 398 | void ConfigList::updateList(ConfigItem* item) |
375 | { | 399 | { |
376 | (void)item;// unused so far | 400 | ConfigItem* last = 0; |
401 | |||
402 | if (!rootEntry) | ||
403 | goto update; | ||
404 | |||
405 | if (rootEntry != &rootmenu && (mode == singleMode || | ||
406 | (mode == symbolMode && rootEntry->parent != &rootmenu))) { | ||
407 | item = firstChild(); | ||
408 | if (!item) | ||
409 | item = new ConfigItem(this, 0, true); | ||
410 | last = item; | ||
411 | } | ||
412 | if (mode == singleMode && rootEntry->sym && rootEntry->prompt) { | ||
413 | item = last ? last->nextSibling() : firstChild(); | ||
414 | if (!item) | ||
415 | item = new ConfigItem(this, last, rootEntry, true); | ||
416 | |||
417 | updateMenuList(item, rootEntry); | ||
418 | triggerUpdate(); | ||
419 | return; | ||
420 | } | ||
421 | update: | ||
377 | updateMenuList(this, rootEntry); | 422 | updateMenuList(this, rootEntry); |
378 | triggerUpdate(); | 423 | triggerUpdate(); |
379 | } | 424 | } |
380 | 425 | ||
381 | void ConfigList::setAllOpen(bool open) | 426 | void 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 | ||
389 | void ConfigList::setValue(ConfigItem* item, tristate val) | 434 | void 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 | ||
414 | void ConfigList::changeValue(ConfigItem* item) | 459 | void 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 | ||
456 | void ConfigList::setRootMenu(struct menu *menu) | 503 | void 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 | ||
471 | void ConfigList::setParentMenu(void) | 518 | void 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 | ||
492 | void ConfigList::keyPressEvent(QKeyEvent* ev) | 538 | void 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 | ||
539 | void ConfigList::contentsMousePressEvent(QMouseEvent* e) | 592 | void 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 | ||
546 | void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) | 599 | void 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 | ||
588 | skip: | 649 | skip: |
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 | ||
593 | void ConfigList::contentsMouseMoveEvent(QMouseEvent* e) | 654 | void 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 | ||
600 | void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) | 661 | void 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 | ||
617 | skip: | 683 | skip: |
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 | ||
622 | void ConfigList::focusInEvent(QFocusEvent *e) | 688 | void 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 | ||
634 | ConfigView* ConfigView::viewList; | 700 | ConfigView* ConfigView::viewList; |
635 | 701 | ||
636 | ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview) | 702 | ConfigView::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 | ||
647 | ConfigView::~ConfigView(void) | 713 | ConfigView::~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 | ||
659 | void ConfigView::updateList(ConfigItem* item) | 725 | void 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 | ||
667 | void ConfigView::updateListAll(void) | 733 | void 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 | */ |
678 | ConfigMainWindow::ConfigMainWindow(void) | 744 | ConfigMainWindow::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 | ||
825 | static QString print_filter(const char *str) | 889 | static 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, "<"); | 896 | res.replace(i, 1, "<"); |
833 | i += 4; | 897 | i += 4; |
834 | break; | 898 | break; |
835 | case '>': | 899 | case '>': |
836 | res.replace(i, 1, ">"); | 900 | res.replace(i, 1, ">"); |
837 | i += 4; | 901 | i += 4; |
838 | break; | 902 | break; |
839 | case '&': | 903 | case '&': |
840 | res.replace(i, 1, "&"); | 904 | res.replace(i, 1, "&"); |
841 | i += 5; | 905 | i += 5; |
842 | break; | 906 | break; |
843 | case '"': | 907 | case '"': |
844 | res.replace(i, 1, """); | 908 | res.replace(i, 1, """); |
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 | ||
856 | static void expr_print_help(void *data, const char *str) | 920 | static 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 | */ |
864 | void ConfigMainWindow::setHelp(QListViewItem* item) | 928 | void 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 += " 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 += " 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 += " 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 += " 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 += " 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 | ||
952 | void ConfigMainWindow::loadConfig(void) | 1034 | void 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 | ||
962 | void ConfigMainWindow::saveConfig(void) | 1044 | void 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 | ||
968 | void ConfigMainWindow::saveConfigAs(void) | 1050 | void 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 | ||
977 | void ConfigMainWindow::changeMenu(struct menu *menu) | 1059 | void 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 | ||
983 | void ConfigMainWindow::listFocusChanged(void) | 1065 | void 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 | ||
994 | void ConfigMainWindow::goBack(void) | 1076 | void 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 | ||
1011 | void ConfigMainWindow::showSingleView(void) | 1093 | void 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 | ||
1024 | void ConfigMainWindow::showSplitView(void) | 1106 | void 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 | ||
1040 | void ConfigMainWindow::showFullView(void) | 1122 | void 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 | ||
1053 | void ConfigMainWindow::setShowAll(bool b) | 1135 | void 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 | ||
1063 | void ConfigMainWindow::setShowDebug(bool b) | 1145 | void 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 | ||
1070 | void ConfigMainWindow::setShowName(bool b) | 1152 | void 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 | ||
1078 | void ConfigMainWindow::setShowRange(bool b) | 1162 | void 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 | ||
1086 | void ConfigMainWindow::setShowData(bool b) | 1172 | void 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 | */ |
1098 | void ConfigMainWindow::closeEvent(QCloseEvent* e) | 1186 | void 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 | ||
1121 | void ConfigMainWindow::showIntro(void) | 1209 | void 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 | ||
1138 | void ConfigMainWindow::showAbout(void) | 1226 | void 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 | ||
1146 | void fixup_rootmenu(struct menu *menu) | 1234 | void 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 | |||
1250 | static const char *progname; | ||
1251 | |||
1252 | static void usage(void) | ||
1253 | { | ||
1254 | printf("%s <config>\n", progname); | ||
1255 | exit(0); | ||
1155 | } | 1256 | } |
1156 | 1257 | ||
1157 | int main(int ac, char** av) | 1258 | int 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 | ||
8 | class ConfigList; | 8 | class ConfigList; |
9 | class ConfigItem; | 9 | class ConfigItem; |
10 | class ConfigLineEdit; | 10 | class ConfigLineEdit; |
11 | class ConfigMainWindow; | 11 | class ConfigMainWindow; |
12 | 12 | ||
13 | class ConfigView : public QVBox { | 13 | class ConfigView : public QVBox { |
14 | Q_OBJECT | 14 | Q_OBJECT |
15 | typedef class QVBox Parent; | 15 | typedef class QVBox Parent; |
16 | public: | 16 | public: |
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 | ||
22 | public: | 22 | public: |
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 | ||
30 | enum colIdx { | 30 | enum colIdx { |
31 | promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr | 31 | promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr |
32 | }; | 32 | }; |
33 | enum listMode { | 33 | enum listMode { |
34 | singleMode, menuMode, symbolMode, fullMode | 34 | singleMode, menuMode, symbolMode, fullMode |
35 | }; | 35 | }; |
36 | 36 | ||
37 | class ConfigList : public QListView { | 37 | class ConfigList : public QListView { |
38 | Q_OBJECT | 38 | Q_OBJECT |
39 | typedef class QListView Parent; | 39 | typedef class QListView Parent; |
40 | public: | 40 | public: |
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 | ||
48 | protected: | 48 | protected: |
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); |
57 | public slots: | 57 | public 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); |
64 | signals: | 64 | signals: |
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 | ||
69 | public: | 69 | public: |
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 | ||
115 | private: | 119 | private: |
116 | int colMap[colNr]; | 120 | int colMap[colNr]; |
117 | int colRevMap[colNr]; | 121 | int colRevMap[colNr]; |
118 | }; | 122 | }; |
119 | 123 | ||
120 | class ConfigItem : public QListViewItem { | 124 | class ConfigItem : public QListViewItem { |
121 | typedef class QListViewItem Parent; | 125 | typedef class QListViewItem Parent; |
122 | public: | 126 | public: |
123 | ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) | 127 | ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) |
124 | : Parent(parent, after), menu(m), visible(v) | 128 | : Parent(parent, after), menu(m), visible(v), goParent(false) |
125 | { | 129 | { |
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 | ||
175 | class ConfigLineEdit : public QLineEdit { | 185 | class ConfigLineEdit : public QLineEdit { |
176 | Q_OBJECT | 186 | Q_OBJECT |
177 | typedef class QLineEdit Parent; | 187 | typedef class QLineEdit Parent; |
178 | public: | 188 | public: |
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 | ||
189 | public: | 199 | public: |
190 | ConfigItem *item; | 200 | ConfigItem *item; |
191 | }; | 201 | }; |
192 | 202 | ||
193 | class ConfigMainWindow : public QMainWindow { | 203 | class ConfigMainWindow : public QMainWindow { |
194 | Q_OBJECT | 204 | Q_OBJECT |
195 | public: | 205 | public: |
196 | ConfigMainWindow(void); | 206 | ConfigMainWindow(void); |
197 | public slots: | 207 | public 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 | ||
216 | protected: | 226 | protected: |
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 | ||
14 | struct symbol symbol_yes = { | 14 | struct 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 | ||
32 | int sym_change_count; | 32 | int sym_change_count; |
33 | struct symbol *modules_sym; | 33 | struct symbol *modules_sym; |
34 | 34 | ||
35 | void sym_add_default(struct symbol *sym, const char *def) | 35 | void sym_add_default(struct symbol *sym, const char *def) |
36 | { | 36 | { |
37 | struct property *prop = create_prop(P_DEFAULT); | 37 | struct property *prop = prop_alloc(P_DEFAULT, sym); |
38 | struct property **propp; | ||
39 | |||
40 | prop->sym = sym; | ||
41 | prop->def = sym_lookup(def, 1); | ||
42 | 38 | ||
43 | /* append property to the prop list of symbol */ | 39 | prop->expr = expr_alloc_symbol(sym_lookup(def, 1)); |
44 | if (prop->sym) { | ||
45 | for (propp = &prop->sym->prop; *propp; propp = &(*propp)->next) | ||
46 | ; | ||
47 | *propp = prop; | ||
48 | } | ||
49 | } | 40 | } |
50 | 41 | ||
51 | void sym_init(void) | 42 | void 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 | ||
84 | int sym_get_type(struct symbol *sym) | 75 | enum 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 | ||
99 | const char *sym_type_name(int type) | 91 | const 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 | ||
118 | struct property *sym_get_choice_prop(struct symbol *sym) | 112 | struct 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 | ||
127 | struct property *sym_get_default_prop(struct symbol *sym) | 121 | struct 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 | ||
140 | void sym_calc_visibility(struct symbol *sym) | 133 | struct 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 | |||
145 | static 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 | ||
171 | static 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 | |||
156 | void sym_calc_value(struct symbol *sym) | 210 | void 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 | |||
243 | out: | ||
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 | ||
294 | void sym_clear_all_valid(void) | 322 | void 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 | ||
304 | void sym_set_changed(struct symbol *sym) | 332 | void 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 | ||
315 | void sym_set_all_changed(void) | 343 | void 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 | ||
324 | bool sym_tristate_within_range(struct symbol *sym, tristate val) | 352 | bool 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 | ||
349 | bool sym_set_tristate_value(struct symbol *sym, tristate val) | 371 | bool 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 | ||
377 | tristate sym_toggle_tristate_value(struct symbol *sym) | 399 | tristate 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 | ||
400 | bool sym_string_valid(struct symbol *sym, const char *str) | 422 | bool 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 | |||
465 | bool 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 | ||
448 | bool sym_set_string_value(struct symbol *sym, const char *newval) | 507 | bool 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 | ||
500 | const char *sym_get_string_value(struct symbol *sym) | 556 | const 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 | ||
523 | bool sym_is_changable(struct symbol *sym) | 579 | bool sym_is_changable(struct symbol *sym) |
524 | { | 580 | { |
525 | if (sym->visible == no) | 581 | return sym->visible > sym->rev_dep.tri; |
526 | return false; | ||
527 | /* at least 'n' and 'y'/'m' is selectable */ | ||
528 | if (sym_is_optional(sym)) | ||
529 | return true; | ||
530 | /* no 'n', so 'y' and 'm' must be selectable */ | ||
531 | if (sym_get_type(sym) == S_TRISTATE && sym->visible == yes) | ||
532 | return true; | ||
533 | return false; | ||
534 | } | 582 | } |
535 | 583 | ||
536 | struct symbol *sym_lookup(const char *name, int isconst) | 584 | struct 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 | ||
582 | struct symbol *sym_find(const char *name) | 630 | struct 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 | ||
659 | struct symbol *sym_check_deps(struct symbol *sym); | ||
660 | |||
661 | static 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 | |||
691 | struct 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 | } | ||
720 | out: | ||
721 | if (sym2) | ||
722 | printf(" %s", sym->name); | ||
723 | sym->flags &= ~SYMBOL_CHECK; | ||
724 | return sym2; | ||
725 | } | ||
726 | |||
727 | struct 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 | |||
749 | struct 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 | |||
611 | const char *prop_get_type_name(enum prop_type type) | 757 | const 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 | ||
21 | char *text; | 21 | char *text; |
22 | static char *text_ptr; | 22 | static char *text_ptr; |
23 | static int text_size, text_asize; | 23 | static int text_size, text_asize; |
24 | 24 | ||
25 | struct buffer { | 25 | struct buffer { |
26 | struct buffer *parent; | 26 | struct buffer *parent; |
27 | YY_BUFFER_STATE state; | 27 | YY_BUFFER_STATE state; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | struct buffer *current_buf; | 30 | struct buffer *current_buf; |
31 | 31 | ||
32 | static int last_ts, first_ts; | 32 | static int last_ts, first_ts; |
33 | 33 | ||
34 | static void zconf_endhelp(void); | 34 | static void zconf_endhelp(void); |
35 | static struct buffer *zconf_endfile(void); | 35 | static struct buffer *zconf_endfile(void); |
36 | 36 | ||
37 | void new_string(void) | 37 | void 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 | ||
46 | void append_string(const char *str, int size) | 46 | void 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 | ||
60 | void alloc_string(const char *str, int size) | 60 | void 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 | %% |
241 | void zconf_starthelp(void) | 248 | void 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 | ||
248 | static void zconf_endhelp(void) | 255 | static 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 | */ |
263 | FILE *zconf_fopen(const char *name) | 270 | FILE *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 | ||
279 | void zconf_initscan(const char *name) | 286 | void 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 | ||
295 | void zconf_nextfile(const char *name) | 302 | void 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 | ||
325 | static struct buffer *zconf_endfile(void) | 332 | static 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 | ||
345 | int zconf_lineno(void) | 352 | int 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 | ||
353 | char *zconf_curname(void) | 360 | char *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 | ||
19 | int cdebug = PRINTD; | 19 | int cdebug = PRINTD; |
20 | 20 | ||
21 | extern int zconflex(void); | 21 | extern int zconflex(void); |
22 | static void zconfprint(const char *err, ...); | 22 | static void zconfprint(const char *err, ...); |
23 | static void zconferror(const char *err); | 23 | static void zconferror(const char *err); |
24 | static bool zconf_endtoken(int token, int starttoken, int endtoken); | 24 | static bool zconf_endtoken(int token, int starttoken, int endtoken); |
25 | 25 | ||
26 | struct symbol *symbol_hash[257]; | 26 | struct symbol *symbol_hash[257]; |
27 | 27 | ||
28 | #define YYERROR_VERBOSE | 28 | #define YYERROR_VERBOSE |
29 | %} | 29 | %} |
30 | %expect 36 | 30 | %expect 40 |
31 | 31 | ||
32 | %union | 32 | %union |
33 | { | 33 | { |
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 | ||
102 | common_block: | 108 | common_block: |
103 | if_stmt | 109 | if_stmt |
104 | | comment_stmt | 110 | | comment_stmt |
105 | | config_stmt | 111 | | config_stmt |
112 | | menuconfig_stmt | ||
106 | | source_stmt | 113 | | source_stmt |
107 | | nl_or_eof | 114 | | nl_or_eof |
108 | ; | 115 | ; |
109 | 116 | ||
110 | 117 | ||
111 | /* config entry */ | 118 | /* config/menuconfig entry */ |
112 | 119 | ||
113 | config_entry_start: T_CONFIG T_WORD | 120 | config_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 | ||
121 | config_stmt: config_entry_start T_EOL config_option_list | 128 | config_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 | ||
134 | menuconfig_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 | |||
142 | menuconfig_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 | |||
127 | config_option_list: | 152 | config_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 | ||
135 | config_option: T_TRISTATE prompt_stmt_opt | 160 | config_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 | ||
141 | config_option: T_BOOLEAN prompt_stmt_opt | 166 | config_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 | |||
173 | config_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 | ||
147 | config_option: T_INT prompt_stmt_opt | 179 | config_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 | |||
186 | config_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 | ||
153 | config_option: T_HEX prompt_stmt_opt | 192 | config_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 | ||
159 | config_option: T_STRING prompt_stmt_opt | 198 | config_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 | ||
165 | config_option: T_PROMPT prompt if_expr | 204 | config_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 | ||
171 | config_option: T_DEFAULT symbol if_expr | 210 | config_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 | ||
216 | config_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 | |||
222 | config_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 | ||
179 | choice: T_CHOICE | 230 | choice: 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 | ||
188 | choice_entry: choice T_EOL choice_option_list | 239 | choice_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 | ||
194 | choice_end: end | 245 | choice_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 | ||
202 | choice_stmt: | 253 | choice_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 | ||
210 | choice_option_list: | 261 | choice_option_list: |
211 | /* empty */ | 262 | /* empty */ |
212 | | choice_option_list choice_option T_EOL | 263 | | choice_option_list choice_option |
213 | | choice_option_list depends T_EOL | 264 | | choice_option_list depends |
214 | | choice_option_list help | 265 | | choice_option_list help |
215 | | choice_option_list T_EOL | 266 | | choice_option_list T_EOL |
216 | ; | 267 | ; |
217 | 268 | ||
218 | choice_option: T_PROMPT prompt if_expr | 269 | choice_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 | ||
224 | choice_option: T_OPTIONAL | 275 | choice_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 | |||
281 | choice_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 | |||
287 | choice_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 | ||
230 | choice_option: T_DEFAULT symbol if_expr | 293 | choice_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 | ||
236 | choice_block: | 299 | choice_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 | ||
243 | if: T_IF expr | 306 | if: 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 | ||
252 | if_end: end | 315 | if_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 | ||
260 | if_stmt: | 323 | if_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 | ||
268 | if_block: | 331 | if_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 | ||
277 | menu: T_MENU prompt | 340 | menu: 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 | ||
284 | menu_entry: menu T_EOL depends_list | 347 | menu_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 | ||
290 | menu_end: end | 353 | menu_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 | ||
298 | menu_stmt: | 361 | menu_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 | ||
306 | menu_block: | 369 | menu_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 | ||
314 | source: T_SOURCE prompt | 377 | source: 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 | ||
320 | source_stmt: source T_EOL | 383 | source_stmt: source |
321 | { | 384 | { |
322 | zconf_nextfile($1); | 385 | zconf_nextfile($1); |
323 | }; | 386 | }; |
324 | 387 | ||
325 | /* comment entry */ | 388 | /* comment entry */ |
326 | 389 | ||
327 | comment: T_COMMENT prompt | 390 | comment: 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 | ||
334 | comment_stmt: comment T_EOL depends_list | 397 | comment_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 | ||
341 | help_start: T_HELP T_EOL | 404 | help_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 | ||
347 | help: help_start T_HELPTEXT | 410 | help: 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 | ||
359 | depends: T_DEPENDS T_ON expr | 422 | depends: 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 | ||
377 | prompt_stmt_opt: | 440 | prompt_stmt_opt: |
378 | /* empty */ | 441 | /* empty */ |
379 | | prompt | 442 | | prompt if_expr |
380 | { | ||
381 | menu_add_prop(P_PROMPT, $1, NULL, NULL); | ||
382 | } | ||
383 | | prompt T_IF expr | ||
384 | { | 443 | { |
385 | menu_add_prop(P_PROMPT, $1, NULL, $3); | 444 | menu_add_prop(P_PROMPT, $1, NULL, $2); |
386 | }; | 445 | }; |
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 | ||
397 | nl_or_eof: | 456 | nl_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 | ||
419 | void conf_parse(const char *name) | 478 | void 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 | ||
438 | const char *zconf_tokenname(int token) | 505 | const 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 | ||
451 | static bool zconf_endtoken(int token, int starttoken, int endtoken) | 518 | static 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 | ||
467 | static void zconfprint(const char *err, ...) | 534 | static void zconfprint(const char *err, ...) |
468 | { | 535 | { |
469 | va_list ap; | 536 | va_list ap; |
470 | 537 | ||
471 | fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); | 538 | fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1); |
472 | va_start(ap, err); | 539 | va_start(ap, err); |
473 | vfprintf(stderr, err, ap); | 540 | vfprintf(stderr, err, ap); |
474 | va_end(ap); | 541 | va_end(ap); |
475 | fprintf(stderr, "\n"); | 542 | fprintf(stderr, "\n"); |
476 | } | 543 | } |
477 | 544 | ||
478 | static void zconferror(const char *err) | 545 | static void zconferror(const char *err) |
479 | { | 546 | { |
480 | fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err); | 547 | fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); |
481 | } | 548 | } |
482 | 549 | ||
483 | void print_quoted_string(FILE *out, const char *str) | 550 | void 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 | ||
500 | void print_symbol(FILE *out, struct menu *menu) | 567 | void 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 | ||
584 | void zconfdump(FILE *out) | 635 | void 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" |