aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/Lindent2
-rw-r--r--scripts/Makefile22
-rw-r--r--scripts/Makefile.build330
-rw-r--r--scripts/Makefile.clean94
-rw-r--r--scripts/Makefile.host155
-rw-r--r--scripts/Makefile.lib267
-rw-r--r--scripts/Makefile.modinst29
-rw-r--r--scripts/Makefile.modpost110
-rw-r--r--scripts/basic/Makefile18
-rw-r--r--scripts/basic/docproc.c398
-rw-r--r--scripts/basic/fixdep.c390
-rw-r--r--scripts/basic/split-include.c226
-rw-r--r--scripts/bin2c.c36
-rw-r--r--scripts/binoffset.c163
-rwxr-xr-xscripts/checkconfig.pl65
-rwxr-xr-xscripts/checkincludes.pl24
-rw-r--r--scripts/checkstack.pl123
-rwxr-xr-xscripts/checkversion.pl72
-rw-r--r--scripts/conmakehash.c293
-rwxr-xr-xscripts/extract-ikconfig77
-rw-r--r--scripts/gcc-version.sh14
-rw-r--r--scripts/gen_initramfs_list.sh203
-rw-r--r--scripts/genksyms/Makefile49
-rw-r--r--scripts/genksyms/genksyms.c591
-rw-r--r--scripts/genksyms/genksyms.h104
-rw-r--r--scripts/genksyms/keywords.c_shipped145
-rw-r--r--scripts/genksyms/keywords.gperf50
-rw-r--r--scripts/genksyms/lex.c_shipped2084
-rw-r--r--scripts/genksyms/lex.l407
-rw-r--r--scripts/genksyms/parse.c_shipped1577
-rw-r--r--scripts/genksyms/parse.h_shipped46
-rw-r--r--scripts/genksyms/parse.y469
-rw-r--r--scripts/kallsyms.c686
-rw-r--r--scripts/kconfig/Makefile208
-rw-r--r--scripts/kconfig/conf.c583
-rw-r--r--scripts/kconfig/confdata.c460
-rw-r--r--scripts/kconfig/expr.c1099
-rw-r--r--scripts/kconfig/expr.h195
-rw-r--r--scripts/kconfig/gconf.c1639
-rw-r--r--scripts/kconfig/gconf.glade543
-rw-r--r--scripts/kconfig/images.c326
-rw-r--r--scripts/kconfig/kconfig_load.c35
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped3688
-rw-r--r--scripts/kconfig/lkc.h123
-rw-r--r--scripts/kconfig/lkc_proto.h40
-rw-r--r--scripts/kconfig/mconf.c1090
-rw-r--r--scripts/kconfig/menu.c390
-rw-r--r--scripts/kconfig/qconf.cc1407
-rw-r--r--scripts/kconfig/qconf.h263
-rw-r--r--scripts/kconfig/symbol.c816
-rw-r--r--scripts/kconfig/util.c109
-rw-r--r--scripts/kconfig/zconf.l366
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped2130
-rw-r--r--scripts/kconfig/zconf.tab.h_shipped125
-rw-r--r--scripts/kconfig/zconf.y690
-rwxr-xr-xscripts/kernel-doc1831
-rw-r--r--scripts/ksymoops/README8
-rw-r--r--scripts/lxdialog/BIG.FAT.WARNING4
-rw-r--r--scripts/lxdialog/Makefile42
-rw-r--r--scripts/lxdialog/checklist.c373
-rw-r--r--scripts/lxdialog/colors.h155
-rw-r--r--scripts/lxdialog/dialog.h187
-rw-r--r--scripts/lxdialog/inputbox.c240
-rw-r--r--scripts/lxdialog/lxdialog.c226
-rw-r--r--scripts/lxdialog/menubox.c445
-rw-r--r--scripts/lxdialog/msgbox.c85
-rw-r--r--scripts/lxdialog/textbox.c556
-rw-r--r--scripts/lxdialog/util.c359
-rw-r--r--scripts/lxdialog/yesno.c118
-rwxr-xr-xscripts/makelst31
-rwxr-xr-xscripts/makeman185
-rwxr-xr-xscripts/mkcompile_h78
-rw-r--r--scripts/mkmakefile31
-rw-r--r--scripts/mksysmap44
-rwxr-xr-xscripts/mkuboot.sh16
-rw-r--r--scripts/mkversion6
-rw-r--r--scripts/mod/Makefile16
-rw-r--r--scripts/mod/empty.c1
-rw-r--r--scripts/mod/file2alias.c308
-rw-r--r--scripts/mod/mk_elfconfig.c65
-rw-r--r--scripts/mod/modpost.c797
-rw-r--r--scripts/mod/modpost.h107
-rw-r--r--scripts/mod/sumversion.c498
-rw-r--r--scripts/namespace.pl454
-rw-r--r--scripts/package/Makefile89
-rw-r--r--scripts/package/builddeb79
-rwxr-xr-xscripts/package/mkspec82
-rwxr-xr-xscripts/patch-kernel257
-rw-r--r--scripts/pnmtologo.c508
-rw-r--r--scripts/reference_discarded.pl110
-rw-r--r--scripts/reference_init.pl107
-rw-r--r--scripts/show_delta129
-rwxr-xr-xscripts/split-man112
-rwxr-xr-xscripts/ver_linux95
94 files changed, 34478 insertions, 0 deletions
diff --git a/scripts/Lindent b/scripts/Lindent
new file mode 100755
index 000000000000..34ed785116b6
--- /dev/null
+++ b/scripts/Lindent
@@ -0,0 +1,2 @@
1#!/bin/sh
2indent -kr -i8 -ts8 -sob -l80 -ss -ncs "$@"
diff --git a/scripts/Makefile b/scripts/Makefile
new file mode 100644
index 000000000000..67763eeb8a3e
--- /dev/null
+++ b/scripts/Makefile
@@ -0,0 +1,22 @@
1###
2# scripts contains sources for various helper programs used throughout
3# the kernel for the build process.
4# ---------------------------------------------------------------------------
5# kallsyms: Find all symbols in vmlinux
6# pnmttologo: Convert pnm files to logo files
7# conmakehash: Create chartable
8# conmakehash: Create arrays for initializing the kernel console tables
9
10hostprogs-$(CONFIG_KALLSYMS) += kallsyms
11hostprogs-$(CONFIG_LOGO) += pnmtologo
12hostprogs-$(CONFIG_VT) += conmakehash
13hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash
14hostprogs-$(CONFIG_IKCONFIG) += bin2c
15
16always := $(hostprogs-y)
17
18subdir-$(CONFIG_MODVERSIONS) += genksyms
19subdir-$(CONFIG_MODULES) += mod
20
21# Let clean descend into subdirs
22subdir- += basic lxdialog kconfig package
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
new file mode 100644
index 000000000000..352d531ee3c1
--- /dev/null
+++ b/scripts/Makefile.build
@@ -0,0 +1,330 @@
1# ==========================================================================
2# Building
3# ==========================================================================
4
5src := $(obj)
6
7.PHONY: __build
8__build:
9
10# Read .config if it exist, otherwise ignore
11-include .config
12
13include $(if $(wildcard $(obj)/Kbuild), $(obj)/Kbuild, $(obj)/Makefile)
14
15include scripts/Makefile.lib
16
17ifdef host-progs
18ifneq ($(hostprogs-y),$(host-progs))
19$(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please replace with hostprogs-y!)
20hostprogs-y += $(host-progs)
21endif
22endif
23
24# Do not include host rules unles needed
25ifneq ($(hostprogs-y)$(hostprogs-m),)
26include scripts/Makefile.host
27endif
28
29ifneq ($(KBUILD_SRC),)
30# Create output directory if not already present
31_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
32
33# Create directories for object files if directory does not exist
34# Needed when obj-y := dir/file.o syntax is used
35_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
36endif
37
38
39ifdef EXTRA_TARGETS
40$(warning kbuild: $(obj)/Makefile - Usage of EXTRA_TARGETS is obsolete in 2.6. Please fix!)
41endif
42
43ifdef build-targets
44$(warning kbuild: $(obj)/Makefile - Usage of build-targets is obsolete in 2.6. Please fix!)
45endif
46
47ifdef export-objs
48$(warning kbuild: $(obj)/Makefile - Usage of export-objs is obsolete in 2.6. Please fix!)
49endif
50
51ifdef O_TARGET
52$(warning kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.6. Please fix!)
53endif
54
55ifdef L_TARGET
56$(error kbuild: $(obj)/Makefile - Use of L_TARGET is replaced by lib-y in 2.6. Please fix!)
57endif
58
59ifdef list-multi
60$(warning kbuild: $(obj)/Makefile - list-multi := $(list-multi) is obsolete in 2.6. Please fix!)
61endif
62
63ifndef obj
64$(warning kbuild: Makefile.build is included improperly)
65endif
66
67# ===========================================================================
68
69ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
70lib-target := $(obj)/lib.a
71endif
72
73ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
74builtin-target := $(obj)/built-in.o
75endif
76
77# We keep a list of all modules in $(MODVERDIR)
78
79__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
80 $(if $(KBUILD_MODULES),$(obj-m)) \
81 $(subdir-ym) $(always)
82 @:
83
84# Linus' kernel sanity checking tool
85ifneq ($(KBUILD_CHECKSRC),0)
86 ifeq ($(KBUILD_CHECKSRC),2)
87 quiet_cmd_force_checksrc = CHECK $<
88 cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
89 else
90 quiet_cmd_checksrc = CHECK $<
91 cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
92 endif
93endif
94
95
96# Compile C sources (.c)
97# ---------------------------------------------------------------------------
98
99# Default is built-in, unless we know otherwise
100modkern_cflags := $(CFLAGS_KERNEL)
101quiet_modtag := $(empty) $(empty)
102
103$(real-objs-m) : modkern_cflags := $(CFLAGS_MODULE)
104$(real-objs-m:.o=.i) : modkern_cflags := $(CFLAGS_MODULE)
105$(real-objs-m:.o=.s) : modkern_cflags := $(CFLAGS_MODULE)
106$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
107
108$(real-objs-m) : quiet_modtag := [M]
109$(real-objs-m:.o=.i) : quiet_modtag := [M]
110$(real-objs-m:.o=.s) : quiet_modtag := [M]
111$(real-objs-m:.o=.lst): quiet_modtag := [M]
112
113$(obj-m) : quiet_modtag := [M]
114
115# Default for not multi-part modules
116modname = $(*F)
117
118$(multi-objs-m) : modname = $(modname-multi)
119$(multi-objs-m:.o=.i) : modname = $(modname-multi)
120$(multi-objs-m:.o=.s) : modname = $(modname-multi)
121$(multi-objs-m:.o=.lst) : modname = $(modname-multi)
122$(multi-objs-y) : modname = $(modname-multi)
123$(multi-objs-y:.o=.i) : modname = $(modname-multi)
124$(multi-objs-y:.o=.s) : modname = $(modname-multi)
125$(multi-objs-y:.o=.lst) : modname = $(modname-multi)
126
127quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
128cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
129
130%.s: %.c FORCE
131 $(call if_changed_dep,cc_s_c)
132
133quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
134cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
135
136%.i: %.c FORCE
137 $(call if_changed_dep,cc_i_c)
138
139# C (.c) files
140# The C file is compiled and updated dependency information is generated.
141# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
142
143quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
144
145ifndef CONFIG_MODVERSIONS
146cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
147
148else
149# When module versioning is enabled the following steps are executed:
150# o compile a .tmp_<file>.o from <file>.c
151# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
152# not export symbols, we just rename .tmp_<file>.o to <file>.o and
153# are done.
154# o otherwise, we calculate symbol versions using the good old
155# genksyms on the preprocessed source and postprocess them in a way
156# that they are usable as a linker script
157# o generate <file>.o from .tmp_<file>.o using the linker to
158# replace the unresolved symbols __crc_exported_symbol with
159# the actual value of the checksum generated by genksyms
160
161cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
162cmd_modversions = \
163 if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
164 $(CPP) -D__GENKSYMS__ $(c_flags) $< \
165 | $(GENKSYMS) \
166 > $(@D)/.tmp_$(@F:.o=.ver); \
167 \
168 $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
169 -T $(@D)/.tmp_$(@F:.o=.ver); \
170 rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
171 else \
172 mv $(@D)/.tmp_$(@F) $@; \
173 fi;
174endif
175
176define rule_cc_o_c
177 $(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \
178 $(cmd_checksrc) \
179 $(if $($(quiet)cmd_cc_o_c),echo ' $($(quiet)cmd_cc_o_c)';) \
180 $(cmd_cc_o_c); \
181 $(cmd_modversions) \
182 scripts/basic/fixdep $(depfile) $@ '$(cmd_cc_o_c)' > $(@D)/.$(@F).tmp; \
183 rm -f $(depfile); \
184 mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
185endef
186
187# Built-in and composite module parts
188
189%.o: %.c FORCE
190 $(call cmd,force_checksrc)
191 $(call if_changed_rule,cc_o_c)
192
193# Single-part modules are special since we need to mark them in $(MODVERDIR)
194
195$(single-used-m): %.o: %.c FORCE
196 $(call cmd,force_checksrc)
197 $(call if_changed_rule,cc_o_c)
198 @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
199
200quiet_cmd_cc_lst_c = MKLST $@
201 cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
202 $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
203 System.map $(OBJDUMP) > $@
204
205%.lst: %.c FORCE
206 $(call if_changed_dep,cc_lst_c)
207
208# Compile assembler sources (.S)
209# ---------------------------------------------------------------------------
210
211modkern_aflags := $(AFLAGS_KERNEL)
212
213$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE)
214$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
215
216quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
217cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
218
219%.s: %.S FORCE
220 $(call if_changed_dep,as_s_S)
221
222quiet_cmd_as_o_S = AS $(quiet_modtag) $@
223cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
224
225%.o: %.S FORCE
226 $(call if_changed_dep,as_o_S)
227
228targets += $(real-objs-y) $(real-objs-m) $(lib-y)
229targets += $(extra-y) $(MAKECMDGOALS) $(always)
230
231# Linker scripts preprocessor (.lds.S -> .lds)
232# ---------------------------------------------------------------------------
233quiet_cmd_cpp_lds_S = LDS $@
234 cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $<
235
236%.lds: %.lds.S FORCE
237 $(call if_changed_dep,cpp_lds_S)
238
239# Build the compiled-in targets
240# ---------------------------------------------------------------------------
241
242# To build objects in subdirs, we need to descend into the directories
243$(sort $(subdir-obj-y)): $(subdir-ym) ;
244
245#
246# Rule to compile a set of .o files into one .o file
247#
248ifdef builtin-target
249quiet_cmd_link_o_target = LD $@
250# If the list of objects to link is empty, just create an empty built-in.o
251cmd_link_o_target = $(if $(strip $(obj-y)),\
252 $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\
253 rm -f $@; $(AR) rcs $@)
254
255$(builtin-target): $(obj-y) FORCE
256 $(call if_changed,link_o_target)
257
258targets += $(builtin-target)
259endif # builtin-target
260
261#
262# Rule to compile a set of .o files into one .a file
263#
264ifdef lib-target
265quiet_cmd_link_l_target = AR $@
266cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-y)
267
268$(lib-target): $(lib-y) FORCE
269 $(call if_changed,link_l_target)
270
271targets += $(lib-target)
272endif
273
274#
275# Rule to link composite objects
276#
277# Composite objects are specified in kbuild makefile as follows:
278# <composite-object>-objs := <list of .o files>
279# or
280# <composite-object>-y := <list of .o files>
281link_multi_deps = \
282$(filter $(addprefix $(obj)/, \
283$($(subst $(obj)/,,$(@:.o=-objs))) \
284$($(subst $(obj)/,,$(@:.o=-y)))), $^)
285
286quiet_cmd_link_multi-y = LD $@
287cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps)
288
289quiet_cmd_link_multi-m = LD [M] $@
290cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps)
291
292# We would rather have a list of rules like
293# foo.o: $(foo-objs)
294# but that's not so easy, so we rather make all composite objects depend
295# on the set of all their parts
296$(multi-used-y) : %.o: $(multi-objs-y) FORCE
297 $(call if_changed,link_multi-y)
298
299$(multi-used-m) : %.o: $(multi-objs-m) FORCE
300 $(call if_changed,link_multi-m)
301 @{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
302
303targets += $(multi-used-y) $(multi-used-m)
304
305
306# Descending
307# ---------------------------------------------------------------------------
308
309.PHONY: $(subdir-ym)
310$(subdir-ym):
311 $(Q)$(MAKE) $(build)=$@
312
313# Add FORCE to the prequisites of a target to force it to be always rebuilt.
314# ---------------------------------------------------------------------------
315
316.PHONY: FORCE
317
318FORCE:
319
320# Read all saved command lines and dependencies for the $(targets) we
321# may be building above, using $(if_changed{,_dep}). As an
322# optimization, we don't need to read them if the target does not
323# exist, we will rebuild anyway in that case.
324
325targets := $(wildcard $(sort $(targets)))
326cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
327
328ifneq ($(cmd_files),)
329 include $(cmd_files)
330endif
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
new file mode 100644
index 000000000000..ff3e87dbf387
--- /dev/null
+++ b/scripts/Makefile.clean
@@ -0,0 +1,94 @@
1# ==========================================================================
2# Cleaning up
3# ==========================================================================
4
5src := $(obj)
6
7.PHONY: __clean
8__clean:
9
10include $(if $(wildcard $(obj)/Kbuild), $(obj)/Kbuild, $(obj)/Makefile)
11
12# Figure out what we need to build from the various variables
13# ==========================================================================
14
15__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
16subdir-y += $(__subdir-y)
17__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
18subdir-m += $(__subdir-m)
19__subdir-n := $(patsubst %/,%,$(filter %/, $(obj-n)))
20subdir-n += $(__subdir-n)
21__subdir- := $(patsubst %/,%,$(filter %/, $(obj-)))
22subdir- += $(__subdir-)
23
24# Subdirectories we need to descend into
25
26subdir-ym := $(sort $(subdir-y) $(subdir-m))
27subdir-ymn := $(sort $(subdir-ym) $(subdir-n) $(subdir-))
28
29# Add subdir path
30
31subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
32
33# build a list of files to remove, usually releative to the current
34# directory
35
36__clean-files := $(extra-y) $(EXTRA_TARGETS) $(always) \
37 $(targets) $(clean-files) \
38 $(host-progs) \
39 $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
40
41# as clean-files is given relative to the current directory, this adds
42# a $(obj) prefix, except for absolute paths
43
44__clean-files := $(wildcard \
45 $(addprefix $(obj)/, $(filter-out /%, $(__clean-files))) \
46 $(filter /%, $(__clean-files)))
47
48# as clean-dirs is given relative to the current directory, this adds
49# a $(obj) prefix, except for absolute paths
50
51__clean-dirs := $(wildcard \
52 $(addprefix $(obj)/, $(filter-out /%, $(clean-dirs))) \
53 $(filter /%, $(clean-dirs)))
54
55# ==========================================================================
56
57quiet_cmd_clean = CLEAN $(obj)
58 cmd_clean = rm -f $(__clean-files)
59quiet_cmd_cleandir = CLEAN $(__clean-dirs)
60 cmd_cleandir = rm -rf $(__clean-dirs)
61
62
63__clean: $(subdir-ymn)
64ifneq ($(strip $(__clean-files)),)
65 +$(call cmd,clean)
66endif
67ifneq ($(strip $(__clean-dirs)),)
68 +$(call cmd,cleandir)
69endif
70ifneq ($(strip $(clean-rule)),)
71 +$(clean-rule)
72endif
73 @:
74
75
76# ===========================================================================
77# Generic stuff
78# ===========================================================================
79
80# Descending
81# ---------------------------------------------------------------------------
82
83.PHONY: $(subdir-ymn)
84$(subdir-ymn):
85 $(Q)$(MAKE) $(clean)=$@
86
87# If quiet is set, only print short version of command
88
89cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1))
90
91# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
92# Usage:
93# $(Q)$(MAKE) $(clean)=dir
94clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
new file mode 100644
index 000000000000..2821a2b83bbb
--- /dev/null
+++ b/scripts/Makefile.host
@@ -0,0 +1,155 @@
1# ==========================================================================
2# Building binaries on the host system
3# Binaries are used during the compilation of the kernel, for example
4# to preprocess a data file.
5#
6# Both C and C++ is supported, but preferred language is C for such utilities.
7#
8# Samle syntax (see Documentation/kbuild/makefile.txt for reference)
9# hostprogs-y := bin2hex
10# Will compile bin2hex.c and create an executable named bin2hex
11#
12# hostprogs-y := lxdialog
13# lxdialog-objs := checklist.o lxdialog.o
14# Will compile lxdialog.c and checklist.c, and then link the executable
15# lxdialog, based on checklist.o and lxdialog.o
16#
17# hostprogs-y := qconf
18# qconf-cxxobjs := qconf.o
19# qconf-objs := menu.o
20# Will compile qconf as a C++ program, and menu as a C program.
21# They are linked as C++ code to the executable qconf
22
23# hostprogs-y := conf
24# conf-objs := conf.o libkconfig.so
25# libkconfig-objs := expr.o type.o
26# Will create a shared library named libkconfig.so that consist of
27# expr.o and type.o (they are both compiled as C code and the object file
28# are made as position independent code).
29# conf.c is compiled as a c program, and conf.o is linked together with
30# libkconfig.so as the executable conf.
31# Note: Shared libraries consisting of C++ files are not supported
32
33__hostprogs := $(sort $(hostprogs-y)$(hostprogs-m))
34
35# hostprogs-y := tools/build may have been specified. Retreive directory
36obj-dirs += $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
37obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs))))
38
39
40# C code
41# Executables compiled from a single .c file
42host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m)))
43
44# C executables linked based on several .o files
45host-cmulti := $(foreach m,$(__hostprogs),\
46 $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
47
48# Object (.o) files compiled from .c files
49host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
50
51# C++ code
52# C++ executables compiled from at least on .cc file
53# and zero or more .c files
54host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m)))
55
56# C++ Object (.o) files compiled from .cc files
57host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
58
59# Shared libaries (only .c supported)
60# Shared libraries (.so) - all .so files referenced in "xxx-objs"
61host-cshlib := $(sort $(filter %.so, $(host-cobjs)))
62# Remove .so files from "xxx-objs"
63host-cobjs := $(filter-out %.so,$(host-cobjs))
64
65#Object (.o) files used by the shared libaries
66host-cshobjs := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs))))
67
68__hostprogs := $(addprefix $(obj)/,$(__hostprogs))
69host-csingle := $(addprefix $(obj)/,$(host-csingle))
70host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
71host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
72host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
73host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
74host-cshlib := $(addprefix $(obj)/,$(host-cshlib))
75host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs))
76obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
77
78#####
79# Handle options to gcc. Support building with separate output directory
80
81_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o)
82_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o)
83
84ifeq ($(KBUILD_SRC),)
85__hostc_flags = $(_hostc_flags)
86__hostcxx_flags = $(_hostcxx_flags)
87else
88__hostc_flags = -I$(obj) $(call flags,_hostc_flags)
89__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags)
90endif
91
92hostc_flags = -Wp,-MD,$(depfile) $(__hostc_flags)
93hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags)
94
95#####
96# Compile programs on the host
97
98# Create executable from a single .c file
99# host-csingle -> Executable
100quiet_cmd_host-csingle = HOSTCC $@
101 cmd_host-csingle = $(HOSTCC) $(hostc_flags) $(HOST_LOADLIBES) -o $@ $<
102$(host-csingle): %: %.c FORCE
103 $(call if_changed_dep,host-csingle)
104
105# Link an executable based on list of .o files, all plain c
106# host-cmulti -> executable
107quiet_cmd_host-cmulti = HOSTLD $@
108 cmd_host-cmulti = $(HOSTCC) $(HOSTLDFLAGS) -o $@ \
109 $(addprefix $(obj)/,$($(@F)-objs)) \
110 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
111$(host-cmulti): %: $(host-cobjs) $(host-cshlib) FORCE
112 $(call if_changed,host-cmulti)
113
114# Create .o file from a single .c file
115# host-cobjs -> .o
116quiet_cmd_host-cobjs = HOSTCC $@
117 cmd_host-cobjs = $(HOSTCC) $(hostc_flags) -c -o $@ $<
118$(host-cobjs): %.o: %.c FORCE
119 $(call if_changed_dep,host-cobjs)
120
121# Link an executable based on list of .o files, a mixture of .c and .cc
122# host-cxxmulti -> executable
123quiet_cmd_host-cxxmulti = HOSTLD $@
124 cmd_host-cxxmulti = $(HOSTCXX) $(HOSTLDFLAGS) -o $@ \
125 $(foreach o,objs cxxobjs,\
126 $(addprefix $(obj)/,$($(@F)-$(o)))) \
127 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
128$(host-cxxmulti): %: $(host-cobjs) $(host-cxxobjs) $(host-cshlib) FORCE
129 $(call if_changed,host-cxxmulti)
130
131# Create .o file from a single .cc (C++) file
132quiet_cmd_host-cxxobjs = HOSTCXX $@
133 cmd_host-cxxobjs = $(HOSTCXX) $(hostcxx_flags) -c -o $@ $<
134$(host-cxxobjs): %.o: %.cc FORCE
135 $(call if_changed_dep,host-cxxobjs)
136
137# Compile .c file, create position independent .o file
138# host-cshobjs -> .o
139quiet_cmd_host-cshobjs = HOSTCC -fPIC $@
140 cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
141$(host-cshobjs): %.o: %.c FORCE
142 $(call if_changed_dep,host-cshobjs)
143
144# Link a shared library, based on position independent .o files
145# *.o -> .so shared library (host-cshlib)
146quiet_cmd_host-cshlib = HOSTLLD -shared $@
147 cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
148 $(addprefix $(obj)/,$($(@F:.so=-objs))) \
149 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
150$(host-cshlib): %: $(host-cshobjs) FORCE
151 $(call if_changed,host-cshlib)
152
153targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\
154 $(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs)
155
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
new file mode 100644
index 000000000000..7cf75cc4f849
--- /dev/null
+++ b/scripts/Makefile.lib
@@ -0,0 +1,267 @@
1# ===========================================================================
2# kbuild: Generic definitions
3# ===========================================================================
4
5# Standard vars
6
7comma := ,
8empty :=
9space := $(empty) $(empty)
10
11# Backward compatibility - to be removed...
12extra-y += $(EXTRA_TARGETS)
13# Figure out what we need to build from the various variables
14# ===========================================================================
15
16# When an object is listed to be built compiled-in and modular,
17# only build the compiled-in version
18
19obj-m := $(filter-out $(obj-y),$(obj-m))
20
21# Libraries are always collected in one lib file.
22# Filter out objects already built-in
23
24lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
25
26
27# Handle objects in subdirs
28# ---------------------------------------------------------------------------
29# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o
30# and add the directory to the list of dirs to descend into: $(subdir-y)
31# o if we encounter foo/ in $(obj-m), remove it from $(obj-m)
32# and add the directory to the list of dirs to descend into: $(subdir-m)
33
34__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
35subdir-y += $(__subdir-y)
36__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
37subdir-m += $(__subdir-m)
38obj-y := $(patsubst %/, %/built-in.o, $(obj-y))
39obj-m := $(filter-out %/, $(obj-m))
40
41# Subdirectories we need to descend into
42
43subdir-ym := $(sort $(subdir-y) $(subdir-m))
44
45# if $(foo-objs) exists, foo.o is a composite object
46multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
47multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
48multi-used := $(multi-used-y) $(multi-used-m)
49single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
50
51# Build list of the parts of our composite objects, our composite
52# objects depend on those (obviously)
53multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y)))
54multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)))
55multi-objs := $(multi-objs-y) $(multi-objs-m)
56
57# $(subdir-obj-y) is the list of objects in $(obj-y) which do not live
58# in the local directory
59subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
60
61# $(obj-dirs) is a list of directories that contain object files
62obj-dirs := $(dir $(multi-objs) $(subdir-obj-y))
63
64# Replace multi-part objects by their individual parts, look at local dir only
65real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y)
66real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
67
68# Add subdir path
69
70extra-y := $(addprefix $(obj)/,$(extra-y))
71always := $(addprefix $(obj)/,$(always))
72targets := $(addprefix $(obj)/,$(targets))
73obj-y := $(addprefix $(obj)/,$(obj-y))
74obj-m := $(addprefix $(obj)/,$(obj-m))
75lib-y := $(addprefix $(obj)/,$(lib-y))
76subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y))
77real-objs-y := $(addprefix $(obj)/,$(real-objs-y))
78real-objs-m := $(addprefix $(obj)/,$(real-objs-m))
79single-used-m := $(addprefix $(obj)/,$(single-used-m))
80multi-used-y := $(addprefix $(obj)/,$(multi-used-y))
81multi-used-m := $(addprefix $(obj)/,$(multi-used-m))
82multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y))
83multi-objs-m := $(addprefix $(obj)/,$(multi-objs-m))
84subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
85obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
86
87# The temporary file to save gcc -MD generated dependencies must not
88# contain a comma
89depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
90
91# These flags are needed for modversions and compiling, so we define them here
92# already
93# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will
94# end up in (or would, if it gets compiled in)
95# Note: It's possible that one object gets potentially linked into more
96# than one module. In that case KBUILD_MODNAME will be set to foo_bar,
97# where foo and bar are the name of the modules.
98basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
99modname_flags = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
100
101_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
102_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
103_cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F))
104
105# If building the kernel in a separate objtree expand all occurrences
106# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
107
108ifeq ($(KBUILD_SRC),)
109__c_flags = $(_c_flags)
110__a_flags = $(_a_flags)
111__cpp_flags = $(_cpp_flags)
112else
113
114# Prefix -I with $(srctree) if it is not an absolute path
115addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1)
116# Find all -I options and call addtree
117flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
118
119# -I$(obj) locates generated .h files
120# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files
121# and locates generated .h files
122# FIXME: Replace both with specific CFLAGS* statements in the makefiles
123__c_flags = $(call addtree,-I$(obj)) $(call flags,_c_flags)
124__a_flags = $(call flags,_a_flags)
125__cpp_flags = $(call flags,_cpp_flags)
126endif
127
128c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
129 $(__c_flags) $(modkern_cflags) \
130 $(basename_flags) $(modname_flags)
131
132a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
133 $(__a_flags) $(modkern_aflags)
134
135cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags)
136
137ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS)
138
139# Finds the multi-part object the current object will be linked into
140modname-multi = $(sort $(foreach m,$(multi-used),\
141 $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=))))
142
143# Shipped files
144# ===========================================================================
145
146quiet_cmd_shipped = SHIPPED $@
147cmd_shipped = cat $< > $@
148
149$(obj)/%:: $(src)/%_shipped
150 $(call cmd,shipped)
151
152# Commands useful for building a boot image
153# ===========================================================================
154#
155# Use as following:
156#
157# target: source(s) FORCE
158# $(if_changed,ld/objcopy/gzip)
159#
160# and add target to EXTRA_TARGETS so that we know we have to
161# read in the saved command line
162
163# Linking
164# ---------------------------------------------------------------------------
165
166quiet_cmd_ld = LD $@
167cmd_ld = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) \
168 $(filter-out FORCE,$^) -o $@
169
170# Objcopy
171# ---------------------------------------------------------------------------
172
173quiet_cmd_objcopy = OBJCOPY $@
174cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
175
176# Gzip
177# ---------------------------------------------------------------------------
178
179quiet_cmd_gzip = GZIP $@
180cmd_gzip = gzip -f -9 < $< > $@
181
182# ===========================================================================
183# Generic stuff
184# ===========================================================================
185
186ifneq ($(KBUILD_NOCMDDEP),1)
187# Check if both arguments has same arguments. Result in empty string if equal
188# User may override this check using make KBUILD_NOCMDDEP=1
189arg-check = $(strip $(filter-out $(1), $(2)) $(filter-out $(2), $(1)) )
190
191endif
192
193# echo command. Short version is $(quiet) equals quiet, otherwise full command
194echo-cmd = $(if $($(quiet)cmd_$(1)), \
195 echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';)
196
197# function to only execute the passed command if necessary
198# >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file
199# note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars
200#
201if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
202 @set -e; \
203 $(echo-cmd) \
204 $(cmd_$(1)); \
205 echo 'cmd_$@ := $(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
206
207
208# execute the command and also postprocess generated .d dependencies
209# file
210
211if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
212 $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
213 @set -e; \
214 $(echo-cmd) \
215 $(cmd_$(1)); \
216 scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
217 rm -f $(depfile); \
218 mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
219
220# Usage: $(call if_changed_rule,foo)
221# will check if $(cmd_foo) changed, or any of the prequisites changed,
222# and if so will execute $(rule_foo)
223
224if_changed_rule = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\
225 @set -e; \
226 $(rule_$(1)))
227
228# If quiet is set, only print short version of command
229
230cmd = @$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))' &&) $(cmd_$(1))
231
232# $(call descend,<dir>,<target>)
233# Recursively call a sub-make in <dir> with target <target>
234# Usage is deprecated, because make do not see this as an invocation of make.
235descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
236
237# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
238# Usage:
239# $(Q)$(MAKE) $(build)=dir
240build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
241
242# filechk is used to check if the content of a generated file is updated.
243# Sample usage:
244# define filechk_sample
245# echo $KERNELRELEASE
246# endef
247# version.h : Makefile
248# $(call filechk,sample)
249# The rule defined shall write to stdout the content of the new file.
250# The existing file will be compared with the new one.
251# - If no file exist it is created
252# - If the content differ the new file is used
253# - If they are equal no change, and no timestamp update
254
255define filechk
256 $(Q)set -e; \
257 echo ' CHK $@'; \
258 mkdir -p $(dir $@); \
259 $(filechk_$(1)) $(2) > $@.tmp; \
260 if [ -r $@ ] && cmp -s $@ $@.tmp; then \
261 rm -f $@.tmp; \
262 else \
263 echo ' UPD $@'; \
264 mv -f $@.tmp $@; \
265 fi
266endef
267
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
new file mode 100644
index 000000000000..85d6494e3c24
--- /dev/null
+++ b/scripts/Makefile.modinst
@@ -0,0 +1,29 @@
1# ==========================================================================
2# Installing modules
3# ==========================================================================
4
5.PHONY: __modinst
6__modinst:
7
8include scripts/Makefile.lib
9
10#
11
12__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
13modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
14
15.PHONY: $(modules)
16__modinst: $(modules)
17 @:
18
19quiet_cmd_modules_install = INSTALL $@
20 cmd_modules_install = mkdir -p $(2); cp $@ $(2)
21
22# Modules built outside the kernel source tree go into extra by default
23INSTALL_MOD_DIR ?= extra
24ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(KBUILD_EXTMOD),,$(@D))
25
26modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
27
28$(modules):
29 $(call cmd,modules_install,$(MODLIB)/$(modinst_dir))
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
new file mode 100644
index 000000000000..94b550e21be8
--- /dev/null
+++ b/scripts/Makefile.modpost
@@ -0,0 +1,110 @@
1# ===========================================================================
2# Module versions
3# ===========================================================================
4#
5# Stage one of module building created the following:
6# a) The individual .o files used for the module
7# b) A <module>.o file wich is the .o files above linked together
8# c) A <module>.mod file in $(MODVERDIR)/, listing the name of the
9# the preliminary <module>.o file, plus all .o files
10
11# Stage 2 is handled by this file and does the following
12# 1) Find all modules from the files listed in $(MODVERDIR)/
13# 2) modpost is then used to
14# 3) create one <module>.mod.c file pr. module
15# 4) create one Module.symvers file with CRC for all exported symbols
16# 5) compile all <module>.mod.c files
17# 6) final link of the module to a <module.ko> file
18
19# Step 3 is used to place certain information in the module's ELF
20# section, including information such as:
21# Version magic (see include/vermagic.h for full details)
22# - Kernel release
23# - SMP is CONFIG_SMP
24# - PREEMPT is CONFIG_PREEMPT
25# - GCC Version
26# Module info
27# - Module version (MODULE_VERSION)
28# - Module alias'es (MODULE_ALIAS)
29# - Module license (MODULE_LICENSE)
30# - See include/linux/module.h for more details
31
32# Step 4 is solely used to allow module versioning in external modules,
33# where the CRC of each module is retreived from the Module.symers file.
34
35.PHONY: _modpost
36_modpost: __modpost
37
38include .config
39include scripts/Makefile.lib
40
41symverfile := $(objtree)/Module.symvers
42
43# Step 1), find all modules listed in $(MODVERDIR)/
44__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
45modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
46
47_modpost: $(modules)
48
49
50# Step 2), invoke modpost
51# Includes step 3,4
52quiet_cmd_modpost = MODPOST
53 cmd_modpost = scripts/mod/modpost \
54 $(if $(CONFIG_MODVERSIONS),-m) \
55 $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \
56 $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \
57 $(filter-out FORCE,$^)
58
59.PHONY: __modpost
60__modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE
61 $(call cmd,modpost)
62
63# Declare generated files as targets for modpost
64$(symverfile): __modpost ;
65$(modules:.ko=.mod.c): __modpost ;
66
67
68# Step 5), compile all *.mod.c files
69
70# modname is set to make c_flags define KBUILD_MODNAME
71modname = $(*F)
72
73quiet_cmd_cc_o_c = CC $@
74 cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \
75 -c -o $@ $<
76
77$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
78 $(call if_changed_dep,cc_o_c)
79
80targets += $(modules:.ko=.mod.o)
81
82# Step 6), final link of the modules
83quiet_cmd_ld_ko_o = LD [M] $@
84 cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
85 $(filter-out FORCE,$^)
86
87$(modules): %.ko :%.o %.mod.o FORCE
88 $(call if_changed,ld_ko_o)
89
90targets += $(modules)
91
92
93# Add FORCE to the prequisites of a target to force it to be always rebuilt.
94# ---------------------------------------------------------------------------
95
96.PHONY: FORCE
97
98FORCE:
99
100# Read all saved command lines and dependencies for the $(targets) we
101# may be building above, using $(if_changed{,_dep}). As an
102# optimization, we don't need to read them if the target does not
103# exist, we will rebuild anyway in that case.
104
105targets := $(wildcard $(sort $(targets)))
106cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
107
108ifneq ($(cmd_files),)
109 include $(cmd_files)
110endif
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
new file mode 100644
index 000000000000..f22e94c3a2d1
--- /dev/null
+++ b/scripts/basic/Makefile
@@ -0,0 +1,18 @@
1###
2# Makefile.basic list the most basic programs used during the build process.
3# The programs listed herein is what is needed to do the basic stuff,
4# such as splitting .config and fix dependency file.
5# This initial step is needed to avoid files to be recompiled
6# when kernel configuration changes (which is what happens when
7# .config is included by main Makefile.
8# ---------------------------------------------------------------------------
9# fixdep: Used to generate dependency information during build process
10# split-include: Divide all config symbols up in a number of files in
11# include/config/...
12# docproc: Used in Documentation/docbook
13
14hostprogs-y := fixdep split-include docproc
15always := $(hostprogs-y)
16
17# fixdep is needed to compile other host programs
18$(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
new file mode 100644
index 000000000000..8ca7ecdb68fb
--- /dev/null
+++ b/scripts/basic/docproc.c
@@ -0,0 +1,398 @@
1/*
2 * docproc is a simple preprocessor for the template files
3 * used as placeholders for the kernel internal documentation.
4 * docproc is used for documentation-frontend and
5 * dependency-generator.
6 * The two usages have in common that they require
7 * some knowledge of the .tmpl syntax, therefore they
8 * are kept together.
9 *
10 * documentation-frontend
11 * Scans the template file and call kernel-doc for
12 * all occurrences of ![EIF]file
13 * Beforehand each referenced file are scanned for
14 * any exported sympols "EXPORT_SYMBOL()" statements.
15 * This is used to create proper -function and
16 * -nofunction arguments in calls to kernel-doc.
17 * Usage: docproc doc file.tmpl
18 *
19 * dependency-generator:
20 * Scans the template file and list all files
21 * referenced in a format recognized by make.
22 * Usage: docproc depend file.tmpl
23 * Writes dependency information to stdout
24 * in the following format:
25 * file.tmpl src.c src2.c
26 * The filenames are obtained from the following constructs:
27 * !Efilename
28 * !Ifilename
29 * !Dfilename
30 * !Ffilename
31 *
32 */
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <ctype.h>
38#include <unistd.h>
39#include <limits.h>
40#include <sys/types.h>
41#include <sys/wait.h>
42
43/* exitstatus is used to keep track of any failing calls to kernel-doc,
44 * but execution continues. */
45int exitstatus = 0;
46
47typedef void DFL(char *);
48DFL *defaultline;
49
50typedef void FILEONLY(char * file);
51FILEONLY *internalfunctions;
52FILEONLY *externalfunctions;
53FILEONLY *symbolsonly;
54
55typedef void FILELINE(char * file, signed char * line);
56FILELINE * singlefunctions;
57FILELINE * entity_system;
58
59#define MAXLINESZ 2048
60#define MAXFILES 250
61#define KERNELDOCPATH "scripts/"
62#define KERNELDOC "kernel-doc"
63#define DOCBOOK "-docbook"
64#define FUNCTION "-function"
65#define NOFUNCTION "-nofunction"
66
67void usage (void)
68{
69 fprintf(stderr, "Usage: docproc {doc|depend} file\n");
70 fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
71 fprintf(stderr, "doc: frontend when generating kernel documentation\n");
72 fprintf(stderr, "depend: generate list of files referenced within file\n");
73}
74
75/*
76 * Execute kernel-doc with parameters givin in svec
77 */
78void exec_kernel_doc(char **svec)
79{
80 pid_t pid;
81 int ret;
82 char real_filename[PATH_MAX + 1];
83 /* Make sure output generated so far are flushed */
84 fflush(stdout);
85 switch(pid=fork()) {
86 case -1:
87 perror("fork");
88 exit(1);
89 case 0:
90 memset(real_filename, 0, sizeof(real_filename));
91 strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
92 strncat(real_filename, KERNELDOCPATH KERNELDOC,
93 PATH_MAX - strlen(real_filename));
94 execvp(real_filename, svec);
95 fprintf(stderr, "exec ");
96 perror(real_filename);
97 exit(1);
98 default:
99 waitpid(pid, &ret ,0);
100 }
101 if (WIFEXITED(ret))
102 exitstatus |= WEXITSTATUS(ret);
103 else
104 exitstatus = 0xff;
105}
106
107/* Types used to create list of all exported symbols in a number of files */
108struct symbols
109{
110 char *name;
111};
112
113struct symfile
114{
115 char *filename;
116 struct symbols *symbollist;
117 int symbolcnt;
118};
119
120struct symfile symfilelist[MAXFILES];
121int symfilecnt = 0;
122
123void add_new_symbol(struct symfile *sym, char * symname)
124{
125 sym->symbollist =
126 realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *));
127 sym->symbollist[sym->symbolcnt++].name = strdup(symname);
128}
129
130/* Add a filename to the list */
131struct symfile * add_new_file(char * filename)
132{
133 symfilelist[symfilecnt++].filename = strdup(filename);
134 return &symfilelist[symfilecnt - 1];
135}
136/* Check if file already are present in the list */
137struct symfile * filename_exist(char * filename)
138{
139 int i;
140 for (i=0; i < symfilecnt; i++)
141 if (strcmp(symfilelist[i].filename, filename) == 0)
142 return &symfilelist[i];
143 return NULL;
144}
145
146/*
147 * List all files referenced within the template file.
148 * Files are separated by tabs.
149 */
150void adddep(char * file) { printf("\t%s", file); }
151void adddep2(char * file, signed char * line) { line = line; adddep(file); }
152void noaction(char * line) { line = line; }
153void noaction2(char * file, signed char * line) { file = file; line = line; }
154
155/* Echo the line without further action */
156void printline(char * line) { printf("%s", line); }
157
158/*
159 * Find all symbols exported with EXPORT_SYMBOL and EXPORT_SYMBOL_GPL
160 * in filename.
161 * All symbols located are stored in symfilelist.
162 */
163void find_export_symbols(char * filename)
164{
165 FILE * fp;
166 struct symfile *sym;
167 char line[MAXLINESZ];
168 if (filename_exist(filename) == NULL) {
169 char real_filename[PATH_MAX + 1];
170 memset(real_filename, 0, sizeof(real_filename));
171 strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
172 strncat(real_filename, filename,
173 PATH_MAX - strlen(real_filename));
174 sym = add_new_file(filename);
175 fp = fopen(real_filename, "r");
176 if (fp == NULL)
177 {
178 fprintf(stderr, "docproc: ");
179 perror(real_filename);
180 }
181 while(fgets(line, MAXLINESZ, fp)) {
182 signed char *p;
183 signed char *e;
184 if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) ||
185 ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) {
186 /* Skip EXPORT_SYMBOL{_GPL} */
187 while (isalnum(*p) || *p == '_')
188 p++;
189 /* Remove paranteses and additional ws */
190 while (isspace(*p))
191 p++;
192 if (*p != '(')
193 continue; /* Syntax error? */
194 else
195 p++;
196 while (isspace(*p))
197 p++;
198 e = p;
199 while (isalnum(*e) || *e == '_')
200 e++;
201 *e = '\0';
202 add_new_symbol(sym, p);
203 }
204 }
205 fclose(fp);
206 }
207}
208
209/*
210 * Document all external or internal functions in a file.
211 * Call kernel-doc with following parameters:
212 * kernel-doc -docbook -nofunction function_name1 filename
213 * function names are obtained from all the the src files
214 * by find_export_symbols.
215 * intfunc uses -nofunction
216 * extfunc uses -function
217 */
218void docfunctions(char * filename, char * type)
219{
220 int i,j;
221 int symcnt = 0;
222 int idx = 0;
223 char **vec;
224
225 for (i=0; i <= symfilecnt; i++)
226 symcnt += symfilelist[i].symbolcnt;
227 vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*));
228 if (vec == NULL) {
229 perror("docproc: ");
230 exit(1);
231 }
232 vec[idx++] = KERNELDOC;
233 vec[idx++] = DOCBOOK;
234 for (i=0; i < symfilecnt; i++) {
235 struct symfile * sym = &symfilelist[i];
236 for (j=0; j < sym->symbolcnt; j++) {
237 vec[idx++] = type;
238 vec[idx++] = sym->symbollist[j].name;
239 }
240 }
241 vec[idx++] = filename;
242 vec[idx] = NULL;
243 printf("<!-- %s -->\n", filename);
244 exec_kernel_doc(vec);
245 fflush(stdout);
246 free(vec);
247}
248void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); }
249void extfunc(char * filename) { docfunctions(filename, FUNCTION); }
250
251/*
252 * Document spåecific function(s) in a file.
253 * Call kernel-doc with the following parameters:
254 * kernel-doc -docbook -function function1 [-function function2]
255 */
256void singfunc(char * filename, signed char * line)
257{
258 char *vec[200]; /* Enough for specific functions */
259 int i, idx = 0;
260 int startofsym = 1;
261 vec[idx++] = KERNELDOC;
262 vec[idx++] = DOCBOOK;
263
264 /* Split line up in individual parameters preceeded by FUNCTION */
265 for (i=0; line[i]; i++) {
266 if (isspace(line[i])) {
267 line[i] = '\0';
268 startofsym = 1;
269 continue;
270 }
271 if (startofsym) {
272 startofsym = 0;
273 vec[idx++] = FUNCTION;
274 vec[idx++] = &line[i];
275 }
276 }
277 vec[idx++] = filename;
278 vec[idx] = NULL;
279 exec_kernel_doc(vec);
280}
281
282/*
283 * Parse file, calling action specific functions for:
284 * 1) Lines containing !E
285 * 2) Lines containing !I
286 * 3) Lines containing !D
287 * 4) Lines containing !F
288 * 5) Default lines - lines not matching the above
289 */
290void parse_file(FILE *infile)
291{
292 char line[MAXLINESZ];
293 signed char * s;
294 while(fgets(line, MAXLINESZ, infile)) {
295 if (line[0] == '!') {
296 s = line + 2;
297 switch (line[1]) {
298 case 'E':
299 while (*s && !isspace(*s)) s++;
300 *s = '\0';
301 externalfunctions(line+2);
302 break;
303 case 'I':
304 while (*s && !isspace(*s)) s++;
305 *s = '\0';
306 internalfunctions(line+2);
307 break;
308 case 'D':
309 while (*s && !isspace(*s)) s++;
310 *s = '\0';
311 symbolsonly(line+2);
312 break;
313 case 'F':
314 /* filename */
315 while (*s && !isspace(*s)) s++;
316 *s++ = '\0';
317 /* function names */
318 while (isspace(*s))
319 s++;
320 singlefunctions(line +2, s);
321 break;
322 default:
323 defaultline(line);
324 }
325 }
326 else {
327 defaultline(line);
328 }
329 }
330 fflush(stdout);
331}
332
333
334int main(int argc, char *argv[])
335{
336 FILE * infile;
337 if (argc != 3) {
338 usage();
339 exit(1);
340 }
341 /* Open file, exit on error */
342 infile = fopen(argv[2], "r");
343 if (infile == NULL) {
344 fprintf(stderr, "docproc: ");
345 perror(argv[2]);
346 exit(2);
347 }
348
349 if (strcmp("doc", argv[1]) == 0)
350 {
351 /* Need to do this in two passes.
352 * First pass is used to collect all symbols exported
353 * in the various files.
354 * Second pass generate the documentation.
355 * This is required because function are declared
356 * and exported in different files :-((
357 */
358 /* Collect symbols */
359 defaultline = noaction;
360 internalfunctions = find_export_symbols;
361 externalfunctions = find_export_symbols;
362 symbolsonly = find_export_symbols;
363 singlefunctions = noaction2;
364 parse_file(infile);
365
366 /* Rewind to start from beginning of file again */
367 fseek(infile, 0, SEEK_SET);
368 defaultline = printline;
369 internalfunctions = intfunc;
370 externalfunctions = extfunc;
371 symbolsonly = printline;
372 singlefunctions = singfunc;
373
374 parse_file(infile);
375 }
376 else if (strcmp("depend", argv[1]) == 0)
377 {
378 /* Create first part of dependency chain
379 * file.tmpl */
380 printf("%s\t", argv[2]);
381 defaultline = noaction;
382 internalfunctions = adddep;
383 externalfunctions = adddep;
384 symbolsonly = adddep;
385 singlefunctions = adddep2;
386 parse_file(infile);
387 printf("\n");
388 }
389 else
390 {
391 fprintf(stderr, "Unknown option: %s\n", argv[1]);
392 exit(1);
393 }
394 fclose(infile);
395 fflush(stdout);
396 return exitstatus;
397}
398
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
new file mode 100644
index 000000000000..7f42c5d8a5a2
--- /dev/null
+++ b/scripts/basic/fixdep.c
@@ -0,0 +1,390 @@
1/*
2 * "Optimize" a list of dependencies as spit out by gcc -MD
3 * for the kernel build
4 * ===========================================================================
5 *
6 * Author Kai Germaschewski
7 * Copyright 2002 by Kai Germaschewski <kai.germaschewski@gmx.de>
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 *
12 *
13 * Introduction:
14 *
15 * gcc produces a very nice and correct list of dependencies which
16 * tells make when to remake a file.
17 *
18 * To use this list as-is however has the drawback that virtually
19 * every file in the kernel includes <linux/config.h> which then again
20 * includes <linux/autoconf.h>
21 *
22 * If the user re-runs make *config, linux/autoconf.h will be
23 * regenerated. make notices that and will rebuild every file which
24 * includes autoconf.h, i.e. basically all files. This is extremely
25 * annoying if the user just changed CONFIG_HIS_DRIVER from n to m.
26 *
27 * So we play the same trick that "mkdep" played before. We replace
28 * the dependency on linux/autoconf.h by a dependency on every config
29 * option which is mentioned in any of the listed prequisites.
30 *
31 * To be exact, split-include populates a tree in include/config/,
32 * e.g. include/config/his/driver.h, which contains the #define/#undef
33 * for the CONFIG_HIS_DRIVER option.
34 *
35 * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
36 * which depend on "include/linux/config/his/driver.h" will be rebuilt,
37 * so most likely only his driver ;-)
38 *
39 * The idea above dates, by the way, back to Michael E Chastain, AFAIK.
40 *
41 * So to get dependencies right, there are two issues:
42 * o if any of the files the compiler read changed, we need to rebuild
43 * o if the command line given to the compile the file changed, we
44 * better rebuild as well.
45 *
46 * The former is handled by using the -MD output, the later by saving
47 * the command line used to compile the old object and comparing it
48 * to the one we would now use.
49 *
50 * Again, also this idea is pretty old and has been discussed on
51 * kbuild-devel a long time ago. I don't have a sensibly working
52 * internet connection right now, so I rather don't mention names
53 * without double checking.
54 *
55 * This code here has been based partially based on mkdep.c, which
56 * says the following about its history:
57 *
58 * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
59 * This is a C version of syncdep.pl by Werner Almesberger.
60 *
61 *
62 * It is invoked as
63 *
64 * fixdep <depfile> <target> <cmdline>
65 *
66 * and will read the dependency file <depfile>
67 *
68 * The transformed dependency snipped is written to stdout.
69 *
70 * It first generates a line
71 *
72 * cmd_<target> = <cmdline>
73 *
74 * and then basically copies the .<target>.d file to stdout, in the
75 * process filtering out the dependency on linux/autoconf.h and adding
76 * dependencies on include/config/my/option.h for every
77 * CONFIG_MY_OPTION encountered in any of the prequisites.
78 *
79 * It will also filter out all the dependencies on *.ver. We need
80 * to make sure that the generated version checksum are globally up
81 * to date before even starting the recursive build, so it's too late
82 * at this point anyway.
83 *
84 * The algorithm to grep for "CONFIG_..." is bit unusual, but should
85 * be fast ;-) We don't even try to really parse the header files, but
86 * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
87 * be picked up as well. It's not a problem with respect to
88 * correctness, since that can only give too many dependencies, thus
89 * we cannot miss a rebuild. Since people tend to not mention totally
90 * unrelated CONFIG_ options all over the place, it's not an
91 * efficiency problem either.
92 *
93 * (Note: it'd be easy to port over the complete mkdep state machine,
94 * but I don't think the added complexity is worth it)
95 */
96/*
97 * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
98 * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
99 * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
100 * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
101 * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
102 * those files will have correct dependencies.
103 */
104
105#include <sys/types.h>
106#include <sys/stat.h>
107#include <sys/mman.h>
108#include <unistd.h>
109#include <fcntl.h>
110#include <string.h>
111#include <stdlib.h>
112#include <stdio.h>
113#include <limits.h>
114#include <ctype.h>
115#include <arpa/inet.h>
116
117#define INT_CONF ntohl(0x434f4e46)
118#define INT_ONFI ntohl(0x4f4e4649)
119#define INT_NFIG ntohl(0x4e464947)
120#define INT_FIG_ ntohl(0x4649475f)
121
122char *target;
123char *depfile;
124char *cmdline;
125
126void usage(void)
127
128{
129 fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
130 exit(1);
131}
132
133void print_cmdline(void)
134{
135 printf("cmd_%s := %s\n\n", target, cmdline);
136}
137
138char * str_config = NULL;
139int size_config = 0;
140int len_config = 0;
141
142/*
143 * Grow the configuration string to a desired length.
144 * Usually the first growth is plenty.
145 */
146void grow_config(int len)
147{
148 while (len_config + len > size_config) {
149 if (size_config == 0)
150 size_config = 2048;
151 str_config = realloc(str_config, size_config *= 2);
152 if (str_config == NULL)
153 { perror("fixdep:malloc"); exit(1); }
154 }
155}
156
157
158
159/*
160 * Lookup a value in the configuration string.
161 */
162int is_defined_config(const char * name, int len)
163{
164 const char * pconfig;
165 const char * plast = str_config + len_config - len;
166 for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
167 if (pconfig[ -1] == '\n'
168 && pconfig[len] == '\n'
169 && !memcmp(pconfig, name, len))
170 return 1;
171 }
172 return 0;
173}
174
175/*
176 * Add a new value to the configuration string.
177 */
178void define_config(const char * name, int len)
179{
180 grow_config(len + 1);
181
182 memcpy(str_config+len_config, name, len);
183 len_config += len;
184 str_config[len_config++] = '\n';
185}
186
187/*
188 * Clear the set of configuration strings.
189 */
190void clear_config(void)
191{
192 len_config = 0;
193 define_config("", 0);
194}
195
196/*
197 * Record the use of a CONFIG_* word.
198 */
199void use_config(char *m, int slen)
200{
201 char s[PATH_MAX];
202 char *p;
203
204 if (is_defined_config(m, slen))
205 return;
206
207 define_config(m, slen);
208
209 memcpy(s, m, slen); s[slen] = 0;
210
211 for (p = s; p < s + slen; p++) {
212 if (*p == '_')
213 *p = '/';
214 else
215 *p = tolower((unsigned char)*p);
216 }
217 printf(" $(wildcard include/config/%s.h) \\\n", s);
218}
219
220void parse_config_file(signed char *map, size_t len)
221{
222 int *end = (int *) (map + len);
223 /* start at +1, so that p can never be < map */
224 int *m = (int *) map + 1;
225 signed char *p, *q;
226
227 for (; m < end; m++) {
228 if (*m == INT_CONF) { p = (signed char *) m ; goto conf; }
229 if (*m == INT_ONFI) { p = (signed char *) m-1; goto conf; }
230 if (*m == INT_NFIG) { p = (signed char *) m-2; goto conf; }
231 if (*m == INT_FIG_) { p = (signed char *) m-3; goto conf; }
232 continue;
233 conf:
234 if (p > map + len - 7)
235 continue;
236 if (memcmp(p, "CONFIG_", 7))
237 continue;
238 for (q = p + 7; q < map + len; q++) {
239 if (!(isalnum(*q) || *q == '_'))
240 goto found;
241 }
242 continue;
243
244 found:
245 use_config(p+7, q-p-7);
246 }
247}
248
249/* test is s ends in sub */
250int strrcmp(char *s, char *sub)
251{
252 int slen = strlen(s);
253 int sublen = strlen(sub);
254
255 if (sublen > slen)
256 return 1;
257
258 return memcmp(s + slen - sublen, sub, sublen);
259}
260
261void do_config_file(char *filename)
262{
263 struct stat st;
264 int fd;
265 void *map;
266
267 fd = open(filename, O_RDONLY);
268 if (fd < 0) {
269 fprintf(stderr, "fixdep: ");
270 perror(filename);
271 exit(2);
272 }
273 fstat(fd, &st);
274 if (st.st_size == 0) {
275 close(fd);
276 return;
277 }
278 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
279 if ((long) map == -1) {
280 perror("fixdep: mmap");
281 close(fd);
282 return;
283 }
284
285 parse_config_file(map, st.st_size);
286
287 munmap(map, st.st_size);
288
289 close(fd);
290}
291
292void parse_dep_file(void *map, size_t len)
293{
294 signed char *m = map;
295 signed char *end = m + len;
296 signed char *p;
297 char s[PATH_MAX];
298
299 p = strchr(m, ':');
300 if (!p) {
301 fprintf(stderr, "fixdep: parse error\n");
302 exit(1);
303 }
304 memcpy(s, m, p-m); s[p-m] = 0;
305 printf("deps_%s := \\\n", target);
306 m = p+1;
307
308 clear_config();
309
310 while (m < end) {
311 while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
312 m++;
313 p = m;
314 while (p < end && *p != ' ') p++;
315 if (p == end) {
316 do p--; while (!isalnum(*p));
317 p++;
318 }
319 memcpy(s, m, p-m); s[p-m] = 0;
320 if (strrcmp(s, "include/linux/autoconf.h") &&
321 strrcmp(s, "arch/um/include/uml-config.h") &&
322 strrcmp(s, ".ver")) {
323 printf(" %s \\\n", s);
324 do_config_file(s);
325 }
326 m = p + 1;
327 }
328 printf("\n%s: $(deps_%s)\n\n", target, target);
329 printf("$(deps_%s):\n", target);
330}
331
332void print_deps(void)
333{
334 struct stat st;
335 int fd;
336 void *map;
337
338 fd = open(depfile, O_RDONLY);
339 if (fd < 0) {
340 fprintf(stderr, "fixdep: ");
341 perror(depfile);
342 exit(2);
343 }
344 fstat(fd, &st);
345 if (st.st_size == 0) {
346 fprintf(stderr,"fixdep: %s is empty\n",depfile);
347 close(fd);
348 return;
349 }
350 map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
351 if ((long) map == -1) {
352 perror("fixdep: mmap");
353 close(fd);
354 return;
355 }
356
357 parse_dep_file(map, st.st_size);
358
359 munmap(map, st.st_size);
360
361 close(fd);
362}
363
364void traps(void)
365{
366 static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
367
368 if (*(int *)test != INT_CONF) {
369 fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
370 *(int *)test);
371 exit(2);
372 }
373}
374
375int main(int argc, char *argv[])
376{
377 traps();
378
379 if (argc != 4)
380 usage();
381
382 depfile = argv[1];
383 target = argv[2];
384 cmdline = argv[3];
385
386 print_cmdline();
387 print_deps();
388
389 return 0;
390}
diff --git a/scripts/basic/split-include.c b/scripts/basic/split-include.c
new file mode 100644
index 000000000000..60fc4d8ebaa9
--- /dev/null
+++ b/scripts/basic/split-include.c
@@ -0,0 +1,226 @@
1/*
2 * split-include.c
3 *
4 * Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
5 * This is a C version of syncdep.pl by Werner Almesberger.
6 *
7 * This program takes autoconf.h as input and outputs a directory full
8 * of one-line include files, merging onto the old values.
9 *
10 * Think of the configuration options as key-value pairs. Then there
11 * are five cases:
12 *
13 * key old value new value action
14 *
15 * KEY-1 VALUE-1 VALUE-1 leave file alone
16 * KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file
17 * KEY-3 - VALUE-3 write VALUE-3 into file
18 * KEY-4 VALUE-4 - write an empty file
19 * KEY-5 (empty) - leave old empty file alone
20 */
21
22#include <sys/stat.h>
23#include <sys/types.h>
24
25#include <ctype.h>
26#include <errno.h>
27#include <fcntl.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32
33#define ERROR_EXIT(strExit) \
34 { \
35 const int errnoSave = errno; \
36 fprintf(stderr, "%s: ", str_my_name); \
37 errno = errnoSave; \
38 perror((strExit)); \
39 exit(1); \
40 }
41
42
43
44int main(int argc, const char * argv [])
45{
46 const char * str_my_name;
47 const char * str_file_autoconf;
48 const char * str_dir_config;
49
50 FILE * fp_config;
51 FILE * fp_target;
52 FILE * fp_find;
53
54 int buffer_size;
55
56 char * line;
57 char * old_line;
58 char * list_target;
59 char * ptarget;
60
61 struct stat stat_buf;
62
63 /* Check arg count. */
64 if (argc != 3)
65 {
66 fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]);
67 exit(1);
68 }
69
70 str_my_name = argv[0];
71 str_file_autoconf = argv[1];
72 str_dir_config = argv[2];
73
74 /* Find a buffer size. */
75 if (stat(str_file_autoconf, &stat_buf) != 0)
76 ERROR_EXIT(str_file_autoconf);
77 buffer_size = 2 * stat_buf.st_size + 4096;
78
79 /* Allocate buffers. */
80 if ( (line = malloc(buffer_size)) == NULL
81 || (old_line = malloc(buffer_size)) == NULL
82 || (list_target = malloc(buffer_size)) == NULL )
83 ERROR_EXIT(str_file_autoconf);
84
85 /* Open autoconfig file. */
86 if ((fp_config = fopen(str_file_autoconf, "r")) == NULL)
87 ERROR_EXIT(str_file_autoconf);
88
89 /* Make output directory if needed. */
90 if (stat(str_dir_config, &stat_buf) != 0)
91 {
92 if (mkdir(str_dir_config, 0755) != 0)
93 ERROR_EXIT(str_dir_config);
94 }
95
96 /* Change to output directory. */
97 if (chdir(str_dir_config) != 0)
98 ERROR_EXIT(str_dir_config);
99
100 /* Put initial separator into target list. */
101 ptarget = list_target;
102 *ptarget++ = '\n';
103
104 /* Read config lines. */
105 while (fgets(line, buffer_size, fp_config))
106 {
107 const signed char * str_config;
108 int is_same;
109 int itarget;
110
111 if (line[0] != '#')
112 continue;
113 if ((str_config = strstr(line, "CONFIG_")) == NULL)
114 continue;
115
116 /* Make the output file name. */
117 str_config += sizeof("CONFIG_") - 1;
118 for (itarget = 0; !isspace(str_config[itarget]); itarget++)
119 {
120 int c = (unsigned char) str_config[itarget];
121 if (isupper(c)) c = tolower(c);
122 if (c == '_') c = '/';
123 ptarget[itarget] = c;
124 }
125 ptarget[itarget++] = '.';
126 ptarget[itarget++] = 'h';
127 ptarget[itarget++] = '\0';
128
129 /* Check for existing file. */
130 is_same = 0;
131 if ((fp_target = fopen(ptarget, "r")) != NULL)
132 {
133 fgets(old_line, buffer_size, fp_target);
134 if (fclose(fp_target) != 0)
135 ERROR_EXIT(ptarget);
136 if (!strcmp(line, old_line))
137 is_same = 1;
138 }
139
140 if (!is_same)
141 {
142 /* Auto-create directories. */
143 int islash;
144 for (islash = 0; islash < itarget; islash++)
145 {
146 if (ptarget[islash] == '/')
147 {
148 ptarget[islash] = '\0';
149 if (stat(ptarget, &stat_buf) != 0
150 && mkdir(ptarget, 0755) != 0)
151 ERROR_EXIT( ptarget );
152 ptarget[islash] = '/';
153 }
154 }
155
156 /* Write the file. */
157 if ((fp_target = fopen(ptarget, "w" )) == NULL)
158 ERROR_EXIT(ptarget);
159 fputs(line, fp_target);
160 if (ferror(fp_target) || fclose(fp_target) != 0)
161 ERROR_EXIT(ptarget);
162 }
163
164 /* Update target list */
165 ptarget += itarget;
166 *(ptarget-1) = '\n';
167 }
168
169 /*
170 * Close autoconfig file.
171 * Terminate the target list.
172 */
173 if (fclose(fp_config) != 0)
174 ERROR_EXIT(str_file_autoconf);
175 *ptarget = '\0';
176
177 /*
178 * Fix up existing files which have no new value.
179 * This is Case 4 and Case 5.
180 *
181 * I re-read the tree and filter it against list_target.
182 * This is crude. But it avoids data copies. Also, list_target
183 * is compact and contiguous, so it easily fits into cache.
184 *
185 * Notice that list_target contains strings separated by \n,
186 * with a \n before the first string and after the last.
187 * fgets gives the incoming names a terminating \n.
188 * So by having an initial \n, strstr will find exact matches.
189 */
190
191 fp_find = popen("find * -type f -name \"*.h\" -print", "r");
192 if (fp_find == 0)
193 ERROR_EXIT( "find" );
194
195 line[0] = '\n';
196 while (fgets(line+1, buffer_size, fp_find))
197 {
198 if (strstr(list_target, line) == NULL)
199 {
200 /*
201 * This is an old file with no CONFIG_* flag in autoconf.h.
202 */
203
204 /* First strip the \n. */
205 line[strlen(line)-1] = '\0';
206
207 /* Grab size. */
208 if (stat(line+1, &stat_buf) != 0)
209 ERROR_EXIT(line);
210
211 /* If file is not empty, make it empty and give it a fresh date. */
212 if (stat_buf.st_size != 0)
213 {
214 if ((fp_target = fopen(line+1, "w")) == NULL)
215 ERROR_EXIT(line);
216 if (fclose(fp_target) != 0)
217 ERROR_EXIT(line);
218 }
219 }
220 }
221
222 if (pclose(fp_find) != 0)
223 ERROR_EXIT("find");
224
225 return 0;
226}
diff --git a/scripts/bin2c.c b/scripts/bin2c.c
new file mode 100644
index 000000000000..96dd2bcbb407
--- /dev/null
+++ b/scripts/bin2c.c
@@ -0,0 +1,36 @@
1/*
2 * Unloved program to convert a binary on stdin to a C include on stdout
3 *
4 * Jan 1999 Matt Mackall <mpm@selenic.com>
5 *
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
8 */
9
10#include <stdio.h>
11
12int main(int argc, char *argv[])
13{
14 int ch, total=0;
15
16 if (argc > 1)
17 printf("const char %s[] %s=\n",
18 argv[1], argc > 2 ? argv[2] : "");
19
20 do {
21 printf("\t\"");
22 while ((ch = getchar()) != EOF)
23 {
24 total++;
25 printf("\\x%02x",ch);
26 if (total % 16 == 0)
27 break;
28 }
29 printf("\"\n");
30 } while (ch != EOF);
31
32 if (argc > 1)
33 printf("\t;\n\nconst int %s_size = %d;\n", argv[1], total);
34
35 return 0;
36}
diff --git a/scripts/binoffset.c b/scripts/binoffset.c
new file mode 100644
index 000000000000..591309d85518
--- /dev/null
+++ b/scripts/binoffset.c
@@ -0,0 +1,163 @@
1/***************************************************************************
2 * binoffset.c
3 * (C) 2002 Randy Dunlap <rddunlap@osdl.org>
4
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19# binoffset.c:
20# - searches a (binary) file for a specified (binary) pattern
21# - returns the offset of the located pattern or ~0 if not found
22# - exits with exit status 0 normally or non-0 if pattern is not found
23# or any other error occurs.
24
25****************************************************************/
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <errno.h>
31#include <unistd.h>
32#include <fcntl.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <sys/mman.h>
36
37#define VERSION "0.1"
38#define BUF_SIZE (16 * 1024)
39#define PAT_SIZE 100
40
41char *progname;
42char *inputname;
43int inputfd;
44unsigned int bix; /* buf index */
45unsigned char patterns [PAT_SIZE] = {0}; /* byte-sized pattern array */
46int pat_len; /* actual number of pattern bytes */
47unsigned char *madr; /* mmap address */
48size_t filesize;
49int num_matches = 0;
50off_t firstloc = 0;
51
52void usage (void)
53{
54 fprintf (stderr, "%s ver. %s\n", progname, VERSION);
55 fprintf (stderr, "usage: %s filename pattern_bytes\n",
56 progname);
57 fprintf (stderr, " [prints location of pattern_bytes in file]\n");
58 exit (1);
59}
60
61void get_pattern (int pat_count, char *pats [])
62{
63 int ix, err, tmp;
64
65#ifdef DEBUG
66 fprintf (stderr,"get_pattern: count = %d\n", pat_count);
67 for (ix = 0; ix < pat_count; ix++)
68 fprintf (stderr, " pat # %d: [%s]\n", ix, pats[ix]);
69#endif
70
71 for (ix = 0; ix < pat_count; ix++) {
72 tmp = 0;
73 err = sscanf (pats[ix], "%5i", &tmp);
74 if (err != 1 || tmp > 0xff) {
75 fprintf (stderr, "pattern or value error in pattern # %d [%s]\n",
76 ix, pats[ix]);
77 usage ();
78 }
79 patterns [ix] = tmp;
80 }
81 pat_len = pat_count;
82}
83
84void search_pattern (void)
85{
86 for (bix = 0; bix < filesize; bix++) {
87 if (madr[bix] == patterns[0]) {
88 if (memcmp (&madr[bix], patterns, pat_len) == 0) {
89 if (num_matches == 0)
90 firstloc = bix;
91 num_matches++;
92 }
93 }
94 }
95}
96
97#ifdef NOTDEF
98size_t get_filesize (int fd)
99{
100 off_t end_off = lseek (fd, 0, SEEK_END);
101 lseek (fd, 0, SEEK_SET);
102 return (size_t) end_off;
103}
104#endif
105
106size_t get_filesize (int fd)
107{
108 int err;
109 struct stat stat;
110
111 err = fstat (fd, &stat);
112 fprintf (stderr, "filesize: %ld\n", err < 0 ? (long)err : stat.st_size);
113 if (err < 0)
114 return err;
115 return (size_t) stat.st_size;
116}
117
118int main (int argc, char *argv [])
119{
120 progname = argv[0];
121
122 if (argc < 3)
123 usage ();
124
125 get_pattern (argc - 2, argv + 2);
126
127 inputname = argv[1];
128
129 inputfd = open (inputname, O_RDONLY);
130 if (inputfd == -1) {
131 fprintf (stderr, "%s: cannot open '%s'\n",
132 progname, inputname);
133 exit (3);
134 }
135
136 filesize = get_filesize (inputfd);
137
138 madr = mmap (0, filesize, PROT_READ, MAP_PRIVATE, inputfd, 0);
139 if (madr == MAP_FAILED) {
140 fprintf (stderr, "mmap error = %d\n", errno);
141 close (inputfd);
142 exit (4);
143 }
144
145 search_pattern ();
146
147 if (munmap (madr, filesize))
148 fprintf (stderr, "munmap error = %d\n", errno);
149
150 if (close (inputfd))
151 fprintf (stderr, "%s: error %d closing '%s'\n",
152 progname, errno, inputname);
153
154 fprintf (stderr, "number of pattern matches = %d\n", num_matches);
155 if (num_matches == 0)
156 firstloc = ~0;
157 printf ("%ld\n", firstloc);
158 fprintf (stderr, "%ld\n", firstloc);
159
160 exit (num_matches ? 0 : 2);
161}
162
163/* end binoffset.c */
diff --git a/scripts/checkconfig.pl b/scripts/checkconfig.pl
new file mode 100755
index 000000000000..ca1f231b15a6
--- /dev/null
+++ b/scripts/checkconfig.pl
@@ -0,0 +1,65 @@
1#! /usr/bin/perl
2#
3# checkconfig: find uses of CONFIG_* names without matching definitions.
4# Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>.
5
6use integer;
7
8$| = 1;
9
10foreach $file (@ARGV)
11{
12 # Open this file.
13 open(FILE, $file) || die "Can't open $file: $!\n";
14
15 # Initialize variables.
16 my $fInComment = 0;
17 my $fInString = 0;
18 my $fUseConfig = 0;
19 my $iLinuxConfig = 0;
20 my %configList = ();
21
22 LINE: while ( <FILE> )
23 {
24 # Strip comments.
25 $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
26 m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
27
28 # Pick up definitions.
29 if ( m/^\s*#/o )
30 {
31 $iLinuxConfig = $. if m/^\s*#\s*include\s*"linux\/config\.h"/o;
32 $configList{uc $1} = 1 if m/^\s*#\s*include\s*"config\/(\S*)\.h"/o;
33 }
34
35 # Strip strings.
36 $fInString && (s+^.*?"+ +o ? ($fInString = 0) : next);
37 m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1)));
38
39 # Pick up definitions.
40 if ( m/^\s*#/o )
41 {
42 $iLinuxConfig = $. if m/^\s*#\s*include\s*<linux\/config\.h>/o;
43 $configList{uc $1} = 1 if m/^\s*#\s*include\s*<config\/(\S*)\.h>/o;
44 $configList{$1} = 1 if m/^\s*#\s*define\s+CONFIG_(\w*)/o;
45 $configList{$1} = 1 if m/^\s*#\s*undef\s+CONFIG_(\w*)/o;
46 }
47
48 # Look for usages.
49 next unless m/CONFIG_/o;
50 WORD: while ( m/\bCONFIG_(\w+)/og )
51 {
52 $fUseConfig = 1;
53 last LINE if $iLinuxConfig;
54 next WORD if exists $configList{$1};
55 print "$file: $.: need CONFIG_$1.\n";
56 $configList{$1} = 0;
57 }
58 }
59
60 # Report superfluous includes.
61 if ( $iLinuxConfig && ! $fUseConfig )
62 { print "$file: $iLinuxConfig: linux/config.h not needed.\n"; }
63
64 close(FILE);
65}
diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl
new file mode 100755
index 000000000000..8e6b716c191c
--- /dev/null
+++ b/scripts/checkincludes.pl
@@ -0,0 +1,24 @@
1#!/usr/bin/perl
2#
3# checkincludes: Find files included more than once in (other) files.
4# Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>.
5
6foreach $file (@ARGV) {
7 open(FILE, $file) or die "Cannot open $file: $!.\n";
8
9 my %includedfiles = ();
10
11 while (<FILE>) {
12 if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
13 ++$includedfiles{$1};
14 }
15 }
16
17 foreach $filename (keys %includedfiles) {
18 if ($includedfiles{$filename} > 1) {
19 print "$file: $filename is included more than once.\n";
20 }
21 }
22
23 close(FILE);
24}
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
new file mode 100644
index 000000000000..dadfa20ffec0
--- /dev/null
+++ b/scripts/checkstack.pl
@@ -0,0 +1,123 @@
1#!/usr/bin/perl
2
3# Check the stack usage of functions
4#
5# Copyright Joern Engel <joern@wh.fh-wedel.de>
6# Inspired by Linus Torvalds
7# Original idea maybe from Keith Owens
8# s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
9# Mips port by Juan Quintela <quintela@mandrakesoft.com>
10# IA64 port via Andreas Dilger
11# Arm port by Holger Schurig
12# sh64 port by Paul Mundt
13# Random bits by Matt Mackall <mpm@selenic.com>
14# M68k port by Geert Uytterhoeven and Andreas Schwab
15#
16# Usage:
17# objdump -d vmlinux | stackcheck.pl [arch]
18#
19# TODO : Port to all architectures (one regex per arch)
20
21# check for arch
22#
23# $re is used for two matches:
24# $& (whole re) matches the complete objdump line with the stack growth
25# $1 (first bracket) matches the size of the stack growth
26#
27# use anything else and feel the pain ;)
28my (@stack, $re, $x, $xs);
29{
30 my $arch = shift;
31 if ($arch eq "") {
32 $arch = `uname -m`;
33 }
34
35 $x = "[0-9a-f]"; # hex character
36 $xs = "[0-9a-f ]"; # hex character or space
37 if ($arch eq 'arm') {
38 #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
39 $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
40 } elsif ($arch =~ /^i[3456]86$/) {
41 #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
42 $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%esp$/o;
43 } elsif ($arch eq 'x86_64') {
44 # 2f60: 48 81 ec e8 05 00 00 sub $0x5e8,%rsp
45 $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%rsp$/o;
46 } elsif ($arch eq 'ia64') {
47 #e0000000044011fc: 01 0f fc 8c adds r12=-384,r12
48 $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o;
49 } elsif ($arch eq 'm68k') {
50 # 2b6c: 4e56 fb70 linkw %fp,#-1168
51 # 1df770: defc ffe4 addaw #-28,%sp
52 $re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o;
53 } elsif ($arch eq 'mips64') {
54 #8800402c: 67bdfff0 daddiu sp,sp,-16
55 $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
56 } elsif ($arch eq 'mips') {
57 #88003254: 27bdffe0 addiu sp,sp,-32
58 $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
59 } elsif ($arch eq 'ppc') {
60 #c00029f4: 94 21 ff 30 stwu r1,-208(r1)
61 $re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
62 } elsif ($arch eq 'ppc64') {
63 #XXX
64 $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
65 } elsif ($arch =~ /^s390x?$/) {
66 # 11160: a7 fb ff 60 aghi %r15,-160
67 $re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o;
68 } elsif ($arch =~ /^sh64$/) {
69 #XXX: we only check for the immediate case presently,
70 # though we will want to check for the movi/sub
71 # pair for larger users. -- PFM.
72 #a00048e0: d4fc40f0 addi.l r15,-240,r15
73 $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o;
74 } else {
75 print("wrong or unknown architecture\n");
76 exit
77 }
78}
79
80sub bysize($) {
81 my ($asize, $bsize);
82 ($asize = $a) =~ s/.*: *(.*)$/$1/;
83 ($bsize = $b) =~ s/.*: *(.*)$/$1/;
84 $bsize <=> $asize
85}
86
87#
88# main()
89#
90my $funcre = qr/^$x* <(.*)>:$/;
91my $func;
92while (my $line = <STDIN>) {
93 if ($line =~ m/$funcre/) {
94 $func = $1;
95 }
96 if ($line =~ m/$re/) {
97 my $size = $1;
98 $size = hex($size) if ($size =~ /^0x/);
99
100 if ($size > 0xf0000000) {
101 $size = - $size;
102 $size += 0x80000000;
103 $size += 0x80000000;
104 }
105 next if ($size > 0x10000000);
106
107 next if $line !~ m/^($xs*)/;
108 my $addr = $1;
109 $addr =~ s/ /0/g;
110 $addr = "0x$addr";
111
112 my $intro = "$addr $func:";
113 my $padlen = 56 - length($intro);
114 while ($padlen > 0) {
115 $intro .= ' ';
116 $padlen -= 8;
117 }
118 next if ($size < 100);
119 push @stack, "$intro$size\n";
120 }
121}
122
123print sort bysize @stack;
diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl
new file mode 100755
index 000000000000..df10db662eb1
--- /dev/null
+++ b/scripts/checkversion.pl
@@ -0,0 +1,72 @@
1#! /usr/bin/perl
2#
3# checkversion find uses of LINUX_VERSION_CODE, KERNEL_VERSION, or
4# UTS_RELEASE without including <linux/version.h>, or cases of
5# including <linux/version.h> that don't need it.
6# Copyright (C) 2003, Randy Dunlap <rddunlap@osdl.org>
7
8$| = 1;
9
10my $debugging = 0;
11
12foreach $file (@ARGV)
13{
14 # Open this file.
15 open(FILE, $file) || die "Can't open $file: $!\n";
16
17 # Initialize variables.
18 my $fInComment = 0;
19 my $fInString = 0;
20 my $fUseVersion = 0;
21 my $iLinuxVersion = 0;
22
23 LINE: while ( <FILE> )
24 {
25 # Strip comments.
26 $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
27 m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
28
29 # Pick up definitions.
30 if ( m/^\s*#/o ) {
31 $iLinuxVersion = $. if m/^\s*#\s*include\s*"linux\/version\.h"/o;
32 }
33
34 # Strip strings.
35 $fInString && (s+^.*?"+ +o ? ($fInString = 0) : next);
36 m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1)));
37
38 # Pick up definitions.
39 if ( m/^\s*#/o ) {
40 $iLinuxVersion = $. if m/^\s*#\s*include\s*<linux\/version\.h>/o;
41 }
42
43 # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE
44 if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/) ||
45 ($_ =~ /UTS_RELEASE/)) {
46 $fUseVersion = 1;
47 last LINE if $iLinuxVersion;
48 }
49 }
50
51 # Report used version IDs without include?
52 if ($fUseVersion && ! $iLinuxVersion) {
53 print "$file: $.: need linux/version.h\n";
54 }
55
56 # Report superfluous includes.
57 if ($iLinuxVersion && ! $fUseVersion) {
58 print "$file: $iLinuxVersion linux/version.h not needed.\n";
59 }
60
61 # debug: report OK results:
62 if ($debugging) {
63 if ($iLinuxVersion && $fUseVersion) {
64 print "$file: version use is OK ($iLinuxVersion)\n";
65 }
66 if (! $iLinuxVersion && ! $fUseVersion) {
67 print "$file: version use is OK (none)\n";
68 }
69 }
70
71 close(FILE);
72}
diff --git a/scripts/conmakehash.c b/scripts/conmakehash.c
new file mode 100644
index 000000000000..93dd23f21ec9
--- /dev/null
+++ b/scripts/conmakehash.c
@@ -0,0 +1,293 @@
1/*
2 * conmakehash.c
3 *
4 * Create arrays for initializing the kernel folded tables (using a hash
5 * table turned out to be to limiting...) Unfortunately we can't simply
6 * preinitialize the tables at compile time since kfree() cannot accept
7 * memory not allocated by kmalloc(), and doing our own memory management
8 * just for this seems like massive overkill.
9 *
10 * Copyright (C) 1995-1997 H. Peter Anvin
11 *
12 * This program is a part of the Linux kernel, and may be freely
13 * copied under the terms of the GNU General Public License (GPL),
14 * version 2, or at your option any later version.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <sysexits.h>
20#include <string.h>
21#include <ctype.h>
22
23#define MAX_FONTLEN 256
24
25typedef unsigned short unicode;
26
27void usage(char *argv0)
28{
29 fprintf(stderr, "Usage: \n"
30 " %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
31 exit(EX_USAGE);
32}
33
34int getunicode(char **p0)
35{
36 unsigned char *p = *p0;
37
38 while (*p == ' ' || *p == '\t')
39 p++;
40 if (*p != 'U' || p[1] != '+' ||
41 !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
42 !isxdigit(p[5]) || isxdigit(p[6]))
43 return -1;
44 *p0 = p+6;
45 return strtol(p+2,0,16);
46}
47
48unicode unitable[MAX_FONTLEN][255];
49 /* Massive overkill, but who cares? */
50int unicount[MAX_FONTLEN];
51
52void addpair(int fp, int un)
53{
54 int i;
55
56 if ( un <= 0xfffe )
57 {
58 /* Check it isn't a duplicate */
59
60 for ( i = 0 ; i < unicount[fp] ; i++ )
61 if ( unitable[fp][i] == un )
62 return;
63
64 /* Add to list */
65
66 if ( unicount[fp] > 254 )
67 {
68 fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n");
69 exit(EX_DATAERR);
70 }
71
72 unitable[fp][unicount[fp]] = un;
73 unicount[fp]++;
74 }
75
76 /* otherwise: ignore */
77}
78
79int main(int argc, char *argv[])
80{
81 FILE *ctbl;
82 char *tblname;
83 char buffer[65536];
84 int fontlen;
85 int i, nuni, nent;
86 int fp0, fp1, un0, un1;
87 char *p, *p1;
88
89 if ( argc < 2 || argc > 5 )
90 usage(argv[0]);
91
92 if ( !strcmp(argv[1],"-") )
93 {
94 ctbl = stdin;
95 tblname = "stdin";
96 }
97 else
98 {
99 ctbl = fopen(tblname = argv[1], "r");
100 if ( !ctbl )
101 {
102 perror(tblname);
103 exit(EX_NOINPUT);
104 }
105 }
106
107 /* For now we assume the default font is always 256 characters. */
108 fontlen = 256;
109
110 /* Initialize table */
111
112 for ( i = 0 ; i < fontlen ; i++ )
113 unicount[i] = 0;
114
115 /* Now we come to the tricky part. Parse the input table. */
116
117 while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
118 {
119 if ( (p = strchr(buffer, '\n')) != NULL )
120 *p = '\0';
121 else
122 fprintf(stderr, "%s: Warning: line too long\n", tblname);
123
124 p = buffer;
125
126/*
127 * Syntax accepted:
128 * <fontpos> <unicode> <unicode> ...
129 * <range> idem
130 * <range> <unicode range>
131 *
132 * where <range> ::= <fontpos>-<fontpos>
133 * and <unicode> ::= U+<h><h><h><h>
134 * and <h> ::= <hexadecimal digit>
135 */
136
137 while (*p == ' ' || *p == '\t')
138 p++;
139 if (!*p || *p == '#')
140 continue; /* skip comment or blank line */
141
142 fp0 = strtol(p, &p1, 0);
143 if (p1 == p)
144 {
145 fprintf(stderr, "Bad input line: %s\n", buffer);
146 exit(EX_DATAERR);
147 }
148 p = p1;
149
150 while (*p == ' ' || *p == '\t')
151 p++;
152 if (*p == '-')
153 {
154 p++;
155 fp1 = strtol(p, &p1, 0);
156 if (p1 == p)
157 {
158 fprintf(stderr, "Bad input line: %s\n", buffer);
159 exit(EX_DATAERR);
160 }
161 p = p1;
162 }
163 else
164 fp1 = 0;
165
166 if ( fp0 < 0 || fp0 >= fontlen )
167 {
168 fprintf(stderr,
169 "%s: Glyph number (0x%x) larger than font length\n",
170 tblname, fp0);
171 exit(EX_DATAERR);
172 }
173 if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
174 {
175 fprintf(stderr,
176 "%s: Bad end of range (0x%x)\n",
177 tblname, fp1);
178 exit(EX_DATAERR);
179 }
180
181 if (fp1)
182 {
183 /* we have a range; expect the word "idem" or a Unicode range of the
184 same length */
185 while (*p == ' ' || *p == '\t')
186 p++;
187 if (!strncmp(p, "idem", 4))
188 {
189 for (i=fp0; i<=fp1; i++)
190 addpair(i,i);
191 p += 4;
192 }
193 else
194 {
195 un0 = getunicode(&p);
196 while (*p == ' ' || *p == '\t')
197 p++;
198 if (*p != '-')
199 {
200 fprintf(stderr,
201"%s: Corresponding to a range of font positions, there should be a Unicode range\n",
202 tblname);
203 exit(EX_DATAERR);
204 }
205 p++;
206 un1 = getunicode(&p);
207 if (un0 < 0 || un1 < 0)
208 {
209 fprintf(stderr,
210"%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
211 tblname, fp0, fp1);
212 exit(EX_DATAERR);
213 }
214 if (un1 - un0 != fp1 - fp0)
215 {
216 fprintf(stderr,
217"%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
218 tblname, un0, un1, fp0, fp1);
219 exit(EX_DATAERR);
220 }
221 for(i=fp0; i<=fp1; i++)
222 addpair(i,un0-fp0+i);
223 }
224 }
225 else
226 {
227 /* no range; expect a list of unicode values for a single font position */
228
229 while ( (un0 = getunicode(&p)) >= 0 )
230 addpair(fp0, un0);
231 }
232 while (*p == ' ' || *p == '\t')
233 p++;
234 if (*p && *p != '#')
235 fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
236 }
237
238 /* Okay, we hit EOF, now output hash table */
239
240 fclose(ctbl);
241
242
243 /* Compute total size of Unicode list */
244 nuni = 0;
245 for ( i = 0 ; i < fontlen ; i++ )
246 nuni += unicount[i];
247
248 printf("\
249/*\n\
250 * Do not edit this file; it was automatically generated by\n\
251 *\n\
252 * conmakehash %s > [this file]\n\
253 *\n\
254 */\n\
255\n\
256#include <linux/types.h>\n\
257\n\
258u8 dfont_unicount[%d] = \n\
259{\n\t", argv[1], fontlen);
260
261 for ( i = 0 ; i < fontlen ; i++ )
262 {
263 printf("%3d", unicount[i]);
264 if ( i == fontlen-1 )
265 printf("\n};\n");
266 else if ( i % 8 == 7 )
267 printf(",\n\t");
268 else
269 printf(", ");
270 }
271
272 printf("\nu16 dfont_unitable[%d] = \n{\n\t", nuni);
273
274 fp0 = 0;
275 nent = 0;
276 for ( i = 0 ; i < nuni ; i++ )
277 {
278 while ( nent >= unicount[fp0] )
279 {
280 fp0++;
281 nent = 0;
282 }
283 printf("0x%04x", unitable[fp0][nent++]);
284 if ( i == nuni-1 )
285 printf("\n};\n");
286 else if ( i % 8 == 7 )
287 printf(",\n\t");
288 else
289 printf(", ");
290 }
291
292 exit(EX_OK);
293}
diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig
new file mode 100755
index 000000000000..d9f9f34b22ab
--- /dev/null
+++ b/scripts/extract-ikconfig
@@ -0,0 +1,77 @@
1#!/bin/sh
2# extracts .config info from a [b]zImage file
3# uses: binoffset (new), dd, zcat, strings, grep
4# $arg1 is [b]zImage filename
5
6binoffset="./scripts/binoffset"
7
8IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54"
9IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44"
10function dump_config {
11 typeset file="$1"
12
13 start=`$binoffset $file $IKCFG_ST 2>/dev/null`
14 [ "$?" != "0" ] && start="-1"
15 if [ "$start" -eq "-1" ]; then
16 return
17 fi
18 end=`$binoffset $file $IKCFG_ED 2>/dev/null`
19
20 let start="$start + 8"
21 let size="$end - $start"
22
23 head --bytes="$end" "$file" | tail --bytes="$size" | zcat
24
25 clean_up
26 exit 0
27}
28
29
30usage()
31{
32 echo " usage: extract-ikconfig [b]zImage_filename"
33}
34
35clean_up()
36{
37 if [ "$TMPFILE" != "" ]; then
38 rm -f $TMPFILE
39 fi
40}
41
42if [ $# -lt 1 ]
43then
44 usage
45 exit 1
46fi
47
48TMPFILE="/tmp/ikconfig-$$"
49image="$1"
50
51# vmlinux: Attempt to dump the configuration from the file directly
52dump_config "$image"
53
54GZHDR1="0x1f 0x8b 0x08 0x00"
55GZHDR2="0x1f 0x8b 0x08 0x08"
56
57# vmlinux.gz: Check for a compressed images
58off=`$binoffset "$image" $GZHDR1 2>/dev/null`
59[ "$?" != "0" ] && off="-1"
60if [ "$off" -eq "-1" ]; then
61 off=`$binoffset "$image" $GZHDR2 2>/dev/null`
62 [ "$?" != "0" ] && off="-1"
63fi
64if [ "$off" -eq "0" ]; then
65 zcat <"$image" >"$TMPFILE"
66 dump_config "$TMPFILE"
67elif [ "$off" -ne "-1" ]; then
68 (dd ibs="$off" skip=1 count=0 && dd bs=512k) <"$image" 2>/dev/null | \
69 zcat >"$TMPFILE"
70 dump_config "$TMPFILE"
71fi
72
73echo "ERROR: Unable to extract kernel configuration information."
74echo " This kernel image may not have the config info."
75
76clean_up
77exit 1
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
new file mode 100644
index 000000000000..bb4fbeab8320
--- /dev/null
+++ b/scripts/gcc-version.sh
@@ -0,0 +1,14 @@
1#!/bin/sh
2#
3# gcc-version gcc-command
4#
5# Prints the gcc version of `gcc-command' in a canonical 4-digit form
6# such as `0295' for gcc-2.95, `0303' for gcc-3.3, etc.
7#
8
9compiler="$*"
10
11MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1)
12MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1)
13printf "%02d%02d\\n" $MAJOR $MINOR
14
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
new file mode 100644
index 000000000000..6d411169bfa6
--- /dev/null
+++ b/scripts/gen_initramfs_list.sh
@@ -0,0 +1,203 @@
1#!/bin/bash
2# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
3# Released under the terms of the GNU GPL
4#
5# Generate a newline separated list of entries from the file/directory
6# supplied as an argument.
7#
8# If a file/directory is not supplied then generate a small dummy file.
9#
10# The output is suitable for gen_init_cpio built from usr/gen_init_cpio.c.
11#
12
13default_initramfs() {
14 cat <<-EOF
15 # This is a very simple, default initramfs
16
17 dir /dev 0755 0 0
18 nod /dev/console 0600 0 0 c 5 1
19 dir /root 0700 0 0
20 EOF
21}
22
23filetype() {
24 local argv1="$1"
25
26 # symlink test must come before file test
27 if [ -L "${argv1}" ]; then
28 echo "slink"
29 elif [ -f "${argv1}" ]; then
30 echo "file"
31 elif [ -d "${argv1}" ]; then
32 echo "dir"
33 elif [ -b "${argv1}" -o -c "${argv1}" ]; then
34 echo "nod"
35 elif [ -p "${argv1}" ]; then
36 echo "pipe"
37 elif [ -S "${argv1}" ]; then
38 echo "sock"
39 else
40 echo "invalid"
41 fi
42 return 0
43}
44
45print_mtime() {
46 local argv1="$1"
47 local my_mtime="0"
48
49 if [ -e "${argv1}" ]; then
50 my_mtime=$(find "${argv1}" -printf "%T@\n" | sort -r | head -n 1)
51 fi
52
53 echo "# Last modified: ${my_mtime}"
54 echo
55}
56
57parse() {
58 local location="$1"
59 local name="${location/${srcdir}//}"
60 # change '//' into '/'
61 name="${name//\/\///}"
62 local mode="$2"
63 local uid="$3"
64 local gid="$4"
65 local ftype=$(filetype "${location}")
66 # remap uid/gid to 0 if necessary
67 [ "$uid" -eq "$root_uid" ] && uid=0
68 [ "$gid" -eq "$root_gid" ] && gid=0
69 local str="${mode} ${uid} ${gid}"
70
71 [ "${ftype}" == "invalid" ] && return 0
72 [ "${location}" == "${srcdir}" ] && return 0
73
74 case "${ftype}" in
75 "file")
76 str="${ftype} ${name} ${location} ${str}"
77 ;;
78 "nod")
79 local dev_type=
80 local maj=$(LC_ALL=C ls -l "${location}" | \
81 gawk '{sub(/,/, "", $5); print $5}')
82 local min=$(LC_ALL=C ls -l "${location}" | \
83 gawk '{print $6}')
84
85 if [ -b "${location}" ]; then
86 dev_type="b"
87 else
88 dev_type="c"
89 fi
90 str="${ftype} ${name} ${str} ${dev_type} ${maj} ${min}"
91 ;;
92 "slink")
93 local target=$(LC_ALL=C ls -l "${location}" | \
94 gawk '{print $11}')
95 str="${ftype} ${name} ${target} ${str}"
96 ;;
97 *)
98 str="${ftype} ${name} ${str}"
99 ;;
100 esac
101
102 echo "${str}"
103
104 return 0
105}
106
107usage() {
108 printf "Usage:\n"
109 printf "$0 [ [-u <root_uid>] [-g <root_gid>] [-d | <cpio_source>] ] . . .\n"
110 printf "\n"
111 printf -- "-u <root_uid> User ID to map to user ID 0 (root).\n"
112 printf " <root_uid> is only meaningful if <cpio_source>\n"
113 printf " is a directory.\n"
114 printf -- "-g <root_gid> Group ID to map to group ID 0 (root).\n"
115 printf " <root_gid> is only meaningful if <cpio_source>\n"
116 printf " is a directory.\n"
117 printf "<cpio_source> File list or directory for cpio archive.\n"
118 printf " If <cpio_source> is not provided then a\n"
119 printf " a default list will be output.\n"
120 printf -- "-d Output the default cpio list. If no <cpio_source>\n"
121 printf " is given then the default cpio list will be output.\n"
122 printf "\n"
123 printf "All options may be repeated and are interpreted sequentially\n"
124 printf "and immediately. -u and -g states are preserved across\n"
125 printf "<cpio_source> options so an explicit \"-u 0 -g 0\" is required\n"
126 printf "to reset the root/group mapping.\n"
127}
128
129build_list() {
130 printf "\n#####################\n# $cpio_source\n"
131
132 if [ -f "$cpio_source" ]; then
133 print_mtime "$cpio_source"
134 cat "$cpio_source"
135 elif [ -d "$cpio_source" ]; then
136 srcdir=$(echo "$cpio_source" | sed -e 's://*:/:g')
137 dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null)
138
139 # If $dirlist is only one line, then the directory is empty
140 if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
141 print_mtime "$cpio_source"
142
143 echo "${dirlist}" | \
144 while read x; do
145 parse ${x}
146 done
147 else
148 # Failsafe in case directory is empty
149 default_initramfs
150 fi
151 else
152 echo " $0: Cannot open '$cpio_source'" >&2
153 exit 1
154 fi
155}
156
157
158root_uid=0
159root_gid=0
160
161while [ $# -gt 0 ]; do
162 arg="$1"
163 shift
164 case "$arg" in
165 "-u")
166 root_uid="$1"
167 shift
168 ;;
169 "-g")
170 root_gid="$1"
171 shift
172 ;;
173 "-d")
174 default_list="$arg"
175 default_initramfs
176 ;;
177 "-h")
178 usage
179 exit 0
180 ;;
181 *)
182 case "$arg" in
183 "-"*)
184 printf "ERROR: unknown option \"$arg\"\n" >&2
185 printf "If the filename validly begins with '-', then it must be prefixed\n" >&2
186 printf "by './' so that it won't be interpreted as an option." >&2
187 printf "\n" >&2
188 usage >&2
189 exit 1
190 ;;
191 *)
192 cpio_source="$arg"
193 build_list
194 ;;
195 esac
196 ;;
197 esac
198done
199
200# spit out the default cpio list if a source hasn't been specified
201[ -z "$cpio_source" -a -z "$default_list" ] && default_initramfs
202
203exit 0
diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile
new file mode 100644
index 000000000000..5875f29a8602
--- /dev/null
+++ b/scripts/genksyms/Makefile
@@ -0,0 +1,49 @@
1
2hostprogs-y := genksyms
3always := $(hostprogs-y)
4
5genksyms-objs := genksyms.o parse.o lex.o
6
7# -I needed for generated C source (shipped source)
8HOSTCFLAGS_parse.o := -Wno-uninitialized -I$(src)
9
10# dependencies on generated files need to be listed explicitly
11$(obj)/lex.o: $(obj)/parse.h $(obj)/keywords.c
12
13# -I needed for generated C source (shipped source)
14HOSTCFLAGS_lex.o := -I$(src)
15
16ifdef GENERATE_PARSER
17
18# gperf
19
20quiet_cmd_keywords.c = GPERF $@
21 cmd_keywords.c = gperf -L ANSI-C -a -C -E -g -H is_reserved_hash \
22 -k 1,3,$$ -N is_reserved_word -p -t $< > $@
23
24$(obj)/keywords.c: $(obj)/keywords.gperf FORCE
25 $(call if_changed,keywords.c)
26
27# flex
28
29quiet_cmd_lex.c = FLEX $@
30 cmd_lex.c = flex -o$@ -d $(filter-out FORCE,$^)
31
32$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h FORCE
33 $(call if_changed,lex.c)
34
35# bison
36
37quiet_cmd_parse.c = BISON $@
38 cmd_parse.c = bison -o$@ -dtv $(filter-out FORCE,$^)
39
40$(obj)/parse.c: $(obj)/parse.y FORCE
41 $(call if_changed,parse.c)
42
43$(obj)/parse.h: $(obj)/parse.c ;
44
45clean-files += parse.output
46
47endif
48
49targets += keywords.c lex.c parse.c parse.h
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
new file mode 100644
index 000000000000..416a694b0998
--- /dev/null
+++ b/scripts/genksyms/genksyms.c
@@ -0,0 +1,591 @@
1/* Generate kernel symbol version hashes.
2 Copyright 1996, 1997 Linux International.
3
4 New implementation contributed by Richard Henderson <rth@tamu.edu>
5 Based on original work by Bjorn Ekwall <bj0rn@blox.se>
6
7 This file was part of the Linux modutils 2.4.22: moved back into the
8 kernel sources by Rusty Russell/Kai Germaschewski.
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2 of the License, or (at your
13 option) any later version.
14
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation,
22 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <assert.h>
29#include <stdarg.h>
30#ifdef __GNU_LIBRARY__
31#include <getopt.h>
32#endif /* __GNU_LIBRARY__ */
33
34#include "genksyms.h"
35
36/*----------------------------------------------------------------------*/
37
38#define HASH_BUCKETS 4096
39
40static struct symbol *symtab[HASH_BUCKETS];
41FILE *debugfile;
42
43int cur_line = 1;
44char *cur_filename, *output_directory;
45
46int flag_debug, flag_dump_defs, flag_warnings;
47
48static int errors;
49static int nsyms;
50
51static struct symbol *expansion_trail;
52
53static const char * const symbol_type_name[] = {
54 "normal", "typedef", "enum", "struct", "union"
55};
56
57/*----------------------------------------------------------------------*/
58
59static const unsigned int crctab32[] =
60{
61 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
62 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
63 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
64 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
65 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
66 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
67 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
68 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
69 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
70 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
71 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
72 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
73 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
74 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
75 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
76 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
77 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
78 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
79 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
80 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
81 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
82 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
83 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
84 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
85 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
86 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
87 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
88 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
89 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
90 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
91 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
92 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
93 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
94 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
95 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
96 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
97 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
98 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
99 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
100 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
101 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
102 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
103 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
104 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
105 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
106 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
107 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
108 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
109 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
110 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
111 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
112 0x2d02ef8dU
113};
114
115static inline unsigned long
116partial_crc32_one(unsigned char c, unsigned long crc)
117{
118 return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
119}
120
121static inline unsigned long
122partial_crc32(const char *s, unsigned long crc)
123{
124 while (*s)
125 crc = partial_crc32_one(*s++, crc);
126 return crc;
127}
128
129static inline unsigned long
130crc32(const char *s)
131{
132 return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
133}
134
135
136/*----------------------------------------------------------------------*/
137
138static inline enum symbol_type
139map_to_ns(enum symbol_type t)
140{
141 if (t == SYM_TYPEDEF)
142 t = SYM_NORMAL;
143 else if (t == SYM_UNION)
144 t = SYM_STRUCT;
145 return t;
146}
147
148struct symbol *
149find_symbol(const char *name, enum symbol_type ns)
150{
151 unsigned long h = crc32(name) % HASH_BUCKETS;
152 struct symbol *sym;
153
154 for (sym = symtab[h]; sym ; sym = sym->hash_next)
155 if (map_to_ns(sym->type) == map_to_ns(ns) && strcmp(name, sym->name) == 0)
156 break;
157
158 return sym;
159}
160
161struct symbol *
162add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern)
163{
164 unsigned long h = crc32(name) % HASH_BUCKETS;
165 struct symbol *sym;
166
167 for (sym = symtab[h]; sym ; sym = sym->hash_next)
168 if (map_to_ns(sym->type) == map_to_ns(type)
169 && strcmp(name, sym->name) == 0)
170 {
171 if (!equal_list(sym->defn, defn))
172 error_with_pos("redefinition of %s", name);
173 return sym;
174 }
175
176 sym = xmalloc(sizeof(*sym));
177 sym->name = name;
178 sym->type = type;
179 sym->defn = defn;
180 sym->expansion_trail = NULL;
181 sym->is_extern = is_extern;
182
183 sym->hash_next = symtab[h];
184 symtab[h] = sym;
185
186 if (flag_debug)
187 {
188 fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type], name);
189 if (is_extern)
190 fputs("extern ", debugfile);
191 print_list(debugfile, defn);
192 fputs(">\n", debugfile);
193 }
194
195 ++nsyms;
196 return sym;
197}
198
199
200/*----------------------------------------------------------------------*/
201
202inline void
203free_node(struct string_list *node)
204{
205 free(node->string);
206 free(node);
207}
208
209void
210free_list(struct string_list *s, struct string_list *e)
211{
212 while (s != e)
213 {
214 struct string_list *next = s->next;
215 free_node(s);
216 s = next;
217 }
218}
219
220inline struct string_list *
221copy_node(struct string_list *node)
222{
223 struct string_list *newnode;
224
225 newnode = xmalloc(sizeof(*newnode));
226 newnode->string = xstrdup(node->string);
227 newnode->tag = node->tag;
228
229 return newnode;
230}
231
232struct string_list *
233copy_list(struct string_list *s, struct string_list *e)
234{
235 struct string_list *h, *p;
236
237 if (s == e)
238 return NULL;
239
240 p = h = copy_node(s);
241 while ((s = s->next) != e)
242 p = p->next = copy_node(s);
243 p->next = NULL;
244
245 return h;
246}
247
248int
249equal_list(struct string_list *a, struct string_list *b)
250{
251 while (a && b)
252 {
253 if (a->tag != b->tag || strcmp(a->string, b->string))
254 return 0;
255 a = a->next;
256 b = b->next;
257 }
258
259 return !a && !b;
260}
261
262static inline void
263print_node(FILE *f, struct string_list *list)
264{
265 switch (list->tag)
266 {
267 case SYM_STRUCT:
268 putc('s', f);
269 goto printit;
270 case SYM_UNION:
271 putc('u', f);
272 goto printit;
273 case SYM_ENUM:
274 putc('e', f);
275 goto printit;
276 case SYM_TYPEDEF:
277 putc('t', f);
278 goto printit;
279
280 printit:
281 putc('#', f);
282 case SYM_NORMAL:
283 fputs(list->string, f);
284 break;
285 }
286}
287
288void
289print_list(FILE *f, struct string_list *list)
290{
291 struct string_list **e, **b;
292 struct string_list *tmp, **tmp2;
293 int elem = 1;
294
295 if (list == NULL)
296 {
297 fputs("(nil)", f);
298 return;
299 }
300
301 tmp = list;
302 while((tmp = tmp->next) != NULL)
303 elem++;
304
305 b = alloca(elem * sizeof(*e));
306 e = b + elem;
307 tmp2 = e - 1;
308
309 (*tmp2--) = list;
310 while((list = list->next) != NULL)
311 *(tmp2--) = list;
312
313 while (b != e)
314 {
315 print_node(f, *b++);
316 putc(' ', f);
317 }
318}
319
320static unsigned long
321expand_and_crc_list(struct string_list *list, unsigned long crc)
322{
323 struct string_list **e, **b;
324 struct string_list *tmp, **tmp2;
325 int elem = 1;
326
327 if (!list)
328 return crc;
329
330 tmp = list;
331 while((tmp = tmp->next) != NULL)
332 elem++;
333
334 b = alloca(elem * sizeof(*e));
335 e = b + elem;
336 tmp2 = e - 1;
337
338 *(tmp2--) = list;
339 while ((list = list->next) != NULL)
340 *(tmp2--) = list;
341
342 while (b != e)
343 {
344 struct string_list *cur;
345 struct symbol *subsym;
346
347 cur = *(b++);
348 switch (cur->tag)
349 {
350 case SYM_NORMAL:
351 if (flag_dump_defs)
352 fprintf(debugfile, "%s ", cur->string);
353 crc = partial_crc32(cur->string, crc);
354 crc = partial_crc32_one(' ', crc);
355 break;
356
357 case SYM_TYPEDEF:
358 subsym = find_symbol(cur->string, cur->tag);
359 if (subsym->expansion_trail)
360 {
361 if (flag_dump_defs)
362 fprintf(debugfile, "%s ", cur->string);
363 crc = partial_crc32(cur->string, crc);
364 crc = partial_crc32_one(' ', crc);
365 }
366 else
367 {
368 subsym->expansion_trail = expansion_trail;
369 expansion_trail = subsym;
370 crc = expand_and_crc_list(subsym->defn, crc);
371 }
372 break;
373
374 case SYM_STRUCT:
375 case SYM_UNION:
376 case SYM_ENUM:
377 subsym = find_symbol(cur->string, cur->tag);
378 if (!subsym)
379 {
380 struct string_list *n, *t = NULL;
381
382 error_with_pos("expand undefined %s %s",
383 symbol_type_name[cur->tag], cur->string);
384
385 n = xmalloc(sizeof(*n));
386 n->string = xstrdup(symbol_type_name[cur->tag]);
387 n->tag = SYM_NORMAL;
388 n->next = t;
389 t = n;
390
391 n = xmalloc(sizeof(*n));
392 n->string = xstrdup(cur->string);
393 n->tag = SYM_NORMAL;
394 n->next = t;
395 t = n;
396
397 n = xmalloc(sizeof(*n));
398 n->string = xstrdup("{ UNKNOWN }");
399 n->tag = SYM_NORMAL;
400 n->next = t;
401
402 subsym = add_symbol(cur->string, cur->tag, n, 0);
403 }
404 if (subsym->expansion_trail)
405 {
406 if (flag_dump_defs)
407 {
408 fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag],
409 cur->string);
410 }
411
412 crc = partial_crc32(symbol_type_name[cur->tag], crc);
413 crc = partial_crc32_one(' ', crc);
414 crc = partial_crc32(cur->string, crc);
415 crc = partial_crc32_one(' ', crc);
416 }
417 else
418 {
419 subsym->expansion_trail = expansion_trail;
420 expansion_trail = subsym;
421 crc = expand_and_crc_list(subsym->defn, crc);
422 }
423 break;
424 }
425 }
426
427 return crc;
428}
429
430void
431export_symbol(const char *name)
432{
433 struct symbol *sym;
434
435 sym = find_symbol(name, SYM_NORMAL);
436 if (!sym)
437 error_with_pos("export undefined symbol %s", name);
438 else
439 {
440 unsigned long crc;
441
442 if (flag_dump_defs)
443 fprintf(debugfile, "Export %s == <", name);
444
445 expansion_trail = (struct symbol *)-1L;
446
447 crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff;
448
449 sym = expansion_trail;
450 while (sym != (struct symbol *)-1L)
451 {
452 struct symbol *n = sym->expansion_trail;
453 sym->expansion_trail = 0;
454 sym = n;
455 }
456
457 if (flag_dump_defs)
458 fputs(">\n", debugfile);
459
460 /* Used as a linker script. */
461 printf("__crc_%s = 0x%08lx ;\n", name, crc);
462 }
463}
464
465/*----------------------------------------------------------------------*/
466
467void
468error(const char *fmt, ...)
469{
470 va_list args;
471
472 if (flag_warnings)
473 {
474 va_start(args, fmt);
475 vfprintf(stderr, fmt, args);
476 va_end(args);
477 putc('\n', stderr);
478
479 errors++;
480 }
481}
482
483void
484error_with_pos(const char *fmt, ...)
485{
486 va_list args;
487
488 if (flag_warnings)
489 {
490 fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
491
492 va_start(args, fmt);
493 vfprintf(stderr, fmt, args);
494 va_end(args);
495 putc('\n', stderr);
496
497 errors++;
498 }
499}
500
501
502void genksyms_usage(void)
503{
504 fputs("Usage:\n"
505 "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n"
506 "\n"
507#ifdef __GNU_LIBRARY__
508 " -d, --debug Increment the debug level (repeatable)\n"
509 " -D, --dump Dump expanded symbol defs (for debugging only)\n"
510 " -w, --warnings Enable warnings\n"
511 " -q, --quiet Disable warnings (default)\n"
512 " -h, --help Print this message\n"
513 " -V, --version Print the release version\n"
514#else /* __GNU_LIBRARY__ */
515 " -d Increment the debug level (repeatable)\n"
516 " -D Dump expanded symbol defs (for debugging only)\n"
517 " -w Enable warnings\n"
518 " -q Disable warnings (default)\n"
519 " -h Print this message\n"
520 " -V Print the release version\n"
521#endif /* __GNU_LIBRARY__ */
522 , stderr);
523}
524
525int
526main(int argc, char **argv)
527{
528 int o;
529
530#ifdef __GNU_LIBRARY__
531 struct option long_opts[] = {
532 {"debug", 0, 0, 'd'},
533 {"warnings", 0, 0, 'w'},
534 {"quiet", 0, 0, 'q'},
535 {"dump", 0, 0, 'D'},
536 {"version", 0, 0, 'V'},
537 {"help", 0, 0, 'h'},
538 {0, 0, 0, 0}
539 };
540
541 while ((o = getopt_long(argc, argv, "dwqVDk:p:",
542 &long_opts[0], NULL)) != EOF)
543#else /* __GNU_LIBRARY__ */
544 while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF)
545#endif /* __GNU_LIBRARY__ */
546 switch (o)
547 {
548 case 'd':
549 flag_debug++;
550 break;
551 case 'w':
552 flag_warnings = 1;
553 break;
554 case 'q':
555 flag_warnings = 0;
556 break;
557 case 'V':
558 fputs("genksyms version 2.5.60\n", stderr);
559 break;
560 case 'D':
561 flag_dump_defs = 1;
562 break;
563 case 'h':
564 genksyms_usage();
565 return 0;
566 default:
567 genksyms_usage();
568 return 1;
569 }
570
571 {
572 extern int yydebug;
573 extern int yy_flex_debug;
574
575 yydebug = (flag_debug > 1);
576 yy_flex_debug = (flag_debug > 2);
577
578 debugfile = stderr;
579 /* setlinebuf(debugfile); */
580 }
581
582 yyparse();
583
584 if (flag_debug)
585 {
586 fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
587 nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS);
588 }
589
590 return errors != 0;
591}
diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h
new file mode 100644
index 000000000000..f09af47ab281
--- /dev/null
+++ b/scripts/genksyms/genksyms.h
@@ -0,0 +1,104 @@
1/* Generate kernel symbol version hashes.
2 Copyright 1996, 1997 Linux International.
3
4 New implementation contributed by Richard Henderson <rth@tamu.edu>
5 Based on original work by Bjorn Ekwall <bj0rn@blox.se>
6
7 This file is part of the Linux modutils.
8
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2 of the License, or (at your
12 option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23
24#ifndef MODUTILS_GENKSYMS_H
25#define MODUTILS_GENKSYMS_H 1
26
27#include <stdio.h>
28
29
30enum symbol_type
31{
32 SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
33};
34
35struct string_list
36{
37 struct string_list *next;
38 enum symbol_type tag;
39 char *string;
40};
41
42struct symbol
43{
44 struct symbol *hash_next;
45 const char *name;
46 enum symbol_type type;
47 struct string_list *defn;
48 struct symbol *expansion_trail;
49 int is_extern;
50};
51
52typedef struct string_list **yystype;
53#define YYSTYPE yystype
54
55extern FILE *outfile, *debugfile;
56
57extern int cur_line;
58extern char *cur_filename, *output_directory;
59
60extern int flag_debug, flag_dump_defs, flag_warnings;
61extern int checksum_version, kernel_version;
62
63extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents;
64extern struct string_list *current_list, *next_list;
65
66
67struct symbol *find_symbol(const char *name, enum symbol_type ns);
68struct symbol *add_symbol(const char *name, enum symbol_type type,
69 struct string_list *defn, int is_extern);
70void export_symbol(const char *);
71
72struct string_list *reset_list(void);
73void free_list(struct string_list *s, struct string_list *e);
74void free_node(struct string_list *list);
75struct string_list *copy_node(struct string_list *);
76struct string_list *copy_list(struct string_list *s, struct string_list *e);
77int equal_list(struct string_list *a, struct string_list *b);
78void print_list(FILE *, struct string_list *list);
79
80int yylex(void);
81int yyparse(void);
82
83void error_with_pos(const char *, ...);
84
85#define version(a,b,c) ((a << 16) | (b << 8) | (c))
86
87/*----------------------------------------------------------------------*/
88
89#define MODUTILS_VERSION "<in-kernel>"
90
91#define xmalloc(size) ({ void *__ptr = malloc(size); \
92 if(!__ptr && size != 0) { \
93 fprintf(stderr, "out of memory\n"); \
94 exit(1); \
95 } \
96 __ptr; })
97#define xstrdup(str) ({ char *__str = strdup(str); \
98 if (!__str) { \
99 fprintf(stderr, "out of memory\n"); \
100 exit(1); \
101 } \
102 __str; })
103
104#endif /* genksyms.h */
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
new file mode 100644
index 000000000000..eabaf7401cd6
--- /dev/null
+++ b/scripts/genksyms/keywords.c_shipped
@@ -0,0 +1,145 @@
1/* ANSI-C code produced by gperf version 2.7.2 */
2/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */
3struct resword { const char *name; int token; };
4/* maximum key range = 109, duplicates = 0 */
5
6#ifdef __GNUC__
7__inline
8#else
9#ifdef __cplusplus
10inline
11#endif
12#endif
13static unsigned int
14is_reserved_hash (register const char *str, register unsigned int len)
15{
16 static const unsigned char asso_values[] =
17 {
18 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
19 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
20 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
21 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
22 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
23 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
24 113, 113, 113, 113, 113, 113, 113, 113, 113, 5,
25 113, 113, 113, 113, 113, 113, 0, 113, 113, 113,
26 0, 113, 113, 113, 113, 113, 113, 113, 113, 113,
27 113, 113, 113, 113, 113, 0, 113, 0, 113, 20,
28 25, 0, 35, 30, 113, 20, 113, 113, 40, 30,
29 30, 0, 0, 113, 0, 51, 0, 15, 5, 113,
30 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
31 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
32 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
33 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
34 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
35 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
36 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
37 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
38 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
39 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
40 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
41 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
42 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
43 113, 113, 113, 113, 113, 113
44 };
45 return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
46}
47
48#ifdef __GNUC__
49__inline
50#endif
51const struct resword *
52is_reserved_word (register const char *str, register unsigned int len)
53{
54 enum
55 {
56 TOTAL_KEYWORDS = 41,
57 MIN_WORD_LENGTH = 3,
58 MAX_WORD_LENGTH = 17,
59 MIN_HASH_VALUE = 4,
60 MAX_HASH_VALUE = 112
61 };
62
63 static const struct resword wordlist[] =
64 {
65 {""}, {""}, {""}, {""},
66 {"auto", AUTO_KEYW},
67 {""}, {""},
68 {"__asm__", ASM_KEYW},
69 {""},
70 {"_restrict", RESTRICT_KEYW},
71 {"__typeof__", TYPEOF_KEYW},
72 {"__attribute", ATTRIBUTE_KEYW},
73 {"__restrict__", RESTRICT_KEYW},
74 {"__attribute__", ATTRIBUTE_KEYW},
75 {""},
76 {"__volatile", VOLATILE_KEYW},
77 {""},
78 {"__volatile__", VOLATILE_KEYW},
79 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
80 {""}, {""}, {""},
81 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
82 {"int", INT_KEYW},
83 {"char", CHAR_KEYW},
84 {""}, {""},
85 {"__const", CONST_KEYW},
86 {"__inline", INLINE_KEYW},
87 {"__const__", CONST_KEYW},
88 {"__inline__", INLINE_KEYW},
89 {""}, {""}, {""}, {""},
90 {"__asm", ASM_KEYW},
91 {"extern", EXTERN_KEYW},
92 {""},
93 {"register", REGISTER_KEYW},
94 {""},
95 {"float", FLOAT_KEYW},
96 {"typeof", TYPEOF_KEYW},
97 {"typedef", TYPEDEF_KEYW},
98 {""}, {""},
99 {"_Bool", BOOL_KEYW},
100 {"double", DOUBLE_KEYW},
101 {""}, {""},
102 {"enum", ENUM_KEYW},
103 {""}, {""}, {""},
104 {"volatile", VOLATILE_KEYW},
105 {"void", VOID_KEYW},
106 {"const", CONST_KEYW},
107 {"short", SHORT_KEYW},
108 {"struct", STRUCT_KEYW},
109 {""},
110 {"restrict", RESTRICT_KEYW},
111 {""},
112 {"__signed__", SIGNED_KEYW},
113 {""},
114 {"asm", ASM_KEYW},
115 {""}, {""},
116 {"inline", INLINE_KEYW},
117 {""}, {""}, {""},
118 {"union", UNION_KEYW},
119 {""}, {""}, {""}, {""}, {""}, {""},
120 {"static", STATIC_KEYW},
121 {""}, {""}, {""}, {""}, {""}, {""},
122 {"__signed", SIGNED_KEYW},
123 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
124 {""}, {""}, {""}, {""}, {""},
125 {"unsigned", UNSIGNED_KEYW},
126 {""}, {""}, {""}, {""},
127 {"long", LONG_KEYW},
128 {""}, {""}, {""}, {""}, {""}, {""}, {""},
129 {"signed", SIGNED_KEYW}
130 };
131
132 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
133 {
134 register int key = is_reserved_hash (str, len);
135
136 if (key <= MAX_HASH_VALUE && key >= 0)
137 {
138 register const char *s = wordlist[key].name;
139
140 if (*str == *s && !strcmp (str + 1, s + 1))
141 return &wordlist[key];
142 }
143 }
144 return 0;
145}
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
new file mode 100644
index 000000000000..b6bec765996e
--- /dev/null
+++ b/scripts/genksyms/keywords.gperf
@@ -0,0 +1,50 @@
1%{
2%}
3struct resword { const char *name; int token; }
4%%
5EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
6EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
7__asm, ASM_KEYW
8__asm__, ASM_KEYW
9__attribute, ATTRIBUTE_KEYW
10__attribute__, ATTRIBUTE_KEYW
11__const, CONST_KEYW
12__const__, CONST_KEYW
13__inline, INLINE_KEYW
14__inline__, INLINE_KEYW
15__signed, SIGNED_KEYW
16__signed__, SIGNED_KEYW
17__volatile, VOLATILE_KEYW
18__volatile__, VOLATILE_KEYW
19# According to rth, c99 defines _Bool, __restrict, __restrict__, restrict. KAO
20_Bool, BOOL_KEYW
21_restrict, RESTRICT_KEYW
22__restrict__, RESTRICT_KEYW
23restrict, RESTRICT_KEYW
24asm, ASM_KEYW
25# attribute commented out in modutils 2.4.2. People are using 'attribute' as a
26# field name which breaks the genksyms parser. It is not a gcc keyword anyway.
27# KAO.
28# attribute, ATTRIBUTE_KEYW
29auto, AUTO_KEYW
30char, CHAR_KEYW
31const, CONST_KEYW
32double, DOUBLE_KEYW
33enum, ENUM_KEYW
34extern, EXTERN_KEYW
35float, FLOAT_KEYW
36inline, INLINE_KEYW
37int, INT_KEYW
38long, LONG_KEYW
39register, REGISTER_KEYW
40short, SHORT_KEYW
41signed, SIGNED_KEYW
42static, STATIC_KEYW
43struct, STRUCT_KEYW
44typedef, TYPEDEF_KEYW
45union, UNION_KEYW
46unsigned, UNSIGNED_KEYW
47void, VOID_KEYW
48volatile, VOLATILE_KEYW
49typeof, TYPEOF_KEYW
50__typeof__, TYPEOF_KEYW
diff --git a/scripts/genksyms/lex.c_shipped b/scripts/genksyms/lex.c_shipped
new file mode 100644
index 000000000000..d9bfbb5948f2
--- /dev/null
+++ b/scripts/genksyms/lex.c_shipped
@@ -0,0 +1,2084 @@
1#line 2 "scripts/genksyms/lex.c"
2/* A lexical scanner generated by flex */
3
4/* Scanner skeleton version:
5 * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
6 */
7
8#define FLEX_SCANNER
9#define YY_FLEX_MAJOR_VERSION 2
10#define YY_FLEX_MINOR_VERSION 5
11
12#include <stdio.h>
13#include <unistd.h>
14
15
16/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
17#ifdef c_plusplus
18#ifndef __cplusplus
19#define __cplusplus
20#endif
21#endif
22
23
24#ifdef __cplusplus
25
26#include <stdlib.h>
27
28/* Use prototypes in function declarations. */
29#define YY_USE_PROTOS
30
31/* The "const" storage-class-modifier is valid. */
32#define YY_USE_CONST
33
34#else /* ! __cplusplus */
35
36#if __STDC__
37
38#define YY_USE_PROTOS
39#define YY_USE_CONST
40
41#endif /* __STDC__ */
42#endif /* ! __cplusplus */
43
44#ifdef __TURBOC__
45 #pragma warn -rch
46 #pragma warn -use
47#include <io.h>
48#include <stdlib.h>
49#define YY_USE_CONST
50#define YY_USE_PROTOS
51#endif
52
53#ifdef YY_USE_CONST
54#define yyconst const
55#else
56#define yyconst
57#endif
58
59
60#ifdef YY_USE_PROTOS
61#define YY_PROTO(proto) proto
62#else
63#define YY_PROTO(proto) ()
64#endif
65
66/* Returned upon end-of-file. */
67#define YY_NULL 0
68
69/* Promotes a possibly negative, possibly signed char to an unsigned
70 * integer for use as an array index. If the signed char is negative,
71 * we want to instead treat it as an 8-bit unsigned char, hence the
72 * double cast.
73 */
74#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
75
76/* Enter a start condition. This macro really ought to take a parameter,
77 * but we do it the disgusting crufty way forced on us by the ()-less
78 * definition of BEGIN.
79 */
80#define BEGIN yy_start = 1 + 2 *
81
82/* Translate the current start state into a value that can be later handed
83 * to BEGIN to return to the state. The YYSTATE alias is for lex
84 * compatibility.
85 */
86#define YY_START ((yy_start - 1) / 2)
87#define YYSTATE YY_START
88
89/* Action number for EOF rule of a given start state. */
90#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
91
92/* Special action meaning "start processing a new file". */
93#define YY_NEW_FILE yyrestart( yyin )
94
95#define YY_END_OF_BUFFER_CHAR 0
96
97/* Size of default input buffer. */
98#define YY_BUF_SIZE 16384
99
100typedef struct yy_buffer_state *YY_BUFFER_STATE;
101
102extern int yyleng;
103extern FILE *yyin, *yyout;
104
105#define EOB_ACT_CONTINUE_SCAN 0
106#define EOB_ACT_END_OF_FILE 1
107#define EOB_ACT_LAST_MATCH 2
108
109/* The funky do-while in the following #define is used to turn the definition
110 * int a single C statement (which needs a semi-colon terminator). This
111 * avoids problems with code like:
112 *
113 * if ( condition_holds )
114 * yyless( 5 );
115 * else
116 * do_something_else();
117 *
118 * Prior to using the do-while the compiler would get upset at the
119 * "else" because it interpreted the "if" statement as being all
120 * done when it reached the ';' after the yyless() call.
121 */
122
123/* Return all but the first 'n' matched characters back to the input stream. */
124
125#define yyless(n) \
126 do \
127 { \
128 /* Undo effects of setting up yytext. */ \
129 *yy_cp = yy_hold_char; \
130 YY_RESTORE_YY_MORE_OFFSET \
131 yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
132 YY_DO_BEFORE_ACTION; /* set up yytext again */ \
133 } \
134 while ( 0 )
135
136#define unput(c) yyunput( c, yytext_ptr )
137
138/* The following is because we cannot portably get our hands on size_t
139 * (without autoconf's help, which isn't available because we want
140 * flex-generated scanners to compile on their own).
141 */
142typedef unsigned int yy_size_t;
143
144
145struct yy_buffer_state
146 {
147 FILE *yy_input_file;
148
149 char *yy_ch_buf; /* input buffer */
150 char *yy_buf_pos; /* current position in input buffer */
151
152 /* Size of input buffer in bytes, not including room for EOB
153 * characters.
154 */
155 yy_size_t yy_buf_size;
156
157 /* Number of characters read into yy_ch_buf, not including EOB
158 * characters.
159 */
160 int yy_n_chars;
161
162 /* Whether we "own" the buffer - i.e., we know we created it,
163 * and can realloc() it to grow it, and should free() it to
164 * delete it.
165 */
166 int yy_is_our_buffer;
167
168 /* Whether this is an "interactive" input source; if so, and
169 * if we're using stdio for input, then we want to use getc()
170 * instead of fread(), to make sure we stop fetching input after
171 * each newline.
172 */
173 int yy_is_interactive;
174
175 /* Whether we're considered to be at the beginning of a line.
176 * If so, '^' rules will be active on the next match, otherwise
177 * not.
178 */
179 int yy_at_bol;
180
181 /* Whether to try to fill the input buffer when we reach the
182 * end of it.
183 */
184 int yy_fill_buffer;
185
186 int yy_buffer_status;
187#define YY_BUFFER_NEW 0
188#define YY_BUFFER_NORMAL 1
189 /* When an EOF's been seen but there's still some text to process
190 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
191 * shouldn't try reading from the input source any more. We might
192 * still have a bunch of tokens to match, though, because of
193 * possible backing-up.
194 *
195 * When we actually see the EOF, we change the status to "new"
196 * (via yyrestart()), so that the user can continue scanning by
197 * just pointing yyin at a new input file.
198 */
199#define YY_BUFFER_EOF_PENDING 2
200 };
201
202static YY_BUFFER_STATE yy_current_buffer = 0;
203
204/* We provide macros for accessing buffer states in case in the
205 * future we want to put the buffer states in a more general
206 * "scanner state".
207 */
208#define YY_CURRENT_BUFFER yy_current_buffer
209
210
211/* yy_hold_char holds the character lost when yytext is formed. */
212static char yy_hold_char;
213
214static int yy_n_chars; /* number of characters read into yy_ch_buf */
215
216
217int yyleng;
218
219/* Points to current character in buffer. */
220static char *yy_c_buf_p = (char *) 0;
221static int yy_init = 1; /* whether we need to initialize */
222static int yy_start = 0; /* start state number */
223
224/* Flag which is used to allow yywrap()'s to do buffer switches
225 * instead of setting up a fresh yyin. A bit of a hack ...
226 */
227static int yy_did_buffer_switch_on_eof;
228
229void yyrestart YY_PROTO(( FILE *input_file ));
230
231void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
232void yy_load_buffer_state YY_PROTO(( void ));
233YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
234void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
235void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
236void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
237#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
238
239YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
240YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
241YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
242
243static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
244static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
245static void yy_flex_free YY_PROTO(( void * ));
246
247#define yy_new_buffer yy_create_buffer
248
249#define yy_set_interactive(is_interactive) \
250 { \
251 if ( ! yy_current_buffer ) \
252 yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
253 yy_current_buffer->yy_is_interactive = is_interactive; \
254 }
255
256#define yy_set_bol(at_bol) \
257 { \
258 if ( ! yy_current_buffer ) \
259 yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
260 yy_current_buffer->yy_at_bol = at_bol; \
261 }
262
263#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
264
265
266#define yywrap() 1
267#define YY_SKIP_YYWRAP
268
269#define FLEX_DEBUG
270typedef unsigned char YY_CHAR;
271FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
272typedef int yy_state_type;
273
274#define FLEX_DEBUG
275extern char *yytext;
276#define yytext_ptr yytext
277
278static yy_state_type yy_get_previous_state YY_PROTO(( void ));
279static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
280static int yy_get_next_buffer YY_PROTO(( void ));
281static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
282
283/* Done after the current pattern has been matched and before the
284 * corresponding action - sets up yytext.
285 */
286#define YY_DO_BEFORE_ACTION \
287 yytext_ptr = yy_bp; \
288 yyleng = (int) (yy_cp - yy_bp); \
289 yy_hold_char = *yy_cp; \
290 *yy_cp = '\0'; \
291 yy_c_buf_p = yy_cp;
292
293#define YY_NUM_RULES 13
294#define YY_END_OF_BUFFER 14
295static yyconst short int yy_accept[76] =
296 { 0,
297 0, 0, 0, 0, 14, 12, 4, 3, 12, 7,
298 12, 12, 7, 12, 12, 12, 12, 12, 9, 9,
299 12, 12, 12, 4, 0, 5, 0, 7, 0, 6,
300 0, 0, 0, 0, 0, 0, 2, 8, 10, 10,
301 9, 0, 0, 9, 9, 0, 9, 0, 0, 11,
302 0, 0, 0, 10, 0, 10, 9, 9, 0, 0,
303 0, 0, 0, 0, 0, 10, 10, 0, 0, 0,
304 0, 0, 0, 1, 0
305 } ;
306
307static yyconst int yy_ec[256] =
308 { 0,
309 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
310 4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
311 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
312 1, 2, 1, 5, 6, 7, 8, 9, 10, 1,
313 1, 8, 11, 1, 12, 13, 8, 14, 15, 15,
314 15, 15, 15, 15, 15, 16, 16, 1, 1, 17,
315 18, 19, 1, 1, 20, 20, 20, 20, 21, 22,
316 7, 7, 7, 7, 7, 23, 7, 7, 7, 7,
317 7, 7, 7, 7, 24, 7, 7, 25, 7, 7,
318 1, 26, 1, 8, 7, 1, 20, 20, 20, 20,
319
320 21, 22, 7, 7, 7, 7, 7, 27, 7, 7,
321 7, 7, 7, 7, 7, 7, 24, 7, 7, 25,
322 7, 7, 1, 28, 1, 8, 1, 1, 1, 1,
323 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
324 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
325 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
326 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
327 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
328 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
329 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
330
331 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
332 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
333 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
334 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
335 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
336 1, 1, 1, 1, 1
337 } ;
338
339static yyconst int yy_meta[29] =
340 { 0,
341 1, 1, 2, 1, 1, 1, 3, 1, 1, 1,
342 4, 4, 5, 6, 6, 6, 1, 1, 1, 7,
343 8, 7, 3, 3, 3, 1, 3, 1
344 } ;
345
346static yyconst short int yy_base[88] =
347 { 0,
348 0, 147, 21, 140, 145, 284, 39, 284, 26, 0,
349 32, 126, 40, 44, 115, 35, 36, 46, 50, 53,
350 39, 61, 54, 79, 65, 284, 0, 0, 66, 284,
351 0, 119, 79, 75, 123, 104, 284, 284, 107, 0,
352 79, 73, 76, 76, 66, 0, 0, 85, 86, 284,
353 133, 83, 91, 284, 99, 147, 284, 114, 122, 70,
354 107, 141, 172, 151, 135, 181, 284, 137, 114, 157,
355 149, 48, 45, 284, 284, 208, 214, 222, 230, 238,
356 246, 250, 255, 256, 261, 267, 275
357 } ;
358
359static yyconst short int yy_def[88] =
360 { 0,
361 75, 1, 1, 3, 75, 75, 75, 75, 76, 77,
362 78, 75, 77, 79, 75, 75, 75, 75, 75, 19,
363 75, 75, 75, 75, 76, 75, 80, 77, 78, 75,
364 81, 75, 76, 78, 79, 79, 75, 75, 75, 39,
365 19, 82, 83, 75, 75, 84, 20, 76, 78, 75,
366 79, 51, 85, 75, 75, 75, 75, 84, 79, 51,
367 79, 79, 79, 51, 75, 75, 75, 86, 79, 63,
368 86, 87, 87, 75, 0, 75, 75, 75, 75, 75,
369 75, 75, 75, 75, 75, 75, 75
370 } ;
371
372static yyconst short int yy_nxt[313] =
373 { 0,
374 6, 7, 8, 7, 9, 6, 10, 6, 6, 11,
375 6, 6, 12, 6, 6, 6, 6, 6, 6, 10,
376 10, 10, 13, 10, 10, 6, 10, 6, 15, 16,
377 26, 15, 17, 18, 19, 20, 20, 21, 15, 22,
378 24, 30, 24, 38, 33, 36, 37, 74, 23, 34,
379 74, 27, 38, 38, 38, 38, 38, 31, 32, 39,
380 39, 39, 40, 41, 41, 42, 47, 47, 47, 26,
381 43, 38, 44, 45, 46, 30, 44, 75, 38, 38,
382 24, 38, 24, 26, 30, 40, 55, 55, 57, 26,
383 27, 31, 57, 43, 35, 30, 64, 64, 64, 57,
384
385 31, 65, 65, 75, 27, 36, 37, 35, 59, 37,
386 27, 31, 56, 56, 56, 59, 37, 51, 52, 52,
387 39, 39, 39, 59, 37, 37, 68, 53, 54, 54,
388 69, 50, 38, 54, 59, 37, 44, 45, 32, 37,
389 44, 35, 59, 37, 75, 14, 60, 60, 66, 66,
390 66, 37, 14, 72, 75, 61, 62, 63, 59, 61,
391 56, 56, 56, 69, 64, 64, 64, 69, 67, 67,
392 75, 75, 75, 67, 37, 35, 75, 75, 75, 61,
393 62, 75, 75, 61, 75, 70, 70, 70, 75, 75,
394 75, 70, 70, 70, 66, 66, 66, 75, 75, 75,
395
396 75, 75, 54, 54, 75, 75, 75, 54, 25, 25,
397 25, 25, 25, 25, 25, 25, 28, 75, 75, 28,
398 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,
399 35, 35, 35, 35, 35, 35, 35, 35, 48, 75,
400 48, 48, 48, 48, 48, 48, 49, 75, 49, 49,
401 49, 49, 49, 49, 42, 42, 75, 42, 56, 75,
402 56, 58, 58, 58, 66, 75, 66, 71, 71, 71,
403 71, 71, 71, 71, 71, 73, 73, 73, 73, 73,
404 73, 73, 73, 5, 75, 75, 75, 75, 75, 75,
405 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
406
407 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
408 75, 75
409 } ;
410
411static yyconst short int yy_chk[313] =
412 { 0,
413 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
414 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
415 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
416 9, 3, 3, 3, 3, 3, 3, 3, 3, 3,
417 7, 11, 7, 16, 13, 14, 14, 73, 3, 13,
418 72, 9, 16, 17, 17, 21, 21, 11, 18, 18,
419 18, 18, 19, 19, 19, 19, 20, 20, 20, 25,
420 19, 23, 19, 19, 19, 29, 19, 20, 22, 22,
421 24, 23, 24, 33, 34, 42, 43, 43, 45, 48,
422 25, 29, 45, 42, 60, 49, 52, 52, 52, 44,
423
424 34, 53, 53, 41, 33, 36, 36, 52, 61, 61,
425 48, 49, 55, 55, 55, 69, 69, 36, 36, 36,
426 39, 39, 39, 59, 59, 35, 59, 39, 39, 39,
427 61, 32, 15, 39, 51, 51, 58, 58, 12, 68,
428 58, 68, 62, 62, 5, 4, 51, 51, 65, 65,
429 65, 71, 2, 71, 0, 51, 51, 51, 70, 51,
430 56, 56, 56, 62, 64, 64, 64, 62, 56, 56,
431 0, 0, 0, 56, 63, 64, 0, 0, 0, 70,
432 70, 0, 0, 70, 0, 63, 63, 63, 0, 0,
433 0, 63, 63, 63, 66, 66, 66, 0, 0, 0,
434
435 0, 0, 66, 66, 0, 0, 0, 66, 76, 76,
436 76, 76, 76, 76, 76, 76, 77, 0, 0, 77,
437 77, 77, 78, 78, 78, 78, 78, 78, 78, 78,
438 79, 79, 79, 79, 79, 79, 79, 79, 80, 0,
439 80, 80, 80, 80, 80, 80, 81, 0, 81, 81,
440 81, 81, 81, 81, 82, 82, 0, 82, 83, 0,
441 83, 84, 84, 84, 85, 0, 85, 86, 86, 86,
442 86, 86, 86, 86, 86, 87, 87, 87, 87, 87,
443 87, 87, 87, 75, 75, 75, 75, 75, 75, 75,
444 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
445
446 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
447 75, 75
448 } ;
449
450static yy_state_type yy_last_accepting_state;
451static char *yy_last_accepting_cpos;
452
453extern int yy_flex_debug;
454int yy_flex_debug = 1;
455
456static yyconst short int yy_rule_linenum[13] =
457 { 0,
458 69, 70, 71, 74, 77, 78, 79, 85, 86, 87,
459 89, 92
460 } ;
461
462/* The intent behind this definition is that it'll catch
463 * any uses of REJECT which flex missed.
464 */
465#define REJECT reject_used_but_not_detected
466#define yymore() yymore_used_but_not_detected
467#define YY_MORE_ADJ 0
468#define YY_RESTORE_YY_MORE_OFFSET
469char *yytext;
470#line 1 "scripts/genksyms/lex.l"
471#define INITIAL 0
472/* Lexical analysis for genksyms.
473 Copyright 1996, 1997 Linux International.
474
475 New implementation contributed by Richard Henderson <rth@tamu.edu>
476 Based on original work by Bjorn Ekwall <bj0rn@blox.se>
477
478 Taken from Linux modutils 2.4.22.
479
480 This program is free software; you can redistribute it and/or modify it
481 under the terms of the GNU General Public License as published by the
482 Free Software Foundation; either version 2 of the License, or (at your
483 option) any later version.
484
485 This program is distributed in the hope that it will be useful, but
486 WITHOUT ANY WARRANTY; without even the implied warranty of
487 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
488 General Public License for more details.
489
490 You should have received a copy of the GNU General Public License
491 along with this program; if not, write to the Free Software Foundation,
492 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
493#line 25 "scripts/genksyms/lex.l"
494
495#include <limits.h>
496#include <stdlib.h>
497#include <string.h>
498#include <ctype.h>
499
500#include "genksyms.h"
501#include "parse.h"
502
503/* We've got a two-level lexer here. We let flex do basic tokenization
504 and then we categorize those basic tokens in the second stage. */
505#define YY_DECL static int yylex1(void)
506
507/* Version 2 checksumming does proper tokenization; version 1 wasn't
508 quite so pedantic. */
509#define V2_TOKENS 1
510
511/* We don't do multiple input files. */
512#line 513 "scripts/genksyms/lex.c"
513
514/* Macros after this point can all be overridden by user definitions in
515 * section 1.
516 */
517
518#ifndef YY_SKIP_YYWRAP
519#ifdef __cplusplus
520extern "C" int yywrap YY_PROTO(( void ));
521#else
522extern int yywrap YY_PROTO(( void ));
523#endif
524#endif
525
526#ifndef YY_NO_UNPUT
527static void yyunput YY_PROTO(( int c, char *buf_ptr ));
528#endif
529
530#ifndef yytext_ptr
531static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
532#endif
533
534#ifdef YY_NEED_STRLEN
535static int yy_flex_strlen YY_PROTO(( yyconst char * ));
536#endif
537
538#ifndef YY_NO_INPUT
539#ifdef __cplusplus
540static int yyinput YY_PROTO(( void ));
541#else
542static int input YY_PROTO(( void ));
543#endif
544#endif
545
546#if YY_STACK_USED
547static int yy_start_stack_ptr = 0;
548static int yy_start_stack_depth = 0;
549static int *yy_start_stack = 0;
550#ifndef YY_NO_PUSH_STATE
551static void yy_push_state YY_PROTO(( int new_state ));
552#endif
553#ifndef YY_NO_POP_STATE
554static void yy_pop_state YY_PROTO(( void ));
555#endif
556#ifndef YY_NO_TOP_STATE
557static int yy_top_state YY_PROTO(( void ));
558#endif
559
560#else
561#define YY_NO_PUSH_STATE 1
562#define YY_NO_POP_STATE 1
563#define YY_NO_TOP_STATE 1
564#endif
565
566#ifdef YY_MALLOC_DECL
567YY_MALLOC_DECL
568#else
569#if __STDC__
570#ifndef __cplusplus
571#include <stdlib.h>
572#endif
573#else
574/* Just try to get by without declaring the routines. This will fail
575 * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
576 * or sizeof(void*) != sizeof(int).
577 */
578#endif
579#endif
580
581/* Amount of stuff to slurp up with each read. */
582#ifndef YY_READ_BUF_SIZE
583#define YY_READ_BUF_SIZE 8192
584#endif
585
586/* Copy whatever the last rule matched to the standard output. */
587
588#ifndef ECHO
589/* This used to be an fputs(), but since the string might contain NUL's,
590 * we now use fwrite().
591 */
592#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
593#endif
594
595/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
596 * is returned in "result".
597 */
598#ifndef YY_INPUT
599#define YY_INPUT(buf,result,max_size) \
600 if ( yy_current_buffer->yy_is_interactive ) \
601 { \
602 int c = '*', n; \
603 for ( n = 0; n < max_size && \
604 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
605 buf[n] = (char) c; \
606 if ( c == '\n' ) \
607 buf[n++] = (char) c; \
608 if ( c == EOF && ferror( yyin ) ) \
609 YY_FATAL_ERROR( "input in flex scanner failed" ); \
610 result = n; \
611 } \
612 else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
613 && ferror( yyin ) ) \
614 YY_FATAL_ERROR( "input in flex scanner failed" );
615#endif
616
617/* No semi-colon after return; correct usage is to write "yyterminate();" -
618 * we don't want an extra ';' after the "return" because that will cause
619 * some compilers to complain about unreachable statements.
620 */
621#ifndef yyterminate
622#define yyterminate() return YY_NULL
623#endif
624
625/* Number of entries by which start-condition stack grows. */
626#ifndef YY_START_STACK_INCR
627#define YY_START_STACK_INCR 25
628#endif
629
630/* Report a fatal error. */
631#ifndef YY_FATAL_ERROR
632#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
633#endif
634
635/* Default declaration of generated scanner - a define so the user can
636 * easily add parameters.
637 */
638#ifndef YY_DECL
639#define YY_DECL int yylex YY_PROTO(( void ))
640#endif
641
642/* Code executed at the beginning of each rule, after yytext and yyleng
643 * have been set up.
644 */
645#ifndef YY_USER_ACTION
646#define YY_USER_ACTION
647#endif
648
649/* Code executed at the end of each rule. */
650#ifndef YY_BREAK
651#define YY_BREAK break;
652#endif
653
654#define YY_RULE_SETUP \
655 if ( yyleng > 0 ) \
656 yy_current_buffer->yy_at_bol = \
657 (yytext[yyleng - 1] == '\n'); \
658 YY_USER_ACTION
659
660YY_DECL
661 {
662 register yy_state_type yy_current_state;
663 register char *yy_cp = NULL, *yy_bp = NULL;
664 register int yy_act;
665
666#line 65 "scripts/genksyms/lex.l"
667
668
669
670 /* Keep track of our location in the original source files. */
671#line 672 "scripts/genksyms/lex.c"
672
673 if ( yy_init )
674 {
675 yy_init = 0;
676
677#ifdef YY_USER_INIT
678 YY_USER_INIT;
679#endif
680
681 if ( ! yy_start )
682 yy_start = 1; /* first start state */
683
684 if ( ! yyin )
685 yyin = stdin;
686
687 if ( ! yyout )
688 yyout = stdout;
689
690 if ( ! yy_current_buffer )
691 yy_current_buffer =
692 yy_create_buffer( yyin, YY_BUF_SIZE );
693
694 yy_load_buffer_state();
695 }
696
697 while ( 1 ) /* loops until end-of-file is reached */
698 {
699 yy_cp = yy_c_buf_p;
700
701 /* Support of yytext. */
702 *yy_cp = yy_hold_char;
703
704 /* yy_bp points to the position in yy_ch_buf of the start of
705 * the current run.
706 */
707 yy_bp = yy_cp;
708
709 yy_current_state = yy_start;
710 yy_current_state += YY_AT_BOL();
711yy_match:
712 do
713 {
714 register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
715 if ( yy_accept[yy_current_state] )
716 {
717 yy_last_accepting_state = yy_current_state;
718 yy_last_accepting_cpos = yy_cp;
719 }
720 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
721 {
722 yy_current_state = (int) yy_def[yy_current_state];
723 if ( yy_current_state >= 76 )
724 yy_c = yy_meta[(unsigned int) yy_c];
725 }
726 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
727 ++yy_cp;
728 }
729 while ( yy_base[yy_current_state] != 284 );
730
731yy_find_action:
732 yy_act = yy_accept[yy_current_state];
733 if ( yy_act == 0 )
734 { /* have to back up */
735 yy_cp = yy_last_accepting_cpos;
736 yy_current_state = yy_last_accepting_state;
737 yy_act = yy_accept[yy_current_state];
738 }
739
740 YY_DO_BEFORE_ACTION;
741
742
743do_action: /* This label is used only to access EOF actions. */
744
745 if ( yy_flex_debug )
746 {
747 if ( yy_act == 0 )
748 fprintf( stderr, "--scanner backing up\n" );
749 else if ( yy_act < 13 )
750 fprintf( stderr, "--accepting rule at line %d (\"%s\")\n",
751 yy_rule_linenum[yy_act], yytext );
752 else if ( yy_act == 13 )
753 fprintf( stderr, "--accepting default rule (\"%s\")\n",
754 yytext );
755 else if ( yy_act == 14 )
756 fprintf( stderr, "--(end of buffer or a NUL)\n" );
757 else
758 fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
759 }
760
761 switch ( yy_act )
762 { /* beginning of action switch */
763 case 0: /* must back up */
764 /* undo the effects of YY_DO_BEFORE_ACTION */
765 *yy_cp = yy_hold_char;
766 yy_cp = yy_last_accepting_cpos;
767 yy_current_state = yy_last_accepting_state;
768 goto yy_find_action;
769
770case 1:
771YY_RULE_SETUP
772#line 69 "scripts/genksyms/lex.l"
773return FILENAME;
774 YY_BREAK
775case 2:
776YY_RULE_SETUP
777#line 70 "scripts/genksyms/lex.l"
778cur_line++;
779 YY_BREAK
780case 3:
781YY_RULE_SETUP
782#line 71 "scripts/genksyms/lex.l"
783cur_line++;
784 YY_BREAK
785/* Ignore all other whitespace. */
786case 4:
787YY_RULE_SETUP
788#line 74 "scripts/genksyms/lex.l"
789;
790 YY_BREAK
791case 5:
792YY_RULE_SETUP
793#line 77 "scripts/genksyms/lex.l"
794return STRING;
795 YY_BREAK
796case 6:
797YY_RULE_SETUP
798#line 78 "scripts/genksyms/lex.l"
799return CHAR;
800 YY_BREAK
801case 7:
802YY_RULE_SETUP
803#line 79 "scripts/genksyms/lex.l"
804return IDENT;
805 YY_BREAK
806/* The Pedant requires that the other C multi-character tokens be
807 recognized as tokens. We don't actually use them since we don't
808 parse expressions, but we do want whitespace to be arranged
809 around them properly. */
810case 8:
811YY_RULE_SETUP
812#line 85 "scripts/genksyms/lex.l"
813return OTHER;
814 YY_BREAK
815case 9:
816YY_RULE_SETUP
817#line 86 "scripts/genksyms/lex.l"
818return INT;
819 YY_BREAK
820case 10:
821YY_RULE_SETUP
822#line 87 "scripts/genksyms/lex.l"
823return REAL;
824 YY_BREAK
825case 11:
826YY_RULE_SETUP
827#line 89 "scripts/genksyms/lex.l"
828return DOTS;
829 YY_BREAK
830/* All other tokens are single characters. */
831case 12:
832YY_RULE_SETUP
833#line 92 "scripts/genksyms/lex.l"
834return yytext[0];
835 YY_BREAK
836case 13:
837YY_RULE_SETUP
838#line 95 "scripts/genksyms/lex.l"
839ECHO;
840 YY_BREAK
841#line 842 "scripts/genksyms/lex.c"
842case YY_STATE_EOF(INITIAL):
843case YY_STATE_EOF(V2_TOKENS):
844 yyterminate();
845
846 case YY_END_OF_BUFFER:
847 {
848 /* Amount of text matched not including the EOB char. */
849 int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
850
851 /* Undo the effects of YY_DO_BEFORE_ACTION. */
852 *yy_cp = yy_hold_char;
853 YY_RESTORE_YY_MORE_OFFSET
854
855 if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
856 {
857 /* We're scanning a new file or input source. It's
858 * possible that this happened because the user
859 * just pointed yyin at a new source and called
860 * yylex(). If so, then we have to assure
861 * consistency between yy_current_buffer and our
862 * globals. Here is the right place to do so, because
863 * this is the first action (other than possibly a
864 * back-up) that will match for the new input source.
865 */
866 yy_n_chars = yy_current_buffer->yy_n_chars;
867 yy_current_buffer->yy_input_file = yyin;
868 yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
869 }
870
871 /* Note that here we test for yy_c_buf_p "<=" to the position
872 * of the first EOB in the buffer, since yy_c_buf_p will
873 * already have been incremented past the NUL character
874 * (since all states make transitions on EOB to the
875 * end-of-buffer state). Contrast this with the test
876 * in input().
877 */
878 if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
879 { /* This was really a NUL. */
880 yy_state_type yy_next_state;
881
882 yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
883
884 yy_current_state = yy_get_previous_state();
885
886 /* Okay, we're now positioned to make the NUL
887 * transition. We couldn't have
888 * yy_get_previous_state() go ahead and do it
889 * for us because it doesn't know how to deal
890 * with the possibility of jamming (and we don't
891 * want to build jamming into it because then it
892 * will run more slowly).
893 */
894
895 yy_next_state = yy_try_NUL_trans( yy_current_state );
896
897 yy_bp = yytext_ptr + YY_MORE_ADJ;
898
899 if ( yy_next_state )
900 {
901 /* Consume the NUL. */
902 yy_cp = ++yy_c_buf_p;
903 yy_current_state = yy_next_state;
904 goto yy_match;
905 }
906
907 else
908 {
909 yy_cp = yy_c_buf_p;
910 goto yy_find_action;
911 }
912 }
913
914 else switch ( yy_get_next_buffer() )
915 {
916 case EOB_ACT_END_OF_FILE:
917 {
918 yy_did_buffer_switch_on_eof = 0;
919
920 if ( yywrap() )
921 {
922 /* Note: because we've taken care in
923 * yy_get_next_buffer() to have set up
924 * yytext, we can now set up
925 * yy_c_buf_p so that if some total
926 * hoser (like flex itself) wants to
927 * call the scanner after we return the
928 * YY_NULL, it'll still work - another
929 * YY_NULL will get returned.
930 */
931 yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
932
933 yy_act = YY_STATE_EOF(YY_START);
934 goto do_action;
935 }
936
937 else
938 {
939 if ( ! yy_did_buffer_switch_on_eof )
940 YY_NEW_FILE;
941 }
942 break;
943 }
944
945 case EOB_ACT_CONTINUE_SCAN:
946 yy_c_buf_p =
947 yytext_ptr + yy_amount_of_matched_text;
948
949 yy_current_state = yy_get_previous_state();
950
951 yy_cp = yy_c_buf_p;
952 yy_bp = yytext_ptr + YY_MORE_ADJ;
953 goto yy_match;
954
955 case EOB_ACT_LAST_MATCH:
956 yy_c_buf_p =
957 &yy_current_buffer->yy_ch_buf[yy_n_chars];
958
959 yy_current_state = yy_get_previous_state();
960
961 yy_cp = yy_c_buf_p;
962 yy_bp = yytext_ptr + YY_MORE_ADJ;
963 goto yy_find_action;
964 }
965 break;
966 }
967
968 default:
969 YY_FATAL_ERROR(
970 "fatal flex scanner internal error--no action found" );
971 } /* end of action switch */
972 } /* end of scanning one token */
973 } /* end of yylex */
974
975
976/* yy_get_next_buffer - try to read in a new buffer
977 *
978 * Returns a code representing an action:
979 * EOB_ACT_LAST_MATCH -
980 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
981 * EOB_ACT_END_OF_FILE - end of file
982 */
983
984static int yy_get_next_buffer()
985 {
986 register char *dest = yy_current_buffer->yy_ch_buf;
987 register char *source = yytext_ptr;
988 register int number_to_move, i;
989 int ret_val;
990
991 if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
992 YY_FATAL_ERROR(
993 "fatal flex scanner internal error--end of buffer missed" );
994
995 if ( yy_current_buffer->yy_fill_buffer == 0 )
996 { /* Don't try to fill the buffer, so this is an EOF. */
997 if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
998 {
999 /* We matched a single character, the EOB, so
1000 * treat this as a final EOF.
1001 */
1002 return EOB_ACT_END_OF_FILE;
1003 }
1004
1005 else
1006 {
1007 /* We matched some text prior to the EOB, first
1008 * process it.
1009 */
1010 return EOB_ACT_LAST_MATCH;
1011 }
1012 }
1013
1014 /* Try to read more data. */
1015
1016 /* First move last chars to start of buffer. */
1017 number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
1018
1019 for ( i = 0; i < number_to_move; ++i )
1020 *(dest++) = *(source++);
1021
1022 if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
1023 /* don't do the read, it's not guaranteed to return an EOF,
1024 * just force an EOF
1025 */
1026 yy_current_buffer->yy_n_chars = yy_n_chars = 0;
1027
1028 else
1029 {
1030 int num_to_read =
1031 yy_current_buffer->yy_buf_size - number_to_move - 1;
1032
1033 while ( num_to_read <= 0 )
1034 { /* Not enough room in the buffer - grow it. */
1035#ifdef YY_USES_REJECT
1036 YY_FATAL_ERROR(
1037"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
1038#else
1039
1040 /* just a shorter name for the current buffer */
1041 YY_BUFFER_STATE b = yy_current_buffer;
1042
1043 int yy_c_buf_p_offset =
1044 (int) (yy_c_buf_p - b->yy_ch_buf);
1045
1046 if ( b->yy_is_our_buffer )
1047 {
1048 int new_size = b->yy_buf_size * 2;
1049
1050 if ( new_size <= 0 )
1051 b->yy_buf_size += b->yy_buf_size / 8;
1052 else
1053 b->yy_buf_size *= 2;
1054
1055 b->yy_ch_buf = (char *)
1056 /* Include room in for 2 EOB chars. */
1057 yy_flex_realloc( (void *) b->yy_ch_buf,
1058 b->yy_buf_size + 2 );
1059 }
1060 else
1061 /* Can't grow it, we don't own it. */
1062 b->yy_ch_buf = 0;
1063
1064 if ( ! b->yy_ch_buf )
1065 YY_FATAL_ERROR(
1066 "fatal error - scanner input buffer overflow" );
1067
1068 yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
1069
1070 num_to_read = yy_current_buffer->yy_buf_size -
1071 number_to_move - 1;
1072#endif
1073 }
1074
1075 if ( num_to_read > YY_READ_BUF_SIZE )
1076 num_to_read = YY_READ_BUF_SIZE;
1077
1078 /* Read in more data. */
1079 YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
1080 yy_n_chars, num_to_read );
1081
1082 yy_current_buffer->yy_n_chars = yy_n_chars;
1083 }
1084
1085 if ( yy_n_chars == 0 )
1086 {
1087 if ( number_to_move == YY_MORE_ADJ )
1088 {
1089 ret_val = EOB_ACT_END_OF_FILE;
1090 yyrestart( yyin );
1091 }
1092
1093 else
1094 {
1095 ret_val = EOB_ACT_LAST_MATCH;
1096 yy_current_buffer->yy_buffer_status =
1097 YY_BUFFER_EOF_PENDING;
1098 }
1099 }
1100
1101 else
1102 ret_val = EOB_ACT_CONTINUE_SCAN;
1103
1104 yy_n_chars += number_to_move;
1105 yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
1106 yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
1107
1108 yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
1109
1110 return ret_val;
1111 }
1112
1113
1114/* yy_get_previous_state - get the state just before the EOB char was reached */
1115
1116static yy_state_type yy_get_previous_state()
1117 {
1118 register yy_state_type yy_current_state;
1119 register char *yy_cp;
1120
1121 yy_current_state = yy_start;
1122 yy_current_state += YY_AT_BOL();
1123
1124 for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
1125 {
1126 register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
1127 if ( yy_accept[yy_current_state] )
1128 {
1129 yy_last_accepting_state = yy_current_state;
1130 yy_last_accepting_cpos = yy_cp;
1131 }
1132 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1133 {
1134 yy_current_state = (int) yy_def[yy_current_state];
1135 if ( yy_current_state >= 76 )
1136 yy_c = yy_meta[(unsigned int) yy_c];
1137 }
1138 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1139 }
1140
1141 return yy_current_state;
1142 }
1143
1144
1145/* yy_try_NUL_trans - try to make a transition on the NUL character
1146 *
1147 * synopsis
1148 * next_state = yy_try_NUL_trans( current_state );
1149 */
1150
1151#ifdef YY_USE_PROTOS
1152static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
1153#else
1154static yy_state_type yy_try_NUL_trans( yy_current_state )
1155yy_state_type yy_current_state;
1156#endif
1157 {
1158 register int yy_is_jam;
1159 register char *yy_cp = yy_c_buf_p;
1160
1161 register YY_CHAR yy_c = 1;
1162 if ( yy_accept[yy_current_state] )
1163 {
1164 yy_last_accepting_state = yy_current_state;
1165 yy_last_accepting_cpos = yy_cp;
1166 }
1167 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1168 {
1169 yy_current_state = (int) yy_def[yy_current_state];
1170 if ( yy_current_state >= 76 )
1171 yy_c = yy_meta[(unsigned int) yy_c];
1172 }
1173 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1174 yy_is_jam = (yy_current_state == 75);
1175
1176 return yy_is_jam ? 0 : yy_current_state;
1177 }
1178
1179
1180#ifndef YY_NO_UNPUT
1181#ifdef YY_USE_PROTOS
1182static void yyunput( int c, register char *yy_bp )
1183#else
1184static void yyunput( c, yy_bp )
1185int c;
1186register char *yy_bp;
1187#endif
1188 {
1189 register char *yy_cp = yy_c_buf_p;
1190
1191 /* undo effects of setting up yytext */
1192 *yy_cp = yy_hold_char;
1193
1194 if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
1195 { /* need to shift things up to make room */
1196 /* +2 for EOB chars. */
1197 register int number_to_move = yy_n_chars + 2;
1198 register char *dest = &yy_current_buffer->yy_ch_buf[
1199 yy_current_buffer->yy_buf_size + 2];
1200 register char *source =
1201 &yy_current_buffer->yy_ch_buf[number_to_move];
1202
1203 while ( source > yy_current_buffer->yy_ch_buf )
1204 *--dest = *--source;
1205
1206 yy_cp += (int) (dest - source);
1207 yy_bp += (int) (dest - source);
1208 yy_current_buffer->yy_n_chars =
1209 yy_n_chars = yy_current_buffer->yy_buf_size;
1210
1211 if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
1212 YY_FATAL_ERROR( "flex scanner push-back overflow" );
1213 }
1214
1215 *--yy_cp = (char) c;
1216
1217
1218 yytext_ptr = yy_bp;
1219 yy_hold_char = *yy_cp;
1220 yy_c_buf_p = yy_cp;
1221 }
1222#endif /* ifndef YY_NO_UNPUT */
1223
1224
1225#ifdef __cplusplus
1226static int yyinput()
1227#else
1228static int input()
1229#endif
1230 {
1231 int c;
1232
1233 *yy_c_buf_p = yy_hold_char;
1234
1235 if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
1236 {
1237 /* yy_c_buf_p now points to the character we want to return.
1238 * If this occurs *before* the EOB characters, then it's a
1239 * valid NUL; if not, then we've hit the end of the buffer.
1240 */
1241 if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
1242 /* This was really a NUL. */
1243 *yy_c_buf_p = '\0';
1244
1245 else
1246 { /* need more input */
1247 int offset = yy_c_buf_p - yytext_ptr;
1248 ++yy_c_buf_p;
1249
1250 switch ( yy_get_next_buffer() )
1251 {
1252 case EOB_ACT_LAST_MATCH:
1253 /* This happens because yy_g_n_b()
1254 * sees that we've accumulated a
1255 * token and flags that we need to
1256 * try matching the token before
1257 * proceeding. But for input(),
1258 * there's no matching to consider.
1259 * So convert the EOB_ACT_LAST_MATCH
1260 * to EOB_ACT_END_OF_FILE.
1261 */
1262
1263 /* Reset buffer status. */
1264 yyrestart( yyin );
1265
1266 /* fall through */
1267
1268 case EOB_ACT_END_OF_FILE:
1269 {
1270 if ( yywrap() )
1271 return EOF;
1272
1273 if ( ! yy_did_buffer_switch_on_eof )
1274 YY_NEW_FILE;
1275#ifdef __cplusplus
1276 return yyinput();
1277#else
1278 return input();
1279#endif
1280 }
1281
1282 case EOB_ACT_CONTINUE_SCAN:
1283 yy_c_buf_p = yytext_ptr + offset;
1284 break;
1285 }
1286 }
1287 }
1288
1289 c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
1290 *yy_c_buf_p = '\0'; /* preserve yytext */
1291 yy_hold_char = *++yy_c_buf_p;
1292
1293 yy_current_buffer->yy_at_bol = (c == '\n');
1294
1295 return c;
1296 }
1297
1298
1299#ifdef YY_USE_PROTOS
1300void yyrestart( FILE *input_file )
1301#else
1302void yyrestart( input_file )
1303FILE *input_file;
1304#endif
1305 {
1306 if ( ! yy_current_buffer )
1307 yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
1308
1309 yy_init_buffer( yy_current_buffer, input_file );
1310 yy_load_buffer_state();
1311 }
1312
1313
1314#ifdef YY_USE_PROTOS
1315void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
1316#else
1317void yy_switch_to_buffer( new_buffer )
1318YY_BUFFER_STATE new_buffer;
1319#endif
1320 {
1321 if ( yy_current_buffer == new_buffer )
1322 return;
1323
1324 if ( yy_current_buffer )
1325 {
1326 /* Flush out information for old buffer. */
1327 *yy_c_buf_p = yy_hold_char;
1328 yy_current_buffer->yy_buf_pos = yy_c_buf_p;
1329 yy_current_buffer->yy_n_chars = yy_n_chars;
1330 }
1331
1332 yy_current_buffer = new_buffer;
1333 yy_load_buffer_state();
1334
1335 /* We don't actually know whether we did this switch during
1336 * EOF (yywrap()) processing, but the only time this flag
1337 * is looked at is after yywrap() is called, so it's safe
1338 * to go ahead and always set it.
1339 */
1340 yy_did_buffer_switch_on_eof = 1;
1341 }
1342
1343
1344#ifdef YY_USE_PROTOS
1345void yy_load_buffer_state( void )
1346#else
1347void yy_load_buffer_state()
1348#endif
1349 {
1350 yy_n_chars = yy_current_buffer->yy_n_chars;
1351 yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
1352 yyin = yy_current_buffer->yy_input_file;
1353 yy_hold_char = *yy_c_buf_p;
1354 }
1355
1356
1357#ifdef YY_USE_PROTOS
1358YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
1359#else
1360YY_BUFFER_STATE yy_create_buffer( file, size )
1361FILE *file;
1362int size;
1363#endif
1364 {
1365 YY_BUFFER_STATE b;
1366
1367 b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
1368 if ( ! b )
1369 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1370
1371 b->yy_buf_size = size;
1372
1373 /* yy_ch_buf has to be 2 characters longer than the size given because
1374 * we need to put in 2 end-of-buffer characters.
1375 */
1376 b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
1377 if ( ! b->yy_ch_buf )
1378 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1379
1380 b->yy_is_our_buffer = 1;
1381
1382 yy_init_buffer( b, file );
1383
1384 return b;
1385 }
1386
1387
1388#ifdef YY_USE_PROTOS
1389void yy_delete_buffer( YY_BUFFER_STATE b )
1390#else
1391void yy_delete_buffer( b )
1392YY_BUFFER_STATE b;
1393#endif
1394 {
1395 if ( ! b )
1396 return;
1397
1398 if ( b == yy_current_buffer )
1399 yy_current_buffer = (YY_BUFFER_STATE) 0;
1400
1401 if ( b->yy_is_our_buffer )
1402 yy_flex_free( (void *) b->yy_ch_buf );
1403
1404 yy_flex_free( (void *) b );
1405 }
1406
1407
1408
1409#ifdef YY_USE_PROTOS
1410void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
1411#else
1412void yy_init_buffer( b, file )
1413YY_BUFFER_STATE b;
1414FILE *file;
1415#endif
1416
1417
1418 {
1419 yy_flush_buffer( b );
1420
1421 b->yy_input_file = file;
1422 b->yy_fill_buffer = 1;
1423
1424#if YY_ALWAYS_INTERACTIVE
1425 b->yy_is_interactive = 1;
1426#else
1427#if YY_NEVER_INTERACTIVE
1428 b->yy_is_interactive = 0;
1429#else
1430 b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
1431#endif
1432#endif
1433 }
1434
1435
1436#ifdef YY_USE_PROTOS
1437void yy_flush_buffer( YY_BUFFER_STATE b )
1438#else
1439void yy_flush_buffer( b )
1440YY_BUFFER_STATE b;
1441#endif
1442
1443 {
1444 if ( ! b )
1445 return;
1446
1447 b->yy_n_chars = 0;
1448
1449 /* We always need two end-of-buffer characters. The first causes
1450 * a transition to the end-of-buffer state. The second causes
1451 * a jam in that state.
1452 */
1453 b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
1454 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
1455
1456 b->yy_buf_pos = &b->yy_ch_buf[0];
1457
1458 b->yy_at_bol = 1;
1459 b->yy_buffer_status = YY_BUFFER_NEW;
1460
1461 if ( b == yy_current_buffer )
1462 yy_load_buffer_state();
1463 }
1464
1465
1466#ifndef YY_NO_SCAN_BUFFER
1467#ifdef YY_USE_PROTOS
1468YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
1469#else
1470YY_BUFFER_STATE yy_scan_buffer( base, size )
1471char *base;
1472yy_size_t size;
1473#endif
1474 {
1475 YY_BUFFER_STATE b;
1476
1477 if ( size < 2 ||
1478 base[size-2] != YY_END_OF_BUFFER_CHAR ||
1479 base[size-1] != YY_END_OF_BUFFER_CHAR )
1480 /* They forgot to leave room for the EOB's. */
1481 return 0;
1482
1483 b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
1484 if ( ! b )
1485 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
1486
1487 b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
1488 b->yy_buf_pos = b->yy_ch_buf = base;
1489 b->yy_is_our_buffer = 0;
1490 b->yy_input_file = 0;
1491 b->yy_n_chars = b->yy_buf_size;
1492 b->yy_is_interactive = 0;
1493 b->yy_at_bol = 1;
1494 b->yy_fill_buffer = 0;
1495 b->yy_buffer_status = YY_BUFFER_NEW;
1496
1497 yy_switch_to_buffer( b );
1498
1499 return b;
1500 }
1501#endif
1502
1503
1504#ifndef YY_NO_SCAN_STRING
1505#ifdef YY_USE_PROTOS
1506YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
1507#else
1508YY_BUFFER_STATE yy_scan_string( yy_str )
1509yyconst char *yy_str;
1510#endif
1511 {
1512 int len;
1513 for ( len = 0; yy_str[len]; ++len )
1514 ;
1515
1516 return yy_scan_bytes( yy_str, len );
1517 }
1518#endif
1519
1520
1521#ifndef YY_NO_SCAN_BYTES
1522#ifdef YY_USE_PROTOS
1523YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
1524#else
1525YY_BUFFER_STATE yy_scan_bytes( bytes, len )
1526yyconst char *bytes;
1527int len;
1528#endif
1529 {
1530 YY_BUFFER_STATE b;
1531 char *buf;
1532 yy_size_t n;
1533 int i;
1534
1535 /* Get memory for full buffer, including space for trailing EOB's. */
1536 n = len + 2;
1537 buf = (char *) yy_flex_alloc( n );
1538 if ( ! buf )
1539 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
1540
1541 for ( i = 0; i < len; ++i )
1542 buf[i] = bytes[i];
1543
1544 buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
1545
1546 b = yy_scan_buffer( buf, n );
1547 if ( ! b )
1548 YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
1549
1550 /* It's okay to grow etc. this buffer, and we should throw it
1551 * away when we're done.
1552 */
1553 b->yy_is_our_buffer = 1;
1554
1555 return b;
1556 }
1557#endif
1558
1559
1560#ifndef YY_NO_PUSH_STATE
1561#ifdef YY_USE_PROTOS
1562static void yy_push_state( int new_state )
1563#else
1564static void yy_push_state( new_state )
1565int new_state;
1566#endif
1567 {
1568 if ( yy_start_stack_ptr >= yy_start_stack_depth )
1569 {
1570 yy_size_t new_size;
1571
1572 yy_start_stack_depth += YY_START_STACK_INCR;
1573 new_size = yy_start_stack_depth * sizeof( int );
1574
1575 if ( ! yy_start_stack )
1576 yy_start_stack = (int *) yy_flex_alloc( new_size );
1577
1578 else
1579 yy_start_stack = (int *) yy_flex_realloc(
1580 (void *) yy_start_stack, new_size );
1581
1582 if ( ! yy_start_stack )
1583 YY_FATAL_ERROR(
1584 "out of memory expanding start-condition stack" );
1585 }
1586
1587 yy_start_stack[yy_start_stack_ptr++] = YY_START;
1588
1589 BEGIN(new_state);
1590 }
1591#endif
1592
1593
1594#ifndef YY_NO_POP_STATE
1595static void yy_pop_state()
1596 {
1597 if ( --yy_start_stack_ptr < 0 )
1598 YY_FATAL_ERROR( "start-condition stack underflow" );
1599
1600 BEGIN(yy_start_stack[yy_start_stack_ptr]);
1601 }
1602#endif
1603
1604
1605#ifndef YY_NO_TOP_STATE
1606static int yy_top_state()
1607 {
1608 return yy_start_stack[yy_start_stack_ptr - 1];
1609 }
1610#endif
1611
1612#ifndef YY_EXIT_FAILURE
1613#define YY_EXIT_FAILURE 2
1614#endif
1615
1616#ifdef YY_USE_PROTOS
1617static void yy_fatal_error( yyconst char msg[] )
1618#else
1619static void yy_fatal_error( msg )
1620char msg[];
1621#endif
1622 {
1623 (void) fprintf( stderr, "%s\n", msg );
1624 exit( YY_EXIT_FAILURE );
1625 }
1626
1627
1628
1629/* Redefine yyless() so it works in section 3 code. */
1630
1631#undef yyless
1632#define yyless(n) \
1633 do \
1634 { \
1635 /* Undo effects of setting up yytext. */ \
1636 yytext[yyleng] = yy_hold_char; \
1637 yy_c_buf_p = yytext + n; \
1638 yy_hold_char = *yy_c_buf_p; \
1639 *yy_c_buf_p = '\0'; \
1640 yyleng = n; \
1641 } \
1642 while ( 0 )
1643
1644
1645/* Internal utility routines. */
1646
1647#ifndef yytext_ptr
1648#ifdef YY_USE_PROTOS
1649static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
1650#else
1651static void yy_flex_strncpy( s1, s2, n )
1652char *s1;
1653yyconst char *s2;
1654int n;
1655#endif
1656 {
1657 register int i;
1658 for ( i = 0; i < n; ++i )
1659 s1[i] = s2[i];
1660 }
1661#endif
1662
1663#ifdef YY_NEED_STRLEN
1664#ifdef YY_USE_PROTOS
1665static int yy_flex_strlen( yyconst char *s )
1666#else
1667static int yy_flex_strlen( s )
1668yyconst char *s;
1669#endif
1670 {
1671 register int n;
1672 for ( n = 0; s[n]; ++n )
1673 ;
1674
1675 return n;
1676 }
1677#endif
1678
1679
1680#ifdef YY_USE_PROTOS
1681static void *yy_flex_alloc( yy_size_t size )
1682#else
1683static void *yy_flex_alloc( size )
1684yy_size_t size;
1685#endif
1686 {
1687 return (void *) malloc( size );
1688 }
1689
1690#ifdef YY_USE_PROTOS
1691static void *yy_flex_realloc( void *ptr, yy_size_t size )
1692#else
1693static void *yy_flex_realloc( ptr, size )
1694void *ptr;
1695yy_size_t size;
1696#endif
1697 {
1698 /* The cast to (char *) in the following accommodates both
1699 * implementations that use char* generic pointers, and those
1700 * that use void* generic pointers. It works with the latter
1701 * because both ANSI C and C++ allow castless assignment from
1702 * any pointer type to void*, and deal with argument conversions
1703 * as though doing an assignment.
1704 */
1705 return (void *) realloc( (char *) ptr, size );
1706 }
1707
1708#ifdef YY_USE_PROTOS
1709static void yy_flex_free( void *ptr )
1710#else
1711static void yy_flex_free( ptr )
1712void *ptr;
1713#endif
1714 {
1715 free( ptr );
1716 }
1717
1718#if YY_MAIN
1719int main()
1720 {
1721 yylex();
1722 return 0;
1723 }
1724#endif
1725#line 95 "scripts/genksyms/lex.l"
1726
1727
1728/* Bring in the keyword recognizer. */
1729
1730#include "keywords.c"
1731
1732
1733/* Macros to append to our phrase collection list. */
1734
1735#define _APP(T,L) do { \
1736 cur_node = next_node; \
1737 next_node = xmalloc(sizeof(*next_node)); \
1738 next_node->next = cur_node; \
1739 cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
1740 cur_node->tag = SYM_NORMAL; \
1741 } while (0)
1742
1743#define APP _APP(yytext, yyleng)
1744
1745
1746/* The second stage lexer. Here we incorporate knowledge of the state
1747 of the parser to tailor the tokens that are returned. */
1748
1749int
1750yylex(void)
1751{
1752 static enum {
1753 ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE,
1754 ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
1755 ST_TABLE_5, ST_TABLE_6
1756 } lexstate = ST_NOTSTARTED;
1757
1758 static int suppress_type_lookup, dont_want_brace_phrase;
1759 static struct string_list *next_node;
1760
1761 int token, count = 0;
1762 struct string_list *cur_node;
1763
1764 if (lexstate == ST_NOTSTARTED)
1765 {
1766 BEGIN(V2_TOKENS);
1767 next_node = xmalloc(sizeof(*next_node));
1768 next_node->next = NULL;
1769 lexstate = ST_NORMAL;
1770 }
1771
1772repeat:
1773 token = yylex1();
1774
1775 if (token == 0)
1776 return 0;
1777 else if (token == FILENAME)
1778 {
1779 char *file, *e;
1780
1781 /* Save the filename and line number for later error messages. */
1782
1783 if (cur_filename)
1784 free(cur_filename);
1785
1786 file = strchr(yytext, '\"')+1;
1787 e = strchr(file, '\"');
1788 *e = '\0';
1789 cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
1790 cur_line = atoi(yytext+2);
1791
1792 goto repeat;
1793 }
1794
1795 switch (lexstate)
1796 {
1797 case ST_NORMAL:
1798 switch (token)
1799 {
1800 case IDENT:
1801 APP;
1802 {
1803 const struct resword *r = is_reserved_word(yytext, yyleng);
1804 if (r)
1805 {
1806 switch (token = r->token)
1807 {
1808 case ATTRIBUTE_KEYW:
1809 lexstate = ST_ATTRIBUTE;
1810 count = 0;
1811 goto repeat;
1812 case ASM_KEYW:
1813 lexstate = ST_ASM;
1814 count = 0;
1815 goto repeat;
1816
1817 case STRUCT_KEYW:
1818 case UNION_KEYW:
1819 dont_want_brace_phrase = 3;
1820 case ENUM_KEYW:
1821 suppress_type_lookup = 2;
1822 goto fini;
1823
1824 case EXPORT_SYMBOL_KEYW:
1825 goto fini;
1826 }
1827 }
1828 if (!suppress_type_lookup)
1829 {
1830 struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
1831 if (sym && sym->type == SYM_TYPEDEF)
1832 token = TYPE;
1833 }
1834 }
1835 break;
1836
1837 case '[':
1838 APP;
1839 lexstate = ST_BRACKET;
1840 count = 1;
1841 goto repeat;
1842
1843 case '{':
1844 APP;
1845 if (dont_want_brace_phrase)
1846 break;
1847 lexstate = ST_BRACE;
1848 count = 1;
1849 goto repeat;
1850
1851 case '=': case ':':
1852 APP;
1853 lexstate = ST_EXPRESSION;
1854 break;
1855
1856 case DOTS:
1857 default:
1858 APP;
1859 break;
1860 }
1861 break;
1862
1863 case ST_ATTRIBUTE:
1864 APP;
1865 switch (token)
1866 {
1867 case '(':
1868 ++count;
1869 goto repeat;
1870 case ')':
1871 if (--count == 0)
1872 {
1873 lexstate = ST_NORMAL;
1874 token = ATTRIBUTE_PHRASE;
1875 break;
1876 }
1877 goto repeat;
1878 default:
1879 goto repeat;
1880 }
1881 break;
1882
1883 case ST_ASM:
1884 APP;
1885 switch (token)
1886 {
1887 case '(':
1888 ++count;
1889 goto repeat;
1890 case ')':
1891 if (--count == 0)
1892 {
1893 lexstate = ST_NORMAL;
1894 token = ASM_PHRASE;
1895 break;
1896 }
1897 goto repeat;
1898 default:
1899 goto repeat;
1900 }
1901 break;
1902
1903 case ST_BRACKET:
1904 APP;
1905 switch (token)
1906 {
1907 case '[':
1908 ++count;
1909 goto repeat;
1910 case ']':
1911 if (--count == 0)
1912 {
1913 lexstate = ST_NORMAL;
1914 token = BRACKET_PHRASE;
1915 break;
1916 }
1917 goto repeat;
1918 default:
1919 goto repeat;
1920 }
1921 break;
1922
1923 case ST_BRACE:
1924 APP;
1925 switch (token)
1926 {
1927 case '{':
1928 ++count;
1929 goto repeat;
1930 case '}':
1931 if (--count == 0)
1932 {
1933 lexstate = ST_NORMAL;
1934 token = BRACE_PHRASE;
1935 break;
1936 }
1937 goto repeat;
1938 default:
1939 goto repeat;
1940 }
1941 break;
1942
1943 case ST_EXPRESSION:
1944 switch (token)
1945 {
1946 case '(': case '[': case '{':
1947 ++count;
1948 APP;
1949 goto repeat;
1950 case ')': case ']': case '}':
1951 --count;
1952 APP;
1953 goto repeat;
1954 case ',': case ';':
1955 if (count == 0)
1956 {
1957 /* Put back the token we just read so's we can find it again
1958 after registering the expression. */
1959 unput(token);
1960
1961 lexstate = ST_NORMAL;
1962 token = EXPRESSION_PHRASE;
1963 break;
1964 }
1965 APP;
1966 goto repeat;
1967 default:
1968 APP;
1969 goto repeat;
1970 }
1971 break;
1972
1973 case ST_TABLE_1:
1974 goto repeat;
1975
1976 case ST_TABLE_2:
1977 if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
1978 {
1979 token = EXPORT_SYMBOL_KEYW;
1980 lexstate = ST_TABLE_5;
1981 APP;
1982 break;
1983 }
1984 lexstate = ST_TABLE_6;
1985 /* FALLTHRU */
1986
1987 case ST_TABLE_6:
1988 switch (token)
1989 {
1990 case '{': case '[': case '(':
1991 ++count;
1992 break;
1993 case '}': case ']': case ')':
1994 --count;
1995 break;
1996 case ',':
1997 if (count == 0)
1998 lexstate = ST_TABLE_2;
1999 break;
2000 };
2001 goto repeat;
2002
2003 case ST_TABLE_3:
2004 goto repeat;
2005
2006 case ST_TABLE_4:
2007 if (token == ';')
2008 lexstate = ST_NORMAL;
2009 goto repeat;
2010
2011 case ST_TABLE_5:
2012 switch (token)
2013 {
2014 case ',':
2015 token = ';';
2016 lexstate = ST_TABLE_2;
2017 APP;
2018 break;
2019 default:
2020 APP;
2021 break;
2022 }
2023 break;
2024
2025 default:
2026 abort();
2027 }
2028fini:
2029
2030 if (suppress_type_lookup > 0)
2031 --suppress_type_lookup;
2032 if (dont_want_brace_phrase > 0)
2033 --dont_want_brace_phrase;
2034
2035 yylval = &next_node->next;
2036
2037 return token;
2038}
2039#ifndef YYSTYPE
2040#define YYSTYPE int
2041#endif
2042#define ASM_KEYW 257
2043#define ATTRIBUTE_KEYW 258
2044#define AUTO_KEYW 259
2045#define BOOL_KEYW 260
2046#define CHAR_KEYW 261
2047#define CONST_KEYW 262
2048#define DOUBLE_KEYW 263
2049#define ENUM_KEYW 264
2050#define EXTERN_KEYW 265
2051#define FLOAT_KEYW 266
2052#define INLINE_KEYW 267
2053#define INT_KEYW 268
2054#define LONG_KEYW 269
2055#define REGISTER_KEYW 270
2056#define RESTRICT_KEYW 271
2057#define SHORT_KEYW 272
2058#define SIGNED_KEYW 273
2059#define STATIC_KEYW 274
2060#define STRUCT_KEYW 275
2061#define TYPEDEF_KEYW 276
2062#define UNION_KEYW 277
2063#define UNSIGNED_KEYW 278
2064#define VOID_KEYW 279
2065#define VOLATILE_KEYW 280
2066#define TYPEOF_KEYW 281
2067#define EXPORT_SYMBOL_KEYW 282
2068#define ASM_PHRASE 283
2069#define ATTRIBUTE_PHRASE 284
2070#define BRACE_PHRASE 285
2071#define BRACKET_PHRASE 286
2072#define EXPRESSION_PHRASE 287
2073#define CHAR 288
2074#define DOTS 289
2075#define IDENT 290
2076#define INT 291
2077#define REAL 292
2078#define STRING 293
2079#define TYPE 294
2080#define OTHER 295
2081#define FILENAME 296
2082
2083
2084extern YYSTYPE yylval;
diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l
new file mode 100644
index 000000000000..fe0dfeedf0ff
--- /dev/null
+++ b/scripts/genksyms/lex.l
@@ -0,0 +1,407 @@
1/* Lexical analysis for genksyms.
2 Copyright 1996, 1997 Linux International.
3
4 New implementation contributed by Richard Henderson <rth@tamu.edu>
5 Based on original work by Bjorn Ekwall <bj0rn@blox.se>
6
7 Taken from Linux modutils 2.4.22.
8
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2 of the License, or (at your
12 option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23
24%{
25
26#include <limits.h>
27#include <stdlib.h>
28#include <string.h>
29#include <ctype.h>
30
31#include "genksyms.h"
32#include "parse.h"
33
34/* We've got a two-level lexer here. We let flex do basic tokenization
35 and then we categorize those basic tokens in the second stage. */
36#define YY_DECL static int yylex1(void)
37
38%}
39
40IDENT [A-Za-z_\$][A-Za-z0-9_\$]*
41
42O_INT 0[0-7]*
43D_INT [1-9][0-9]*
44X_INT 0[Xx][0-9A-Fa-f]+
45I_SUF [Uu]|[Ll]|[Uu][Ll]|[Ll][Uu]
46INT ({O_INT}|{D_INT}|{X_INT}){I_SUF}?
47
48FRAC ([0-9]*\.[0-9]+)|([0-9]+\.)
49EXP [Ee][+-]?[0-9]+
50F_SUF [FfLl]
51REAL ({FRAC}{EXP}?{F_SUF}?)|([0-9]+{EXP}{F_SUF}?)
52
53STRING L?\"([^\\\"]*\\.)*[^\\\"]*\"
54CHAR L?\'([^\\\']*\\.)*[^\\\']*\'
55
56MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
57
58/* Version 2 checksumming does proper tokenization; version 1 wasn't
59 quite so pedantic. */
60%s V2_TOKENS
61
62/* We don't do multiple input files. */
63%option noyywrap
64
65%%
66
67
68 /* Keep track of our location in the original source files. */
69^#[ \t]+{INT}[ \t]+\"[^\"\n]+\".*\n return FILENAME;
70^#.*\n cur_line++;
71\n cur_line++;
72
73 /* Ignore all other whitespace. */
74[ \t\f\v\r]+ ;
75
76
77{STRING} return STRING;
78{CHAR} return CHAR;
79{IDENT} return IDENT;
80
81 /* The Pedant requires that the other C multi-character tokens be
82 recognized as tokens. We don't actually use them since we don't
83 parse expressions, but we do want whitespace to be arranged
84 around them properly. */
85<V2_TOKENS>{MC_TOKEN} return OTHER;
86<V2_TOKENS>{INT} return INT;
87<V2_TOKENS>{REAL} return REAL;
88
89"..." return DOTS;
90
91 /* All other tokens are single characters. */
92. return yytext[0];
93
94
95%%
96
97/* Bring in the keyword recognizer. */
98
99#include "keywords.c"
100
101
102/* Macros to append to our phrase collection list. */
103
104#define _APP(T,L) do { \
105 cur_node = next_node; \
106 next_node = xmalloc(sizeof(*next_node)); \
107 next_node->next = cur_node; \
108 cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
109 cur_node->tag = SYM_NORMAL; \
110 } while (0)
111
112#define APP _APP(yytext, yyleng)
113
114
115/* The second stage lexer. Here we incorporate knowledge of the state
116 of the parser to tailor the tokens that are returned. */
117
118int
119yylex(void)
120{
121 static enum {
122 ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE,
123 ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
124 ST_TABLE_5, ST_TABLE_6
125 } lexstate = ST_NOTSTARTED;
126
127 static int suppress_type_lookup, dont_want_brace_phrase;
128 static struct string_list *next_node;
129
130 int token, count = 0;
131 struct string_list *cur_node;
132
133 if (lexstate == ST_NOTSTARTED)
134 {
135 BEGIN(V2_TOKENS);
136 next_node = xmalloc(sizeof(*next_node));
137 next_node->next = NULL;
138 lexstate = ST_NORMAL;
139 }
140
141repeat:
142 token = yylex1();
143
144 if (token == 0)
145 return 0;
146 else if (token == FILENAME)
147 {
148 char *file, *e;
149
150 /* Save the filename and line number for later error messages. */
151
152 if (cur_filename)
153 free(cur_filename);
154
155 file = strchr(yytext, '\"')+1;
156 e = strchr(file, '\"');
157 *e = '\0';
158 cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
159 cur_line = atoi(yytext+2);
160
161 goto repeat;
162 }
163
164 switch (lexstate)
165 {
166 case ST_NORMAL:
167 switch (token)
168 {
169 case IDENT:
170 APP;
171 {
172 const struct resword *r = is_reserved_word(yytext, yyleng);
173 if (r)
174 {
175 switch (token = r->token)
176 {
177 case ATTRIBUTE_KEYW:
178 lexstate = ST_ATTRIBUTE;
179 count = 0;
180 goto repeat;
181 case ASM_KEYW:
182 lexstate = ST_ASM;
183 count = 0;
184 goto repeat;
185
186 case STRUCT_KEYW:
187 case UNION_KEYW:
188 dont_want_brace_phrase = 3;
189 case ENUM_KEYW:
190 suppress_type_lookup = 2;
191 goto fini;
192
193 case EXPORT_SYMBOL_KEYW:
194 goto fini;
195 }
196 }
197 if (!suppress_type_lookup)
198 {
199 struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
200 if (sym && sym->type == SYM_TYPEDEF)
201 token = TYPE;
202 }
203 }
204 break;
205
206 case '[':
207 APP;
208 lexstate = ST_BRACKET;
209 count = 1;
210 goto repeat;
211
212 case '{':
213 APP;
214 if (dont_want_brace_phrase)
215 break;
216 lexstate = ST_BRACE;
217 count = 1;
218 goto repeat;
219
220 case '=': case ':':
221 APP;
222 lexstate = ST_EXPRESSION;
223 break;
224
225 case DOTS:
226 default:
227 APP;
228 break;
229 }
230 break;
231
232 case ST_ATTRIBUTE:
233 APP;
234 switch (token)
235 {
236 case '(':
237 ++count;
238 goto repeat;
239 case ')':
240 if (--count == 0)
241 {
242 lexstate = ST_NORMAL;
243 token = ATTRIBUTE_PHRASE;
244 break;
245 }
246 goto repeat;
247 default:
248 goto repeat;
249 }
250 break;
251
252 case ST_ASM:
253 APP;
254 switch (token)
255 {
256 case '(':
257 ++count;
258 goto repeat;
259 case ')':
260 if (--count == 0)
261 {
262 lexstate = ST_NORMAL;
263 token = ASM_PHRASE;
264 break;
265 }
266 goto repeat;
267 default:
268 goto repeat;
269 }
270 break;
271
272 case ST_BRACKET:
273 APP;
274 switch (token)
275 {
276 case '[':
277 ++count;
278 goto repeat;
279 case ']':
280 if (--count == 0)
281 {
282 lexstate = ST_NORMAL;
283 token = BRACKET_PHRASE;
284 break;
285 }
286 goto repeat;
287 default:
288 goto repeat;
289 }
290 break;
291
292 case ST_BRACE:
293 APP;
294 switch (token)
295 {
296 case '{':
297 ++count;
298 goto repeat;
299 case '}':
300 if (--count == 0)
301 {
302 lexstate = ST_NORMAL;
303 token = BRACE_PHRASE;
304 break;
305 }
306 goto repeat;
307 default:
308 goto repeat;
309 }
310 break;
311
312 case ST_EXPRESSION:
313 switch (token)
314 {
315 case '(': case '[': case '{':
316 ++count;
317 APP;
318 goto repeat;
319 case ')': case ']': case '}':
320 --count;
321 APP;
322 goto repeat;
323 case ',': case ';':
324 if (count == 0)
325 {
326 /* Put back the token we just read so's we can find it again
327 after registering the expression. */
328 unput(token);
329
330 lexstate = ST_NORMAL;
331 token = EXPRESSION_PHRASE;
332 break;
333 }
334 APP;
335 goto repeat;
336 default:
337 APP;
338 goto repeat;
339 }
340 break;
341
342 case ST_TABLE_1:
343 goto repeat;
344
345 case ST_TABLE_2:
346 if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
347 {
348 token = EXPORT_SYMBOL_KEYW;
349 lexstate = ST_TABLE_5;
350 APP;
351 break;
352 }
353 lexstate = ST_TABLE_6;
354 /* FALLTHRU */
355
356 case ST_TABLE_6:
357 switch (token)
358 {
359 case '{': case '[': case '(':
360 ++count;
361 break;
362 case '}': case ']': case ')':
363 --count;
364 break;
365 case ',':
366 if (count == 0)
367 lexstate = ST_TABLE_2;
368 break;
369 };
370 goto repeat;
371
372 case ST_TABLE_3:
373 goto repeat;
374
375 case ST_TABLE_4:
376 if (token == ';')
377 lexstate = ST_NORMAL;
378 goto repeat;
379
380 case ST_TABLE_5:
381 switch (token)
382 {
383 case ',':
384 token = ';';
385 lexstate = ST_TABLE_2;
386 APP;
387 break;
388 default:
389 APP;
390 break;
391 }
392 break;
393
394 default:
395 abort();
396 }
397fini:
398
399 if (suppress_type_lookup > 0)
400 --suppress_type_lookup;
401 if (dont_want_brace_phrase > 0)
402 --dont_want_brace_phrase;
403
404 yylval = &next_node->next;
405
406 return token;
407}
diff --git a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped
new file mode 100644
index 000000000000..2c6b1286b638
--- /dev/null
+++ b/scripts/genksyms/parse.c_shipped
@@ -0,0 +1,1577 @@
1
2/* A Bison parser, made from scripts/genksyms/parse.y
3 by GNU Bison version 1.28 */
4
5#define YYBISON 1 /* Identify Bison output. */
6
7#define ASM_KEYW 257
8#define ATTRIBUTE_KEYW 258
9#define AUTO_KEYW 259
10#define BOOL_KEYW 260
11#define CHAR_KEYW 261
12#define CONST_KEYW 262
13#define DOUBLE_KEYW 263
14#define ENUM_KEYW 264
15#define EXTERN_KEYW 265
16#define FLOAT_KEYW 266
17#define INLINE_KEYW 267
18#define INT_KEYW 268
19#define LONG_KEYW 269
20#define REGISTER_KEYW 270
21#define RESTRICT_KEYW 271
22#define SHORT_KEYW 272
23#define SIGNED_KEYW 273
24#define STATIC_KEYW 274
25#define STRUCT_KEYW 275
26#define TYPEDEF_KEYW 276
27#define UNION_KEYW 277
28#define UNSIGNED_KEYW 278
29#define VOID_KEYW 279
30#define VOLATILE_KEYW 280
31#define TYPEOF_KEYW 281
32#define EXPORT_SYMBOL_KEYW 282
33#define ASM_PHRASE 283
34#define ATTRIBUTE_PHRASE 284
35#define BRACE_PHRASE 285
36#define BRACKET_PHRASE 286
37#define EXPRESSION_PHRASE 287
38#define CHAR 288
39#define DOTS 289
40#define IDENT 290
41#define INT 291
42#define REAL 292
43#define STRING 293
44#define TYPE 294
45#define OTHER 295
46#define FILENAME 296
47
48#line 24 "scripts/genksyms/parse.y"
49
50
51#include <assert.h>
52#include <malloc.h>
53#include "genksyms.h"
54
55static int is_typedef;
56static int is_extern;
57static char *current_name;
58static struct string_list *decl_spec;
59
60static void yyerror(const char *);
61
62static inline void
63remove_node(struct string_list **p)
64{
65 struct string_list *node = *p;
66 *p = node->next;
67 free_node(node);
68}
69
70static inline void
71remove_list(struct string_list **pb, struct string_list **pe)
72{
73 struct string_list *b = *pb, *e = *pe;
74 *pb = e;
75 free_list(b, e);
76}
77
78#ifndef YYSTYPE
79#define YYSTYPE int
80#endif
81#ifndef YYDEBUG
82#define YYDEBUG 1
83#endif
84
85#include <stdio.h>
86
87#ifndef __cplusplus
88#ifndef __STDC__
89#define const
90#endif
91#endif
92
93
94
95#define YYFINAL 172
96#define YYFLAG -32768
97#define YYNTBASE 52
98
99#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 96)
100
101static const char yytranslate[] = { 0,
102 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
103 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
104 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
105 2, 2, 2, 2, 2, 2, 2, 2, 2, 46,
106 47, 48, 2, 45, 2, 2, 2, 2, 2, 2,
107 2, 2, 2, 2, 2, 2, 2, 51, 43, 2,
108 49, 2, 2, 2, 2, 2, 2, 2, 2, 2,
109 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
110 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
111 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
112 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
113 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
114 2, 2, 50, 2, 44, 2, 2, 2, 2, 2,
115 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
116 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
117 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
118 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
119 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
120 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
121 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
122 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
123 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
124 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
125 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
126 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
127 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
128 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
129 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
130 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
131 37, 38, 39, 40, 41, 42
132};
133
134#if YYDEBUG != 0
135static const short yyprhs[] = { 0,
136 0, 2, 5, 6, 9, 10, 14, 16, 18, 20,
137 22, 25, 28, 32, 33, 35, 37, 41, 46, 47,
138 49, 51, 54, 56, 58, 60, 62, 64, 66, 68,
139 70, 72, 77, 80, 83, 86, 90, 94, 98, 101,
140 104, 107, 109, 111, 113, 115, 117, 119, 121, 123,
141 125, 127, 129, 132, 133, 135, 137, 140, 142, 144,
142 146, 148, 151, 153, 155, 160, 165, 168, 172, 176,
143 179, 181, 183, 185, 190, 195, 198, 202, 206, 209,
144 211, 215, 216, 218, 220, 224, 227, 230, 232, 233,
145 235, 237, 242, 247, 250, 254, 258, 262, 263, 265,
146 268, 272, 276, 277, 279, 281, 284, 288, 291, 292,
147 294, 296, 300, 303, 306, 308, 311, 312, 314, 317,
148 318, 320
149};
150
151static const short yyrhs[] = { 53,
152 0, 52, 53, 0, 0, 54, 55, 0, 0, 22,
153 56, 57, 0, 57, 0, 81, 0, 93, 0, 95,
154 0, 1, 43, 0, 1, 44, 0, 61, 58, 43,
155 0, 0, 59, 0, 60, 0, 59, 45, 60, 0,
156 71, 94, 92, 82, 0, 0, 62, 0, 63, 0,
157 62, 63, 0, 64, 0, 65, 0, 5, 0, 16,
158 0, 20, 0, 11, 0, 13, 0, 66, 0, 70,
159 0, 27, 46, 62, 47, 0, 21, 36, 0, 23,
160 36, 0, 10, 36, 0, 21, 36, 84, 0, 23,
161 36, 84, 0, 10, 36, 31, 0, 10, 31, 0,
162 21, 84, 0, 23, 84, 0, 7, 0, 18, 0,
163 14, 0, 15, 0, 19, 0, 24, 0, 12, 0,
164 9, 0, 25, 0, 6, 0, 40, 0, 48, 68,
165 0, 0, 69, 0, 70, 0, 69, 70, 0, 8,
166 0, 26, 0, 30, 0, 17, 0, 67, 71, 0,
167 72, 0, 36, 0, 72, 46, 75, 47, 0, 72,
168 46, 1, 47, 0, 72, 32, 0, 46, 71, 47,
169 0, 46, 1, 47, 0, 67, 73, 0, 74, 0,
170 36, 0, 40, 0, 74, 46, 75, 47, 0, 74,
171 46, 1, 47, 0, 74, 32, 0, 46, 73, 47,
172 0, 46, 1, 47, 0, 76, 35, 0, 76, 0,
173 77, 45, 35, 0, 0, 77, 0, 78, 0, 77,
174 45, 78, 0, 62, 79, 0, 67, 79, 0, 80,
175 0, 0, 36, 0, 40, 0, 80, 46, 75, 47,
176 0, 80, 46, 1, 47, 0, 80, 32, 0, 46,
177 79, 47, 0, 46, 1, 47, 0, 61, 71, 31,
178 0, 0, 83, 0, 49, 33, 0, 50, 85, 44,
179 0, 50, 1, 44, 0, 0, 86, 0, 87, 0,
180 86, 87, 0, 61, 88, 43, 0, 1, 43, 0,
181 0, 89, 0, 90, 0, 89, 45, 90, 0, 73,
182 92, 0, 36, 91, 0, 91, 0, 51, 33, 0,
183 0, 30, 0, 29, 43, 0, 0, 29, 0, 28,
184 46, 36, 47, 43, 0
185};
186
187#endif
188
189#if YYDEBUG != 0
190static const short yyrline[] = { 0,
191 101, 103, 106, 109, 112, 114, 115, 116, 117, 118,
192 119, 120, 123, 137, 139, 142, 151, 163, 169, 171,
193 174, 176, 179, 186, 189, 191, 192, 193, 194, 197,
194 199, 200, 204, 206, 208, 212, 219, 226, 235, 236,
195 237, 240, 242, 243, 244, 245, 246, 247, 248, 249,
196 250, 251, 254, 259, 261, 264, 266, 269, 270, 270,
197 271, 278, 280, 283, 293, 295, 297, 299, 301, 307,
198 309, 312, 314, 315, 317, 319, 321, 323, 327, 329,
199 330, 333, 335, 338, 340, 344, 349, 352, 355, 357,
200 365, 369, 371, 373, 375, 377, 381, 390, 392, 396,
201 401, 403, 406, 408, 411, 413, 416, 419, 423, 425,
202 428, 430, 433, 435, 436, 439, 443, 445, 448, 452,
203 454, 457
204};
205#endif
206
207
208#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
209
210static const char * const yytname[] = { "$","error","$undefined.","ASM_KEYW",
211"ATTRIBUTE_KEYW","AUTO_KEYW","BOOL_KEYW","CHAR_KEYW","CONST_KEYW","DOUBLE_KEYW",
212"ENUM_KEYW","EXTERN_KEYW","FLOAT_KEYW","INLINE_KEYW","INT_KEYW","LONG_KEYW",
213"REGISTER_KEYW","RESTRICT_KEYW","SHORT_KEYW","SIGNED_KEYW","STATIC_KEYW","STRUCT_KEYW",
214"TYPEDEF_KEYW","UNION_KEYW","UNSIGNED_KEYW","VOID_KEYW","VOLATILE_KEYW","TYPEOF_KEYW",
215"EXPORT_SYMBOL_KEYW","ASM_PHRASE","ATTRIBUTE_PHRASE","BRACE_PHRASE","BRACKET_PHRASE",
216"EXPRESSION_PHRASE","CHAR","DOTS","IDENT","INT","REAL","STRING","TYPE","OTHER",
217"FILENAME","';'","'}'","','","'('","')'","'*'","'='","'{'","':'","declaration_seq",
218"declaration","@1","declaration1","@2","simple_declaration","init_declarator_list_opt",
219"init_declarator_list","init_declarator","decl_specifier_seq_opt","decl_specifier_seq",
220"decl_specifier","storage_class_specifier","type_specifier","simple_type_specifier",
221"ptr_operator","cvar_qualifier_seq_opt","cvar_qualifier_seq","cvar_qualifier",
222"declarator","direct_declarator","nested_declarator","direct_nested_declarator",
223"parameter_declaration_clause","parameter_declaration_list_opt","parameter_declaration_list",
224"parameter_declaration","m_abstract_declarator","direct_m_abstract_declarator",
225"function_definition","initializer_opt","initializer","class_body","member_specification_opt",
226"member_specification","member_declaration","member_declarator_list_opt","member_declarator_list",
227"member_declarator","member_bitfield_declarator","attribute_opt","asm_definition",
228"asm_phrase_opt","export_definition", NULL
229};
230#endif
231
232static const short yyr1[] = { 0,
233 52, 52, 54, 53, 56, 55, 55, 55, 55, 55,
234 55, 55, 57, 58, 58, 59, 59, 60, 61, 61,
235 62, 62, 63, 63, 64, 64, 64, 64, 64, 65,
236 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
237 65, 66, 66, 66, 66, 66, 66, 66, 66, 66,
238 66, 66, 67, 68, 68, 69, 69, 70, 70, 70,
239 70, 71, 71, 72, 72, 72, 72, 72, 72, 73,
240 73, 74, 74, 74, 74, 74, 74, 74, 75, 75,
241 75, 76, 76, 77, 77, 78, 79, 79, 80, 80,
242 80, 80, 80, 80, 80, 80, 81, 82, 82, 83,
243 84, 84, 85, 85, 86, 86, 87, 87, 88, 88,
244 89, 89, 90, 90, 90, 91, 92, 92, 93, 94,
245 94, 95
246};
247
248static const short yyr2[] = { 0,
249 1, 2, 0, 2, 0, 3, 1, 1, 1, 1,
250 2, 2, 3, 0, 1, 1, 3, 4, 0, 1,
251 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
252 1, 4, 2, 2, 2, 3, 3, 3, 2, 2,
253 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
254 1, 1, 2, 0, 1, 1, 2, 1, 1, 1,
255 1, 2, 1, 1, 4, 4, 2, 3, 3, 2,
256 1, 1, 1, 4, 4, 2, 3, 3, 2, 1,
257 3, 0, 1, 1, 3, 2, 2, 1, 0, 1,
258 1, 4, 4, 2, 3, 3, 3, 0, 1, 2,
259 3, 3, 0, 1, 1, 2, 3, 2, 0, 1,
260 1, 3, 2, 2, 1, 2, 0, 1, 2, 0,
261 1, 5
262};
263
264static const short yydefact[] = { 3,
265 3, 1, 0, 2, 0, 25, 51, 42, 58, 49,
266 0, 28, 48, 29, 44, 45, 26, 61, 43, 46,
267 27, 0, 5, 0, 47, 50, 59, 0, 0, 0,
268 60, 52, 4, 7, 14, 20, 21, 23, 24, 30,
269 31, 8, 9, 10, 11, 12, 39, 35, 33, 0,
270 40, 19, 34, 41, 0, 0, 119, 64, 0, 54,
271 0, 15, 16, 0, 120, 63, 22, 38, 36, 0,
272 109, 0, 0, 105, 6, 14, 37, 0, 0, 0,
273 0, 53, 55, 56, 13, 0, 62, 121, 97, 117,
274 67, 0, 108, 102, 72, 73, 0, 0, 0, 117,
275 71, 0, 110, 111, 115, 101, 0, 106, 120, 32,
276 0, 69, 68, 57, 17, 118, 98, 0, 89, 0,
277 80, 83, 84, 114, 0, 72, 0, 116, 70, 113,
278 76, 0, 107, 0, 122, 0, 18, 99, 66, 90,
279 52, 0, 89, 86, 88, 65, 79, 0, 78, 77,
280 0, 0, 112, 100, 0, 91, 0, 87, 94, 0,
281 81, 85, 75, 74, 96, 95, 0, 0, 93, 92,
282 0, 0
283};
284
285static const short yydefgoto[] = { 1,
286 2, 3, 33, 52, 34, 61, 62, 63, 71, 36,
287 37, 38, 39, 40, 64, 82, 83, 41, 109, 66,
288 100, 101, 120, 121, 122, 123, 144, 145, 42, 137,
289 138, 51, 72, 73, 74, 102, 103, 104, 105, 117,
290 43, 90, 44
291};
292
293static const short yypact[] = {-32768,
294 15,-32768, 197,-32768, 23,-32768,-32768,-32768,-32768,-32768,
295 -18,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
296-32768, -28,-32768, -25,-32768,-32768,-32768, -26, -22, -12,
297-32768,-32768,-32768,-32768, 49, 493,-32768,-32768,-32768,-32768,
298-32768,-32768,-32768,-32768,-32768,-32768,-32768, 27, -8, 101,
299-32768, 493, -8,-32768, 493, 10,-32768,-32768, 11, 9,
300 18, 26,-32768, 49, -15, -13,-32768,-32768,-32768, 25,
301 24, 48, 149,-32768,-32768, 49,-32768, 414, 39, 40,
302 47,-32768, 9,-32768,-32768, 49,-32768,-32768,-32768, 66,
303-32768, 241,-32768,-32768, 50,-32768, 5, 65, 42, 66,
304 17, 56, 55,-32768,-32768,-32768, 60,-32768, 75,-32768,
305 80,-32768,-32768,-32768,-32768,-32768, 81, 82, 370, 85,
306 98, 89,-32768,-32768, 88,-32768, 91,-32768,-32768,-32768,
307-32768, 284,-32768, 24,-32768, 103,-32768,-32768,-32768,-32768,
308-32768, 8, 43,-32768, 30,-32768,-32768, 457,-32768,-32768,
309 92, 93,-32768,-32768, 95,-32768, 96,-32768,-32768, 327,
310-32768,-32768,-32768,-32768,-32768,-32768, 99, 104,-32768,-32768,
311 148,-32768
312};
313
314static const short yypgoto[] = {-32768,
315 152,-32768,-32768,-32768, 119,-32768,-32768, 94, 0, -55,
316 -35,-32768,-32768,-32768, -69,-32768,-32768, -56, -30,-32768,
317 -76,-32768, -122,-32768,-32768, 29, -62,-32768,-32768,-32768,
318-32768, -17,-32768,-32768, 105,-32768,-32768, 52, 86, 83,
319-32768,-32768,-32768
320};
321
322
323#define YYLAST 533
324
325
326static const short yytable[] = { 78,
327 67, 99, 35, 84, 65, 125, 54, 49, 155, 152,
328 53, 80, 47, 88, 171, 89, 9, 48, 91, 55,
329 127, 50, 129, 56, 50, 18, 114, 99, 81, 99,
330 57, 69, 92, 87, 27, 77, 119, 168, 31, -89,
331 126, 50, 67, 140, 96, 79, 58, 156, 131, 143,
332 97, 76, 60, 142, -89, 60, 59, 68, 60, 95,
333 85, 159, 132, 96, 99, 45, 46, 93, 94, 97,
334 86, 60, 143, 143, 98, 160, 119, 126, 140, 157,
335 158, 96, 156, 67, 58, 111, 112, 97, 142, 60,
336 60, 106, 119, 113, 59, 116, 60, 128, 133, 134,
337 98, 70, 93, 88, 119, 6, 7, 8, 9, 10,
338 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
339 21, 22, 135, 24, 25, 26, 27, 28, 139, 136,
340 31, 146, 147, 148, 149, 154, -19, 150, 163, 164,
341 32, 165, 166, -19, -103, 169, -19, 172, -19, 107,
342 170, -19, 4, 6, 7, 8, 9, 10, 11, 12,
343 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
344 75, 24, 25, 26, 27, 28, 162, 108, 31, 115,
345 124, 0, 130, 0, -19, 153, 0, 0, 32, 0,
346 0, -19, -104, 0, -19, 0, -19, 5, 0, -19,
347 0, 6, 7, 8, 9, 10, 11, 12, 13, 14,
348 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
349 25, 26, 27, 28, 29, 30, 31, 0, 0, 0,
350 0, 0, -19, 0, 0, 0, 32, 0, 0, -19,
351 0, 118, -19, 0, -19, 6, 7, 8, 9, 10,
352 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
353 21, 22, 0, 24, 25, 26, 27, 28, 0, 0,
354 31, 0, 0, 0, 0, -82, 0, 0, 0, 0,
355 32, 0, 0, 0, 151, 0, 0, -82, 6, 7,
356 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
357 18, 19, 20, 21, 22, 0, 24, 25, 26, 27,
358 28, 0, 0, 31, 0, 0, 0, 0, -82, 0,
359 0, 0, 0, 32, 0, 0, 0, 167, 0, 0,
360 -82, 6, 7, 8, 9, 10, 11, 12, 13, 14,
361 15, 16, 17, 18, 19, 20, 21, 22, 0, 24,
362 25, 26, 27, 28, 0, 0, 31, 0, 0, 0,
363 0, -82, 0, 0, 0, 0, 32, 0, 0, 0,
364 0, 0, 0, -82, 6, 7, 8, 9, 10, 11,
365 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
366 22, 0, 24, 25, 26, 27, 28, 0, 0, 31,
367 0, 0, 0, 0, 0, 140, 0, 0, 0, 141,
368 0, 0, 0, 0, 0, 142, 0, 60, 6, 7,
369 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
370 18, 19, 20, 21, 22, 0, 24, 25, 26, 27,
371 28, 0, 0, 31, 0, 0, 0, 0, 0, 0,
372 0, 0, 0, 32, 0, 0, 0, 0, 0, 0,
373 110, 6, 7, 8, 9, 10, 11, 12, 13, 14,
374 15, 16, 17, 18, 19, 20, 21, 22, 0, 24,
375 25, 26, 27, 28, 0, 0, 31, 0, 0, 0,
376 0, 161, 0, 0, 0, 0, 32, 6, 7, 8,
377 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
378 19, 20, 21, 22, 0, 24, 25, 26, 27, 28,
379 0, 0, 31, 0, 0, 0, 0, 0, 0, 0,
380 0, 0, 32
381};
382
383static const short yycheck[] = { 55,
384 36, 71, 3, 60, 35, 1, 24, 36, 1, 132,
385 36, 1, 31, 29, 0, 31, 8, 36, 32, 46,
386 97, 50, 99, 46, 50, 17, 83, 97, 59, 99,
387 43, 49, 46, 64, 26, 53, 92, 160, 30, 32,
388 36, 50, 78, 36, 40, 36, 36, 40, 32, 119,
389 46, 52, 48, 46, 47, 48, 46, 31, 48, 36,
390 43, 32, 46, 40, 134, 43, 44, 43, 44, 46,
391 45, 48, 142, 143, 51, 46, 132, 36, 36, 142,
392 143, 40, 40, 119, 36, 47, 47, 46, 46, 48,
393 48, 44, 148, 47, 46, 30, 48, 33, 43, 45,
394 51, 1, 43, 29, 160, 5, 6, 7, 8, 9,
395 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
396 20, 21, 43, 23, 24, 25, 26, 27, 47, 49,
397 30, 47, 35, 45, 47, 33, 36, 47, 47, 47,
398 40, 47, 47, 43, 44, 47, 46, 0, 48, 1,
399 47, 51, 1, 5, 6, 7, 8, 9, 10, 11,
400 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
401 52, 23, 24, 25, 26, 27, 148, 73, 30, 86,
402 95, -1, 100, -1, 36, 134, -1, -1, 40, -1,
403 -1, 43, 44, -1, 46, -1, 48, 1, -1, 51,
404 -1, 5, 6, 7, 8, 9, 10, 11, 12, 13,
405 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
406 24, 25, 26, 27, 28, 29, 30, -1, -1, -1,
407 -1, -1, 36, -1, -1, -1, 40, -1, -1, 43,
408 -1, 1, 46, -1, 48, 5, 6, 7, 8, 9,
409 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
410 20, 21, -1, 23, 24, 25, 26, 27, -1, -1,
411 30, -1, -1, -1, -1, 35, -1, -1, -1, -1,
412 40, -1, -1, -1, 1, -1, -1, 47, 5, 6,
413 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
414 17, 18, 19, 20, 21, -1, 23, 24, 25, 26,
415 27, -1, -1, 30, -1, -1, -1, -1, 35, -1,
416 -1, -1, -1, 40, -1, -1, -1, 1, -1, -1,
417 47, 5, 6, 7, 8, 9, 10, 11, 12, 13,
418 14, 15, 16, 17, 18, 19, 20, 21, -1, 23,
419 24, 25, 26, 27, -1, -1, 30, -1, -1, -1,
420 -1, 35, -1, -1, -1, -1, 40, -1, -1, -1,
421 -1, -1, -1, 47, 5, 6, 7, 8, 9, 10,
422 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
423 21, -1, 23, 24, 25, 26, 27, -1, -1, 30,
424 -1, -1, -1, -1, -1, 36, -1, -1, -1, 40,
425 -1, -1, -1, -1, -1, 46, -1, 48, 5, 6,
426 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
427 17, 18, 19, 20, 21, -1, 23, 24, 25, 26,
428 27, -1, -1, 30, -1, -1, -1, -1, -1, -1,
429 -1, -1, -1, 40, -1, -1, -1, -1, -1, -1,
430 47, 5, 6, 7, 8, 9, 10, 11, 12, 13,
431 14, 15, 16, 17, 18, 19, 20, 21, -1, 23,
432 24, 25, 26, 27, -1, -1, 30, -1, -1, -1,
433 -1, 35, -1, -1, -1, -1, 40, 5, 6, 7,
434 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
435 18, 19, 20, 21, -1, 23, 24, 25, 26, 27,
436 -1, -1, 30, -1, -1, -1, -1, -1, -1, -1,
437 -1, -1, 40
438};
439/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
440#line 3 "/usr/lib/bison.simple"
441/* This file comes from bison-1.28. */
442
443/* Skeleton output parser for bison,
444 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
445
446 This program is free software; you can redistribute it and/or modify
447 it under the terms of the GNU General Public License as published by
448 the Free Software Foundation; either version 2, or (at your option)
449 any later version.
450
451 This program is distributed in the hope that it will be useful,
452 but WITHOUT ANY WARRANTY; without even the implied warranty of
453 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
454 GNU General Public License for more details.
455
456 You should have received a copy of the GNU General Public License
457 along with this program; if not, write to the Free Software
458 Foundation, Inc., 59 Temple Place - Suite 330,
459 Boston, MA 02111-1307, USA. */
460
461/* As a special exception, when this file is copied by Bison into a
462 Bison output file, you may use that output file without restriction.
463 This special exception was added by the Free Software Foundation
464 in version 1.24 of Bison. */
465
466/* This is the parser code that is written into each bison parser
467 when the %semantic_parser declaration is not specified in the grammar.
468 It was written by Richard Stallman by simplifying the hairy parser
469 used when %semantic_parser is specified. */
470
471#ifndef YYSTACK_USE_ALLOCA
472#ifdef alloca
473#define YYSTACK_USE_ALLOCA
474#else /* alloca not defined */
475#ifdef __GNUC__
476#define YYSTACK_USE_ALLOCA
477#define alloca __builtin_alloca
478#else /* not GNU C. */
479#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
480#define YYSTACK_USE_ALLOCA
481#include <alloca.h>
482#else /* not sparc */
483/* We think this test detects Watcom and Microsoft C. */
484/* This used to test MSDOS, but that is a bad idea
485 since that symbol is in the user namespace. */
486#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
487#if 0 /* No need for malloc.h, which pollutes the namespace;
488 instead, just don't use alloca. */
489#include <malloc.h>
490#endif
491#else /* not MSDOS, or __TURBOC__ */
492#if defined(_AIX)
493/* I don't know what this was needed for, but it pollutes the namespace.
494 So I turned it off. rms, 2 May 1997. */
495/* #include <malloc.h> */
496 #pragma alloca
497#define YYSTACK_USE_ALLOCA
498#else /* not MSDOS, or __TURBOC__, or _AIX */
499#if 0
500#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
501 and on HPUX 10. Eventually we can turn this on. */
502#define YYSTACK_USE_ALLOCA
503#define alloca __builtin_alloca
504#endif /* __hpux */
505#endif
506#endif /* not _AIX */
507#endif /* not MSDOS, or __TURBOC__ */
508#endif /* not sparc */
509#endif /* not GNU C */
510#endif /* alloca not defined */
511#endif /* YYSTACK_USE_ALLOCA not defined */
512
513#ifdef YYSTACK_USE_ALLOCA
514#define YYSTACK_ALLOC alloca
515#else
516#define YYSTACK_ALLOC malloc
517#endif
518
519/* Note: there must be only one dollar sign in this file.
520 It is replaced by the list of actions, each action
521 as one case of the switch. */
522
523#define yyerrok (yyerrstatus = 0)
524#define yyclearin (yychar = YYEMPTY)
525#define YYEMPTY -2
526#define YYEOF 0
527#define YYACCEPT goto yyacceptlab
528#define YYABORT goto yyabortlab
529#define YYERROR goto yyerrlab1
530/* Like YYERROR except do call yyerror.
531 This remains here temporarily to ease the
532 transition to the new meaning of YYERROR, for GCC.
533 Once GCC version 2 has supplanted version 1, this can go. */
534#define YYFAIL goto yyerrlab
535#define YYRECOVERING() (!!yyerrstatus)
536#define YYBACKUP(token, value) \
537do \
538 if (yychar == YYEMPTY && yylen == 1) \
539 { yychar = (token), yylval = (value); \
540 yychar1 = YYTRANSLATE (yychar); \
541 YYPOPSTACK; \
542 goto yybackup; \
543 } \
544 else \
545 { yyerror ("syntax error: cannot back up"); YYERROR; } \
546while (0)
547
548#define YYTERROR 1
549#define YYERRCODE 256
550
551#ifndef YYPURE
552#define YYLEX yylex()
553#endif
554
555#ifdef YYPURE
556#ifdef YYLSP_NEEDED
557#ifdef YYLEX_PARAM
558#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
559#else
560#define YYLEX yylex(&yylval, &yylloc)
561#endif
562#else /* not YYLSP_NEEDED */
563#ifdef YYLEX_PARAM
564#define YYLEX yylex(&yylval, YYLEX_PARAM)
565#else
566#define YYLEX yylex(&yylval)
567#endif
568#endif /* not YYLSP_NEEDED */
569#endif
570
571/* If nonreentrant, generate the variables here */
572
573#ifndef YYPURE
574
575int yychar; /* the lookahead symbol */
576YYSTYPE yylval; /* the semantic value of the */
577 /* lookahead symbol */
578
579#ifdef YYLSP_NEEDED
580YYLTYPE yylloc; /* location data for the lookahead */
581 /* symbol */
582#endif
583
584int yynerrs; /* number of parse errors so far */
585#endif /* not YYPURE */
586
587#if YYDEBUG != 0
588int yydebug; /* nonzero means print parse trace */
589/* Since this is uninitialized, it does not stop multiple parsers
590 from coexisting. */
591#endif
592
593/* YYINITDEPTH indicates the initial size of the parser's stacks */
594
595#ifndef YYINITDEPTH
596#define YYINITDEPTH 200
597#endif
598
599/* YYMAXDEPTH is the maximum size the stacks can grow to
600 (effective only if the built-in stack extension method is used). */
601
602#if YYMAXDEPTH == 0
603#undef YYMAXDEPTH
604#endif
605
606#ifndef YYMAXDEPTH
607#define YYMAXDEPTH 10000
608#endif
609
610/* Define __yy_memcpy. Note that the size argument
611 should be passed with type unsigned int, because that is what the non-GCC
612 definitions require. With GCC, __builtin_memcpy takes an arg
613 of type size_t, but it can handle unsigned int. */
614
615#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
616#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
617#else /* not GNU C or C++ */
618#ifndef __cplusplus
619
620/* This is the most reliable way to avoid incompatibilities
621 in available built-in functions on various systems. */
622static void
623__yy_memcpy (to, from, count)
624 char *to;
625 char *from;
626 unsigned int count;
627{
628 register char *f = from;
629 register char *t = to;
630 register int i = count;
631
632 while (i-- > 0)
633 *t++ = *f++;
634}
635
636#else /* __cplusplus */
637
638/* This is the most reliable way to avoid incompatibilities
639 in available built-in functions on various systems. */
640static void
641__yy_memcpy (char *to, char *from, unsigned int count)
642{
643 register char *t = to;
644 register char *f = from;
645 register int i = count;
646
647 while (i-- > 0)
648 *t++ = *f++;
649}
650
651#endif
652#endif
653
654#line 217 "/usr/lib/bison.simple"
655
656/* The user can define YYPARSE_PARAM as the name of an argument to be passed
657 into yyparse. The argument should have type void *.
658 It should actually point to an object.
659 Grammar actions can access the variable by casting it
660 to the proper pointer type. */
661
662#ifdef YYPARSE_PARAM
663#ifdef __cplusplus
664#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
665#define YYPARSE_PARAM_DECL
666#else /* not __cplusplus */
667#define YYPARSE_PARAM_ARG YYPARSE_PARAM
668#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
669#endif /* not __cplusplus */
670#else /* not YYPARSE_PARAM */
671#define YYPARSE_PARAM_ARG
672#define YYPARSE_PARAM_DECL
673#endif /* not YYPARSE_PARAM */
674
675/* Prevent warning if -Wstrict-prototypes. */
676#ifdef __GNUC__
677#ifdef YYPARSE_PARAM
678int yyparse (void *);
679#else
680int yyparse (void);
681#endif
682#endif
683
684int
685yyparse(YYPARSE_PARAM_ARG)
686 YYPARSE_PARAM_DECL
687{
688 register int yystate;
689 register int yyn;
690 register short *yyssp;
691 register YYSTYPE *yyvsp;
692 int yyerrstatus; /* number of tokens to shift before error messages enabled */
693 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
694
695 short yyssa[YYINITDEPTH]; /* the state stack */
696 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
697
698 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
699 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
700
701#ifdef YYLSP_NEEDED
702 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
703 YYLTYPE *yyls = yylsa;
704 YYLTYPE *yylsp;
705
706#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
707#else
708#define YYPOPSTACK (yyvsp--, yyssp--)
709#endif
710
711 int yystacksize = YYINITDEPTH;
712 int yyfree_stacks = 0;
713
714#ifdef YYPURE
715 int yychar;
716 YYSTYPE yylval;
717 int yynerrs;
718#ifdef YYLSP_NEEDED
719 YYLTYPE yylloc;
720#endif
721#endif
722
723 YYSTYPE yyval; /* the variable used to return */
724 /* semantic values from the action */
725 /* routines */
726
727 int yylen;
728
729#if YYDEBUG != 0
730 if (yydebug)
731 fprintf(stderr, "Starting parse\n");
732#endif
733
734 yystate = 0;
735 yyerrstatus = 0;
736 yynerrs = 0;
737 yychar = YYEMPTY; /* Cause a token to be read. */
738
739 /* Initialize stack pointers.
740 Waste one element of value and location stack
741 so that they stay on the same level as the state stack.
742 The wasted elements are never initialized. */
743
744 yyssp = yyss - 1;
745 yyvsp = yyvs;
746#ifdef YYLSP_NEEDED
747 yylsp = yyls;
748#endif
749
750/* Push a new state, which is found in yystate . */
751/* In all cases, when you get here, the value and location stacks
752 have just been pushed. so pushing a state here evens the stacks. */
753yynewstate:
754
755 *++yyssp = yystate;
756
757 if (yyssp >= yyss + yystacksize - 1)
758 {
759 /* Give user a chance to reallocate the stack */
760 /* Use copies of these so that the &'s don't force the real ones into memory. */
761 YYSTYPE *yyvs1 = yyvs;
762 short *yyss1 = yyss;
763#ifdef YYLSP_NEEDED
764 YYLTYPE *yyls1 = yyls;
765#endif
766
767 /* Get the current used size of the three stacks, in elements. */
768 int size = yyssp - yyss + 1;
769
770#ifdef yyoverflow
771 /* Each stack pointer address is followed by the size of
772 the data in use in that stack, in bytes. */
773#ifdef YYLSP_NEEDED
774 /* This used to be a conditional around just the two extra args,
775 but that might be undefined if yyoverflow is a macro. */
776 yyoverflow("parser stack overflow",
777 &yyss1, size * sizeof (*yyssp),
778 &yyvs1, size * sizeof (*yyvsp),
779 &yyls1, size * sizeof (*yylsp),
780 &yystacksize);
781#else
782 yyoverflow("parser stack overflow",
783 &yyss1, size * sizeof (*yyssp),
784 &yyvs1, size * sizeof (*yyvsp),
785 &yystacksize);
786#endif
787
788 yyss = yyss1; yyvs = yyvs1;
789#ifdef YYLSP_NEEDED
790 yyls = yyls1;
791#endif
792#else /* no yyoverflow */
793 /* Extend the stack our own way. */
794 if (yystacksize >= YYMAXDEPTH)
795 {
796 yyerror("parser stack overflow");
797 if (yyfree_stacks)
798 {
799 free (yyss);
800 free (yyvs);
801#ifdef YYLSP_NEEDED
802 free (yyls);
803#endif
804 }
805 return 2;
806 }
807 yystacksize *= 2;
808 if (yystacksize > YYMAXDEPTH)
809 yystacksize = YYMAXDEPTH;
810#ifndef YYSTACK_USE_ALLOCA
811 yyfree_stacks = 1;
812#endif
813 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
814 __yy_memcpy ((char *)yyss, (char *)yyss1,
815 size * (unsigned int) sizeof (*yyssp));
816 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
817 __yy_memcpy ((char *)yyvs, (char *)yyvs1,
818 size * (unsigned int) sizeof (*yyvsp));
819#ifdef YYLSP_NEEDED
820 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
821 __yy_memcpy ((char *)yyls, (char *)yyls1,
822 size * (unsigned int) sizeof (*yylsp));
823#endif
824#endif /* no yyoverflow */
825
826 yyssp = yyss + size - 1;
827 yyvsp = yyvs + size - 1;
828#ifdef YYLSP_NEEDED
829 yylsp = yyls + size - 1;
830#endif
831
832#if YYDEBUG != 0
833 if (yydebug)
834 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
835#endif
836
837 if (yyssp >= yyss + yystacksize - 1)
838 YYABORT;
839 }
840
841#if YYDEBUG != 0
842 if (yydebug)
843 fprintf(stderr, "Entering state %d\n", yystate);
844#endif
845
846 goto yybackup;
847 yybackup:
848
849/* Do appropriate processing given the current state. */
850/* Read a lookahead token if we need one and don't already have one. */
851/* yyresume: */
852
853 /* First try to decide what to do without reference to lookahead token. */
854
855 yyn = yypact[yystate];
856 if (yyn == YYFLAG)
857 goto yydefault;
858
859 /* Not known => get a lookahead token if don't already have one. */
860
861 /* yychar is either YYEMPTY or YYEOF
862 or a valid token in external form. */
863
864 if (yychar == YYEMPTY)
865 {
866#if YYDEBUG != 0
867 if (yydebug)
868 fprintf(stderr, "Reading a token: ");
869#endif
870 yychar = YYLEX;
871 }
872
873 /* Convert token to internal form (in yychar1) for indexing tables with */
874
875 if (yychar <= 0) /* This means end of input. */
876 {
877 yychar1 = 0;
878 yychar = YYEOF; /* Don't call YYLEX any more */
879
880#if YYDEBUG != 0
881 if (yydebug)
882 fprintf(stderr, "Now at end of input.\n");
883#endif
884 }
885 else
886 {
887 yychar1 = YYTRANSLATE(yychar);
888
889#if YYDEBUG != 0
890 if (yydebug)
891 {
892 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
893 /* Give the individual parser a way to print the precise meaning
894 of a token, for further debugging info. */
895#ifdef YYPRINT
896 YYPRINT (stderr, yychar, yylval);
897#endif
898 fprintf (stderr, ")\n");
899 }
900#endif
901 }
902
903 yyn += yychar1;
904 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
905 goto yydefault;
906
907 yyn = yytable[yyn];
908
909 /* yyn is what to do for this token type in this state.
910 Negative => reduce, -yyn is rule number.
911 Positive => shift, yyn is new state.
912 New state is final state => don't bother to shift,
913 just return success.
914 0, or most negative number => error. */
915
916 if (yyn < 0)
917 {
918 if (yyn == YYFLAG)
919 goto yyerrlab;
920 yyn = -yyn;
921 goto yyreduce;
922 }
923 else if (yyn == 0)
924 goto yyerrlab;
925
926 if (yyn == YYFINAL)
927 YYACCEPT;
928
929 /* Shift the lookahead token. */
930
931#if YYDEBUG != 0
932 if (yydebug)
933 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
934#endif
935
936 /* Discard the token being shifted unless it is eof. */
937 if (yychar != YYEOF)
938 yychar = YYEMPTY;
939
940 *++yyvsp = yylval;
941#ifdef YYLSP_NEEDED
942 *++yylsp = yylloc;
943#endif
944
945 /* count tokens shifted since error; after three, turn off error status. */
946 if (yyerrstatus) yyerrstatus--;
947
948 yystate = yyn;
949 goto yynewstate;
950
951/* Do the default action for the current state. */
952yydefault:
953
954 yyn = yydefact[yystate];
955 if (yyn == 0)
956 goto yyerrlab;
957
958/* Do a reduction. yyn is the number of a rule to reduce with. */
959yyreduce:
960 yylen = yyr2[yyn];
961 if (yylen > 0)
962 yyval = yyvsp[1-yylen]; /* implement default value of the action */
963
964#if YYDEBUG != 0
965 if (yydebug)
966 {
967 int i;
968
969 fprintf (stderr, "Reducing via rule %d (line %d), ",
970 yyn, yyrline[yyn]);
971
972 /* Print the symbols being reduced, and their result. */
973 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
974 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
975 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
976 }
977#endif
978
979
980 switch (yyn) {
981
982case 3:
983#line 107 "scripts/genksyms/parse.y"
984{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;
985 break;}
986case 4:
987#line 109 "scripts/genksyms/parse.y"
988{ free_list(*yyvsp[0], NULL); *yyvsp[0] = NULL; ;
989 break;}
990case 5:
991#line 113 "scripts/genksyms/parse.y"
992{ is_typedef = 1; ;
993 break;}
994case 6:
995#line 114 "scripts/genksyms/parse.y"
996{ yyval = yyvsp[0]; ;
997 break;}
998case 11:
999#line 119 "scripts/genksyms/parse.y"
1000{ yyval = yyvsp[0]; ;
1001 break;}
1002case 12:
1003#line 120 "scripts/genksyms/parse.y"
1004{ yyval = yyvsp[0]; ;
1005 break;}
1006case 13:
1007#line 125 "scripts/genksyms/parse.y"
1008{ if (current_name) {
1009 struct string_list *decl = (*yyvsp[0])->next;
1010 (*yyvsp[0])->next = NULL;
1011 add_symbol(current_name,
1012 is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
1013 decl, is_extern);
1014 current_name = NULL;
1015 }
1016 yyval = yyvsp[0];
1017 ;
1018 break;}
1019case 14:
1020#line 138 "scripts/genksyms/parse.y"
1021{ yyval = NULL; ;
1022 break;}
1023case 16:
1024#line 144 "scripts/genksyms/parse.y"
1025{ struct string_list *decl = *yyvsp[0];
1026 *yyvsp[0] = NULL;
1027 add_symbol(current_name,
1028 is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
1029 current_name = NULL;
1030 yyval = yyvsp[0];
1031 ;
1032 break;}
1033case 17:
1034#line 152 "scripts/genksyms/parse.y"
1035{ struct string_list *decl = *yyvsp[0];
1036 *yyvsp[0] = NULL;
1037 free_list(*yyvsp[-1], NULL);
1038 *yyvsp[-1] = decl_spec;
1039 add_symbol(current_name,
1040 is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
1041 current_name = NULL;
1042 yyval = yyvsp[0];
1043 ;
1044 break;}
1045case 18:
1046#line 165 "scripts/genksyms/parse.y"
1047{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1] ? yyvsp[-1] : yyvsp[-2] ? yyvsp[-2] : yyvsp[-3]; ;
1048 break;}
1049case 19:
1050#line 170 "scripts/genksyms/parse.y"
1051{ decl_spec = NULL; ;
1052 break;}
1053case 21:
1054#line 175 "scripts/genksyms/parse.y"
1055{ decl_spec = *yyvsp[0]; ;
1056 break;}
1057case 22:
1058#line 176 "scripts/genksyms/parse.y"
1059{ decl_spec = *yyvsp[0]; ;
1060 break;}
1061case 23:
1062#line 181 "scripts/genksyms/parse.y"
1063{ /* Version 2 checksumming ignores storage class, as that
1064 is really irrelevant to the linkage. */
1065 remove_node(yyvsp[0]);
1066 yyval = yyvsp[0];
1067 ;
1068 break;}
1069case 28:
1070#line 193 "scripts/genksyms/parse.y"
1071{ is_extern = 1; yyval = yyvsp[0]; ;
1072 break;}
1073case 29:
1074#line 194 "scripts/genksyms/parse.y"
1075{ is_extern = 0; yyval = yyvsp[0]; ;
1076 break;}
1077case 33:
1078#line 205 "scripts/genksyms/parse.y"
1079{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_STRUCT; yyval = yyvsp[0]; ;
1080 break;}
1081case 34:
1082#line 207 "scripts/genksyms/parse.y"
1083{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_UNION; yyval = yyvsp[0]; ;
1084 break;}
1085case 35:
1086#line 209 "scripts/genksyms/parse.y"
1087{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_ENUM; yyval = yyvsp[0]; ;
1088 break;}
1089case 36:
1090#line 213 "scripts/genksyms/parse.y"
1091{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
1092 r = copy_node(i); r->tag = SYM_STRUCT;
1093 r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
1094 add_symbol(i->string, SYM_STRUCT, s, is_extern);
1095 yyval = yyvsp[0];
1096 ;
1097 break;}
1098case 37:
1099#line 220 "scripts/genksyms/parse.y"
1100{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
1101 r = copy_node(i); r->tag = SYM_UNION;
1102 r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
1103 add_symbol(i->string, SYM_UNION, s, is_extern);
1104 yyval = yyvsp[0];
1105 ;
1106 break;}
1107case 38:
1108#line 227 "scripts/genksyms/parse.y"
1109{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
1110 r = copy_node(i); r->tag = SYM_ENUM;
1111 r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
1112 add_symbol(i->string, SYM_ENUM, s, is_extern);
1113 yyval = yyvsp[0];
1114 ;
1115 break;}
1116case 39:
1117#line 235 "scripts/genksyms/parse.y"
1118{ yyval = yyvsp[0]; ;
1119 break;}
1120case 40:
1121#line 236 "scripts/genksyms/parse.y"
1122{ yyval = yyvsp[0]; ;
1123 break;}
1124case 41:
1125#line 237 "scripts/genksyms/parse.y"
1126{ yyval = yyvsp[0]; ;
1127 break;}
1128case 52:
1129#line 251 "scripts/genksyms/parse.y"
1130{ (*yyvsp[0])->tag = SYM_TYPEDEF; yyval = yyvsp[0]; ;
1131 break;}
1132case 53:
1133#line 256 "scripts/genksyms/parse.y"
1134{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
1135 break;}
1136case 54:
1137#line 260 "scripts/genksyms/parse.y"
1138{ yyval = NULL; ;
1139 break;}
1140case 57:
1141#line 266 "scripts/genksyms/parse.y"
1142{ yyval = yyvsp[0]; ;
1143 break;}
1144case 61:
1145#line 272 "scripts/genksyms/parse.y"
1146{ /* restrict has no effect in prototypes so ignore it */
1147 remove_node(yyvsp[0]);
1148 yyval = yyvsp[0];
1149 ;
1150 break;}
1151case 62:
1152#line 279 "scripts/genksyms/parse.y"
1153{ yyval = yyvsp[0]; ;
1154 break;}
1155case 64:
1156#line 285 "scripts/genksyms/parse.y"
1157{ if (current_name != NULL) {
1158 error_with_pos("unexpected second declaration name");
1159 YYERROR;
1160 } else {
1161 current_name = (*yyvsp[0])->string;
1162 yyval = yyvsp[0];
1163 }
1164 ;
1165 break;}
1166case 65:
1167#line 294 "scripts/genksyms/parse.y"
1168{ yyval = yyvsp[0]; ;
1169 break;}
1170case 66:
1171#line 296 "scripts/genksyms/parse.y"
1172{ yyval = yyvsp[0]; ;
1173 break;}
1174case 67:
1175#line 298 "scripts/genksyms/parse.y"
1176{ yyval = yyvsp[0]; ;
1177 break;}
1178case 68:
1179#line 300 "scripts/genksyms/parse.y"
1180{ yyval = yyvsp[0]; ;
1181 break;}
1182case 69:
1183#line 302 "scripts/genksyms/parse.y"
1184{ yyval = yyvsp[0]; ;
1185 break;}
1186case 70:
1187#line 308 "scripts/genksyms/parse.y"
1188{ yyval = yyvsp[0]; ;
1189 break;}
1190case 74:
1191#line 316 "scripts/genksyms/parse.y"
1192{ yyval = yyvsp[0]; ;
1193 break;}
1194case 75:
1195#line 318 "scripts/genksyms/parse.y"
1196{ yyval = yyvsp[0]; ;
1197 break;}
1198case 76:
1199#line 320 "scripts/genksyms/parse.y"
1200{ yyval = yyvsp[0]; ;
1201 break;}
1202case 77:
1203#line 322 "scripts/genksyms/parse.y"
1204{ yyval = yyvsp[0]; ;
1205 break;}
1206case 78:
1207#line 324 "scripts/genksyms/parse.y"
1208{ yyval = yyvsp[0]; ;
1209 break;}
1210case 79:
1211#line 328 "scripts/genksyms/parse.y"
1212{ yyval = yyvsp[0]; ;
1213 break;}
1214case 81:
1215#line 330 "scripts/genksyms/parse.y"
1216{ yyval = yyvsp[0]; ;
1217 break;}
1218case 82:
1219#line 334 "scripts/genksyms/parse.y"
1220{ yyval = NULL; ;
1221 break;}
1222case 85:
1223#line 341 "scripts/genksyms/parse.y"
1224{ yyval = yyvsp[0]; ;
1225 break;}
1226case 86:
1227#line 346 "scripts/genksyms/parse.y"
1228{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
1229 break;}
1230case 87:
1231#line 351 "scripts/genksyms/parse.y"
1232{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
1233 break;}
1234case 89:
1235#line 356 "scripts/genksyms/parse.y"
1236{ yyval = NULL; ;
1237 break;}
1238case 90:
1239#line 358 "scripts/genksyms/parse.y"
1240{ /* For version 2 checksums, we don't want to remember
1241 private parameter names. */
1242 remove_node(yyvsp[0]);
1243 yyval = yyvsp[0];
1244 ;
1245 break;}
1246case 91:
1247#line 366 "scripts/genksyms/parse.y"
1248{ remove_node(yyvsp[0]);
1249 yyval = yyvsp[0];
1250 ;
1251 break;}
1252case 92:
1253#line 370 "scripts/genksyms/parse.y"
1254{ yyval = yyvsp[0]; ;
1255 break;}
1256case 93:
1257#line 372 "scripts/genksyms/parse.y"
1258{ yyval = yyvsp[0]; ;
1259 break;}
1260case 94:
1261#line 374 "scripts/genksyms/parse.y"
1262{ yyval = yyvsp[0]; ;
1263 break;}
1264case 95:
1265#line 376 "scripts/genksyms/parse.y"
1266{ yyval = yyvsp[0]; ;
1267 break;}
1268case 96:
1269#line 378 "scripts/genksyms/parse.y"
1270{ yyval = yyvsp[0]; ;
1271 break;}
1272case 97:
1273#line 383 "scripts/genksyms/parse.y"
1274{ struct string_list *decl = *yyvsp[-1];
1275 *yyvsp[-1] = NULL;
1276 add_symbol(current_name, SYM_NORMAL, decl, is_extern);
1277 yyval = yyvsp[0];
1278 ;
1279 break;}
1280case 98:
1281#line 391 "scripts/genksyms/parse.y"
1282{ yyval = NULL; ;
1283 break;}
1284case 100:
1285#line 398 "scripts/genksyms/parse.y"
1286{ remove_list(yyvsp[0], &(*yyvsp[-1])->next); yyval = yyvsp[0]; ;
1287 break;}
1288case 101:
1289#line 402 "scripts/genksyms/parse.y"
1290{ yyval = yyvsp[0]; ;
1291 break;}
1292case 102:
1293#line 403 "scripts/genksyms/parse.y"
1294{ yyval = yyvsp[0]; ;
1295 break;}
1296case 103:
1297#line 407 "scripts/genksyms/parse.y"
1298{ yyval = NULL; ;
1299 break;}
1300case 106:
1301#line 413 "scripts/genksyms/parse.y"
1302{ yyval = yyvsp[0]; ;
1303 break;}
1304case 107:
1305#line 418 "scripts/genksyms/parse.y"
1306{ yyval = yyvsp[0]; ;
1307 break;}
1308case 108:
1309#line 420 "scripts/genksyms/parse.y"
1310{ yyval = yyvsp[0]; ;
1311 break;}
1312case 109:
1313#line 424 "scripts/genksyms/parse.y"
1314{ yyval = NULL; ;
1315 break;}
1316case 112:
1317#line 430 "scripts/genksyms/parse.y"
1318{ yyval = yyvsp[0]; ;
1319 break;}
1320case 113:
1321#line 434 "scripts/genksyms/parse.y"
1322{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
1323 break;}
1324case 114:
1325#line 435 "scripts/genksyms/parse.y"
1326{ yyval = yyvsp[0]; ;
1327 break;}
1328case 116:
1329#line 440 "scripts/genksyms/parse.y"
1330{ yyval = yyvsp[0]; ;
1331 break;}
1332case 117:
1333#line 444 "scripts/genksyms/parse.y"
1334{ yyval = NULL; ;
1335 break;}
1336case 119:
1337#line 449 "scripts/genksyms/parse.y"
1338{ yyval = yyvsp[0]; ;
1339 break;}
1340case 120:
1341#line 453 "scripts/genksyms/parse.y"
1342{ yyval = NULL; ;
1343 break;}
1344case 122:
1345#line 459 "scripts/genksyms/parse.y"
1346{ export_symbol((*yyvsp[-2])->string); yyval = yyvsp[0]; ;
1347 break;}
1348}
1349 /* the action file gets copied in in place of this dollarsign */
1350#line 543 "/usr/lib/bison.simple"
1351
1352 yyvsp -= yylen;
1353 yyssp -= yylen;
1354#ifdef YYLSP_NEEDED
1355 yylsp -= yylen;
1356#endif
1357
1358#if YYDEBUG != 0
1359 if (yydebug)
1360 {
1361 short *ssp1 = yyss - 1;
1362 fprintf (stderr, "state stack now");
1363 while (ssp1 != yyssp)
1364 fprintf (stderr, " %d", *++ssp1);
1365 fprintf (stderr, "\n");
1366 }
1367#endif
1368
1369 *++yyvsp = yyval;
1370
1371#ifdef YYLSP_NEEDED
1372 yylsp++;
1373 if (yylen == 0)
1374 {
1375 yylsp->first_line = yylloc.first_line;
1376 yylsp->first_column = yylloc.first_column;
1377 yylsp->last_line = (yylsp-1)->last_line;
1378 yylsp->last_column = (yylsp-1)->last_column;
1379 yylsp->text = 0;
1380 }
1381 else
1382 {
1383 yylsp->last_line = (yylsp+yylen-1)->last_line;
1384 yylsp->last_column = (yylsp+yylen-1)->last_column;
1385 }
1386#endif
1387
1388 /* Now "shift" the result of the reduction.
1389 Determine what state that goes to,
1390 based on the state we popped back to
1391 and the rule number reduced by. */
1392
1393 yyn = yyr1[yyn];
1394
1395 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1396 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1397 yystate = yytable[yystate];
1398 else
1399 yystate = yydefgoto[yyn - YYNTBASE];
1400
1401 goto yynewstate;
1402
1403yyerrlab: /* here on detecting error */
1404
1405 if (! yyerrstatus)
1406 /* If not already recovering from an error, report this error. */
1407 {
1408 ++yynerrs;
1409
1410#ifdef YYERROR_VERBOSE
1411 yyn = yypact[yystate];
1412
1413 if (yyn > YYFLAG && yyn < YYLAST)
1414 {
1415 int size = 0;
1416 char *msg;
1417 int x, count;
1418
1419 count = 0;
1420 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1421 for (x = (yyn < 0 ? -yyn : 0);
1422 x < (sizeof(yytname) / sizeof(char *)); x++)
1423 if (yycheck[x + yyn] == x)
1424 size += strlen(yytname[x]) + 15, count++;
1425 msg = (char *) malloc(size + 15);
1426 if (msg != 0)
1427 {
1428 strcpy(msg, "parse error");
1429
1430 if (count < 5)
1431 {
1432 count = 0;
1433 for (x = (yyn < 0 ? -yyn : 0);
1434 x < (sizeof(yytname) / sizeof(char *)); x++)
1435 if (yycheck[x + yyn] == x)
1436 {
1437 strcat(msg, count == 0 ? ", expecting `" : " or `");
1438 strcat(msg, yytname[x]);
1439 strcat(msg, "'");
1440 count++;
1441 }
1442 }
1443 yyerror(msg);
1444 free(msg);
1445 }
1446 else
1447 yyerror ("parse error; also virtual memory exceeded");
1448 }
1449 else
1450#endif /* YYERROR_VERBOSE */
1451 yyerror("parse error");
1452 }
1453
1454 goto yyerrlab1;
1455yyerrlab1: /* here on error raised explicitly by an action */
1456
1457 if (yyerrstatus == 3)
1458 {
1459 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1460
1461 /* return failure if at end of input */
1462 if (yychar == YYEOF)
1463 YYABORT;
1464
1465#if YYDEBUG != 0
1466 if (yydebug)
1467 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1468#endif
1469
1470 yychar = YYEMPTY;
1471 }
1472
1473 /* Else will try to reuse lookahead token
1474 after shifting the error token. */
1475
1476 yyerrstatus = 3; /* Each real token shifted decrements this */
1477
1478 goto yyerrhandle;
1479
1480yyerrdefault: /* current state does not do anything special for the error token. */
1481
1482#if 0
1483 /* This is wrong; only states that explicitly want error tokens
1484 should shift them. */
1485 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1486 if (yyn) goto yydefault;
1487#endif
1488
1489yyerrpop: /* pop the current state because it cannot handle the error token */
1490
1491 if (yyssp == yyss) YYABORT;
1492 yyvsp--;
1493 yystate = *--yyssp;
1494#ifdef YYLSP_NEEDED
1495 yylsp--;
1496#endif
1497
1498#if YYDEBUG != 0
1499 if (yydebug)
1500 {
1501 short *ssp1 = yyss - 1;
1502 fprintf (stderr, "Error: state stack now");
1503 while (ssp1 != yyssp)
1504 fprintf (stderr, " %d", *++ssp1);
1505 fprintf (stderr, "\n");
1506 }
1507#endif
1508
1509yyerrhandle:
1510
1511 yyn = yypact[yystate];
1512 if (yyn == YYFLAG)
1513 goto yyerrdefault;
1514
1515 yyn += YYTERROR;
1516 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1517 goto yyerrdefault;
1518
1519 yyn = yytable[yyn];
1520 if (yyn < 0)
1521 {
1522 if (yyn == YYFLAG)
1523 goto yyerrpop;
1524 yyn = -yyn;
1525 goto yyreduce;
1526 }
1527 else if (yyn == 0)
1528 goto yyerrpop;
1529
1530 if (yyn == YYFINAL)
1531 YYACCEPT;
1532
1533#if YYDEBUG != 0
1534 if (yydebug)
1535 fprintf(stderr, "Shifting error token, ");
1536#endif
1537
1538 *++yyvsp = yylval;
1539#ifdef YYLSP_NEEDED
1540 *++yylsp = yylloc;
1541#endif
1542
1543 yystate = yyn;
1544 goto yynewstate;
1545
1546 yyacceptlab:
1547 /* YYACCEPT comes here. */
1548 if (yyfree_stacks)
1549 {
1550 free (yyss);
1551 free (yyvs);
1552#ifdef YYLSP_NEEDED
1553 free (yyls);
1554#endif
1555 }
1556 return 0;
1557
1558 yyabortlab:
1559 /* YYABORT comes here. */
1560 if (yyfree_stacks)
1561 {
1562 free (yyss);
1563 free (yyvs);
1564#ifdef YYLSP_NEEDED
1565 free (yyls);
1566#endif
1567 }
1568 return 1;
1569}
1570#line 463 "scripts/genksyms/parse.y"
1571
1572
1573static void
1574yyerror(const char *e)
1575{
1576 error_with_pos("%s", e);
1577}
diff --git a/scripts/genksyms/parse.h_shipped b/scripts/genksyms/parse.h_shipped
new file mode 100644
index 000000000000..d5b27e3b20c4
--- /dev/null
+++ b/scripts/genksyms/parse.h_shipped
@@ -0,0 +1,46 @@
1#ifndef YYSTYPE
2#define YYSTYPE int
3#endif
4#define ASM_KEYW 257
5#define ATTRIBUTE_KEYW 258
6#define AUTO_KEYW 259
7#define BOOL_KEYW 260
8#define CHAR_KEYW 261
9#define CONST_KEYW 262
10#define DOUBLE_KEYW 263
11#define ENUM_KEYW 264
12#define EXTERN_KEYW 265
13#define FLOAT_KEYW 266
14#define INLINE_KEYW 267
15#define INT_KEYW 268
16#define LONG_KEYW 269
17#define REGISTER_KEYW 270
18#define RESTRICT_KEYW 271
19#define SHORT_KEYW 272
20#define SIGNED_KEYW 273
21#define STATIC_KEYW 274
22#define STRUCT_KEYW 275
23#define TYPEDEF_KEYW 276
24#define UNION_KEYW 277
25#define UNSIGNED_KEYW 278
26#define VOID_KEYW 279
27#define VOLATILE_KEYW 280
28#define TYPEOF_KEYW 281
29#define EXPORT_SYMBOL_KEYW 282
30#define ASM_PHRASE 283
31#define ATTRIBUTE_PHRASE 284
32#define BRACE_PHRASE 285
33#define BRACKET_PHRASE 286
34#define EXPRESSION_PHRASE 287
35#define CHAR 288
36#define DOTS 289
37#define IDENT 290
38#define INT 291
39#define REAL 292
40#define STRING 293
41#define TYPE 294
42#define OTHER 295
43#define FILENAME 296
44
45
46extern YYSTYPE yylval;
diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y
new file mode 100644
index 000000000000..099043713db4
--- /dev/null
+++ b/scripts/genksyms/parse.y
@@ -0,0 +1,469 @@
1/* C global declaration parser for genksyms.
2 Copyright 1996, 1997 Linux International.
3
4 New implementation contributed by Richard Henderson <rth@tamu.edu>
5 Based on original work by Bjorn Ekwall <bj0rn@blox.se>
6
7 This file is part of the Linux modutils.
8
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2 of the License, or (at your
12 option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23
24%{
25
26#include <assert.h>
27#include <malloc.h>
28#include "genksyms.h"
29
30static int is_typedef;
31static int is_extern;
32static char *current_name;
33static struct string_list *decl_spec;
34
35static void yyerror(const char *);
36
37static inline void
38remove_node(struct string_list **p)
39{
40 struct string_list *node = *p;
41 *p = node->next;
42 free_node(node);
43}
44
45static inline void
46remove_list(struct string_list **pb, struct string_list **pe)
47{
48 struct string_list *b = *pb, *e = *pe;
49 *pb = e;
50 free_list(b, e);
51}
52
53%}
54
55%token ASM_KEYW
56%token ATTRIBUTE_KEYW
57%token AUTO_KEYW
58%token BOOL_KEYW
59%token CHAR_KEYW
60%token CONST_KEYW
61%token DOUBLE_KEYW
62%token ENUM_KEYW
63%token EXTERN_KEYW
64%token FLOAT_KEYW
65%token INLINE_KEYW
66%token INT_KEYW
67%token LONG_KEYW
68%token REGISTER_KEYW
69%token RESTRICT_KEYW
70%token SHORT_KEYW
71%token SIGNED_KEYW
72%token STATIC_KEYW
73%token STRUCT_KEYW
74%token TYPEDEF_KEYW
75%token UNION_KEYW
76%token UNSIGNED_KEYW
77%token VOID_KEYW
78%token VOLATILE_KEYW
79%token TYPEOF_KEYW
80
81%token EXPORT_SYMBOL_KEYW
82
83%token ASM_PHRASE
84%token ATTRIBUTE_PHRASE
85%token BRACE_PHRASE
86%token BRACKET_PHRASE
87%token EXPRESSION_PHRASE
88
89%token CHAR
90%token DOTS
91%token IDENT
92%token INT
93%token REAL
94%token STRING
95%token TYPE
96%token OTHER
97%token FILENAME
98
99%%
100
101declaration_seq:
102 declaration
103 | declaration_seq declaration
104 ;
105
106declaration:
107 { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
108 declaration1
109 { free_list(*$2, NULL); *$2 = NULL; }
110 ;
111
112declaration1:
113 TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
114 { $$ = $3; }
115 | simple_declaration
116 | function_definition
117 | asm_definition
118 | export_definition
119 | error ';' { $$ = $2; }
120 | error '}' { $$ = $2; }
121 ;
122
123simple_declaration:
124 decl_specifier_seq_opt init_declarator_list_opt ';'
125 { if (current_name) {
126 struct string_list *decl = (*$3)->next;
127 (*$3)->next = NULL;
128 add_symbol(current_name,
129 is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
130 decl, is_extern);
131 current_name = NULL;
132 }
133 $$ = $3;
134 }
135 ;
136
137init_declarator_list_opt:
138 /* empty */ { $$ = NULL; }
139 | init_declarator_list
140 ;
141
142init_declarator_list:
143 init_declarator
144 { struct string_list *decl = *$1;
145 *$1 = NULL;
146 add_symbol(current_name,
147 is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
148 current_name = NULL;
149 $$ = $1;
150 }
151 | init_declarator_list ',' init_declarator
152 { struct string_list *decl = *$3;
153 *$3 = NULL;
154 free_list(*$2, NULL);
155 *$2 = decl_spec;
156 add_symbol(current_name,
157 is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
158 current_name = NULL;
159 $$ = $3;
160 }
161 ;
162
163init_declarator:
164 declarator asm_phrase_opt attribute_opt initializer_opt
165 { $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
166 ;
167
168/* Hang on to the specifiers so that we can reuse them. */
169decl_specifier_seq_opt:
170 /* empty */ { decl_spec = NULL; }
171 | decl_specifier_seq
172 ;
173
174decl_specifier_seq:
175 decl_specifier { decl_spec = *$1; }
176 | decl_specifier_seq decl_specifier { decl_spec = *$2; }
177 ;
178
179decl_specifier:
180 storage_class_specifier
181 { /* Version 2 checksumming ignores storage class, as that
182 is really irrelevant to the linkage. */
183 remove_node($1);
184 $$ = $1;
185 }
186 | type_specifier
187 ;
188
189storage_class_specifier:
190 AUTO_KEYW
191 | REGISTER_KEYW
192 | STATIC_KEYW
193 | EXTERN_KEYW { is_extern = 1; $$ = $1; }
194 | INLINE_KEYW { is_extern = 0; $$ = $1; }
195 ;
196
197type_specifier:
198 simple_type_specifier
199 | cvar_qualifier
200 | TYPEOF_KEYW '(' decl_specifier_seq ')'
201
202 /* References to s/u/e's defined elsewhere. Rearrange things
203 so that it is easier to expand the definition fully later. */
204 | STRUCT_KEYW IDENT
205 { remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
206 | UNION_KEYW IDENT
207 { remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
208 | ENUM_KEYW IDENT
209 { remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
210
211 /* Full definitions of an s/u/e. Record it. */
212 | STRUCT_KEYW IDENT class_body
213 { struct string_list *s = *$3, *i = *$2, *r;
214 r = copy_node(i); r->tag = SYM_STRUCT;
215 r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
216 add_symbol(i->string, SYM_STRUCT, s, is_extern);
217 $$ = $3;
218 }
219 | UNION_KEYW IDENT class_body
220 { struct string_list *s = *$3, *i = *$2, *r;
221 r = copy_node(i); r->tag = SYM_UNION;
222 r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
223 add_symbol(i->string, SYM_UNION, s, is_extern);
224 $$ = $3;
225 }
226 | ENUM_KEYW IDENT BRACE_PHRASE
227 { struct string_list *s = *$3, *i = *$2, *r;
228 r = copy_node(i); r->tag = SYM_ENUM;
229 r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
230 add_symbol(i->string, SYM_ENUM, s, is_extern);
231 $$ = $3;
232 }
233
234 /* Anonymous s/u/e definitions. Nothing needs doing. */
235 | ENUM_KEYW BRACE_PHRASE { $$ = $2; }
236 | STRUCT_KEYW class_body { $$ = $2; }
237 | UNION_KEYW class_body { $$ = $2; }
238 ;
239
240simple_type_specifier:
241 CHAR_KEYW
242 | SHORT_KEYW
243 | INT_KEYW
244 | LONG_KEYW
245 | SIGNED_KEYW
246 | UNSIGNED_KEYW
247 | FLOAT_KEYW
248 | DOUBLE_KEYW
249 | VOID_KEYW
250 | BOOL_KEYW
251 | TYPE { (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
252 ;
253
254ptr_operator:
255 '*' cvar_qualifier_seq_opt
256 { $$ = $2 ? $2 : $1; }
257 ;
258
259cvar_qualifier_seq_opt:
260 /* empty */ { $$ = NULL; }
261 | cvar_qualifier_seq
262 ;
263
264cvar_qualifier_seq:
265 cvar_qualifier
266 | cvar_qualifier_seq cvar_qualifier { $$ = $2; }
267 ;
268
269cvar_qualifier:
270 CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
271 | RESTRICT_KEYW
272 { /* restrict has no effect in prototypes so ignore it */
273 remove_node($1);
274 $$ = $1;
275 }
276 ;
277
278declarator:
279 ptr_operator declarator { $$ = $2; }
280 | direct_declarator
281 ;
282
283direct_declarator:
284 IDENT
285 { if (current_name != NULL) {
286 error_with_pos("unexpected second declaration name");
287 YYERROR;
288 } else {
289 current_name = (*$1)->string;
290 $$ = $1;
291 }
292 }
293 | direct_declarator '(' parameter_declaration_clause ')'
294 { $$ = $4; }
295 | direct_declarator '(' error ')'
296 { $$ = $4; }
297 | direct_declarator BRACKET_PHRASE
298 { $$ = $2; }
299 | '(' declarator ')'
300 { $$ = $3; }
301 | '(' error ')'
302 { $$ = $3; }
303 ;
304
305/* Nested declarators differ from regular declarators in that they do
306 not record the symbols they find in the global symbol table. */
307nested_declarator:
308 ptr_operator nested_declarator { $$ = $2; }
309 | direct_nested_declarator
310 ;
311
312direct_nested_declarator:
313 IDENT
314 | TYPE
315 | direct_nested_declarator '(' parameter_declaration_clause ')'
316 { $$ = $4; }
317 | direct_nested_declarator '(' error ')'
318 { $$ = $4; }
319 | direct_nested_declarator BRACKET_PHRASE
320 { $$ = $2; }
321 | '(' nested_declarator ')'
322 { $$ = $3; }
323 | '(' error ')'
324 { $$ = $3; }
325 ;
326
327parameter_declaration_clause:
328 parameter_declaration_list_opt DOTS { $$ = $2; }
329 | parameter_declaration_list_opt
330 | parameter_declaration_list ',' DOTS { $$ = $3; }
331 ;
332
333parameter_declaration_list_opt:
334 /* empty */ { $$ = NULL; }
335 | parameter_declaration_list
336 ;
337
338parameter_declaration_list:
339 parameter_declaration
340 | parameter_declaration_list ',' parameter_declaration
341 { $$ = $3; }
342 ;
343
344parameter_declaration:
345 decl_specifier_seq m_abstract_declarator
346 { $$ = $2 ? $2 : $1; }
347 ;
348
349m_abstract_declarator:
350 ptr_operator m_abstract_declarator
351 { $$ = $2 ? $2 : $1; }
352 | direct_m_abstract_declarator
353 ;
354
355direct_m_abstract_declarator:
356 /* empty */ { $$ = NULL; }
357 | IDENT
358 { /* For version 2 checksums, we don't want to remember
359 private parameter names. */
360 remove_node($1);
361 $$ = $1;
362 }
363 /* This wasn't really a typedef name but an identifier that
364 shadows one. */
365 | TYPE
366 { remove_node($1);
367 $$ = $1;
368 }
369 | direct_m_abstract_declarator '(' parameter_declaration_clause ')'
370 { $$ = $4; }
371 | direct_m_abstract_declarator '(' error ')'
372 { $$ = $4; }
373 | direct_m_abstract_declarator BRACKET_PHRASE
374 { $$ = $2; }
375 | '(' m_abstract_declarator ')'
376 { $$ = $3; }
377 | '(' error ')'
378 { $$ = $3; }
379 ;
380
381function_definition:
382 decl_specifier_seq_opt declarator BRACE_PHRASE
383 { struct string_list *decl = *$2;
384 *$2 = NULL;
385 add_symbol(current_name, SYM_NORMAL, decl, is_extern);
386 $$ = $3;
387 }
388 ;
389
390initializer_opt:
391 /* empty */ { $$ = NULL; }
392 | initializer
393 ;
394
395/* We never care about the contents of an initializer. */
396initializer:
397 '=' EXPRESSION_PHRASE
398 { remove_list($2, &(*$1)->next); $$ = $2; }
399 ;
400
401class_body:
402 '{' member_specification_opt '}' { $$ = $3; }
403 | '{' error '}' { $$ = $3; }
404 ;
405
406member_specification_opt:
407 /* empty */ { $$ = NULL; }
408 | member_specification
409 ;
410
411member_specification:
412 member_declaration
413 | member_specification member_declaration { $$ = $2; }
414 ;
415
416member_declaration:
417 decl_specifier_seq_opt member_declarator_list_opt ';'
418 { $$ = $3; }
419 | error ';'
420 { $$ = $2; }
421 ;
422
423member_declarator_list_opt:
424 /* empty */ { $$ = NULL; }
425 | member_declarator_list
426 ;
427
428member_declarator_list:
429 member_declarator
430 | member_declarator_list ',' member_declarator { $$ = $3; }
431 ;
432
433member_declarator:
434 nested_declarator attribute_opt { $$ = $2 ? $2 : $1; }
435 | IDENT member_bitfield_declarator { $$ = $2; }
436 | member_bitfield_declarator
437 ;
438
439member_bitfield_declarator:
440 ':' EXPRESSION_PHRASE { $$ = $2; }
441 ;
442
443attribute_opt:
444 /* empty */ { $$ = NULL; }
445 | ATTRIBUTE_PHRASE
446 ;
447
448asm_definition:
449 ASM_PHRASE ';' { $$ = $2; }
450 ;
451
452asm_phrase_opt:
453 /* empty */ { $$ = NULL; }
454 | ASM_PHRASE
455 ;
456
457export_definition:
458 EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
459 { export_symbol((*$3)->string); $$ = $5; }
460 ;
461
462
463%%
464
465static void
466yyerror(const char *e)
467{
468 error_with_pos("%s", e);
469}
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
new file mode 100644
index 000000000000..090ffda4adbc
--- /dev/null
+++ b/scripts/kallsyms.c
@@ -0,0 +1,686 @@
1/* Generate assembler source containing symbol information
2 *
3 * Copyright 2002 by Kai Germaschewski
4 *
5 * This software may be used and distributed according to the terms
6 * of the GNU General Public License, incorporated herein by reference.
7 *
8 * Usage: nm -n vmlinux | scripts/kallsyms [--all-symbols] > symbols.S
9 *
10 * ChangeLog:
11 *
12 * (25/Aug/2004) Paulo Marques <pmarques@grupopie.com>
13 * Changed the compression method from stem compression to "table lookup"
14 * compression
15 *
16 * Table compression uses all the unused char codes on the symbols and
17 * maps these to the most used substrings (tokens). For instance, it might
18 * map char code 0xF7 to represent "write_" and then in every symbol where
19 * "write_" appears it can be replaced by 0xF7, saving 5 bytes.
20 * The used codes themselves are also placed in the table so that the
21 * decompresion can work without "special cases".
22 * Applied to kernel symbols, this usually produces a compression ratio
23 * of about 50%.
24 *
25 */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <ctype.h>
31
32/* maximum token length used. It doesn't pay to increase it a lot, because
33 * very long substrings probably don't repeat themselves too often. */
34#define MAX_TOK_SIZE 11
35#define KSYM_NAME_LEN 127
36
37/* we use only a subset of the complete symbol table to gather the token count,
38 * to speed up compression, at the expense of a little compression ratio */
39#define WORKING_SET 1024
40
41/* first find the best token only on the list of tokens that would profit more
42 * than GOOD_BAD_THRESHOLD. Only if this list is empty go to the "bad" list.
43 * Increasing this value will put less tokens on the "good" list, so the search
44 * is faster. However, if the good list runs out of tokens, we must painfully
45 * search the bad list. */
46#define GOOD_BAD_THRESHOLD 10
47
48/* token hash parameters */
49#define HASH_BITS 18
50#define HASH_TABLE_SIZE (1 << HASH_BITS)
51#define HASH_MASK (HASH_TABLE_SIZE - 1)
52#define HASH_BASE_OFFSET 2166136261U
53#define HASH_FOLD(a) ((a)&(HASH_MASK))
54
55/* flags to mark symbols */
56#define SYM_FLAG_VALID 1
57#define SYM_FLAG_SAMPLED 2
58
59struct sym_entry {
60 unsigned long long addr;
61 char type;
62 unsigned char flags;
63 unsigned char len;
64 unsigned char *sym;
65};
66
67
68static struct sym_entry *table;
69static int size, cnt;
70static unsigned long long _stext, _etext, _sinittext, _einittext;
71static int all_symbols = 0;
72
73struct token {
74 unsigned char data[MAX_TOK_SIZE];
75 unsigned char len;
76 /* profit: the number of bytes that could be saved by inserting this
77 * token into the table */
78 int profit;
79 struct token *next; /* next token on the hash list */
80 struct token *right; /* next token on the good/bad list */
81 struct token *left; /* previous token on the good/bad list */
82 struct token *smaller; /* token that is less one letter than this one */
83 };
84
85struct token bad_head, good_head;
86struct token *hash_table[HASH_TABLE_SIZE];
87
88/* the table that holds the result of the compression */
89unsigned char best_table[256][MAX_TOK_SIZE+1];
90unsigned char best_table_len[256];
91
92
93static void
94usage(void)
95{
96 fprintf(stderr, "Usage: kallsyms [--all-symbols] < in.map > out.S\n");
97 exit(1);
98}
99
100/*
101 * This ignores the intensely annoying "mapping symbols" found
102 * in ARM ELF files: $a, $t and $d.
103 */
104static inline int
105is_arm_mapping_symbol(const char *str)
106{
107 return str[0] == '$' && strchr("atd", str[1])
108 && (str[2] == '\0' || str[2] == '.');
109}
110
111static int
112read_symbol(FILE *in, struct sym_entry *s)
113{
114 char str[500];
115 int rc;
116
117 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str);
118 if (rc != 3) {
119 if (rc != EOF) {
120 /* skip line */
121 fgets(str, 500, in);
122 }
123 return -1;
124 }
125
126 /* Ignore most absolute/undefined (?) symbols. */
127 if (strcmp(str, "_stext") == 0)
128 _stext = s->addr;
129 else if (strcmp(str, "_etext") == 0)
130 _etext = s->addr;
131 else if (strcmp(str, "_sinittext") == 0)
132 _sinittext = s->addr;
133 else if (strcmp(str, "_einittext") == 0)
134 _einittext = s->addr;
135 else if (toupper(s->type) == 'A')
136 {
137 /* Keep these useful absolute symbols */
138 if (strcmp(str, "__kernel_syscall_via_break") &&
139 strcmp(str, "__kernel_syscall_via_epc") &&
140 strcmp(str, "__kernel_sigtramp") &&
141 strcmp(str, "__gp"))
142 return -1;
143
144 }
145 else if (toupper(s->type) == 'U' ||
146 is_arm_mapping_symbol(str))
147 return -1;
148
149 /* include the type field in the symbol name, so that it gets
150 * compressed together */
151 s->len = strlen(str) + 1;
152 s->sym = (char *) malloc(s->len + 1);
153 strcpy(s->sym + 1, str);
154 s->sym[0] = s->type;
155
156 return 0;
157}
158
159static int
160symbol_valid(struct sym_entry *s)
161{
162 /* Symbols which vary between passes. Passes 1 and 2 must have
163 * identical symbol lists. The kallsyms_* symbols below are only added
164 * after pass 1, they would be included in pass 2 when --all-symbols is
165 * specified so exclude them to get a stable symbol list.
166 */
167 static char *special_symbols[] = {
168 "kallsyms_addresses",
169 "kallsyms_num_syms",
170 "kallsyms_names",
171 "kallsyms_markers",
172 "kallsyms_token_table",
173 "kallsyms_token_index",
174
175 /* Exclude linker generated symbols which vary between passes */
176 "_SDA_BASE_", /* ppc */
177 "_SDA2_BASE_", /* ppc */
178 NULL };
179 int i;
180
181 /* if --all-symbols is not specified, then symbols outside the text
182 * and inittext sections are discarded */
183 if (!all_symbols) {
184 if ((s->addr < _stext || s->addr > _etext)
185 && (s->addr < _sinittext || s->addr > _einittext))
186 return 0;
187 /* Corner case. Discard any symbols with the same value as
188 * _etext or _einittext, they can move between pass 1 and 2
189 * when the kallsyms data is added. If these symbols move then
190 * they may get dropped in pass 2, which breaks the kallsyms
191 * rules.
192 */
193 if ((s->addr == _etext && strcmp(s->sym + 1, "_etext")) ||
194 (s->addr == _einittext && strcmp(s->sym + 1, "_einittext")))
195 return 0;
196 }
197
198 /* Exclude symbols which vary between passes. */
199 if (strstr(s->sym + 1, "_compiled."))
200 return 0;
201
202 for (i = 0; special_symbols[i]; i++)
203 if( strcmp(s->sym + 1, special_symbols[i]) == 0 )
204 return 0;
205
206 return 1;
207}
208
209static void
210read_map(FILE *in)
211{
212 while (!feof(in)) {
213 if (cnt >= size) {
214 size += 10000;
215 table = realloc(table, sizeof(*table) * size);
216 if (!table) {
217 fprintf(stderr, "out of memory\n");
218 exit (1);
219 }
220 }
221 if (read_symbol(in, &table[cnt]) == 0)
222 cnt++;
223 }
224}
225
226static void output_label(char *label)
227{
228 printf(".globl %s\n",label);
229 printf("\tALGN\n");
230 printf("%s:\n",label);
231}
232
233/* uncompress a compressed symbol. When this function is called, the best table
234 * might still be compressed itself, so the function needs to be recursive */
235static int expand_symbol(unsigned char *data, int len, char *result)
236{
237 int c, rlen, total=0;
238
239 while (len) {
240 c = *data;
241 /* if the table holds a single char that is the same as the one
242 * we are looking for, then end the search */
243 if (best_table[c][0]==c && best_table_len[c]==1) {
244 *result++ = c;
245 total++;
246 } else {
247 /* if not, recurse and expand */
248 rlen = expand_symbol(best_table[c], best_table_len[c], result);
249 total += rlen;
250 result += rlen;
251 }
252 data++;
253 len--;
254 }
255 *result=0;
256
257 return total;
258}
259
260static void
261write_src(void)
262{
263 int i, k, off, valid;
264 unsigned int best_idx[256];
265 unsigned int *markers;
266 char buf[KSYM_NAME_LEN+1];
267
268 printf("#include <asm/types.h>\n");
269 printf("#if BITS_PER_LONG == 64\n");
270 printf("#define PTR .quad\n");
271 printf("#define ALGN .align 8\n");
272 printf("#else\n");
273 printf("#define PTR .long\n");
274 printf("#define ALGN .align 4\n");
275 printf("#endif\n");
276
277 printf(".data\n");
278
279 output_label("kallsyms_addresses");
280 valid = 0;
281 for (i = 0; i < cnt; i++) {
282 if (table[i].flags & SYM_FLAG_VALID) {
283 printf("\tPTR\t%#llx\n", table[i].addr);
284 valid++;
285 }
286 }
287 printf("\n");
288
289 output_label("kallsyms_num_syms");
290 printf("\tPTR\t%d\n", valid);
291 printf("\n");
292
293 /* table of offset markers, that give the offset in the compressed stream
294 * every 256 symbols */
295 markers = (unsigned int *) malloc(sizeof(unsigned int)*((valid + 255) / 256));
296
297 output_label("kallsyms_names");
298 valid = 0;
299 off = 0;
300 for (i = 0; i < cnt; i++) {
301
302 if (!table[i].flags & SYM_FLAG_VALID)
303 continue;
304
305 if ((valid & 0xFF) == 0)
306 markers[valid >> 8] = off;
307
308 printf("\t.byte 0x%02x", table[i].len);
309 for (k = 0; k < table[i].len; k++)
310 printf(", 0x%02x", table[i].sym[k]);
311 printf("\n");
312
313 off += table[i].len + 1;
314 valid++;
315 }
316 printf("\n");
317
318 output_label("kallsyms_markers");
319 for (i = 0; i < ((valid + 255) >> 8); i++)
320 printf("\tPTR\t%d\n", markers[i]);
321 printf("\n");
322
323 free(markers);
324
325 output_label("kallsyms_token_table");
326 off = 0;
327 for (i = 0; i < 256; i++) {
328 best_idx[i] = off;
329 expand_symbol(best_table[i],best_table_len[i],buf);
330 printf("\t.asciz\t\"%s\"\n", buf);
331 off += strlen(buf) + 1;
332 }
333 printf("\n");
334
335 output_label("kallsyms_token_index");
336 for (i = 0; i < 256; i++)
337 printf("\t.short\t%d\n", best_idx[i]);
338 printf("\n");
339}
340
341
342/* table lookup compression functions */
343
344static inline unsigned int rehash_token(unsigned int hash, unsigned char data)
345{
346 return ((hash * 16777619) ^ data);
347}
348
349static unsigned int hash_token(unsigned char *data, int len)
350{
351 unsigned int hash=HASH_BASE_OFFSET;
352 int i;
353
354 for (i = 0; i < len; i++)
355 hash = rehash_token(hash, data[i]);
356
357 return HASH_FOLD(hash);
358}
359
360/* find a token given its data and hash value */
361static struct token *find_token_hash(unsigned char *data, int len, unsigned int hash)
362{
363 struct token *ptr;
364
365 ptr = hash_table[hash];
366
367 while (ptr) {
368 if ((ptr->len == len) && (memcmp(ptr->data, data, len) == 0))
369 return ptr;
370 ptr=ptr->next;
371 }
372
373 return NULL;
374}
375
376static inline void insert_token_in_group(struct token *head, struct token *ptr)
377{
378 ptr->right = head->right;
379 ptr->right->left = ptr;
380 head->right = ptr;
381 ptr->left = head;
382}
383
384static inline void remove_token_from_group(struct token *ptr)
385{
386 ptr->left->right = ptr->right;
387 ptr->right->left = ptr->left;
388}
389
390
391/* build the counts for all the tokens that start with "data", and have lenghts
392 * from 2 to "len" */
393static void learn_token(unsigned char *data, int len)
394{
395 struct token *ptr,*last_ptr;
396 int i, newprofit;
397 unsigned int hash = HASH_BASE_OFFSET;
398 unsigned int hashes[MAX_TOK_SIZE + 1];
399
400 if (len > MAX_TOK_SIZE)
401 len = MAX_TOK_SIZE;
402
403 /* calculate and store the hash values for all the sub-tokens */
404 hash = rehash_token(hash, data[0]);
405 for (i = 2; i <= len; i++) {
406 hash = rehash_token(hash, data[i-1]);
407 hashes[i] = HASH_FOLD(hash);
408 }
409
410 last_ptr = NULL;
411 ptr = NULL;
412
413 for (i = len; i >= 2; i--) {
414 hash = hashes[i];
415
416 if (!ptr) ptr = find_token_hash(data, i, hash);
417
418 if (!ptr) {
419 /* create a new token entry */
420 ptr = (struct token *) malloc(sizeof(*ptr));
421
422 memcpy(ptr->data, data, i);
423 ptr->len = i;
424
425 /* when we create an entry, it's profit is 0 because
426 * we also take into account the size of the token on
427 * the compressed table. We then subtract GOOD_BAD_THRESHOLD
428 * so that the test to see if this token belongs to
429 * the good or bad list, is a comparison to zero */
430 ptr->profit = -GOOD_BAD_THRESHOLD;
431
432 ptr->next = hash_table[hash];
433 hash_table[hash] = ptr;
434
435 insert_token_in_group(&bad_head, ptr);
436
437 ptr->smaller = NULL;
438 } else {
439 newprofit = ptr->profit + (ptr->len - 1);
440 /* check to see if this token needs to be moved to a
441 * different list */
442 if((ptr->profit < 0) && (newprofit >= 0)) {
443 remove_token_from_group(ptr);
444 insert_token_in_group(&good_head,ptr);
445 }
446 ptr->profit = newprofit;
447 }
448
449 if (last_ptr) last_ptr->smaller = ptr;
450 last_ptr = ptr;
451
452 ptr = ptr->smaller;
453 }
454}
455
456/* decrease the counts for all the tokens that start with "data", and have lenghts
457 * from 2 to "len". This function is much simpler than learn_token because we have
458 * more guarantees (tho tokens exist, the ->smaller pointer is set, etc.)
459 * The two separate functions exist only because of compression performance */
460static void forget_token(unsigned char *data, int len)
461{
462 struct token *ptr;
463 int i, newprofit;
464 unsigned int hash=0;
465
466 if (len > MAX_TOK_SIZE) len = MAX_TOK_SIZE;
467
468 hash = hash_token(data, len);
469 ptr = find_token_hash(data, len, hash);
470
471 for (i = len; i >= 2; i--) {
472
473 newprofit = ptr->profit - (ptr->len - 1);
474 if ((ptr->profit >= 0) && (newprofit < 0)) {
475 remove_token_from_group(ptr);
476 insert_token_in_group(&bad_head, ptr);
477 }
478 ptr->profit=newprofit;
479
480 ptr=ptr->smaller;
481 }
482}
483
484/* count all the possible tokens in a symbol */
485static void learn_symbol(unsigned char *symbol, int len)
486{
487 int i;
488
489 for (i = 0; i < len - 1; i++)
490 learn_token(symbol + i, len - i);
491}
492
493/* decrease the count for all the possible tokens in a symbol */
494static void forget_symbol(unsigned char *symbol, int len)
495{
496 int i;
497
498 for (i = 0; i < len - 1; i++)
499 forget_token(symbol + i, len - i);
500}
501
502/* set all the symbol flags and do the initial token count */
503static void build_initial_tok_table(void)
504{
505 int i, use_it, valid;
506
507 valid = 0;
508 for (i = 0; i < cnt; i++) {
509 table[i].flags = 0;
510 if ( symbol_valid(&table[i]) ) {
511 table[i].flags |= SYM_FLAG_VALID;
512 valid++;
513 }
514 }
515
516 use_it = 0;
517 for (i = 0; i < cnt; i++) {
518
519 /* subsample the available symbols. This method is almost like
520 * a Bresenham's algorithm to get uniformly distributed samples
521 * across the symbol table */
522 if (table[i].flags & SYM_FLAG_VALID) {
523
524 use_it += WORKING_SET;
525
526 if (use_it >= valid) {
527 table[i].flags |= SYM_FLAG_SAMPLED;
528 use_it -= valid;
529 }
530 }
531 if (table[i].flags & SYM_FLAG_SAMPLED)
532 learn_symbol(table[i].sym, table[i].len);
533 }
534}
535
536/* replace a given token in all the valid symbols. Use the sampled symbols
537 * to update the counts */
538static void compress_symbols(unsigned char *str, int tlen, int idx)
539{
540 int i, len, learn, size;
541 unsigned char *p;
542
543 for (i = 0; i < cnt; i++) {
544
545 if (!(table[i].flags & SYM_FLAG_VALID)) continue;
546
547 len = table[i].len;
548 learn = 0;
549 p = table[i].sym;
550
551 do {
552 /* find the token on the symbol */
553 p = (unsigned char *) strstr((char *) p, (char *) str);
554 if (!p) break;
555
556 if (!learn) {
557 /* if this symbol was used to count, decrease it */
558 if (table[i].flags & SYM_FLAG_SAMPLED)
559 forget_symbol(table[i].sym, len);
560 learn = 1;
561 }
562
563 *p = idx;
564 size = (len - (p - table[i].sym)) - tlen + 1;
565 memmove(p + 1, p + tlen, size);
566 p++;
567 len -= tlen - 1;
568
569 } while (size >= tlen);
570
571 if(learn) {
572 table[i].len = len;
573 /* if this symbol was used to count, learn it again */
574 if(table[i].flags & SYM_FLAG_SAMPLED)
575 learn_symbol(table[i].sym, len);
576 }
577 }
578}
579
580/* search the token with the maximum profit */
581static struct token *find_best_token(void)
582{
583 struct token *ptr,*best,*head;
584 int bestprofit;
585
586 bestprofit=-10000;
587
588 /* failsafe: if the "good" list is empty search from the "bad" list */
589 if(good_head.right == &good_head) head = &bad_head;
590 else head = &good_head;
591
592 ptr = head->right;
593 best = NULL;
594 while (ptr != head) {
595 if (ptr->profit > bestprofit) {
596 bestprofit = ptr->profit;
597 best = ptr;
598 }
599 ptr = ptr->right;
600 }
601
602 return best;
603}
604
605/* this is the core of the algorithm: calculate the "best" table */
606static void optimize_result(void)
607{
608 struct token *best;
609 int i;
610
611 /* using the '\0' symbol last allows compress_symbols to use standard
612 * fast string functions */
613 for (i = 255; i >= 0; i--) {
614
615 /* if this table slot is empty (it is not used by an actual
616 * original char code */
617 if (!best_table_len[i]) {
618
619 /* find the token with the breates profit value */
620 best = find_best_token();
621
622 /* place it in the "best" table */
623 best_table_len[i] = best->len;
624 memcpy(best_table[i], best->data, best_table_len[i]);
625 /* zero terminate the token so that we can use strstr
626 in compress_symbols */
627 best_table[i][best_table_len[i]]='\0';
628
629 /* replace this token in all the valid symbols */
630 compress_symbols(best_table[i], best_table_len[i], i);
631 }
632 }
633}
634
635/* start by placing the symbols that are actually used on the table */
636static void insert_real_symbols_in_table(void)
637{
638 int i, j, c;
639
640 memset(best_table, 0, sizeof(best_table));
641 memset(best_table_len, 0, sizeof(best_table_len));
642
643 for (i = 0; i < cnt; i++) {
644 if (table[i].flags & SYM_FLAG_VALID) {
645 for (j = 0; j < table[i].len; j++) {
646 c = table[i].sym[j];
647 best_table[c][0]=c;
648 best_table_len[c]=1;
649 }
650 }
651 }
652}
653
654static void optimize_token_table(void)
655{
656 memset(hash_table, 0, sizeof(hash_table));
657
658 good_head.left = &good_head;
659 good_head.right = &good_head;
660
661 bad_head.left = &bad_head;
662 bad_head.right = &bad_head;
663
664 build_initial_tok_table();
665
666 insert_real_symbols_in_table();
667
668 optimize_result();
669}
670
671
672int
673main(int argc, char **argv)
674{
675 if (argc == 2 && strcmp(argv[1], "--all-symbols") == 0)
676 all_symbols = 1;
677 else if (argc != 1)
678 usage();
679
680 read_map(stdin);
681 optimize_token_table();
682 write_src();
683
684 return 0;
685}
686
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
new file mode 100644
index 000000000000..5a5ddc40f36c
--- /dev/null
+++ b/scripts/kconfig/Makefile
@@ -0,0 +1,208 @@
1# ===========================================================================
2# Kernel configuration targets
3# These targets are used from top-level makefile
4
5.PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig
6
7xconfig: $(obj)/qconf
8 $< arch/$(ARCH)/Kconfig
9
10gconfig: $(obj)/gconf
11 $< arch/$(ARCH)/Kconfig
12
13menuconfig: $(obj)/mconf
14 $(Q)$(MAKE) $(build)=scripts/lxdialog
15 $< arch/$(ARCH)/Kconfig
16
17config: $(obj)/conf
18 $< arch/$(ARCH)/Kconfig
19
20oldconfig: $(obj)/conf
21 $< -o arch/$(ARCH)/Kconfig
22
23silentoldconfig: $(obj)/conf
24 $< -s arch/$(ARCH)/Kconfig
25
26.PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig
27
28randconfig: $(obj)/conf
29 $< -r arch/$(ARCH)/Kconfig
30
31allyesconfig: $(obj)/conf
32 $< -y arch/$(ARCH)/Kconfig
33
34allnoconfig: $(obj)/conf
35 $< -n arch/$(ARCH)/Kconfig
36
37allmodconfig: $(obj)/conf
38 $< -m arch/$(ARCH)/Kconfig
39
40defconfig: $(obj)/conf
41ifeq ($(KBUILD_DEFCONFIG),)
42 $< -d arch/$(ARCH)/Kconfig
43else
44 @echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)'
45 $(Q)$< -D arch/$(ARCH)/configs/$(KBUILD_DEFCONFIG) arch/$(ARCH)/Kconfig
46endif
47
48%_defconfig: $(obj)/conf
49 $(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig
50
51# Help text used by make help
52help:
53 @echo ' config - Update current config utilising a line-oriented program'
54 @echo ' menuconfig - Update current config utilising a menu based program'
55 @echo ' xconfig - Update current config utilising a QT based front-end'
56 @echo ' gconfig - Update current config utilising a GTK based front-end'
57 @echo ' oldconfig - Update current config utilising a provided .config as base'
58 @echo ' randconfig - New config with random answer to all options'
59 @echo ' defconfig - New config with default answer to all options'
60 @echo ' allmodconfig - New config selecting modules when possible'
61 @echo ' allyesconfig - New config where all options are accepted with yes'
62 @echo ' allnoconfig - New minimal config'
63
64# ===========================================================================
65# Shared Makefile for the various kconfig executables:
66# conf: Used for defconfig, oldconfig and related targets
67# mconf: Used for the mconfig target.
68# Utilizes the lxdialog package
69# qconf: Used for the xconfig target
70# Based on QT which needs to be installed to compile it
71# gconf: Used for the gconfig target
72# Based on GTK which needs to be installed to compile it
73# object files used by all kconfig flavours
74
75hostprogs-y := conf mconf qconf gconf
76conf-objs := conf.o zconf.tab.o
77mconf-objs := mconf.o zconf.tab.o
78
79ifeq ($(MAKECMDGOALS),xconfig)
80 qconf-target := 1
81endif
82ifeq ($(MAKECMDGOALS),gconfig)
83 gconf-target := 1
84endif
85
86
87ifeq ($(qconf-target),1)
88qconf-cxxobjs := qconf.o
89qconf-objs := kconfig_load.o zconf.tab.o
90endif
91
92ifeq ($(gconf-target),1)
93gconf-objs := gconf.o kconfig_load.o zconf.tab.o
94endif
95
96clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
97 .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c
98
99# generated files seem to need this to find local include files
100HOSTCFLAGS_lex.zconf.o := -I$(src)
101HOSTCFLAGS_zconf.tab.o := -I$(src)
102
103HOSTLOADLIBES_qconf = -L$(QTLIBPATH) -Wl,-rpath,$(QTLIBPATH) -l$(QTLIB) -ldl
104HOSTCXXFLAGS_qconf.o = -I$(QTDIR)/include -D LKC_DIRECT_LINK
105
106HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
107HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
108 -D LKC_DIRECT_LINK
109
110$(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h
111
112$(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped
113$(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped
114$(obj)/lex.zconf.c: $(src)/lex.zconf.c_shipped
115
116$(obj)/qconf.o: $(obj)/.tmp_qtcheck
117
118ifeq ($(qconf-target),1)
119MOC = $(QTDIR)/bin/moc
120QTLIBPATH = $(QTDIR)/lib
121-include $(obj)/.tmp_qtcheck
122
123# QT needs some extra effort...
124$(obj)/.tmp_qtcheck:
125 @set -e; for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
126 if [ -f $$d/include/qconfig.h ]; then DIR=$$d; break; fi; \
127 done; \
128 if [ -z "$$DIR" ]; then \
129 echo "*"; \
130 echo "* Unable to find the QT installation. Please make sure that the"; \
131 echo "* QT development package is correctly installed and the QTDIR"; \
132 echo "* environment variable is set to the correct location."; \
133 echo "*"; \
134 false; \
135 fi; \
136 LIBPATH=$$DIR/lib; LIB=qt; \
137 $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
138 LIBPATH=$$DIR/lib/$$($(HOSTCXX) -print-multi-os-directory); \
139 if [ -f $$LIBPATH/libqt-mt.so ]; then LIB=qt-mt; fi; \
140 echo "QTDIR=$$DIR" > $@; echo "QTLIBPATH=$$LIBPATH" >> $@; \
141 echo "QTLIB=$$LIB" >> $@; \
142 if [ ! -x $$DIR/bin/moc -a -x /usr/bin/moc ]; then \
143 echo "*"; \
144 echo "* Unable to find $$DIR/bin/moc, using /usr/bin/moc instead."; \
145 echo "*"; \
146 echo "MOC=/usr/bin/moc" >> $@; \
147 fi
148endif
149
150$(obj)/gconf.o: $(obj)/.tmp_gtkcheck
151
152ifeq ($(gconf-target),1)
153-include $(obj)/.tmp_gtkcheck
154
155# GTK needs some extra effort, too...
156$(obj)/.tmp_gtkcheck:
157 @if `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --exists`; then \
158 if `pkg-config gtk+-2.0 --atleast-version=2.0.0`; then \
159 touch $@; \
160 else \
161 echo "*"; \
162 echo "* GTK+ is present but version >= 2.0.0 is required."; \
163 echo "*"; \
164 false; \
165 fi \
166 else \
167 echo "*"; \
168 echo "* Unable to find the GTK+ installation. Please make sure that"; \
169 echo "* the GTK+ 2.0 development package is correctly installed..."; \
170 echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \
171 echo "*"; \
172 false; \
173 fi
174endif
175
176$(obj)/zconf.tab.o: $(obj)/lex.zconf.c
177
178$(obj)/kconfig_load.o: $(obj)/lkc_defs.h
179
180$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h
181
182$(obj)/gconf.o: $(obj)/lkc_defs.h
183
184$(obj)/%.moc: $(src)/%.h
185 $(MOC) -i $< -o $@
186
187$(obj)/lkc_defs.h: $(src)/lkc_proto.h
188 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
189
190
191###
192# The following requires flex/bison
193# By default we use the _shipped versions, uncomment the following line if
194# you are modifying the flex/bison src.
195# LKC_GENPARSER := 1
196
197ifdef LKC_GENPARSER
198
199$(obj)/zconf.tab.c: $(obj)/zconf.y
200$(obj)/zconf.tab.h: $(obj)/zconf.tab.c
201
202%.tab.c: %.y
203 bison -t -d -v -b $* -p $(notdir $*) $<
204
205lex.%.c: %.l
206 flex -P$(notdir $*) -o$@ $<
207
208endif
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
new file mode 100644
index 000000000000..a494d1aeb9f9
--- /dev/null
+++ b/scripts/kconfig/conf.c
@@ -0,0 +1,583 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <ctype.h>
7#include <stdlib.h>
8#include <string.h>
9#include <unistd.h>
10#include <time.h>
11#include <sys/stat.h>
12
13#define LKC_DIRECT_LINK
14#include "lkc.h"
15
16static void conf(struct menu *menu);
17static void check_conf(struct menu *menu);
18
19enum {
20 ask_all,
21 ask_new,
22 ask_silent,
23 set_default,
24 set_yes,
25 set_mod,
26 set_no,
27 set_random
28} input_mode = ask_all;
29char *defconfig_file;
30
31static int indent = 1;
32static int valid_stdin = 1;
33static int conf_cnt;
34static signed char line[128];
35static struct menu *rootEntry;
36
37static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
38
39static void strip(signed char *str)
40{
41 signed char *p = str;
42 int l;
43
44 while ((isspace(*p)))
45 p++;
46 l = strlen(p);
47 if (p != str)
48 memmove(str, p, l + 1);
49 if (!l)
50 return;
51 p = str + l - 1;
52 while ((isspace(*p)))
53 *p-- = 0;
54}
55
56static void check_stdin(void)
57{
58 if (!valid_stdin && input_mode == ask_silent) {
59 printf("aborted!\n\n");
60 printf("Console input/output is redirected. ");
61 printf("Run 'make oldconfig' to update configuration.\n\n");
62 exit(1);
63 }
64}
65
66static void conf_askvalue(struct symbol *sym, const char *def)
67{
68 enum symbol_type type = sym_get_type(sym);
69 tristate val;
70
71 if (!sym_has_value(sym))
72 printf("(NEW) ");
73
74 line[0] = '\n';
75 line[1] = 0;
76
77 if (!sym_is_changable(sym)) {
78 printf("%s\n", def);
79 line[0] = '\n';
80 line[1] = 0;
81 return;
82 }
83
84 switch (input_mode) {
85 case ask_new:
86 case ask_silent:
87 if (sym_has_value(sym)) {
88 printf("%s\n", def);
89 return;
90 }
91 check_stdin();
92 case ask_all:
93 fflush(stdout);
94 fgets(line, 128, stdin);
95 return;
96 case set_default:
97 printf("%s\n", def);
98 return;
99 default:
100 break;
101 }
102
103 switch (type) {
104 case S_INT:
105 case S_HEX:
106 case S_STRING:
107 printf("%s\n", def);
108 return;
109 default:
110 ;
111 }
112 switch (input_mode) {
113 case set_yes:
114 if (sym_tristate_within_range(sym, yes)) {
115 line[0] = 'y';
116 line[1] = '\n';
117 line[2] = 0;
118 break;
119 }
120 case set_mod:
121 if (type == S_TRISTATE) {
122 if (sym_tristate_within_range(sym, mod)) {
123 line[0] = 'm';
124 line[1] = '\n';
125 line[2] = 0;
126 break;
127 }
128 } else {
129 if (sym_tristate_within_range(sym, yes)) {
130 line[0] = 'y';
131 line[1] = '\n';
132 line[2] = 0;
133 break;
134 }
135 }
136 case set_no:
137 if (sym_tristate_within_range(sym, no)) {
138 line[0] = 'n';
139 line[1] = '\n';
140 line[2] = 0;
141 break;
142 }
143 case set_random:
144 do {
145 val = (tristate)(random() % 3);
146 } while (!sym_tristate_within_range(sym, val));
147 switch (val) {
148 case no: line[0] = 'n'; break;
149 case mod: line[0] = 'm'; break;
150 case yes: line[0] = 'y'; break;
151 }
152 line[1] = '\n';
153 line[2] = 0;
154 break;
155 default:
156 break;
157 }
158 printf("%s", line);
159}
160
161int conf_string(struct menu *menu)
162{
163 struct symbol *sym = menu->sym;
164 const char *def, *help;
165
166 while (1) {
167 printf("%*s%s ", indent - 1, "", menu->prompt->text);
168 printf("(%s) ", sym->name);
169 def = sym_get_string_value(sym);
170 if (sym_get_string_value(sym))
171 printf("[%s] ", def);
172 conf_askvalue(sym, def);
173 switch (line[0]) {
174 case '\n':
175 break;
176 case '?':
177 /* print help */
178 if (line[1] == '\n') {
179 help = nohelp_text;
180 if (menu->sym->help)
181 help = menu->sym->help;
182 printf("\n%s\n", menu->sym->help);
183 def = NULL;
184 break;
185 }
186 default:
187 line[strlen(line)-1] = 0;
188 def = line;
189 }
190 if (def && sym_set_string_value(sym, def))
191 return 0;
192 }
193}
194
195static int conf_sym(struct menu *menu)
196{
197 struct symbol *sym = menu->sym;
198 int type;
199 tristate oldval, newval;
200 const char *help;
201
202 while (1) {
203 printf("%*s%s ", indent - 1, "", menu->prompt->text);
204 if (sym->name)
205 printf("(%s) ", sym->name);
206 type = sym_get_type(sym);
207 putchar('[');
208 oldval = sym_get_tristate_value(sym);
209 switch (oldval) {
210 case no:
211 putchar('N');
212 break;
213 case mod:
214 putchar('M');
215 break;
216 case yes:
217 putchar('Y');
218 break;
219 }
220 if (oldval != no && sym_tristate_within_range(sym, no))
221 printf("/n");
222 if (oldval != mod && sym_tristate_within_range(sym, mod))
223 printf("/m");
224 if (oldval != yes && sym_tristate_within_range(sym, yes))
225 printf("/y");
226 if (sym->help)
227 printf("/?");
228 printf("] ");
229 conf_askvalue(sym, sym_get_string_value(sym));
230 strip(line);
231
232 switch (line[0]) {
233 case 'n':
234 case 'N':
235 newval = no;
236 if (!line[1] || !strcmp(&line[1], "o"))
237 break;
238 continue;
239 case 'm':
240 case 'M':
241 newval = mod;
242 if (!line[1])
243 break;
244 continue;
245 case 'y':
246 case 'Y':
247 newval = yes;
248 if (!line[1] || !strcmp(&line[1], "es"))
249 break;
250 continue;
251 case 0:
252 newval = oldval;
253 break;
254 case '?':
255 goto help;
256 default:
257 continue;
258 }
259 if (sym_set_tristate_value(sym, newval))
260 return 0;
261help:
262 help = nohelp_text;
263 if (sym->help)
264 help = sym->help;
265 printf("\n%s\n", help);
266 }
267}
268
269static int conf_choice(struct menu *menu)
270{
271 struct symbol *sym, *def_sym;
272 struct menu *child;
273 int type;
274 bool is_new;
275
276 sym = menu->sym;
277 type = sym_get_type(sym);
278 is_new = !sym_has_value(sym);
279 if (sym_is_changable(sym)) {
280 conf_sym(menu);
281 sym_calc_value(sym);
282 switch (sym_get_tristate_value(sym)) {
283 case no:
284 return 1;
285 case mod:
286 return 0;
287 case yes:
288 break;
289 }
290 } else {
291 switch (sym_get_tristate_value(sym)) {
292 case no:
293 return 1;
294 case mod:
295 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
296 return 0;
297 case yes:
298 break;
299 }
300 }
301
302 while (1) {
303 int cnt, def;
304
305 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
306 def_sym = sym_get_choice_value(sym);
307 cnt = def = 0;
308 line[0] = '0';
309 line[1] = 0;
310 for (child = menu->list; child; child = child->next) {
311 if (!menu_is_visible(child))
312 continue;
313 if (!child->sym) {
314 printf("%*c %s\n", indent, '*', menu_get_prompt(child));
315 continue;
316 }
317 cnt++;
318 if (child->sym == def_sym) {
319 def = cnt;
320 printf("%*c", indent, '>');
321 } else
322 printf("%*c", indent, ' ');
323 printf(" %d. %s", cnt, menu_get_prompt(child));
324 if (child->sym->name)
325 printf(" (%s)", child->sym->name);
326 if (!sym_has_value(child->sym))
327 printf(" (NEW)");
328 printf("\n");
329 }
330 printf("%*schoice", indent - 1, "");
331 if (cnt == 1) {
332 printf("[1]: 1\n");
333 goto conf_childs;
334 }
335 printf("[1-%d", cnt);
336 if (sym->help)
337 printf("?");
338 printf("]: ");
339 switch (input_mode) {
340 case ask_new:
341 case ask_silent:
342 if (!is_new) {
343 cnt = def;
344 printf("%d\n", cnt);
345 break;
346 }
347 check_stdin();
348 case ask_all:
349 fflush(stdout);
350 fgets(line, 128, stdin);
351 strip(line);
352 if (line[0] == '?') {
353 printf("\n%s\n", menu->sym->help ?
354 menu->sym->help : nohelp_text);
355 continue;
356 }
357 if (!line[0])
358 cnt = def;
359 else if (isdigit(line[0]))
360 cnt = atoi(line);
361 else
362 continue;
363 break;
364 case set_random:
365 def = (random() % cnt) + 1;
366 case set_default:
367 case set_yes:
368 case set_mod:
369 case set_no:
370 cnt = def;
371 printf("%d\n", cnt);
372 break;
373 }
374
375 conf_childs:
376 for (child = menu->list; child; child = child->next) {
377 if (!child->sym || !menu_is_visible(child))
378 continue;
379 if (!--cnt)
380 break;
381 }
382 if (!child)
383 continue;
384 if (line[strlen(line) - 1] == '?') {
385 printf("\n%s\n", child->sym->help ?
386 child->sym->help : nohelp_text);
387 continue;
388 }
389 sym_set_choice_value(sym, child->sym);
390 if (child->list) {
391 indent += 2;
392 conf(child->list);
393 indent -= 2;
394 }
395 return 1;
396 }
397}
398
399static void conf(struct menu *menu)
400{
401 struct symbol *sym;
402 struct property *prop;
403 struct menu *child;
404
405 if (!menu_is_visible(menu))
406 return;
407
408 sym = menu->sym;
409 prop = menu->prompt;
410 if (prop) {
411 const char *prompt;
412
413 switch (prop->type) {
414 case P_MENU:
415 if (input_mode == ask_silent && rootEntry != menu) {
416 check_conf(menu);
417 return;
418 }
419 case P_COMMENT:
420 prompt = menu_get_prompt(menu);
421 if (prompt)
422 printf("%*c\n%*c %s\n%*c\n",
423 indent, '*',
424 indent, '*', prompt,
425 indent, '*');
426 default:
427 ;
428 }
429 }
430
431 if (!sym)
432 goto conf_childs;
433
434 if (sym_is_choice(sym)) {
435 conf_choice(menu);
436 if (sym->curr.tri != mod)
437 return;
438 goto conf_childs;
439 }
440
441 switch (sym->type) {
442 case S_INT:
443 case S_HEX:
444 case S_STRING:
445 conf_string(menu);
446 break;
447 default:
448 conf_sym(menu);
449 break;
450 }
451
452conf_childs:
453 if (sym)
454 indent += 2;
455 for (child = menu->list; child; child = child->next)
456 conf(child);
457 if (sym)
458 indent -= 2;
459}
460
461static void check_conf(struct menu *menu)
462{
463 struct symbol *sym;
464 struct menu *child;
465
466 if (!menu_is_visible(menu))
467 return;
468
469 sym = menu->sym;
470 if (sym) {
471 if (sym_is_changable(sym) && !sym_has_value(sym)) {
472 if (!conf_cnt++)
473 printf("*\n* Restart config...\n*\n");
474 rootEntry = menu_get_parent_menu(menu);
475 conf(rootEntry);
476 }
477 if (sym_is_choice(sym) && sym_get_tristate_value(sym) != mod)
478 return;
479 }
480
481 for (child = menu->list; child; child = child->next)
482 check_conf(child);
483}
484
485int main(int ac, char **av)
486{
487 int i = 1;
488 const char *name;
489 struct stat tmpstat;
490
491 if (ac > i && av[i][0] == '-') {
492 switch (av[i++][1]) {
493 case 'o':
494 input_mode = ask_new;
495 break;
496 case 's':
497 input_mode = ask_silent;
498 valid_stdin = isatty(0) && isatty(1) && isatty(2);
499 break;
500 case 'd':
501 input_mode = set_default;
502 break;
503 case 'D':
504 input_mode = set_default;
505 defconfig_file = av[i++];
506 if (!defconfig_file) {
507 printf("%s: No default config file specified\n",
508 av[0]);
509 exit(1);
510 }
511 break;
512 case 'n':
513 input_mode = set_no;
514 break;
515 case 'm':
516 input_mode = set_mod;
517 break;
518 case 'y':
519 input_mode = set_yes;
520 break;
521 case 'r':
522 input_mode = set_random;
523 srandom(time(NULL));
524 break;
525 case 'h':
526 case '?':
527 printf("%s [-o|-s] config\n", av[0]);
528 exit(0);
529 }
530 }
531 name = av[i];
532 if (!name) {
533 printf("%s: Kconfig file missing\n", av[0]);
534 }
535 conf_parse(name);
536 //zconfdump(stdout);
537 switch (input_mode) {
538 case set_default:
539 if (!defconfig_file)
540 defconfig_file = conf_get_default_confname();
541 if (conf_read(defconfig_file)) {
542 printf("***\n"
543 "*** Can't find default configuration \"%s\"!\n"
544 "***\n", defconfig_file);
545 exit(1);
546 }
547 break;
548 case ask_silent:
549 if (stat(".config", &tmpstat)) {
550 printf("***\n"
551 "*** You have not yet configured your kernel!\n"
552 "***\n"
553 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
554 "*** \"make menuconfig\" or \"make xconfig\").\n"
555 "***\n");
556 exit(1);
557 }
558 case ask_all:
559 case ask_new:
560 conf_read(NULL);
561 break;
562 default:
563 break;
564 }
565
566 if (input_mode != ask_silent) {
567 rootEntry = &rootmenu;
568 conf(&rootmenu);
569 if (input_mode == ask_all) {
570 input_mode = ask_silent;
571 valid_stdin = 1;
572 }
573 }
574 do {
575 conf_cnt = 0;
576 check_conf(&rootmenu);
577 } while (conf_cnt);
578 if (conf_write(NULL)) {
579 fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n");
580 return 1;
581 }
582 return 0;
583}
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
new file mode 100644
index 000000000000..1e82ae390a69
--- /dev/null
+++ b/scripts/kconfig/confdata.c
@@ -0,0 +1,460 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <sys/stat.h>
7#include <ctype.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <time.h>
12#include <unistd.h>
13
14#define LKC_DIRECT_LINK
15#include "lkc.h"
16
17const char conf_def_filename[] = ".config";
18
19const char conf_defname[] = "arch/$ARCH/defconfig";
20
21const char *conf_confnames[] = {
22 ".config",
23 "/lib/modules/$UNAME_RELEASE/.config",
24 "/etc/kernel-config",
25 "/boot/config-$UNAME_RELEASE",
26 conf_defname,
27 NULL,
28};
29
30static char *conf_expand_value(const signed char *in)
31{
32 struct symbol *sym;
33 const signed char *src;
34 static char res_value[SYMBOL_MAXLENGTH];
35 char *dst, name[SYMBOL_MAXLENGTH];
36
37 res_value[0] = 0;
38 dst = name;
39 while ((src = strchr(in, '$'))) {
40 strncat(res_value, in, src - in);
41 src++;
42 dst = name;
43 while (isalnum(*src) || *src == '_')
44 *dst++ = *src++;
45 *dst = 0;
46 sym = sym_lookup(name, 0);
47 sym_calc_value(sym);
48 strcat(res_value, sym_get_string_value(sym));
49 in = src;
50 }
51 strcat(res_value, in);
52
53 return res_value;
54}
55
56char *conf_get_default_confname(void)
57{
58 struct stat buf;
59 static char fullname[PATH_MAX+1];
60 char *env, *name;
61
62 name = conf_expand_value(conf_defname);
63 env = getenv(SRCTREE);
64 if (env) {
65 sprintf(fullname, "%s/%s", env, name);
66 if (!stat(fullname, &buf))
67 return fullname;
68 }
69 return name;
70}
71
72int conf_read(const char *name)
73{
74 FILE *in = NULL;
75 char line[1024];
76 char *p, *p2;
77 int lineno = 0;
78 struct symbol *sym;
79 struct property *prop;
80 struct expr *e;
81 int i;
82
83 if (name) {
84 in = zconf_fopen(name);
85 } else {
86 const char **names = conf_confnames;
87 while ((name = *names++)) {
88 name = conf_expand_value(name);
89 in = zconf_fopen(name);
90 if (in) {
91 printf("#\n"
92 "# using defaults found in %s\n"
93 "#\n", name);
94 break;
95 }
96 }
97 }
98
99 if (!in)
100 return 1;
101
102 for_all_symbols(i, sym) {
103 sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED;
104 sym->flags &= ~SYMBOL_VALID;
105 switch (sym->type) {
106 case S_INT:
107 case S_HEX:
108 case S_STRING:
109 if (sym->user.val)
110 free(sym->user.val);
111 default:
112 sym->user.val = NULL;
113 sym->user.tri = no;
114 }
115 }
116
117 while (fgets(line, sizeof(line), in)) {
118 lineno++;
119 sym = NULL;
120 switch (line[0]) {
121 case '#':
122 if (memcmp(line + 2, "CONFIG_", 7))
123 continue;
124 p = strchr(line + 9, ' ');
125 if (!p)
126 continue;
127 *p++ = 0;
128 if (strncmp(p, "is not set", 10))
129 continue;
130 sym = sym_find(line + 9);
131 if (!sym) {
132 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 9);
133 break;
134 }
135 switch (sym->type) {
136 case S_BOOLEAN:
137 case S_TRISTATE:
138 sym->user.tri = no;
139 sym->flags &= ~SYMBOL_NEW;
140 break;
141 default:
142 ;
143 }
144 break;
145 case 'C':
146 if (memcmp(line, "CONFIG_", 7))
147 continue;
148 p = strchr(line + 7, '=');
149 if (!p)
150 continue;
151 *p++ = 0;
152 p2 = strchr(p, '\n');
153 if (p2)
154 *p2 = 0;
155 sym = sym_find(line + 7);
156 if (!sym) {
157 fprintf(stderr, "%s:%d: trying to assign nonexistent symbol %s\n", name, lineno, line + 7);
158 break;
159 }
160 switch (sym->type) {
161 case S_TRISTATE:
162 if (p[0] == 'm') {
163 sym->user.tri = mod;
164 sym->flags &= ~SYMBOL_NEW;
165 break;
166 }
167 case S_BOOLEAN:
168 if (p[0] == 'y') {
169 sym->user.tri = yes;
170 sym->flags &= ~SYMBOL_NEW;
171 break;
172 }
173 if (p[0] == 'n') {
174 sym->user.tri = no;
175 sym->flags &= ~SYMBOL_NEW;
176 break;
177 }
178 break;
179 case S_STRING:
180 if (*p++ != '"')
181 break;
182 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
183 if (*p2 == '"') {
184 *p2 = 0;
185 break;
186 }
187 memmove(p2, p2 + 1, strlen(p2));
188 }
189 if (!p2) {
190 fprintf(stderr, "%s:%d: invalid string found\n", name, lineno);
191 exit(1);
192 }
193 case S_INT:
194 case S_HEX:
195 if (sym_string_valid(sym, p)) {
196 sym->user.val = strdup(p);
197 sym->flags &= ~SYMBOL_NEW;
198 } else {
199 fprintf(stderr, "%s:%d: symbol value '%s' invalid for %s\n", name, lineno, p, sym->name);
200 exit(1);
201 }
202 break;
203 default:
204 ;
205 }
206 break;
207 case '\n':
208 break;
209 default:
210 continue;
211 }
212 if (sym && sym_is_choice_value(sym)) {
213 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
214 switch (sym->user.tri) {
215 case no:
216 break;
217 case mod:
218 if (cs->user.tri == yes)
219 /* warn? */;
220 break;
221 case yes:
222 if (cs->user.tri != no)
223 /* warn? */;
224 cs->user.val = sym;
225 break;
226 }
227 cs->user.tri = E_OR(cs->user.tri, sym->user.tri);
228 cs->flags &= ~SYMBOL_NEW;
229 }
230 }
231 fclose(in);
232
233 if (modules_sym)
234 sym_calc_value(modules_sym);
235 for_all_symbols(i, sym) {
236 sym_calc_value(sym);
237 if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
238 if (sym->visible == no)
239 sym->flags |= SYMBOL_NEW;
240 switch (sym->type) {
241 case S_STRING:
242 case S_INT:
243 case S_HEX:
244 if (!sym_string_within_range(sym, sym->user.val))
245 sym->flags |= SYMBOL_NEW;
246 default:
247 break;
248 }
249 }
250 if (!sym_is_choice(sym))
251 continue;
252 prop = sym_get_choice_prop(sym);
253 for (e = prop->expr; e; e = e->left.expr)
254 if (e->right.sym->visible != no)
255 sym->flags |= e->right.sym->flags & SYMBOL_NEW;
256 }
257
258 sym_change_count = 1;
259
260 return 0;
261}
262
263int conf_write(const char *name)
264{
265 FILE *out, *out_h;
266 struct symbol *sym;
267 struct menu *menu;
268 const char *basename;
269 char dirname[128], tmpname[128], newname[128];
270 int type, l;
271 const char *str;
272 time_t now;
273 int use_timestamp = 1;
274 char *env;
275
276 dirname[0] = 0;
277 if (name && name[0]) {
278 struct stat st;
279 char *slash;
280
281 if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
282 strcpy(dirname, name);
283 strcat(dirname, "/");
284 basename = conf_def_filename;
285 } else if ((slash = strrchr(name, '/'))) {
286 int size = slash - name + 1;
287 memcpy(dirname, name, size);
288 dirname[size] = 0;
289 if (slash[1])
290 basename = slash + 1;
291 else
292 basename = conf_def_filename;
293 } else
294 basename = name;
295 } else
296 basename = conf_def_filename;
297
298 sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
299 out = fopen(newname, "w");
300 if (!out)
301 return 1;
302 out_h = NULL;
303 if (!name) {
304 out_h = fopen(".tmpconfig.h", "w");
305 if (!out_h)
306 return 1;
307 }
308 sym = sym_lookup("KERNELRELEASE", 0);
309 sym_calc_value(sym);
310 time(&now);
311 env = getenv("KCONFIG_NOTIMESTAMP");
312 if (env && *env)
313 use_timestamp = 0;
314
315 fprintf(out, "#\n"
316 "# Automatically generated make config: don't edit\n"
317 "# Linux kernel version: %s\n"
318 "%s%s"
319 "#\n",
320 sym_get_string_value(sym),
321 use_timestamp ? "# " : "",
322 use_timestamp ? ctime(&now) : "");
323 if (out_h)
324 fprintf(out_h, "/*\n"
325 " * Automatically generated C config: don't edit\n"
326 " * Linux kernel version: %s\n"
327 "%s%s"
328 " */\n"
329 "#define AUTOCONF_INCLUDED\n",
330 sym_get_string_value(sym),
331 use_timestamp ? " * " : "",
332 use_timestamp ? ctime(&now) : "");
333
334 if (!sym_change_count)
335 sym_clear_all_valid();
336
337 menu = rootmenu.list;
338 while (menu) {
339 sym = menu->sym;
340 if (!sym) {
341 if (!menu_is_visible(menu))
342 goto next;
343 str = menu_get_prompt(menu);
344 fprintf(out, "\n"
345 "#\n"
346 "# %s\n"
347 "#\n", str);
348 if (out_h)
349 fprintf(out_h, "\n"
350 "/*\n"
351 " * %s\n"
352 " */\n", str);
353 } else if (!(sym->flags & SYMBOL_CHOICE)) {
354 sym_calc_value(sym);
355 if (!(sym->flags & SYMBOL_WRITE))
356 goto next;
357 sym->flags &= ~SYMBOL_WRITE;
358 type = sym->type;
359 if (type == S_TRISTATE) {
360 sym_calc_value(modules_sym);
361 if (modules_sym->curr.tri == no)
362 type = S_BOOLEAN;
363 }
364 switch (type) {
365 case S_BOOLEAN:
366 case S_TRISTATE:
367 switch (sym_get_tristate_value(sym)) {
368 case no:
369 fprintf(out, "# CONFIG_%s is not set\n", sym->name);
370 if (out_h)
371 fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
372 break;
373 case mod:
374 fprintf(out, "CONFIG_%s=m\n", sym->name);
375 if (out_h)
376 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
377 break;
378 case yes:
379 fprintf(out, "CONFIG_%s=y\n", sym->name);
380 if (out_h)
381 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
382 break;
383 }
384 break;
385 case S_STRING:
386 // fix me
387 str = sym_get_string_value(sym);
388 fprintf(out, "CONFIG_%s=\"", sym->name);
389 if (out_h)
390 fprintf(out_h, "#define CONFIG_%s \"", sym->name);
391 do {
392 l = strcspn(str, "\"\\");
393 if (l) {
394 fwrite(str, l, 1, out);
395 if (out_h)
396 fwrite(str, l, 1, out_h);
397 }
398 str += l;
399 while (*str == '\\' || *str == '"') {
400 fprintf(out, "\\%c", *str);
401 if (out_h)
402 fprintf(out_h, "\\%c", *str);
403 str++;
404 }
405 } while (*str);
406 fputs("\"\n", out);
407 if (out_h)
408 fputs("\"\n", out_h);
409 break;
410 case S_HEX:
411 str = sym_get_string_value(sym);
412 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
413 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
414 if (out_h)
415 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
416 break;
417 }
418 case S_INT:
419 str = sym_get_string_value(sym);
420 fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
421 if (out_h)
422 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
423 break;
424 }
425 }
426
427 next:
428 if (menu->list) {
429 menu = menu->list;
430 continue;
431 }
432 if (menu->next)
433 menu = menu->next;
434 else while ((menu = menu->parent)) {
435 if (menu->next) {
436 menu = menu->next;
437 break;
438 }
439 }
440 }
441 fclose(out);
442 if (out_h) {
443 fclose(out_h);
444 rename(".tmpconfig.h", "include/linux/autoconf.h");
445 file_write_dep(NULL);
446 }
447 if (!name || basename != conf_def_filename) {
448 if (!name)
449 name = conf_def_filename;
450 sprintf(tmpname, "%s.old", name);
451 rename(name, tmpname);
452 }
453 sprintf(tmpname, "%s%s", dirname, basename);
454 if (rename(newname, tmpname))
455 return 1;
456
457 sym_change_count = 0;
458
459 return 0;
460}
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
new file mode 100644
index 000000000000..30e4f9d69c2f
--- /dev/null
+++ b/scripts/kconfig/expr.c
@@ -0,0 +1,1099 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#define LKC_DIRECT_LINK
11#include "lkc.h"
12
13#define DEBUG_EXPR 0
14
15struct expr *expr_alloc_symbol(struct symbol *sym)
16{
17 struct expr *e = malloc(sizeof(*e));
18 memset(e, 0, sizeof(*e));
19 e->type = E_SYMBOL;
20 e->left.sym = sym;
21 return e;
22}
23
24struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
25{
26 struct expr *e = malloc(sizeof(*e));
27 memset(e, 0, sizeof(*e));
28 e->type = type;
29 e->left.expr = ce;
30 return e;
31}
32
33struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
34{
35 struct expr *e = malloc(sizeof(*e));
36 memset(e, 0, sizeof(*e));
37 e->type = type;
38 e->left.expr = e1;
39 e->right.expr = e2;
40 return e;
41}
42
43struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
44{
45 struct expr *e = malloc(sizeof(*e));
46 memset(e, 0, sizeof(*e));
47 e->type = type;
48 e->left.sym = s1;
49 e->right.sym = s2;
50 return e;
51}
52
53struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
54{
55 if (!e1)
56 return e2;
57 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
58}
59
60struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
61{
62 if (!e1)
63 return e2;
64 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
65}
66
67struct expr *expr_copy(struct expr *org)
68{
69 struct expr *e;
70
71 if (!org)
72 return NULL;
73
74 e = malloc(sizeof(*org));
75 memcpy(e, org, sizeof(*org));
76 switch (org->type) {
77 case E_SYMBOL:
78 e->left = org->left;
79 break;
80 case E_NOT:
81 e->left.expr = expr_copy(org->left.expr);
82 break;
83 case E_EQUAL:
84 case E_UNEQUAL:
85 e->left.sym = org->left.sym;
86 e->right.sym = org->right.sym;
87 break;
88 case E_AND:
89 case E_OR:
90 case E_CHOICE:
91 e->left.expr = expr_copy(org->left.expr);
92 e->right.expr = expr_copy(org->right.expr);
93 break;
94 default:
95 printf("can't copy type %d\n", e->type);
96 free(e);
97 e = NULL;
98 break;
99 }
100
101 return e;
102}
103
104void expr_free(struct expr *e)
105{
106 if (!e)
107 return;
108
109 switch (e->type) {
110 case E_SYMBOL:
111 break;
112 case E_NOT:
113 expr_free(e->left.expr);
114 return;
115 case E_EQUAL:
116 case E_UNEQUAL:
117 break;
118 case E_OR:
119 case E_AND:
120 expr_free(e->left.expr);
121 expr_free(e->right.expr);
122 break;
123 default:
124 printf("how to free type %d?\n", e->type);
125 break;
126 }
127 free(e);
128}
129
130static int trans_count;
131
132#define e1 (*ep1)
133#define e2 (*ep2)
134
135static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
136{
137 if (e1->type == type) {
138 __expr_eliminate_eq(type, &e1->left.expr, &e2);
139 __expr_eliminate_eq(type, &e1->right.expr, &e2);
140 return;
141 }
142 if (e2->type == type) {
143 __expr_eliminate_eq(type, &e1, &e2->left.expr);
144 __expr_eliminate_eq(type, &e1, &e2->right.expr);
145 return;
146 }
147 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
148 e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO)))
149 return;
150 if (!expr_eq(e1, e2))
151 return;
152 trans_count++;
153 expr_free(e1); expr_free(e2);
154 switch (type) {
155 case E_OR:
156 e1 = expr_alloc_symbol(&symbol_no);
157 e2 = expr_alloc_symbol(&symbol_no);
158 break;
159 case E_AND:
160 e1 = expr_alloc_symbol(&symbol_yes);
161 e2 = expr_alloc_symbol(&symbol_yes);
162 break;
163 default:
164 ;
165 }
166}
167
168void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
169{
170 if (!e1 || !e2)
171 return;
172 switch (e1->type) {
173 case E_OR:
174 case E_AND:
175 __expr_eliminate_eq(e1->type, ep1, ep2);
176 default:
177 ;
178 }
179 if (e1->type != e2->type) switch (e2->type) {
180 case E_OR:
181 case E_AND:
182 __expr_eliminate_eq(e2->type, ep1, ep2);
183 default:
184 ;
185 }
186 e1 = expr_eliminate_yn(e1);
187 e2 = expr_eliminate_yn(e2);
188}
189
190#undef e1
191#undef e2
192
193int expr_eq(struct expr *e1, struct expr *e2)
194{
195 int res, old_count;
196
197 if (e1->type != e2->type)
198 return 0;
199 switch (e1->type) {
200 case E_EQUAL:
201 case E_UNEQUAL:
202 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
203 case E_SYMBOL:
204 return e1->left.sym == e2->left.sym;
205 case E_NOT:
206 return expr_eq(e1->left.expr, e2->left.expr);
207 case E_AND:
208 case E_OR:
209 e1 = expr_copy(e1);
210 e2 = expr_copy(e2);
211 old_count = trans_count;
212 expr_eliminate_eq(&e1, &e2);
213 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
214 e1->left.sym == e2->left.sym);
215 expr_free(e1);
216 expr_free(e2);
217 trans_count = old_count;
218 return res;
219 case E_CHOICE:
220 case E_RANGE:
221 case E_NONE:
222 /* panic */;
223 }
224
225 if (DEBUG_EXPR) {
226 expr_fprint(e1, stdout);
227 printf(" = ");
228 expr_fprint(e2, stdout);
229 printf(" ?\n");
230 }
231
232 return 0;
233}
234
235struct expr *expr_eliminate_yn(struct expr *e)
236{
237 struct expr *tmp;
238
239 if (e) switch (e->type) {
240 case E_AND:
241 e->left.expr = expr_eliminate_yn(e->left.expr);
242 e->right.expr = expr_eliminate_yn(e->right.expr);
243 if (e->left.expr->type == E_SYMBOL) {
244 if (e->left.expr->left.sym == &symbol_no) {
245 expr_free(e->left.expr);
246 expr_free(e->right.expr);
247 e->type = E_SYMBOL;
248 e->left.sym = &symbol_no;
249 e->right.expr = NULL;
250 return e;
251 } else if (e->left.expr->left.sym == &symbol_yes) {
252 free(e->left.expr);
253 tmp = e->right.expr;
254 *e = *(e->right.expr);
255 free(tmp);
256 return e;
257 }
258 }
259 if (e->right.expr->type == E_SYMBOL) {
260 if (e->right.expr->left.sym == &symbol_no) {
261 expr_free(e->left.expr);
262 expr_free(e->right.expr);
263 e->type = E_SYMBOL;
264 e->left.sym = &symbol_no;
265 e->right.expr = NULL;
266 return e;
267 } else if (e->right.expr->left.sym == &symbol_yes) {
268 free(e->right.expr);
269 tmp = e->left.expr;
270 *e = *(e->left.expr);
271 free(tmp);
272 return e;
273 }
274 }
275 break;
276 case E_OR:
277 e->left.expr = expr_eliminate_yn(e->left.expr);
278 e->right.expr = expr_eliminate_yn(e->right.expr);
279 if (e->left.expr->type == E_SYMBOL) {
280 if (e->left.expr->left.sym == &symbol_no) {
281 free(e->left.expr);
282 tmp = e->right.expr;
283 *e = *(e->right.expr);
284 free(tmp);
285 return e;
286 } else if (e->left.expr->left.sym == &symbol_yes) {
287 expr_free(e->left.expr);
288 expr_free(e->right.expr);
289 e->type = E_SYMBOL;
290 e->left.sym = &symbol_yes;
291 e->right.expr = NULL;
292 return e;
293 }
294 }
295 if (e->right.expr->type == E_SYMBOL) {
296 if (e->right.expr->left.sym == &symbol_no) {
297 free(e->right.expr);
298 tmp = e->left.expr;
299 *e = *(e->left.expr);
300 free(tmp);
301 return e;
302 } else if (e->right.expr->left.sym == &symbol_yes) {
303 expr_free(e->left.expr);
304 expr_free(e->right.expr);
305 e->type = E_SYMBOL;
306 e->left.sym = &symbol_yes;
307 e->right.expr = NULL;
308 return e;
309 }
310 }
311 break;
312 default:
313 ;
314 }
315 return e;
316}
317
318/*
319 * bool FOO!=n => FOO
320 */
321struct expr *expr_trans_bool(struct expr *e)
322{
323 if (!e)
324 return NULL;
325 switch (e->type) {
326 case E_AND:
327 case E_OR:
328 case E_NOT:
329 e->left.expr = expr_trans_bool(e->left.expr);
330 e->right.expr = expr_trans_bool(e->right.expr);
331 break;
332 case E_UNEQUAL:
333 // FOO!=n -> FOO
334 if (e->left.sym->type == S_TRISTATE) {
335 if (e->right.sym == &symbol_no) {
336 e->type = E_SYMBOL;
337 e->right.sym = NULL;
338 }
339 }
340 break;
341 default:
342 ;
343 }
344 return e;
345}
346
347/*
348 * e1 || e2 -> ?
349 */
350struct expr *expr_join_or(struct expr *e1, struct expr *e2)
351{
352 struct expr *tmp;
353 struct symbol *sym1, *sym2;
354
355 if (expr_eq(e1, e2))
356 return expr_copy(e1);
357 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
358 return NULL;
359 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
360 return NULL;
361 if (e1->type == E_NOT) {
362 tmp = e1->left.expr;
363 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
364 return NULL;
365 sym1 = tmp->left.sym;
366 } else
367 sym1 = e1->left.sym;
368 if (e2->type == E_NOT) {
369 if (e2->left.expr->type != E_SYMBOL)
370 return NULL;
371 sym2 = e2->left.expr->left.sym;
372 } else
373 sym2 = e2->left.sym;
374 if (sym1 != sym2)
375 return NULL;
376 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
377 return NULL;
378 if (sym1->type == S_TRISTATE) {
379 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
380 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
381 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
382 // (a='y') || (a='m') -> (a!='n')
383 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
384 }
385 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
386 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
387 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
388 // (a='y') || (a='n') -> (a!='m')
389 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
390 }
391 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
392 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
393 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
394 // (a='m') || (a='n') -> (a!='y')
395 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
396 }
397 }
398 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
399 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
400 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
401 return expr_alloc_symbol(&symbol_yes);
402 }
403
404 if (DEBUG_EXPR) {
405 printf("optimize (");
406 expr_fprint(e1, stdout);
407 printf(") || (");
408 expr_fprint(e2, stdout);
409 printf(")?\n");
410 }
411 return NULL;
412}
413
414struct expr *expr_join_and(struct expr *e1, struct expr *e2)
415{
416 struct expr *tmp;
417 struct symbol *sym1, *sym2;
418
419 if (expr_eq(e1, e2))
420 return expr_copy(e1);
421 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
422 return NULL;
423 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
424 return NULL;
425 if (e1->type == E_NOT) {
426 tmp = e1->left.expr;
427 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
428 return NULL;
429 sym1 = tmp->left.sym;
430 } else
431 sym1 = e1->left.sym;
432 if (e2->type == E_NOT) {
433 if (e2->left.expr->type != E_SYMBOL)
434 return NULL;
435 sym2 = e2->left.expr->left.sym;
436 } else
437 sym2 = e2->left.sym;
438 if (sym1 != sym2)
439 return NULL;
440 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
441 return NULL;
442
443 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
444 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
445 // (a) && (a='y') -> (a='y')
446 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
447
448 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
449 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
450 // (a) && (a!='n') -> (a)
451 return expr_alloc_symbol(sym1);
452
453 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
454 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
455 // (a) && (a!='m') -> (a='y')
456 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
457
458 if (sym1->type == S_TRISTATE) {
459 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
460 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
461 sym2 = e1->right.sym;
462 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
463 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
464 : expr_alloc_symbol(&symbol_no);
465 }
466 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
467 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
468 sym2 = e2->right.sym;
469 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
470 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
471 : expr_alloc_symbol(&symbol_no);
472 }
473 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
474 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
475 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
476 // (a!='y') && (a!='n') -> (a='m')
477 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
478
479 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
480 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
481 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
482 // (a!='y') && (a!='m') -> (a='n')
483 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
484
485 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
486 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
487 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
488 // (a!='m') && (a!='n') -> (a='m')
489 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
490
491 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
492 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
493 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
494 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
495 return NULL;
496 }
497
498 if (DEBUG_EXPR) {
499 printf("optimize (");
500 expr_fprint(e1, stdout);
501 printf(") && (");
502 expr_fprint(e2, stdout);
503 printf(")?\n");
504 }
505 return NULL;
506}
507
508static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
509{
510#define e1 (*ep1)
511#define e2 (*ep2)
512 struct expr *tmp;
513
514 if (e1->type == type) {
515 expr_eliminate_dups1(type, &e1->left.expr, &e2);
516 expr_eliminate_dups1(type, &e1->right.expr, &e2);
517 return;
518 }
519 if (e2->type == type) {
520 expr_eliminate_dups1(type, &e1, &e2->left.expr);
521 expr_eliminate_dups1(type, &e1, &e2->right.expr);
522 return;
523 }
524 if (e1 == e2)
525 return;
526
527 switch (e1->type) {
528 case E_OR: case E_AND:
529 expr_eliminate_dups1(e1->type, &e1, &e1);
530 default:
531 ;
532 }
533
534 switch (type) {
535 case E_OR:
536 tmp = expr_join_or(e1, e2);
537 if (tmp) {
538 expr_free(e1); expr_free(e2);
539 e1 = expr_alloc_symbol(&symbol_no);
540 e2 = tmp;
541 trans_count++;
542 }
543 break;
544 case E_AND:
545 tmp = expr_join_and(e1, e2);
546 if (tmp) {
547 expr_free(e1); expr_free(e2);
548 e1 = expr_alloc_symbol(&symbol_yes);
549 e2 = tmp;
550 trans_count++;
551 }
552 break;
553 default:
554 ;
555 }
556#undef e1
557#undef e2
558}
559
560static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
561{
562#define e1 (*ep1)
563#define e2 (*ep2)
564 struct expr *tmp, *tmp1, *tmp2;
565
566 if (e1->type == type) {
567 expr_eliminate_dups2(type, &e1->left.expr, &e2);
568 expr_eliminate_dups2(type, &e1->right.expr, &e2);
569 return;
570 }
571 if (e2->type == type) {
572 expr_eliminate_dups2(type, &e1, &e2->left.expr);
573 expr_eliminate_dups2(type, &e1, &e2->right.expr);
574 }
575 if (e1 == e2)
576 return;
577
578 switch (e1->type) {
579 case E_OR:
580 expr_eliminate_dups2(e1->type, &e1, &e1);
581 // (FOO || BAR) && (!FOO && !BAR) -> n
582 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
583 tmp2 = expr_copy(e2);
584 tmp = expr_extract_eq_and(&tmp1, &tmp2);
585 if (expr_is_yes(tmp1)) {
586 expr_free(e1);
587 e1 = expr_alloc_symbol(&symbol_no);
588 trans_count++;
589 }
590 expr_free(tmp2);
591 expr_free(tmp1);
592 expr_free(tmp);
593 break;
594 case E_AND:
595 expr_eliminate_dups2(e1->type, &e1, &e1);
596 // (FOO && BAR) || (!FOO || !BAR) -> y
597 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
598 tmp2 = expr_copy(e2);
599 tmp = expr_extract_eq_or(&tmp1, &tmp2);
600 if (expr_is_no(tmp1)) {
601 expr_free(e1);
602 e1 = expr_alloc_symbol(&symbol_yes);
603 trans_count++;
604 }
605 expr_free(tmp2);
606 expr_free(tmp1);
607 expr_free(tmp);
608 break;
609 default:
610 ;
611 }
612#undef e1
613#undef e2
614}
615
616struct expr *expr_eliminate_dups(struct expr *e)
617{
618 int oldcount;
619 if (!e)
620 return e;
621
622 oldcount = trans_count;
623 while (1) {
624 trans_count = 0;
625 switch (e->type) {
626 case E_OR: case E_AND:
627 expr_eliminate_dups1(e->type, &e, &e);
628 expr_eliminate_dups2(e->type, &e, &e);
629 default:
630 ;
631 }
632 if (!trans_count)
633 break;
634 e = expr_eliminate_yn(e);
635 }
636 trans_count = oldcount;
637 return e;
638}
639
640struct expr *expr_transform(struct expr *e)
641{
642 struct expr *tmp;
643
644 if (!e)
645 return NULL;
646 switch (e->type) {
647 case E_EQUAL:
648 case E_UNEQUAL:
649 case E_SYMBOL:
650 case E_CHOICE:
651 break;
652 default:
653 e->left.expr = expr_transform(e->left.expr);
654 e->right.expr = expr_transform(e->right.expr);
655 }
656
657 switch (e->type) {
658 case E_EQUAL:
659 if (e->left.sym->type != S_BOOLEAN)
660 break;
661 if (e->right.sym == &symbol_no) {
662 e->type = E_NOT;
663 e->left.expr = expr_alloc_symbol(e->left.sym);
664 e->right.sym = NULL;
665 break;
666 }
667 if (e->right.sym == &symbol_mod) {
668 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
669 e->type = E_SYMBOL;
670 e->left.sym = &symbol_no;
671 e->right.sym = NULL;
672 break;
673 }
674 if (e->right.sym == &symbol_yes) {
675 e->type = E_SYMBOL;
676 e->right.sym = NULL;
677 break;
678 }
679 break;
680 case E_UNEQUAL:
681 if (e->left.sym->type != S_BOOLEAN)
682 break;
683 if (e->right.sym == &symbol_no) {
684 e->type = E_SYMBOL;
685 e->right.sym = NULL;
686 break;
687 }
688 if (e->right.sym == &symbol_mod) {
689 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
690 e->type = E_SYMBOL;
691 e->left.sym = &symbol_yes;
692 e->right.sym = NULL;
693 break;
694 }
695 if (e->right.sym == &symbol_yes) {
696 e->type = E_NOT;
697 e->left.expr = expr_alloc_symbol(e->left.sym);
698 e->right.sym = NULL;
699 break;
700 }
701 break;
702 case E_NOT:
703 switch (e->left.expr->type) {
704 case E_NOT:
705 // !!a -> a
706 tmp = e->left.expr->left.expr;
707 free(e->left.expr);
708 free(e);
709 e = tmp;
710 e = expr_transform(e);
711 break;
712 case E_EQUAL:
713 case E_UNEQUAL:
714 // !a='x' -> a!='x'
715 tmp = e->left.expr;
716 free(e);
717 e = tmp;
718 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
719 break;
720 case E_OR:
721 // !(a || b) -> !a && !b
722 tmp = e->left.expr;
723 e->type = E_AND;
724 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
725 tmp->type = E_NOT;
726 tmp->right.expr = NULL;
727 e = expr_transform(e);
728 break;
729 case E_AND:
730 // !(a && b) -> !a || !b
731 tmp = e->left.expr;
732 e->type = E_OR;
733 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
734 tmp->type = E_NOT;
735 tmp->right.expr = NULL;
736 e = expr_transform(e);
737 break;
738 case E_SYMBOL:
739 if (e->left.expr->left.sym == &symbol_yes) {
740 // !'y' -> 'n'
741 tmp = e->left.expr;
742 free(e);
743 e = tmp;
744 e->type = E_SYMBOL;
745 e->left.sym = &symbol_no;
746 break;
747 }
748 if (e->left.expr->left.sym == &symbol_mod) {
749 // !'m' -> 'm'
750 tmp = e->left.expr;
751 free(e);
752 e = tmp;
753 e->type = E_SYMBOL;
754 e->left.sym = &symbol_mod;
755 break;
756 }
757 if (e->left.expr->left.sym == &symbol_no) {
758 // !'n' -> 'y'
759 tmp = e->left.expr;
760 free(e);
761 e = tmp;
762 e->type = E_SYMBOL;
763 e->left.sym = &symbol_yes;
764 break;
765 }
766 break;
767 default:
768 ;
769 }
770 break;
771 default:
772 ;
773 }
774 return e;
775}
776
777int expr_contains_symbol(struct expr *dep, struct symbol *sym)
778{
779 if (!dep)
780 return 0;
781
782 switch (dep->type) {
783 case E_AND:
784 case E_OR:
785 return expr_contains_symbol(dep->left.expr, sym) ||
786 expr_contains_symbol(dep->right.expr, sym);
787 case E_SYMBOL:
788 return dep->left.sym == sym;
789 case E_EQUAL:
790 case E_UNEQUAL:
791 return dep->left.sym == sym ||
792 dep->right.sym == sym;
793 case E_NOT:
794 return expr_contains_symbol(dep->left.expr, sym);
795 default:
796 ;
797 }
798 return 0;
799}
800
801bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
802{
803 if (!dep)
804 return false;
805
806 switch (dep->type) {
807 case E_AND:
808 return expr_depends_symbol(dep->left.expr, sym) ||
809 expr_depends_symbol(dep->right.expr, sym);
810 case E_SYMBOL:
811 return dep->left.sym == sym;
812 case E_EQUAL:
813 if (dep->left.sym == sym) {
814 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
815 return true;
816 }
817 break;
818 case E_UNEQUAL:
819 if (dep->left.sym == sym) {
820 if (dep->right.sym == &symbol_no)
821 return true;
822 }
823 break;
824 default:
825 ;
826 }
827 return false;
828}
829
830struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
831{
832 struct expr *tmp = NULL;
833 expr_extract_eq(E_AND, &tmp, ep1, ep2);
834 if (tmp) {
835 *ep1 = expr_eliminate_yn(*ep1);
836 *ep2 = expr_eliminate_yn(*ep2);
837 }
838 return tmp;
839}
840
841struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
842{
843 struct expr *tmp = NULL;
844 expr_extract_eq(E_OR, &tmp, ep1, ep2);
845 if (tmp) {
846 *ep1 = expr_eliminate_yn(*ep1);
847 *ep2 = expr_eliminate_yn(*ep2);
848 }
849 return tmp;
850}
851
852void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
853{
854#define e1 (*ep1)
855#define e2 (*ep2)
856 if (e1->type == type) {
857 expr_extract_eq(type, ep, &e1->left.expr, &e2);
858 expr_extract_eq(type, ep, &e1->right.expr, &e2);
859 return;
860 }
861 if (e2->type == type) {
862 expr_extract_eq(type, ep, ep1, &e2->left.expr);
863 expr_extract_eq(type, ep, ep1, &e2->right.expr);
864 return;
865 }
866 if (expr_eq(e1, e2)) {
867 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
868 expr_free(e2);
869 if (type == E_AND) {
870 e1 = expr_alloc_symbol(&symbol_yes);
871 e2 = expr_alloc_symbol(&symbol_yes);
872 } else if (type == E_OR) {
873 e1 = expr_alloc_symbol(&symbol_no);
874 e2 = expr_alloc_symbol(&symbol_no);
875 }
876 }
877#undef e1
878#undef e2
879}
880
881struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
882{
883 struct expr *e1, *e2;
884
885 if (!e) {
886 e = expr_alloc_symbol(sym);
887 if (type == E_UNEQUAL)
888 e = expr_alloc_one(E_NOT, e);
889 return e;
890 }
891 switch (e->type) {
892 case E_AND:
893 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
894 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
895 if (sym == &symbol_yes)
896 e = expr_alloc_two(E_AND, e1, e2);
897 if (sym == &symbol_no)
898 e = expr_alloc_two(E_OR, e1, e2);
899 if (type == E_UNEQUAL)
900 e = expr_alloc_one(E_NOT, e);
901 return e;
902 case E_OR:
903 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
904 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
905 if (sym == &symbol_yes)
906 e = expr_alloc_two(E_OR, e1, e2);
907 if (sym == &symbol_no)
908 e = expr_alloc_two(E_AND, e1, e2);
909 if (type == E_UNEQUAL)
910 e = expr_alloc_one(E_NOT, e);
911 return e;
912 case E_NOT:
913 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
914 case E_UNEQUAL:
915 case E_EQUAL:
916 if (type == E_EQUAL) {
917 if (sym == &symbol_yes)
918 return expr_copy(e);
919 if (sym == &symbol_mod)
920 return expr_alloc_symbol(&symbol_no);
921 if (sym == &symbol_no)
922 return expr_alloc_one(E_NOT, expr_copy(e));
923 } else {
924 if (sym == &symbol_yes)
925 return expr_alloc_one(E_NOT, expr_copy(e));
926 if (sym == &symbol_mod)
927 return expr_alloc_symbol(&symbol_yes);
928 if (sym == &symbol_no)
929 return expr_copy(e);
930 }
931 break;
932 case E_SYMBOL:
933 return expr_alloc_comp(type, e->left.sym, sym);
934 case E_CHOICE:
935 case E_RANGE:
936 case E_NONE:
937 /* panic */;
938 }
939 return NULL;
940}
941
942tristate expr_calc_value(struct expr *e)
943{
944 tristate val1, val2;
945 const char *str1, *str2;
946
947 if (!e)
948 return yes;
949
950 switch (e->type) {
951 case E_SYMBOL:
952 sym_calc_value(e->left.sym);
953 return e->left.sym->curr.tri;
954 case E_AND:
955 val1 = expr_calc_value(e->left.expr);
956 val2 = expr_calc_value(e->right.expr);
957 return E_AND(val1, val2);
958 case E_OR:
959 val1 = expr_calc_value(e->left.expr);
960 val2 = expr_calc_value(e->right.expr);
961 return E_OR(val1, val2);
962 case E_NOT:
963 val1 = expr_calc_value(e->left.expr);
964 return E_NOT(val1);
965 case E_EQUAL:
966 sym_calc_value(e->left.sym);
967 sym_calc_value(e->right.sym);
968 str1 = sym_get_string_value(e->left.sym);
969 str2 = sym_get_string_value(e->right.sym);
970 return !strcmp(str1, str2) ? yes : no;
971 case E_UNEQUAL:
972 sym_calc_value(e->left.sym);
973 sym_calc_value(e->right.sym);
974 str1 = sym_get_string_value(e->left.sym);
975 str2 = sym_get_string_value(e->right.sym);
976 return !strcmp(str1, str2) ? no : yes;
977 default:
978 printf("expr_calc_value: %d?\n", e->type);
979 return no;
980 }
981}
982
983int expr_compare_type(enum expr_type t1, enum expr_type t2)
984{
985#if 0
986 return 1;
987#else
988 if (t1 == t2)
989 return 0;
990 switch (t1) {
991 case E_EQUAL:
992 case E_UNEQUAL:
993 if (t2 == E_NOT)
994 return 1;
995 case E_NOT:
996 if (t2 == E_AND)
997 return 1;
998 case E_AND:
999 if (t2 == E_OR)
1000 return 1;
1001 case E_OR:
1002 if (t2 == E_CHOICE)
1003 return 1;
1004 case E_CHOICE:
1005 if (t2 == 0)
1006 return 1;
1007 default:
1008 return -1;
1009 }
1010 printf("[%dgt%d?]", t1, t2);
1011 return 0;
1012#endif
1013}
1014
1015void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)
1016{
1017 if (!e) {
1018 fn(data, "y");
1019 return;
1020 }
1021
1022 if (expr_compare_type(prevtoken, e->type) > 0)
1023 fn(data, "(");
1024 switch (e->type) {
1025 case E_SYMBOL:
1026 if (e->left.sym->name)
1027 fn(data, e->left.sym->name);
1028 else
1029 fn(data, "<choice>");
1030 break;
1031 case E_NOT:
1032 fn(data, "!");
1033 expr_print(e->left.expr, fn, data, E_NOT);
1034 break;
1035 case E_EQUAL:
1036 fn(data, e->left.sym->name);
1037 fn(data, "=");
1038 fn(data, e->right.sym->name);
1039 break;
1040 case E_UNEQUAL:
1041 fn(data, e->left.sym->name);
1042 fn(data, "!=");
1043 fn(data, e->right.sym->name);
1044 break;
1045 case E_OR:
1046 expr_print(e->left.expr, fn, data, E_OR);
1047 fn(data, " || ");
1048 expr_print(e->right.expr, fn, data, E_OR);
1049 break;
1050 case E_AND:
1051 expr_print(e->left.expr, fn, data, E_AND);
1052 fn(data, " && ");
1053 expr_print(e->right.expr, fn, data, E_AND);
1054 break;
1055 case E_CHOICE:
1056 fn(data, e->right.sym->name);
1057 if (e->left.expr) {
1058 fn(data, " ^ ");
1059 expr_print(e->left.expr, fn, data, E_CHOICE);
1060 }
1061 break;
1062 case E_RANGE:
1063 fn(data, "[");
1064 fn(data, e->left.sym->name);
1065 fn(data, " ");
1066 fn(data, e->right.sym->name);
1067 fn(data, "]");
1068 break;
1069 default:
1070 {
1071 char buf[32];
1072 sprintf(buf, "<unknown type %d>", e->type);
1073 fn(data, buf);
1074 break;
1075 }
1076 }
1077 if (expr_compare_type(prevtoken, e->type) > 0)
1078 fn(data, ")");
1079}
1080
1081static void expr_print_file_helper(void *data, const char *str)
1082{
1083 fwrite(str, strlen(str), 1, data);
1084}
1085
1086void expr_fprint(struct expr *e, FILE *out)
1087{
1088 expr_print(e, expr_print_file_helper, out, E_NONE);
1089}
1090
1091static void expr_print_gstr_helper(void *data, const char *str)
1092{
1093 str_append((struct gstr*)data, str);
1094}
1095
1096void expr_gstr_print(struct expr *e, struct gstr *gs)
1097{
1098 expr_print(e, expr_print_gstr_helper, gs, E_NONE);
1099}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
new file mode 100644
index 000000000000..7d39ff43e6e1
--- /dev/null
+++ b/scripts/kconfig/expr.h
@@ -0,0 +1,195 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#ifndef EXPR_H
7#define EXPR_H
8
9#ifdef __cplusplus
10extern "C" {
11#endif
12
13#include <stdio.h>
14#ifndef __cplusplus
15#include <stdbool.h>
16#endif
17
18struct file {
19 struct file *next;
20 struct file *parent;
21 char *name;
22 int lineno;
23 int flags;
24};
25
26#define FILE_BUSY 0x0001
27#define FILE_SCANNED 0x0002
28#define FILE_PRINTED 0x0004
29
30typedef enum tristate {
31 no, mod, yes
32} tristate;
33
34enum expr_type {
35 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
36};
37
38union expr_data {
39 struct expr *expr;
40 struct symbol *sym;
41};
42
43struct expr {
44 enum expr_type type;
45 union expr_data left, right;
46};
47
48#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
49#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
50#define E_NOT(dep) (2-(dep))
51
52struct expr_value {
53 struct expr *expr;
54 tristate tri;
55};
56
57struct symbol_value {
58 void *val;
59 tristate tri;
60};
61
62enum symbol_type {
63 S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
64};
65
66struct symbol {
67 struct symbol *next;
68 char *name;
69 char *help;
70 enum symbol_type type;
71 struct symbol_value curr, user;
72 tristate visible;
73 int flags;
74 struct property *prop;
75 struct expr *dep, *dep2;
76 struct expr_value rev_dep;
77};
78
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)
80
81#define SYMBOL_YES 0x0001
82#define SYMBOL_MOD 0x0002
83#define SYMBOL_NO 0x0004
84#define SYMBOL_CONST 0x0007
85#define SYMBOL_CHECK 0x0008
86#define SYMBOL_CHOICE 0x0010
87#define SYMBOL_CHOICEVAL 0x0020
88#define SYMBOL_PRINTED 0x0040
89#define SYMBOL_VALID 0x0080
90#define SYMBOL_OPTIONAL 0x0100
91#define SYMBOL_WRITE 0x0200
92#define SYMBOL_CHANGED 0x0400
93#define SYMBOL_NEW 0x0800
94#define SYMBOL_AUTO 0x1000
95#define SYMBOL_CHECKED 0x2000
96#define SYMBOL_CHECK_DONE 0x4000
97#define SYMBOL_WARNED 0x8000
98
99#define SYMBOL_MAXLENGTH 256
100#define SYMBOL_HASHSIZE 257
101#define SYMBOL_HASHMASK 0xff
102
103enum prop_type {
104 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
105};
106
107struct property {
108 struct property *next;
109 struct symbol *sym;
110 enum prop_type type;
111 const char *text;
112 struct expr_value visible;
113 struct expr *expr;
114 struct menu *menu;
115 struct file *file;
116 int lineno;
117};
118
119#define for_all_properties(sym, st, tok) \
120 for (st = sym->prop; st; st = st->next) \
121 if (st->type == (tok))
122#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
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)
127
128struct menu {
129 struct menu *next;
130 struct menu *parent;
131 struct menu *list;
132 struct symbol *sym;
133 struct property *prompt;
134 struct expr *dep;
135 unsigned int flags;
136 //char *help;
137 struct file *file;
138 int lineno;
139 void *data;
140};
141
142#define MENU_CHANGED 0x0001
143#define MENU_ROOT 0x0002
144
145#ifndef SWIG
146
147extern struct file *file_list;
148extern struct file *current_file;
149struct file *lookup_file(const char *name);
150
151extern struct symbol symbol_yes, symbol_no, symbol_mod;
152extern struct symbol *modules_sym;
153extern int cdebug;
154struct expr *expr_alloc_symbol(struct symbol *sym);
155struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
156struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
157struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
158struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
159struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
160struct expr *expr_copy(struct expr *org);
161void expr_free(struct expr *e);
162int expr_eq(struct expr *e1, struct expr *e2);
163void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
164tristate expr_calc_value(struct expr *e);
165struct expr *expr_eliminate_yn(struct expr *e);
166struct expr *expr_trans_bool(struct expr *e);
167struct expr *expr_eliminate_dups(struct expr *e);
168struct expr *expr_transform(struct expr *e);
169int expr_contains_symbol(struct expr *dep, struct symbol *sym);
170bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
171struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
172struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
173void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
174struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
175
176void expr_fprint(struct expr *e, FILE *out);
177struct gstr; /* forward */
178void expr_gstr_print(struct expr *e, struct gstr *gs);
179
180static inline int expr_is_yes(struct expr *e)
181{
182 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
183}
184
185static inline int expr_is_no(struct expr *e)
186{
187 return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
188}
189#endif
190
191#ifdef __cplusplus
192}
193#endif
194
195#endif /* EXPR_H */
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
new file mode 100644
index 000000000000..6fdbe6e3ce0d
--- /dev/null
+++ b/scripts/kconfig/gconf.c
@@ -0,0 +1,1639 @@
1/* Hey EMACS -*- linux-c -*- */
2/*
3 *
4 * Copyright (C) 2002-2003 Romain Lievin <roms@tilp.info>
5 * Released under the terms of the GNU GPL v2.0.
6 *
7 */
8
9#ifdef HAVE_CONFIG_H
10# include <config.h>
11#endif
12
13#include "lkc.h"
14#include "images.c"
15
16#include <glade/glade.h>
17#include <gtk/gtk.h>
18#include <glib.h>
19#include <gdk/gdkkeysyms.h>
20
21#include <stdio.h>
22#include <string.h>
23#include <unistd.h>
24#include <time.h>
25#include <stdlib.h>
26
27//#define DEBUG
28
29enum {
30 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
31};
32
33static gint view_mode = FULL_VIEW;
34static gboolean show_name = TRUE;
35static gboolean show_range = TRUE;
36static gboolean show_value = TRUE;
37static gboolean show_all = FALSE;
38static gboolean show_debug = FALSE;
39static gboolean resizeable = FALSE;
40
41static gboolean config_changed = FALSE;
42
43static char nohelp_text[] =
44 "Sorry, no help available for this option yet.\n";
45
46GtkWidget *main_wnd = NULL;
47GtkWidget *tree1_w = NULL; // left frame
48GtkWidget *tree2_w = NULL; // right frame
49GtkWidget *text_w = NULL;
50GtkWidget *hpaned = NULL;
51GtkWidget *vpaned = NULL;
52GtkWidget *back_btn = NULL;
53
54GtkTextTag *tag1, *tag2;
55GdkColor color;
56
57GtkTreeStore *tree1, *tree2, *tree;
58GtkTreeModel *model1, *model2;
59static GtkTreeIter *parents[256];
60static gint indent;
61
62static struct menu *current; // current node for SINGLE view
63static struct menu *browsed; // browsed node for SPLIT view
64
65enum {
66 COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
67 COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF,
68 COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD,
69 COL_NUMBER
70};
71
72static void display_list(void);
73static void display_tree(struct menu *menu);
74static void display_tree_part(void);
75static void update_tree(struct menu *src, GtkTreeIter * dst);
76static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
77static gchar **fill_row(struct menu *menu);
78
79
80/* Helping/Debugging Functions */
81
82
83const char *dbg_print_stype(int val)
84{
85 static char buf[256];
86
87 bzero(buf, 256);
88
89 if (val == S_UNKNOWN)
90 strcpy(buf, "unknown");
91 if (val == S_BOOLEAN)
92 strcpy(buf, "boolean");
93 if (val == S_TRISTATE)
94 strcpy(buf, "tristate");
95 if (val == S_INT)
96 strcpy(buf, "int");
97 if (val == S_HEX)
98 strcpy(buf, "hex");
99 if (val == S_STRING)
100 strcpy(buf, "string");
101 if (val == S_OTHER)
102 strcpy(buf, "other");
103
104#ifdef DEBUG
105 printf("%s", buf);
106#endif
107
108 return buf;
109}
110
111const char *dbg_print_flags(int val)
112{
113 static char buf[256];
114
115 bzero(buf, 256);
116
117 if (val & SYMBOL_YES)
118 strcat(buf, "yes/");
119 if (val & SYMBOL_MOD)
120 strcat(buf, "mod/");
121 if (val & SYMBOL_NO)
122 strcat(buf, "no/");
123 if (val & SYMBOL_CONST)
124 strcat(buf, "const/");
125 if (val & SYMBOL_CHECK)
126 strcat(buf, "check/");
127 if (val & SYMBOL_CHOICE)
128 strcat(buf, "choice/");
129 if (val & SYMBOL_CHOICEVAL)
130 strcat(buf, "choiceval/");
131 if (val & SYMBOL_PRINTED)
132 strcat(buf, "printed/");
133 if (val & SYMBOL_VALID)
134 strcat(buf, "valid/");
135 if (val & SYMBOL_OPTIONAL)
136 strcat(buf, "optional/");
137 if (val & SYMBOL_WRITE)
138 strcat(buf, "write/");
139 if (val & SYMBOL_CHANGED)
140 strcat(buf, "changed/");
141 if (val & SYMBOL_NEW)
142 strcat(buf, "new/");
143 if (val & SYMBOL_AUTO)
144 strcat(buf, "auto/");
145
146 buf[strlen(buf) - 1] = '\0';
147#ifdef DEBUG
148 printf("%s", buf);
149#endif
150
151 return buf;
152}
153
154const char *dbg_print_ptype(int val)
155{
156 static char buf[256];
157
158 bzero(buf, 256);
159
160 if (val == P_UNKNOWN)
161 strcpy(buf, "unknown");
162 if (val == P_PROMPT)
163 strcpy(buf, "prompt");
164 if (val == P_COMMENT)
165 strcpy(buf, "comment");
166 if (val == P_MENU)
167 strcpy(buf, "menu");
168 if (val == P_DEFAULT)
169 strcpy(buf, "default");
170 if (val == P_CHOICE)
171 strcpy(buf, "choice");
172
173#ifdef DEBUG
174 printf("%s", buf);
175#endif
176
177 return buf;
178}
179
180
181/* Main Window Initialization */
182
183
184void init_main_window(const gchar * glade_file)
185{
186 GladeXML *xml;
187 GtkWidget *widget;
188 GtkTextBuffer *txtbuf;
189 char title[256];
190 GdkPixmap *pixmap;
191 GdkBitmap *mask;
192 GtkStyle *style;
193
194 xml = glade_xml_new(glade_file, "window1", NULL);
195 if (!xml)
196 g_error("GUI loading failed !\n");
197 glade_xml_signal_autoconnect(xml);
198
199 main_wnd = glade_xml_get_widget(xml, "window1");
200 hpaned = glade_xml_get_widget(xml, "hpaned1");
201 vpaned = glade_xml_get_widget(xml, "vpaned1");
202 tree1_w = glade_xml_get_widget(xml, "treeview1");
203 tree2_w = glade_xml_get_widget(xml, "treeview2");
204 text_w = glade_xml_get_widget(xml, "textview3");
205
206 back_btn = glade_xml_get_widget(xml, "button1");
207 gtk_widget_set_sensitive(back_btn, FALSE);
208
209 widget = glade_xml_get_widget(xml, "show_name1");
210 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
211 show_name);
212
213 widget = glade_xml_get_widget(xml, "show_range1");
214 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
215 show_range);
216
217 widget = glade_xml_get_widget(xml, "show_data1");
218 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
219 show_value);
220
221 style = gtk_widget_get_style(main_wnd);
222 widget = glade_xml_get_widget(xml, "toolbar1");
223
224 pixmap = gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
225 &style->bg[GTK_STATE_NORMAL],
226 (gchar **) xpm_single_view);
227 gtk_image_set_from_pixmap(GTK_IMAGE
228 (((GtkToolbarChild
229 *) (g_list_nth(GTK_TOOLBAR(widget)->
230 children,
231 5)->data))->icon),
232 pixmap, mask);
233 pixmap =
234 gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
235 &style->bg[GTK_STATE_NORMAL],
236 (gchar **) xpm_split_view);
237 gtk_image_set_from_pixmap(GTK_IMAGE
238 (((GtkToolbarChild
239 *) (g_list_nth(GTK_TOOLBAR(widget)->
240 children,
241 6)->data))->icon),
242 pixmap, mask);
243 pixmap =
244 gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
245 &style->bg[GTK_STATE_NORMAL],
246 (gchar **) xpm_tree_view);
247 gtk_image_set_from_pixmap(GTK_IMAGE
248 (((GtkToolbarChild
249 *) (g_list_nth(GTK_TOOLBAR(widget)->
250 children,
251 7)->data))->icon),
252 pixmap, mask);
253
254 switch (view_mode) {
255 case SINGLE_VIEW:
256 widget = glade_xml_get_widget(xml, "button4");
257 g_signal_emit_by_name(widget, "clicked");
258 break;
259 case SPLIT_VIEW:
260 widget = glade_xml_get_widget(xml, "button5");
261 g_signal_emit_by_name(widget, "clicked");
262 break;
263 case FULL_VIEW:
264 widget = glade_xml_get_widget(xml, "button6");
265 g_signal_emit_by_name(widget, "clicked");
266 break;
267 }
268
269 txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
270 tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
271 "foreground", "red",
272 "weight", PANGO_WEIGHT_BOLD,
273 NULL);
274 tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
275 /*"style", PANGO_STYLE_OBLIQUE, */
276 NULL);
277
278 sprintf(title, "Linux Kernel v%s Configuration",
279 getenv("KERNELRELEASE"));
280 gtk_window_set_title(GTK_WINDOW(main_wnd), title);
281
282 gtk_widget_show(main_wnd);
283}
284
285void init_tree_model(void)
286{
287 gint i;
288
289 tree = tree2 = gtk_tree_store_new(COL_NUMBER,
290 G_TYPE_STRING, G_TYPE_STRING,
291 G_TYPE_STRING, G_TYPE_STRING,
292 G_TYPE_STRING, G_TYPE_STRING,
293 G_TYPE_POINTER, GDK_TYPE_COLOR,
294 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
295 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
296 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
297 G_TYPE_BOOLEAN);
298 model2 = GTK_TREE_MODEL(tree2);
299
300 for (parents[0] = NULL, i = 1; i < 256; i++)
301 parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
302
303 tree1 = gtk_tree_store_new(COL_NUMBER,
304 G_TYPE_STRING, G_TYPE_STRING,
305 G_TYPE_STRING, G_TYPE_STRING,
306 G_TYPE_STRING, G_TYPE_STRING,
307 G_TYPE_POINTER, GDK_TYPE_COLOR,
308 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
309 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
310 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
311 G_TYPE_BOOLEAN);
312 model1 = GTK_TREE_MODEL(tree1);
313}
314
315void init_left_tree(void)
316{
317 GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
318 GtkCellRenderer *renderer;
319 GtkTreeSelection *sel;
320 GtkTreeViewColumn *column;
321
322 gtk_tree_view_set_model(view, model1);
323 gtk_tree_view_set_headers_visible(view, TRUE);
324 gtk_tree_view_set_rules_hint(view, FALSE);
325
326 column = gtk_tree_view_column_new();
327 gtk_tree_view_append_column(view, column);
328 gtk_tree_view_column_set_title(column, "Options");
329
330 renderer = gtk_cell_renderer_toggle_new();
331 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
332 renderer, FALSE);
333 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
334 renderer,
335 "active", COL_BTNACT,
336 "inconsistent", COL_BTNINC,
337 "visible", COL_BTNVIS,
338 "radio", COL_BTNRAD, NULL);
339 renderer = gtk_cell_renderer_text_new();
340 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
341 renderer, FALSE);
342 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
343 renderer,
344 "text", COL_OPTION,
345 "foreground-gdk",
346 COL_COLOR, NULL);
347
348 sel = gtk_tree_view_get_selection(view);
349 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
350 gtk_widget_realize(tree1_w);
351}
352
353static void renderer_edited(GtkCellRendererText * cell,
354 const gchar * path_string,
355 const gchar * new_text, gpointer user_data);
356static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle,
357 gchar * arg1, gpointer user_data);
358
359void init_right_tree(void)
360{
361 GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
362 GtkCellRenderer *renderer;
363 GtkTreeSelection *sel;
364 GtkTreeViewColumn *column;
365 gint i;
366
367 gtk_tree_view_set_model(view, model2);
368 gtk_tree_view_set_headers_visible(view, TRUE);
369 gtk_tree_view_set_rules_hint(view, FALSE);
370
371 column = gtk_tree_view_column_new();
372 gtk_tree_view_append_column(view, column);
373 gtk_tree_view_column_set_title(column, "Options");
374
375 renderer = gtk_cell_renderer_pixbuf_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 "pixbuf", COL_PIXBUF,
381 "visible", COL_PIXVIS, NULL);
382 renderer = gtk_cell_renderer_toggle_new();
383 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
384 renderer, FALSE);
385 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
386 renderer,
387 "active", COL_BTNACT,
388 "inconsistent", COL_BTNINC,
389 "visible", COL_BTNVIS,
390 "radio", COL_BTNRAD, NULL);
391 /*g_signal_connect(G_OBJECT(renderer), "toggled",
392 G_CALLBACK(renderer_toggled), NULL); */
393 renderer = gtk_cell_renderer_text_new();
394 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
395 renderer, FALSE);
396 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
397 renderer,
398 "text", COL_OPTION,
399 "foreground-gdk",
400 COL_COLOR, NULL);
401
402 renderer = gtk_cell_renderer_text_new();
403 gtk_tree_view_insert_column_with_attributes(view, -1,
404 "Name", renderer,
405 "text", COL_NAME,
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 "N", renderer,
411 "text", COL_NO,
412 "foreground-gdk",
413 COL_COLOR, NULL);
414 renderer = gtk_cell_renderer_text_new();
415 gtk_tree_view_insert_column_with_attributes(view, -1,
416 "M", renderer,
417 "text", COL_MOD,
418 "foreground-gdk",
419 COL_COLOR, NULL);
420 renderer = gtk_cell_renderer_text_new();
421 gtk_tree_view_insert_column_with_attributes(view, -1,
422 "Y", renderer,
423 "text", COL_YES,
424 "foreground-gdk",
425 COL_COLOR, NULL);
426 renderer = gtk_cell_renderer_text_new();
427 gtk_tree_view_insert_column_with_attributes(view, -1,
428 "Value", renderer,
429 "text", COL_VALUE,
430 "editable",
431 COL_EDIT,
432 "foreground-gdk",
433 COL_COLOR, NULL);
434 g_signal_connect(G_OBJECT(renderer), "edited",
435 G_CALLBACK(renderer_edited), NULL);
436
437 column = gtk_tree_view_get_column(view, COL_NAME);
438 gtk_tree_view_column_set_visible(column, show_name);
439 column = gtk_tree_view_get_column(view, COL_NO);
440 gtk_tree_view_column_set_visible(column, show_range);
441 column = gtk_tree_view_get_column(view, COL_MOD);
442 gtk_tree_view_column_set_visible(column, show_range);
443 column = gtk_tree_view_get_column(view, COL_YES);
444 gtk_tree_view_column_set_visible(column, show_range);
445 column = gtk_tree_view_get_column(view, COL_VALUE);
446 gtk_tree_view_column_set_visible(column, show_value);
447
448 if (resizeable) {
449 for (i = 0; i < COL_VALUE; i++) {
450 column = gtk_tree_view_get_column(view, i);
451 gtk_tree_view_column_set_resizable(column, TRUE);
452 }
453 }
454
455 sel = gtk_tree_view_get_selection(view);
456 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
457}
458
459
460/* Utility Functions */
461
462
463static void text_insert_help(struct menu *menu)
464{
465 GtkTextBuffer *buffer;
466 GtkTextIter start, end;
467 const char *prompt = menu_get_prompt(menu);
468 gchar *name;
469 const char *help = nohelp_text;
470
471 if (!menu->sym)
472 help = "";
473 else if (menu->sym->help)
474 help = menu->sym->help;
475
476 if (menu->sym && menu->sym->name)
477 name = g_strdup_printf(menu->sym->name);
478 else
479 name = g_strdup("");
480
481 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
482 gtk_text_buffer_get_bounds(buffer, &start, &end);
483 gtk_text_buffer_delete(buffer, &start, &end);
484 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
485
486 gtk_text_buffer_get_end_iter(buffer, &end);
487 gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
488 NULL);
489 gtk_text_buffer_insert_at_cursor(buffer, " ", 1);
490 gtk_text_buffer_get_end_iter(buffer, &end);
491 gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1,
492 NULL);
493 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
494 gtk_text_buffer_get_end_iter(buffer, &end);
495 gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2,
496 NULL);
497}
498
499
500static void text_insert_msg(const char *title, const char *message)
501{
502 GtkTextBuffer *buffer;
503 GtkTextIter start, end;
504 const char *msg = message;
505
506 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
507 gtk_text_buffer_get_bounds(buffer, &start, &end);
508 gtk_text_buffer_delete(buffer, &start, &end);
509 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
510
511 gtk_text_buffer_get_end_iter(buffer, &end);
512 gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
513 NULL);
514 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
515 gtk_text_buffer_get_end_iter(buffer, &end);
516 gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
517 NULL);
518}
519
520
521/* Main Windows Callbacks */
522
523void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data);
524gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
525 gpointer user_data)
526{
527 GtkWidget *dialog, *label;
528 gint result;
529
530 if (config_changed == FALSE)
531 return FALSE;
532
533 dialog = gtk_dialog_new_with_buttons("Warning !",
534 GTK_WINDOW(main_wnd),
535 (GtkDialogFlags)
536 (GTK_DIALOG_MODAL |
537 GTK_DIALOG_DESTROY_WITH_PARENT),
538 GTK_STOCK_OK,
539 GTK_RESPONSE_YES,
540 GTK_STOCK_NO,
541 GTK_RESPONSE_NO,
542 GTK_STOCK_CANCEL,
543 GTK_RESPONSE_CANCEL, NULL);
544 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
545 GTK_RESPONSE_CANCEL);
546
547 label = gtk_label_new("\nSave configuration ?\n");
548 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
549 gtk_widget_show(label);
550
551 result = gtk_dialog_run(GTK_DIALOG(dialog));
552 switch (result) {
553 case GTK_RESPONSE_YES:
554 on_save1_activate(NULL, NULL);
555 return FALSE;
556 case GTK_RESPONSE_NO:
557 return FALSE;
558 case GTK_RESPONSE_CANCEL:
559 case GTK_RESPONSE_DELETE_EVENT:
560 default:
561 gtk_widget_destroy(dialog);
562 return TRUE;
563 }
564
565 return FALSE;
566}
567
568
569void on_window1_destroy(GtkObject * object, gpointer user_data)
570{
571 gtk_main_quit();
572}
573
574
575void
576on_window1_size_request(GtkWidget * widget,
577 GtkRequisition * requisition, gpointer user_data)
578{
579 static gint old_h;
580 gint w, h;
581
582 if (widget->window == NULL)
583 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
584 else
585 gdk_window_get_size(widget->window, &w, &h);
586
587 if (h == old_h)
588 return;
589 old_h = h;
590
591 gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
592}
593
594
595/* Menu & Toolbar Callbacks */
596
597
598static void
599load_filename(GtkFileSelection * file_selector, gpointer user_data)
600{
601 const gchar *fn;
602
603 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
604 (user_data));
605
606 if (conf_read(fn))
607 text_insert_msg("Error", "Unable to load configuration !");
608 else
609 display_tree(&rootmenu);
610}
611
612void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
613{
614 GtkWidget *fs;
615
616 fs = gtk_file_selection_new("Load file...");
617 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
618 "clicked",
619 G_CALLBACK(load_filename), (gpointer) fs);
620 g_signal_connect_swapped(GTK_OBJECT
621 (GTK_FILE_SELECTION(fs)->ok_button),
622 "clicked", G_CALLBACK(gtk_widget_destroy),
623 (gpointer) fs);
624 g_signal_connect_swapped(GTK_OBJECT
625 (GTK_FILE_SELECTION(fs)->cancel_button),
626 "clicked", G_CALLBACK(gtk_widget_destroy),
627 (gpointer) fs);
628 gtk_widget_show(fs);
629}
630
631
632void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
633{
634 if (conf_write(NULL))
635 text_insert_msg("Error", "Unable to save configuration !");
636
637 config_changed = FALSE;
638}
639
640
641static void
642store_filename(GtkFileSelection * file_selector, gpointer user_data)
643{
644 const gchar *fn;
645
646 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
647 (user_data));
648
649 if (conf_write(fn))
650 text_insert_msg("Error", "Unable to save configuration !");
651
652 gtk_widget_destroy(GTK_WIDGET(user_data));
653}
654
655void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
656{
657 GtkWidget *fs;
658
659 fs = gtk_file_selection_new("Save file as...");
660 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
661 "clicked",
662 G_CALLBACK(store_filename), (gpointer) fs);
663 g_signal_connect_swapped(GTK_OBJECT
664 (GTK_FILE_SELECTION(fs)->ok_button),
665 "clicked", G_CALLBACK(gtk_widget_destroy),
666 (gpointer) fs);
667 g_signal_connect_swapped(GTK_OBJECT
668 (GTK_FILE_SELECTION(fs)->cancel_button),
669 "clicked", G_CALLBACK(gtk_widget_destroy),
670 (gpointer) fs);
671 gtk_widget_show(fs);
672}
673
674
675void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
676{
677 if (!on_window1_delete_event(NULL, NULL, NULL))
678 gtk_widget_destroy(GTK_WIDGET(main_wnd));
679}
680
681
682void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
683{
684 GtkTreeViewColumn *col;
685
686 show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
687 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
688 if (col)
689 gtk_tree_view_column_set_visible(col, show_name);
690}
691
692
693void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
694{
695 GtkTreeViewColumn *col;
696
697 show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
698 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
699 if (col)
700 gtk_tree_view_column_set_visible(col, show_range);
701 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD);
702 if (col)
703 gtk_tree_view_column_set_visible(col, show_range);
704 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES);
705 if (col)
706 gtk_tree_view_column_set_visible(col, show_range);
707
708}
709
710
711void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
712{
713 GtkTreeViewColumn *col;
714
715 show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
716 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
717 if (col)
718 gtk_tree_view_column_set_visible(col, show_value);
719}
720
721
722void
723on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
724{
725 show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
726
727 gtk_tree_store_clear(tree2);
728 display_tree(&rootmenu); // instead of update_tree to speed-up
729}
730
731
732void
733on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
734{
735 show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
736 update_tree(&rootmenu, NULL);
737}
738
739
740void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
741{
742 GtkWidget *dialog;
743 const gchar *intro_text =
744 "Welcome to gkc, the GTK+ graphical kernel configuration tool\n"
745 "for Linux.\n"
746 "For each option, a blank box indicates the feature is disabled, a\n"
747 "check indicates it is enabled, and a dot indicates that it is to\n"
748 "be compiled as a module. Clicking on the box will cycle through the three states.\n"
749 "\n"
750 "If you do not see an option (e.g., a device driver) that you\n"
751 "believe should be present, try turning on Show All Options\n"
752 "under the Options menu.\n"
753 "Although there is no cross reference yet to help you figure out\n"
754 "what other options must be enabled to support the option you\n"
755 "are interested in, you can still view the help of a grayed-out\n"
756 "option.\n"
757 "\n"
758 "Toggling Show Debug Info under the Options menu will show \n"
759 "the dependencies, which you can then match by examining other options.";
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, intro_text);
765 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
766 G_CALLBACK(gtk_widget_destroy),
767 GTK_OBJECT(dialog));
768 gtk_widget_show_all(dialog);
769}
770
771
772void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
773{
774 GtkWidget *dialog;
775 const gchar *about_text =
776 "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
777 "Based on the source code from Roman Zippel.\n";
778
779 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
780 GTK_DIALOG_DESTROY_WITH_PARENT,
781 GTK_MESSAGE_INFO,
782 GTK_BUTTONS_CLOSE, about_text);
783 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
784 G_CALLBACK(gtk_widget_destroy),
785 GTK_OBJECT(dialog));
786 gtk_widget_show_all(dialog);
787}
788
789
790void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
791{
792 GtkWidget *dialog;
793 const gchar *license_text =
794 "gkc is released under the terms of the GNU GPL v2.\n"
795 "For more information, please see the source code or\n"
796 "visit http://www.fsf.org/licenses/licenses.html\n";
797
798 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
799 GTK_DIALOG_DESTROY_WITH_PARENT,
800 GTK_MESSAGE_INFO,
801 GTK_BUTTONS_CLOSE, license_text);
802 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
803 G_CALLBACK(gtk_widget_destroy),
804 GTK_OBJECT(dialog));
805 gtk_widget_show_all(dialog);
806}
807
808
809void on_back_pressed(GtkButton * button, gpointer user_data)
810{
811 enum prop_type ptype;
812
813 current = current->parent;
814 ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
815 if (ptype != P_MENU)
816 current = current->parent;
817 display_tree_part();
818
819 if (current == &rootmenu)
820 gtk_widget_set_sensitive(back_btn, FALSE);
821}
822
823
824void on_load_pressed(GtkButton * button, gpointer user_data)
825{
826 on_load1_activate(NULL, user_data);
827}
828
829
830void on_save_pressed(GtkButton * button, gpointer user_data)
831{
832 on_save1_activate(NULL, user_data);
833}
834
835
836void on_single_clicked(GtkButton * button, gpointer user_data)
837{
838 view_mode = SINGLE_VIEW;
839 gtk_paned_set_position(GTK_PANED(hpaned), 0);
840 gtk_widget_hide(tree1_w);
841 current = &rootmenu;
842 display_tree_part();
843}
844
845
846void on_split_clicked(GtkButton * button, gpointer user_data)
847{
848 gint w, h;
849 view_mode = SPLIT_VIEW;
850 gtk_widget_show(tree1_w);
851 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
852 gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
853 if (tree2)
854 gtk_tree_store_clear(tree2);
855 display_list();
856}
857
858
859void on_full_clicked(GtkButton * button, gpointer user_data)
860{
861 view_mode = FULL_VIEW;
862 gtk_paned_set_position(GTK_PANED(hpaned), 0);
863 gtk_widget_hide(tree1_w);
864 if (tree2)
865 gtk_tree_store_clear(tree2);
866 display_tree(&rootmenu);
867 gtk_widget_set_sensitive(back_btn, FALSE);
868}
869
870
871void on_collapse_pressed(GtkButton * button, gpointer user_data)
872{
873 gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
874}
875
876
877void on_expand_pressed(GtkButton * button, gpointer user_data)
878{
879 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
880}
881
882
883/* CTree Callbacks */
884
885/* Change hex/int/string value in the cell */
886static void renderer_edited(GtkCellRendererText * cell,
887 const gchar * path_string,
888 const gchar * new_text, gpointer user_data)
889{
890 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
891 GtkTreeIter iter;
892 const char *old_def, *new_def;
893 struct menu *menu;
894 struct symbol *sym;
895
896 if (!gtk_tree_model_get_iter(model2, &iter, path))
897 return;
898
899 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
900 sym = menu->sym;
901
902 gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
903 new_def = new_text;
904
905 sym_set_string_value(sym, new_def);
906
907 config_changed = TRUE;
908 update_tree(&rootmenu, NULL);
909
910 gtk_tree_path_free(path);
911}
912
913/* Change the value of a symbol and update the tree */
914static void change_sym_value(struct menu *menu, gint col)
915{
916 struct symbol *sym = menu->sym;
917 tristate oldval, newval;
918
919 if (!sym)
920 return;
921
922 if (col == COL_NO)
923 newval = no;
924 else if (col == COL_MOD)
925 newval = mod;
926 else if (col == COL_YES)
927 newval = yes;
928 else
929 return;
930
931 switch (sym_get_type(sym)) {
932 case S_BOOLEAN:
933 case S_TRISTATE:
934 oldval = sym_get_tristate_value(sym);
935 if (!sym_tristate_within_range(sym, newval))
936 newval = yes;
937 sym_set_tristate_value(sym, newval);
938 config_changed = TRUE;
939 if (view_mode == FULL_VIEW)
940 update_tree(&rootmenu, NULL);
941 else if (view_mode == SPLIT_VIEW) {
942 update_tree(browsed, NULL);
943 display_list();
944 }
945 else if (view_mode == SINGLE_VIEW)
946 display_tree_part(); //fixme: keep exp/coll
947 break;
948 case S_INT:
949 case S_HEX:
950 case S_STRING:
951 default:
952 break;
953 }
954}
955
956static void toggle_sym_value(struct menu *menu)
957{
958 if (!menu->sym)
959 return;
960
961 sym_toggle_tristate_value(menu->sym);
962 if (view_mode == FULL_VIEW)
963 update_tree(&rootmenu, NULL);
964 else if (view_mode == SPLIT_VIEW) {
965 update_tree(browsed, NULL);
966 display_list();
967 }
968 else if (view_mode == SINGLE_VIEW)
969 display_tree_part(); //fixme: keep exp/coll
970}
971
972static void renderer_toggled(GtkCellRendererToggle * cell,
973 gchar * path_string, gpointer user_data)
974{
975 GtkTreePath *path, *sel_path = NULL;
976 GtkTreeIter iter, sel_iter;
977 GtkTreeSelection *sel;
978 struct menu *menu;
979
980 path = gtk_tree_path_new_from_string(path_string);
981 if (!gtk_tree_model_get_iter(model2, &iter, path))
982 return;
983
984 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w));
985 if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter))
986 sel_path = gtk_tree_model_get_path(model2, &sel_iter);
987 if (!sel_path)
988 goto out1;
989 if (gtk_tree_path_compare(path, sel_path))
990 goto out2;
991
992 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
993 toggle_sym_value(menu);
994
995 out2:
996 gtk_tree_path_free(sel_path);
997 out1:
998 gtk_tree_path_free(path);
999}
1000
1001static gint column2index(GtkTreeViewColumn * column)
1002{
1003 gint i;
1004
1005 for (i = 0; i < COL_NUMBER; i++) {
1006 GtkTreeViewColumn *col;
1007
1008 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i);
1009 if (col == column)
1010 return i;
1011 }
1012
1013 return -1;
1014}
1015
1016
1017/* User click: update choice (full) or goes down (single) */
1018gboolean
1019on_treeview2_button_press_event(GtkWidget * widget,
1020 GdkEventButton * event, gpointer user_data)
1021{
1022 GtkTreeView *view = GTK_TREE_VIEW(widget);
1023 GtkTreePath *path;
1024 GtkTreeViewColumn *column;
1025 GtkTreeIter iter;
1026 struct menu *menu;
1027 gint col;
1028
1029#if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK
1030 gint tx = (gint) event->x;
1031 gint ty = (gint) event->y;
1032 gint cx, cy;
1033
1034 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1035 &cy);
1036#else
1037 gtk_tree_view_get_cursor(view, &path, &column);
1038#endif
1039 if (path == NULL)
1040 return FALSE;
1041
1042 if (!gtk_tree_model_get_iter(model2, &iter, path))
1043 return FALSE;
1044 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1045
1046 col = column2index(column);
1047 if (event->type == GDK_2BUTTON_PRESS) {
1048 enum prop_type ptype;
1049 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1050
1051 if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
1052 // goes down into menu
1053 current = menu;
1054 display_tree_part();
1055 gtk_widget_set_sensitive(back_btn, TRUE);
1056 } else if ((col == COL_OPTION)) {
1057 toggle_sym_value(menu);
1058 gtk_tree_view_expand_row(view, path, TRUE);
1059 }
1060 } else {
1061 if (col == COL_VALUE) {
1062 toggle_sym_value(menu);
1063 gtk_tree_view_expand_row(view, path, TRUE);
1064 } else if (col == COL_NO || col == COL_MOD
1065 || col == COL_YES) {
1066 change_sym_value(menu, col);
1067 gtk_tree_view_expand_row(view, path, TRUE);
1068 }
1069 }
1070
1071 return FALSE;
1072}
1073
1074/* Key pressed: update choice */
1075gboolean
1076on_treeview2_key_press_event(GtkWidget * widget,
1077 GdkEventKey * event, gpointer user_data)
1078{
1079 GtkTreeView *view = GTK_TREE_VIEW(widget);
1080 GtkTreePath *path;
1081 GtkTreeViewColumn *column;
1082 GtkTreeIter iter;
1083 struct menu *menu;
1084 gint col;
1085
1086 gtk_tree_view_get_cursor(view, &path, &column);
1087 if (path == NULL)
1088 return FALSE;
1089
1090 if (event->keyval == GDK_space) {
1091 if (gtk_tree_view_row_expanded(view, path))
1092 gtk_tree_view_collapse_row(view, path);
1093 else
1094 gtk_tree_view_expand_row(view, path, FALSE);
1095 return TRUE;
1096 }
1097 if (event->keyval == GDK_KP_Enter) {
1098 }
1099 if (widget == tree1_w)
1100 return FALSE;
1101
1102 gtk_tree_model_get_iter(model2, &iter, path);
1103 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1104
1105 if (!strcasecmp(event->string, "n"))
1106 col = COL_NO;
1107 else if (!strcasecmp(event->string, "m"))
1108 col = COL_MOD;
1109 else if (!strcasecmp(event->string, "y"))
1110 col = COL_YES;
1111 else
1112 col = -1;
1113 change_sym_value(menu, col);
1114
1115 return FALSE;
1116}
1117
1118
1119/* Row selection changed: update help */
1120void
1121on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
1122{
1123 GtkTreeSelection *selection;
1124 GtkTreeIter iter;
1125 struct menu *menu;
1126
1127 selection = gtk_tree_view_get_selection(treeview);
1128 if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
1129 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1130 text_insert_help(menu);
1131 }
1132}
1133
1134
1135/* User click: display sub-tree in the right frame. */
1136gboolean
1137on_treeview1_button_press_event(GtkWidget * widget,
1138 GdkEventButton * event, gpointer user_data)
1139{
1140 GtkTreeView *view = GTK_TREE_VIEW(widget);
1141 GtkTreePath *path;
1142 GtkTreeViewColumn *column;
1143 GtkTreeIter iter;
1144 struct menu *menu;
1145
1146 gint tx = (gint) event->x;
1147 gint ty = (gint) event->y;
1148 gint cx, cy;
1149
1150 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1151 &cy);
1152 if (path == NULL)
1153 return FALSE;
1154
1155 gtk_tree_model_get_iter(model1, &iter, path);
1156 gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
1157
1158 if (event->type == GDK_2BUTTON_PRESS) {
1159 toggle_sym_value(menu);
1160 current = menu;
1161 display_tree_part();
1162 } else {
1163 browsed = menu;
1164 display_tree_part();
1165 }
1166
1167 gtk_widget_realize(tree2_w);
1168 gtk_tree_view_set_cursor(view, path, NULL, FALSE);
1169 gtk_widget_grab_focus(tree2_w);
1170
1171 return FALSE;
1172}
1173
1174
1175/* Fill a row of strings */
1176static gchar **fill_row(struct menu *menu)
1177{
1178 static gchar *row[COL_NUMBER];
1179 struct symbol *sym = menu->sym;
1180 const char *def;
1181 int stype;
1182 tristate val;
1183 enum prop_type ptype;
1184 int i;
1185
1186 for (i = COL_OPTION; i <= COL_COLOR; i++)
1187 g_free(row[i]);
1188 bzero(row, sizeof(row));
1189
1190 row[COL_OPTION] =
1191 g_strdup_printf("%s %s", menu_get_prompt(menu),
1192 sym ? (sym->
1193 flags & SYMBOL_NEW ? "(NEW)" : "") :
1194 "");
1195
1196 if (show_all && !menu_is_visible(menu))
1197 row[COL_COLOR] = g_strdup("DarkGray");
1198 else
1199 row[COL_COLOR] = g_strdup("Black");
1200
1201 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1202 switch (ptype) {
1203 case P_MENU:
1204 row[COL_PIXBUF] = (gchar *) xpm_menu;
1205 if (view_mode == SINGLE_VIEW)
1206 row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
1207 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1208 break;
1209 case P_COMMENT:
1210 row[COL_PIXBUF] = (gchar *) xpm_void;
1211 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1212 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1213 break;
1214 default:
1215 row[COL_PIXBUF] = (gchar *) xpm_void;
1216 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1217 row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1218 break;
1219 }
1220
1221 if (!sym)
1222 return row;
1223 row[COL_NAME] = g_strdup(sym->name);
1224
1225 sym_calc_value(sym);
1226 sym->flags &= ~SYMBOL_CHANGED;
1227
1228 if (sym_is_choice(sym)) { // parse childs for getting final value
1229 struct menu *child;
1230 struct symbol *def_sym = sym_get_choice_value(sym);
1231 struct menu *def_menu = NULL;
1232
1233 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1234
1235 for (child = menu->list; child; child = child->next) {
1236 if (menu_is_visible(child)
1237 && child->sym == def_sym)
1238 def_menu = child;
1239 }
1240
1241 if (def_menu)
1242 row[COL_VALUE] =
1243 g_strdup(menu_get_prompt(def_menu));
1244 }
1245 if(sym->flags & SYMBOL_CHOICEVAL)
1246 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
1247
1248 stype = sym_get_type(sym);
1249 switch (stype) {
1250 case S_BOOLEAN:
1251 if(GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE)
1252 row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1253 if (sym_is_choice(sym))
1254 break;
1255 case S_TRISTATE:
1256 val = sym_get_tristate_value(sym);
1257 switch (val) {
1258 case no:
1259 row[COL_NO] = g_strdup("N");
1260 row[COL_VALUE] = g_strdup("N");
1261 row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
1262 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1263 break;
1264 case mod:
1265 row[COL_MOD] = g_strdup("M");
1266 row[COL_VALUE] = g_strdup("M");
1267 row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
1268 break;
1269 case yes:
1270 row[COL_YES] = g_strdup("Y");
1271 row[COL_VALUE] = g_strdup("Y");
1272 row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
1273 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1274 break;
1275 }
1276
1277 if (val != no && sym_tristate_within_range(sym, no))
1278 row[COL_NO] = g_strdup("_");
1279 if (val != mod && sym_tristate_within_range(sym, mod))
1280 row[COL_MOD] = g_strdup("_");
1281 if (val != yes && sym_tristate_within_range(sym, yes))
1282 row[COL_YES] = g_strdup("_");
1283 break;
1284 case S_INT:
1285 case S_HEX:
1286 case S_STRING:
1287 def = sym_get_string_value(sym);
1288 row[COL_VALUE] = g_strdup(def);
1289 row[COL_EDIT] = GINT_TO_POINTER(TRUE);
1290 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1291 break;
1292 }
1293
1294 return row;
1295}
1296
1297
1298/* Set the node content with a row of strings */
1299static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
1300{
1301 GdkColor color;
1302 gboolean success;
1303 GdkPixbuf *pix;
1304
1305 pix = gdk_pixbuf_new_from_xpm_data((const char **)
1306 row[COL_PIXBUF]);
1307
1308 gdk_color_parse(row[COL_COLOR], &color);
1309 gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
1310 FALSE, FALSE, &success);
1311
1312 gtk_tree_store_set(tree, node,
1313 COL_OPTION, row[COL_OPTION],
1314 COL_NAME, row[COL_NAME],
1315 COL_NO, row[COL_NO],
1316 COL_MOD, row[COL_MOD],
1317 COL_YES, row[COL_YES],
1318 COL_VALUE, row[COL_VALUE],
1319 COL_MENU, (gpointer) menu,
1320 COL_COLOR, &color,
1321 COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
1322 COL_PIXBUF, pix,
1323 COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
1324 COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
1325 COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
1326 COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
1327 COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
1328 -1);
1329
1330 g_object_unref(pix);
1331}
1332
1333
1334/* Add a node to the tree */
1335static void place_node(struct menu *menu, char **row)
1336{
1337 GtkTreeIter *parent = parents[indent - 1];
1338 GtkTreeIter *node = parents[indent];
1339
1340 gtk_tree_store_append(tree, node, parent);
1341 set_node(node, menu, row);
1342}
1343
1344
1345/* Find a node in the GTK+ tree */
1346static GtkTreeIter found;
1347
1348/*
1349 * Find a menu in the GtkTree starting at parent.
1350 */
1351GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
1352 struct menu *tofind)
1353{
1354 GtkTreeIter iter;
1355 GtkTreeIter *child = &iter;
1356 gboolean valid;
1357 GtkTreeIter *ret;
1358
1359 valid = gtk_tree_model_iter_children(model2, child, parent);
1360 while (valid) {
1361 struct menu *menu;
1362
1363 gtk_tree_model_get(model2, child, 6, &menu, -1);
1364
1365 if (menu == tofind) {
1366 memcpy(&found, child, sizeof(GtkTreeIter));
1367 return &found;
1368 }
1369
1370 ret = gtktree_iter_find_node(child, tofind);
1371 if (ret)
1372 return ret;
1373
1374 valid = gtk_tree_model_iter_next(model2, child);
1375 }
1376
1377 return NULL;
1378}
1379
1380
1381/*
1382 * Update the tree by adding/removing entries
1383 * Does not change other nodes
1384 */
1385static void update_tree(struct menu *src, GtkTreeIter * dst)
1386{
1387 struct menu *child1;
1388 GtkTreeIter iter, tmp;
1389 GtkTreeIter *child2 = &iter;
1390 gboolean valid;
1391 GtkTreeIter *sibling;
1392 struct symbol *sym;
1393 struct property *prop;
1394 struct menu *menu1, *menu2;
1395
1396 if (src == &rootmenu)
1397 indent = 1;
1398
1399 valid = gtk_tree_model_iter_children(model2, child2, dst);
1400 for (child1 = src->list; child1; child1 = child1->next) {
1401
1402 prop = child1->prompt;
1403 sym = child1->sym;
1404
1405 reparse:
1406 menu1 = child1;
1407 if (valid)
1408 gtk_tree_model_get(model2, child2, COL_MENU,
1409 &menu2, -1);
1410 else
1411 menu2 = NULL; // force adding of a first child
1412
1413#ifdef DEBUG
1414 printf("%*c%s | %s\n", indent, ' ',
1415 menu1 ? menu_get_prompt(menu1) : "nil",
1416 menu2 ? menu_get_prompt(menu2) : "nil");
1417#endif
1418
1419 if (!menu_is_visible(child1) && !show_all) { // remove node
1420 if (gtktree_iter_find_node(dst, menu1) != NULL) {
1421 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1422 valid = gtk_tree_model_iter_next(model2,
1423 child2);
1424 gtk_tree_store_remove(tree2, &tmp);
1425 if (!valid)
1426 return; // next parent
1427 else
1428 goto reparse; // next child
1429 } else
1430 continue;
1431 }
1432
1433 if (menu1 != menu2) {
1434 if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node
1435 if (!valid && !menu2)
1436 sibling = NULL;
1437 else
1438 sibling = child2;
1439 gtk_tree_store_insert_before(tree2,
1440 child2,
1441 dst, sibling);
1442 set_node(child2, menu1, fill_row(menu1));
1443 if (menu2 == NULL)
1444 valid = TRUE;
1445 } else { // remove node
1446 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1447 valid = gtk_tree_model_iter_next(model2,
1448 child2);
1449 gtk_tree_store_remove(tree2, &tmp);
1450 if (!valid)
1451 return; // next parent
1452 else
1453 goto reparse; // next child
1454 }
1455 } else if (sym && (sym->flags & SYMBOL_CHANGED)) {
1456 set_node(child2, menu1, fill_row(menu1));
1457 }
1458
1459 indent++;
1460 update_tree(child1, child2);
1461 indent--;
1462
1463 valid = gtk_tree_model_iter_next(model2, child2);
1464 }
1465}
1466
1467
1468/* Display the whole tree (single/split/full view) */
1469static void display_tree(struct menu *menu)
1470{
1471 struct symbol *sym;
1472 struct property *prop;
1473 struct menu *child;
1474 enum prop_type ptype;
1475
1476 if (menu == &rootmenu) {
1477 indent = 1;
1478 current = &rootmenu;
1479 }
1480
1481 for (child = menu->list; child; child = child->next) {
1482 prop = child->prompt;
1483 sym = child->sym;
1484 ptype = prop ? prop->type : P_UNKNOWN;
1485
1486 if (sym)
1487 sym->flags &= ~SYMBOL_CHANGED;
1488
1489 if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) &&
1490 (tree == tree1))
1491 continue;
1492
1493 if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) &&
1494 (tree == tree2))
1495 continue;
1496
1497 if (menu_is_visible(child) || show_all)
1498 place_node(child, fill_row(child));
1499#ifdef DEBUG
1500 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1501 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
1502 dbg_print_ptype(ptype);
1503 printf(" | ");
1504 if (sym) {
1505 dbg_print_stype(sym->type);
1506 printf(" | ");
1507 dbg_print_flags(sym->flags);
1508 printf("\n");
1509 } else
1510 printf("\n");
1511#endif
1512 if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
1513 && (tree == tree2))
1514 continue;
1515/*
1516 if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) ||
1517 (view_mode == FULL_VIEW)
1518 || (view_mode == SPLIT_VIEW))*/
1519 if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
1520 || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW)) {
1521 indent++;
1522 display_tree(child);
1523 indent--;
1524 }
1525 }
1526}
1527
1528/* Display a part of the tree starting at current node (single/split view) */
1529static void display_tree_part(void)
1530{
1531 if (tree2)
1532 gtk_tree_store_clear(tree2);
1533 if(view_mode == SINGLE_VIEW)
1534 display_tree(current);
1535 else if(view_mode == SPLIT_VIEW)
1536 display_tree(browsed);
1537 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
1538}
1539
1540/* Display the list in the left frame (split view) */
1541static void display_list(void)
1542{
1543 if (tree1)
1544 gtk_tree_store_clear(tree1);
1545
1546 tree = tree1;
1547 display_tree(&rootmenu);
1548 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
1549 tree = tree2;
1550}
1551
1552void fixup_rootmenu(struct menu *menu)
1553{
1554 struct menu *child;
1555 static int menu_cnt = 0;
1556
1557 menu->flags |= MENU_ROOT;
1558 for (child = menu->list; child; child = child->next) {
1559 if (child->prompt && child->prompt->type == P_MENU) {
1560 menu_cnt++;
1561 fixup_rootmenu(child);
1562 menu_cnt--;
1563 } else if (!menu_cnt)
1564 fixup_rootmenu(child);
1565 }
1566}
1567
1568
1569/* Main */
1570
1571
1572int main(int ac, char *av[])
1573{
1574 const char *name;
1575 char *env;
1576 gchar *glade_file;
1577
1578#ifndef LKC_DIRECT_LINK
1579 kconfig_load();
1580#endif
1581
1582 /* GTK stuffs */
1583 gtk_set_locale();
1584 gtk_init(&ac, &av);
1585 glade_init();
1586
1587 //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
1588 //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");
1589
1590 /* Determine GUI path */
1591 env = getenv(SRCTREE);
1592 if (env)
1593 glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL);
1594 else if (av[0][0] == '/')
1595 glade_file = g_strconcat(av[0], ".glade", NULL);
1596 else
1597 glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
1598
1599 /* Load the interface and connect signals */
1600 init_main_window(glade_file);
1601 init_tree_model();
1602 init_left_tree();
1603 init_right_tree();
1604
1605 /* Conf stuffs */
1606 if (ac > 1 && av[1][0] == '-') {
1607 switch (av[1][1]) {
1608 case 'a':
1609 //showAll = 1;
1610 break;
1611 case 'h':
1612 case '?':
1613 printf("%s <config>\n", av[0]);
1614 exit(0);
1615 }
1616 name = av[2];
1617 } else
1618 name = av[1];
1619
1620 conf_parse(name);
1621 fixup_rootmenu(&rootmenu);
1622 conf_read(NULL);
1623
1624 switch (view_mode) {
1625 case SINGLE_VIEW:
1626 display_tree_part();
1627 break;
1628 case SPLIT_VIEW:
1629 display_list();
1630 break;
1631 case FULL_VIEW:
1632 display_tree(&rootmenu);
1633 break;
1634 }
1635
1636 gtk_main();
1637
1638 return 0;
1639}
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
new file mode 100644
index 000000000000..1e1736d81ee9
--- /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
new file mode 100644
index 000000000000..d4f84bd4a96b
--- /dev/null
+++ b/scripts/kconfig/images.c
@@ -0,0 +1,326 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6static const char *xpm_load[] = {
7"22 22 5 1",
8". c None",
9"# c #000000",
10"c c #838100",
11"a c #ffff00",
12"b c #ffffff",
13"......................",
14"......................",
15"......................",
16"............####....#.",
17"...........#....##.##.",
18"..................###.",
19".................####.",
20".####...........#####.",
21"#abab##########.......",
22"#babababababab#.......",
23"#ababababababa#.......",
24"#babababababab#.......",
25"#ababab###############",
26"#babab##cccccccccccc##",
27"#abab##cccccccccccc##.",
28"#bab##cccccccccccc##..",
29"#ab##cccccccccccc##...",
30"#b##cccccccccccc##....",
31"###cccccccccccc##.....",
32"##cccccccccccc##......",
33"###############.......",
34"......................"};
35
36static const char *xpm_save[] = {
37"22 22 5 1",
38". c None",
39"# c #000000",
40"a c #838100",
41"b c #c5c2c5",
42"c c #cdb6d5",
43"......................",
44".####################.",
45".#aa#bbbbbbbbbbbb#bb#.",
46".#aa#bbbbbbbbbbbb#bb#.",
47".#aa#bbbbbbbbbcbb####.",
48".#aa#bbbccbbbbbbb#aa#.",
49".#aa#bbbccbbbbbbb#aa#.",
50".#aa#bbbbbbbbbbbb#aa#.",
51".#aa#bbbbbbbbbbbb#aa#.",
52".#aa#bbbbbbbbbbbb#aa#.",
53".#aa#bbbbbbbbbbbb#aa#.",
54".#aaa############aaa#.",
55".#aaaaaaaaaaaaaaaaaa#.",
56".#aaaaaaaaaaaaaaaaaa#.",
57".#aaa#############aa#.",
58".#aaa#########bbb#aa#.",
59".#aaa#########bbb#aa#.",
60".#aaa#########bbb#aa#.",
61".#aaa#########bbb#aa#.",
62".#aaa#########bbb#aa#.",
63"..##################..",
64"......................"};
65
66static const char *xpm_back[] = {
67"22 22 3 1",
68". c None",
69"# c #000083",
70"a c #838183",
71"......................",
72"......................",
73"......................",
74"......................",
75"......................",
76"...........######a....",
77"..#......##########...",
78"..##...####......##a..",
79"..###.###.........##..",
80"..######..........##..",
81"..#####...........##..",
82"..######..........##..",
83"..#######.........##..",
84"..########.......##a..",
85"...............a###...",
86"...............###....",
87"......................",
88"......................",
89"......................",
90"......................",
91"......................",
92"......................"};
93
94static const char *xpm_tree_view[] = {
95"22 22 2 1",
96". c None",
97"# c #000000",
98"......................",
99"......................",
100"......#...............",
101"......#...............",
102"......#...............",
103"......#...............",
104"......#...............",
105"......########........",
106"......#...............",
107"......#...............",
108"......#...............",
109"......#...............",
110"......#...............",
111"......########........",
112"......#...............",
113"......#...............",
114"......#...............",
115"......#...............",
116"......#...............",
117"......########........",
118"......................",
119"......................"};
120
121static const char *xpm_single_view[] = {
122"22 22 2 1",
123". c None",
124"# c #000000",
125"......................",
126"......................",
127"..........#...........",
128"..........#...........",
129"..........#...........",
130"..........#...........",
131"..........#...........",
132"..........#...........",
133"..........#...........",
134"..........#...........",
135"..........#...........",
136"..........#...........",
137"..........#...........",
138"..........#...........",
139"..........#...........",
140"..........#...........",
141"..........#...........",
142"..........#...........",
143"..........#...........",
144"..........#...........",
145"......................",
146"......................"};
147
148static const char *xpm_split_view[] = {
149"22 22 2 1",
150". c None",
151"# c #000000",
152"......................",
153"......................",
154"......#......#........",
155"......#......#........",
156"......#......#........",
157"......#......#........",
158"......#......#........",
159"......#......#........",
160"......#......#........",
161"......#......#........",
162"......#......#........",
163"......#......#........",
164"......#......#........",
165"......#......#........",
166"......#......#........",
167"......#......#........",
168"......#......#........",
169"......#......#........",
170"......#......#........",
171"......#......#........",
172"......................",
173"......................"};
174
175static const char *xpm_symbol_no[] = {
176"12 12 2 1",
177" c white",
178". c black",
179" ",
180" .......... ",
181" . . ",
182" . . ",
183" . . ",
184" . . ",
185" . . ",
186" . . ",
187" . . ",
188" . . ",
189" .......... ",
190" "};
191
192static const char *xpm_symbol_mod[] = {
193"12 12 2 1",
194" c white",
195". c black",
196" ",
197" .......... ",
198" . . ",
199" . . ",
200" . .. . ",
201" . .... . ",
202" . .... . ",
203" . .. . ",
204" . . ",
205" . . ",
206" .......... ",
207" "};
208
209static const char *xpm_symbol_yes[] = {
210"12 12 2 1",
211" c white",
212". c black",
213" ",
214" .......... ",
215" . . ",
216" . . ",
217" . . . ",
218" . .. . ",
219" . . .. . ",
220" . .... . ",
221" . .. . ",
222" . . ",
223" .......... ",
224" "};
225
226static const char *xpm_choice_no[] = {
227"12 12 2 1",
228" c white",
229". c black",
230" ",
231" .... ",
232" .. .. ",
233" . . ",
234" . . ",
235" . . ",
236" . . ",
237" . . ",
238" . . ",
239" .. .. ",
240" .... ",
241" "};
242
243static const char *xpm_choice_yes[] = {
244"12 12 2 1",
245" c white",
246". c black",
247" ",
248" .... ",
249" .. .. ",
250" . . ",
251" . .. . ",
252" . .... . ",
253" . .... . ",
254" . .. . ",
255" . . ",
256" .. .. ",
257" .... ",
258" "};
259
260static const char *xpm_menu[] = {
261"12 12 2 1",
262" c white",
263". c black",
264" ",
265" .......... ",
266" . . ",
267" . .. . ",
268" . .... . ",
269" . ...... . ",
270" . ...... . ",
271" . .... . ",
272" . .. . ",
273" . . ",
274" .......... ",
275" "};
276
277static const char *xpm_menu_inv[] = {
278"12 12 2 1",
279" c white",
280". c black",
281" ",
282" .......... ",
283" .......... ",
284" .. ...... ",
285" .. .... ",
286" .. .. ",
287" .. .. ",
288" .. .... ",
289" .. ...... ",
290" .......... ",
291" .......... ",
292" "};
293
294static const char *xpm_menuback[] = {
295"12 12 2 1",
296" c white",
297". c black",
298" ",
299" .......... ",
300" . . ",
301" . .. . ",
302" . .... . ",
303" . ...... . ",
304" . ...... . ",
305" . .... . ",
306" . .. . ",
307" . . ",
308" .......... ",
309" "};
310
311static const char *xpm_void[] = {
312"12 12 2 1",
313" c white",
314". c black",
315" ",
316" ",
317" ",
318" ",
319" ",
320" ",
321" ",
322" ",
323" ",
324" ",
325" ",
326" "};
diff --git a/scripts/kconfig/kconfig_load.c b/scripts/kconfig/kconfig_load.c
new file mode 100644
index 000000000000..dbdcaad82325
--- /dev/null
+++ b/scripts/kconfig/kconfig_load.c
@@ -0,0 +1,35 @@
1#include <dlfcn.h>
2#include <stdio.h>
3#include <stdlib.h>
4
5#include "lkc.h"
6
7#define P(name,type,arg) type (*name ## _p) arg
8#include "lkc_proto.h"
9#undef P
10
11void kconfig_load(void)
12{
13 void *handle;
14 char *error;
15
16 handle = dlopen("./libkconfig.so", RTLD_LAZY);
17 if (!handle) {
18 handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY);
19 if (!handle) {
20 fprintf(stderr, "%s\n", dlerror());
21 exit(1);
22 }
23 }
24
25#define P(name,type,arg) \
26{ \
27 name ## _p = dlsym(handle, #name); \
28 if ((error = dlerror())) { \
29 fprintf(stderr, "%s\n", error); \
30 exit(1); \
31 } \
32}
33#include "lkc_proto.h"
34#undef P
35}
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
new file mode 100644
index 000000000000..22dda11f758b
--- /dev/null
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -0,0 +1,3688 @@
1
2#line 3 "lex.zconf.c"
3
4#define YY_INT_ALIGNED short int
5
6/* A lexical scanner generated by flex */
7
8#define FLEX_SCANNER
9#define YY_FLEX_MAJOR_VERSION 2
10#define YY_FLEX_MINOR_VERSION 5
11#define YY_FLEX_SUBMINOR_VERSION 31
12#if YY_FLEX_SUBMINOR_VERSION > 0
13#define FLEX_BETA
14#endif
15
16/* First, we deal with platform-specific or compiler-specific issues. */
17
18/* begin standard C headers. */
19#include <stdio.h>
20#include <string.h>
21#include <errno.h>
22#include <stdlib.h>
23
24/* end standard C headers. */
25
26/* flex integer type definitions */
27
28#ifndef FLEXINT_H
29#define FLEXINT_H
30
31/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
32
33#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
34#include <inttypes.h>
35typedef int8_t flex_int8_t;
36typedef uint8_t flex_uint8_t;
37typedef int16_t flex_int16_t;
38typedef uint16_t flex_uint16_t;
39typedef int32_t flex_int32_t;
40typedef uint32_t flex_uint32_t;
41#else
42typedef signed char flex_int8_t;
43typedef short int flex_int16_t;
44typedef int flex_int32_t;
45typedef unsigned char flex_uint8_t;
46typedef unsigned short int flex_uint16_t;
47typedef unsigned int flex_uint32_t;
48#endif /* ! C99 */
49
50/* Limits of integral types. */
51#ifndef INT8_MIN
52#define INT8_MIN (-128)
53#endif
54#ifndef INT16_MIN
55#define INT16_MIN (-32767-1)
56#endif
57#ifndef INT32_MIN
58#define INT32_MIN (-2147483647-1)
59#endif
60#ifndef INT8_MAX
61#define INT8_MAX (127)
62#endif
63#ifndef INT16_MAX
64#define INT16_MAX (32767)
65#endif
66#ifndef INT32_MAX
67#define INT32_MAX (2147483647)
68#endif
69#ifndef UINT8_MAX
70#define UINT8_MAX (255U)
71#endif
72#ifndef UINT16_MAX
73#define UINT16_MAX (65535U)
74#endif
75#ifndef UINT32_MAX
76#define UINT32_MAX (4294967295U)
77#endif
78
79#endif /* ! FLEXINT_H */
80
81#ifdef __cplusplus
82
83/* The "const" storage-class-modifier is valid. */
84#define YY_USE_CONST
85
86#else /* ! __cplusplus */
87
88#if __STDC__
89
90#define YY_USE_CONST
91
92#endif /* __STDC__ */
93#endif /* ! __cplusplus */
94
95#ifdef YY_USE_CONST
96#define yyconst const
97#else
98#define yyconst
99#endif
100
101/* Returned upon end-of-file. */
102#define YY_NULL 0
103
104/* Promotes a possibly negative, possibly signed char to an unsigned
105 * integer for use as an array index. If the signed char is negative,
106 * we want to instead treat it as an 8-bit unsigned char, hence the
107 * double cast.
108 */
109#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
110
111/* Enter a start condition. This macro really ought to take a parameter,
112 * but we do it the disgusting crufty way forced on us by the ()-less
113 * definition of BEGIN.
114 */
115#define BEGIN (yy_start) = 1 + 2 *
116
117/* Translate the current start state into a value that can be later handed
118 * to BEGIN to return to the state. The YYSTATE alias is for lex
119 * compatibility.
120 */
121#define YY_START (((yy_start) - 1) / 2)
122#define YYSTATE YY_START
123
124/* Action number for EOF rule of a given start state. */
125#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
126
127/* Special action meaning "start processing a new file". */
128#define YY_NEW_FILE zconfrestart(zconfin )
129
130#define YY_END_OF_BUFFER_CHAR 0
131
132/* Size of default input buffer. */
133#ifndef YY_BUF_SIZE
134#define YY_BUF_SIZE 16384
135#endif
136
137#ifndef YY_TYPEDEF_YY_BUFFER_STATE
138#define YY_TYPEDEF_YY_BUFFER_STATE
139typedef struct yy_buffer_state *YY_BUFFER_STATE;
140#endif
141
142extern int zconfleng;
143
144extern FILE *zconfin, *zconfout;
145
146#define EOB_ACT_CONTINUE_SCAN 0
147#define EOB_ACT_END_OF_FILE 1
148#define EOB_ACT_LAST_MATCH 2
149
150 #define YY_LESS_LINENO(n)
151
152/* Return all but the first "n" matched characters back to the input stream. */
153#define yyless(n) \
154 do \
155 { \
156 /* Undo effects of setting up zconftext. */ \
157 int yyless_macro_arg = (n); \
158 YY_LESS_LINENO(yyless_macro_arg);\
159 *yy_cp = (yy_hold_char); \
160 YY_RESTORE_YY_MORE_OFFSET \
161 (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
162 YY_DO_BEFORE_ACTION; /* set up zconftext again */ \
163 } \
164 while ( 0 )
165
166#define unput(c) yyunput( c, (yytext_ptr) )
167
168/* The following is because we cannot portably get our hands on size_t
169 * (without autoconf's help, which isn't available because we want
170 * flex-generated scanners to compile on their own).
171 */
172
173#ifndef YY_TYPEDEF_YY_SIZE_T
174#define YY_TYPEDEF_YY_SIZE_T
175typedef unsigned int yy_size_t;
176#endif
177
178#ifndef YY_STRUCT_YY_BUFFER_STATE
179#define YY_STRUCT_YY_BUFFER_STATE
180struct yy_buffer_state
181 {
182 FILE *yy_input_file;
183
184 char *yy_ch_buf; /* input buffer */
185 char *yy_buf_pos; /* current position in input buffer */
186
187 /* Size of input buffer in bytes, not including room for EOB
188 * characters.
189 */
190 yy_size_t yy_buf_size;
191
192 /* Number of characters read into yy_ch_buf, not including EOB
193 * characters.
194 */
195 int yy_n_chars;
196
197 /* Whether we "own" the buffer - i.e., we know we created it,
198 * and can realloc() it to grow it, and should free() it to
199 * delete it.
200 */
201 int yy_is_our_buffer;
202
203 /* Whether this is an "interactive" input source; if so, and
204 * if we're using stdio for input, then we want to use getc()
205 * instead of fread(), to make sure we stop fetching input after
206 * each newline.
207 */
208 int yy_is_interactive;
209
210 /* Whether we're considered to be at the beginning of a line.
211 * If so, '^' rules will be active on the next match, otherwise
212 * not.
213 */
214 int yy_at_bol;
215
216 int yy_bs_lineno; /**< The line count. */
217 int yy_bs_column; /**< The column count. */
218
219 /* Whether to try to fill the input buffer when we reach the
220 * end of it.
221 */
222 int yy_fill_buffer;
223
224 int yy_buffer_status;
225
226#define YY_BUFFER_NEW 0
227#define YY_BUFFER_NORMAL 1
228 /* When an EOF's been seen but there's still some text to process
229 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
230 * shouldn't try reading from the input source any more. We might
231 * still have a bunch of tokens to match, though, because of
232 * possible backing-up.
233 *
234 * When we actually see the EOF, we change the status to "new"
235 * (via zconfrestart()), so that the user can continue scanning by
236 * just pointing zconfin at a new input file.
237 */
238#define YY_BUFFER_EOF_PENDING 2
239
240 };
241#endif /* !YY_STRUCT_YY_BUFFER_STATE */
242
243/* Stack of input buffers. */
244static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
245static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
246static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
247
248/* We provide macros for accessing buffer states in case in the
249 * future we want to put the buffer states in a more general
250 * "scanner state".
251 *
252 * Returns the top of the stack, or NULL.
253 */
254#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
255 ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
256 : NULL)
257
258/* Same as previous macro, but useful when we know that the buffer stack is not
259 * NULL or when we need an lvalue. For internal use only.
260 */
261#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
262
263/* yy_hold_char holds the character lost when zconftext is formed. */
264static char yy_hold_char;
265static int yy_n_chars; /* number of characters read into yy_ch_buf */
266int zconfleng;
267
268/* Points to current character in buffer. */
269static char *yy_c_buf_p = (char *) 0;
270static int yy_init = 1; /* whether we need to initialize */
271static int yy_start = 0; /* start state number */
272
273/* Flag which is used to allow zconfwrap()'s to do buffer switches
274 * instead of setting up a fresh zconfin. A bit of a hack ...
275 */
276static int yy_did_buffer_switch_on_eof;
277
278void zconfrestart (FILE *input_file );
279void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer );
280YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size );
281void zconf_delete_buffer (YY_BUFFER_STATE b );
282void zconf_flush_buffer (YY_BUFFER_STATE b );
283void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer );
284void zconfpop_buffer_state (void );
285
286static void zconfensure_buffer_stack (void );
287static void zconf_load_buffer_state (void );
288static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file );
289
290#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER )
291
292YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size );
293YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str );
294YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len );
295
296void *zconfalloc (yy_size_t );
297void *zconfrealloc (void *,yy_size_t );
298void zconffree (void * );
299
300#define yy_new_buffer zconf_create_buffer
301
302#define yy_set_interactive(is_interactive) \
303 { \
304 if ( ! YY_CURRENT_BUFFER ){ \
305 zconfensure_buffer_stack (); \
306 YY_CURRENT_BUFFER_LVALUE = \
307 zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
308 } \
309 YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
310 }
311
312#define yy_set_bol(at_bol) \
313 { \
314 if ( ! YY_CURRENT_BUFFER ){\
315 zconfensure_buffer_stack (); \
316 YY_CURRENT_BUFFER_LVALUE = \
317 zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
318 } \
319 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
320 }
321
322#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
323
324/* Begin user sect3 */
325
326#define zconfwrap(n) 1
327#define YY_SKIP_YYWRAP
328
329typedef unsigned char YY_CHAR;
330
331FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0;
332
333typedef int yy_state_type;
334
335extern int zconflineno;
336
337int zconflineno = 1;
338
339extern char *zconftext;
340#define yytext_ptr zconftext
341static yyconst flex_int16_t yy_nxt[][38] =
342 {
343 {
344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
345 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
347 0, 0, 0, 0, 0, 0, 0, 0
348 },
349
350 {
351 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
352 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
353 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
354 12, 12, 12, 12, 12, 12, 12, 12
355 },
356
357 {
358 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
359 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
360
361 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
362 12, 12, 12, 12, 12, 12, 12, 12
363 },
364
365 {
366 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
367 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
368 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
369 27, 18, 28, 29, 30, 18, 18, 16
370 },
371
372 {
373 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
374 16, 16, 16, 18, 16, 16, 18, 18, 19, 20,
375 21, 22, 18, 18, 23, 24, 18, 25, 18, 26,
376 27, 18, 28, 29, 30, 18, 18, 16
377
378 },
379
380 {
381 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
382 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
383 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
384 31, 31, 31, 31, 31, 31, 31, 31
385 },
386
387 {
388 11, 31, 32, 33, 31, 31, 31, 31, 31, 31,
389 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
390 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
391 31, 31, 31, 31, 31, 31, 31, 31
392 },
393
394 {
395 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
396 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
397
398 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
399 34, 34, 34, 34, 34, 34, 34, 34
400 },
401
402 {
403 11, 34, 34, 35, 34, 36, 34, 34, 36, 34,
404 34, 34, 34, 34, 34, 37, 34, 34, 34, 34,
405 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
406 34, 34, 34, 34, 34, 34, 34, 34
407 },
408
409 {
410 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
411 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
412 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
413 47, 47, 47, 47, 47, 47, 47, 52
414
415 },
416
417 {
418 11, 38, 38, 39, 40, 41, 42, 43, 41, 44,
419 45, 46, 47, 47, 48, 49, 47, 47, 47, 47,
420 47, 47, 47, 47, 47, 50, 47, 47, 47, 51,
421 47, 47, 47, 47, 47, 47, 47, 52
422 },
423
424 {
425 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
426 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
427 -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
428 -11, -11, -11, -11, -11, -11, -11, -11
429 },
430
431 {
432 11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
433 -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
434
435 -12, -12, -12, -12, -12, -12, -12, -12, -12, -12,
436 -12, -12, -12, -12, -12, -12, -12, -12
437 },
438
439 {
440 11, -13, 53, 54, -13, -13, 55, -13, -13, -13,
441 -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
442 -13, -13, -13, -13, -13, -13, -13, -13, -13, -13,
443 -13, -13, -13, -13, -13, -13, -13, -13
444 },
445
446 {
447 11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
448 -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
449 -14, -14, -14, -14, -14, -14, -14, -14, -14, -14,
450 -14, -14, -14, -14, -14, -14, -14, -14
451
452 },
453
454 {
455 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
456 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
457 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
458 56, 56, 56, 56, 56, 56, 56, 56
459 },
460
461 {
462 11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
463 -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
464 -16, -16, -16, -16, -16, -16, -16, -16, -16, -16,
465 -16, -16, -16, -16, -16, -16, -16, -16
466 },
467
468 {
469 11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
470 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
471
472 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
473 -17, -17, -17, -17, -17, -17, -17, -17
474 },
475
476 {
477 11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
478 -18, -18, -18, 58, -18, -18, 58, 58, 58, 58,
479 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
480 58, 58, 58, 58, 58, 58, 58, -18
481 },
482
483 {
484 11, -19, -19, -19, -19, -19, -19, -19, -19, -19,
485 -19, -19, -19, 58, -19, -19, 58, 58, 58, 58,
486 58, 58, 58, 58, 58, 58, 58, 58, 58, 59,
487 58, 58, 58, 58, 58, 58, 58, -19
488
489 },
490
491 {
492 11, -20, -20, -20, -20, -20, -20, -20, -20, -20,
493 -20, -20, -20, 58, -20, -20, 58, 58, 58, 58,
494 58, 58, 58, 58, 60, 58, 58, 58, 58, 61,
495 58, 58, 58, 58, 58, 58, 58, -20
496 },
497
498 {
499 11, -21, -21, -21, -21, -21, -21, -21, -21, -21,
500 -21, -21, -21, 58, -21, -21, 58, 58, 58, 58,
501 58, 62, 58, 58, 58, 58, 58, 58, 58, 58,
502 58, 58, 58, 58, 58, 58, 58, -21
503 },
504
505 {
506 11, -22, -22, -22, -22, -22, -22, -22, -22, -22,
507 -22, -22, -22, 58, -22, -22, 58, 58, 58, 58,
508
509 58, 58, 58, 58, 58, 58, 58, 58, 63, 58,
510 58, 58, 58, 58, 58, 58, 58, -22
511 },
512
513 {
514 11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
515 -23, -23, -23, 58, -23, -23, 58, 58, 58, 58,
516 58, 64, 58, 58, 58, 58, 58, 58, 58, 58,
517 58, 58, 58, 58, 58, 58, 58, -23
518 },
519
520 {
521 11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
522 -24, -24, -24, 58, -24, -24, 58, 58, 58, 58,
523 58, 58, 65, 58, 58, 58, 58, 58, 66, 58,
524 58, 58, 58, 58, 58, 58, 58, -24
525
526 },
527
528 {
529 11, -25, -25, -25, -25, -25, -25, -25, -25, -25,
530 -25, -25, -25, 58, -25, -25, 58, 67, 58, 58,
531 58, 68, 58, 58, 58, 58, 58, 58, 58, 58,
532 58, 58, 58, 58, 58, 58, 58, -25
533 },
534
535 {
536 11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
537 -26, -26, -26, 58, -26, -26, 58, 58, 58, 58,
538 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
539 69, 58, 58, 58, 58, 58, 58, -26
540 },
541
542 {
543 11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
544 -27, -27, -27, 58, -27, -27, 58, 58, 58, 58,
545
546 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
547 58, 58, 70, 58, 58, 58, 58, -27
548 },
549
550 {
551 11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
552 -28, -28, -28, 58, -28, -28, 58, 71, 58, 58,
553 58, 72, 58, 58, 58, 58, 58, 58, 58, 58,
554 58, 58, 58, 58, 58, 58, 58, -28
555 },
556
557 {
558 11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
559 -29, -29, -29, 58, -29, -29, 58, 58, 58, 58,
560 58, 73, 58, 58, 58, 58, 58, 58, 58, 74,
561 58, 58, 58, 58, 75, 58, 58, -29
562
563 },
564
565 {
566 11, -30, -30, -30, -30, -30, -30, -30, -30, -30,
567 -30, -30, -30, 58, -30, -30, 58, 58, 58, 58,
568 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
569 58, 58, 76, 58, 58, 58, 58, -30
570 },
571
572 {
573 11, 77, 77, -31, 77, 77, 77, 77, 77, 77,
574 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
575 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
576 77, 77, 77, 77, 77, 77, 77, 77
577 },
578
579 {
580 11, -32, 78, 79, -32, -32, -32, -32, -32, -32,
581 -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
582
583 -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
584 -32, -32, -32, -32, -32, -32, -32, -32
585 },
586
587 {
588 11, 80, -33, -33, 80, 80, 80, 80, 80, 80,
589 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
590 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
591 80, 80, 80, 80, 80, 80, 80, 80
592 },
593
594 {
595 11, 81, 81, 82, 81, -34, 81, 81, -34, 81,
596 81, 81, 81, 81, 81, -34, 81, 81, 81, 81,
597 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
598 81, 81, 81, 81, 81, 81, 81, 81
599
600 },
601
602 {
603 11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
604 -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
605 -35, -35, -35, -35, -35, -35, -35, -35, -35, -35,
606 -35, -35, -35, -35, -35, -35, -35, -35
607 },
608
609 {
610 11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
611 -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
612 -36, -36, -36, -36, -36, -36, -36, -36, -36, -36,
613 -36, -36, -36, -36, -36, -36, -36, -36
614 },
615
616 {
617 11, 83, 83, 84, 83, 83, 83, 83, 83, 83,
618 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
619
620 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
621 83, 83, 83, 83, 83, 83, 83, 83
622 },
623
624 {
625 11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
626 -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
627 -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
628 -38, -38, -38, -38, -38, -38, -38, -38
629 },
630
631 {
632 11, -39, -39, -39, -39, -39, -39, -39, -39, -39,
633 -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
634 -39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
635 -39, -39, -39, -39, -39, -39, -39, -39
636
637 },
638
639 {
640 11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
641 -40, -40, -40, -40, 85, -40, -40, -40, -40, -40,
642 -40, -40, -40, -40, -40, -40, -40, -40, -40, -40,
643 -40, -40, -40, -40, -40, -40, -40, -40
644 },
645
646 {
647 11, -41, -41, -41, -41, -41, -41, -41, -41, -41,
648 -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
649 -41, -41, -41, -41, -41, -41, -41, -41, -41, -41,
650 -41, -41, -41, -41, -41, -41, -41, -41
651 },
652
653 {
654 11, 86, 86, -42, 86, 86, 86, 86, 86, 86,
655 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
656
657 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
658 86, 86, 86, 86, 86, 86, 86, 86
659 },
660
661 {
662 11, -43, -43, -43, -43, -43, -43, 87, -43, -43,
663 -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
664 -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
665 -43, -43, -43, -43, -43, -43, -43, -43
666 },
667
668 {
669 11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
670 -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
671 -44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
672 -44, -44, -44, -44, -44, -44, -44, -44
673
674 },
675
676 {
677 11, -45, -45, -45, -45, -45, -45, -45, -45, -45,
678 -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
679 -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
680 -45, -45, -45, -45, -45, -45, -45, -45
681 },
682
683 {
684 11, -46, -46, -46, -46, -46, -46, -46, -46, -46,
685 -46, 88, 89, 89, -46, -46, 89, 89, 89, 89,
686 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
687 89, 89, 89, 89, 89, 89, 89, -46
688 },
689
690 {
691 11, -47, -47, -47, -47, -47, -47, -47, -47, -47,
692 -47, 89, 89, 89, -47, -47, 89, 89, 89, 89,
693
694 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
695 89, 89, 89, 89, 89, 89, 89, -47
696 },
697
698 {
699 11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
700 -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
701 -48, -48, -48, -48, -48, -48, -48, -48, -48, -48,
702 -48, -48, -48, -48, -48, -48, -48, -48
703 },
704
705 {
706 11, -49, -49, 90, -49, -49, -49, -49, -49, -49,
707 -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
708 -49, -49, -49, -49, -49, -49, -49, -49, -49, -49,
709 -49, -49, -49, -49, -49, -49, -49, -49
710
711 },
712
713 {
714 11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
715 -50, 89, 89, 89, -50, -50, 89, 89, 89, 89,
716 89, 89, 91, 89, 89, 89, 89, 89, 89, 89,
717 89, 89, 89, 89, 89, 89, 89, -50
718 },
719
720 {
721 11, -51, -51, -51, -51, -51, -51, -51, -51, -51,
722 -51, 89, 89, 89, -51, -51, 89, 89, 89, 89,
723 89, 89, 89, 89, 89, 89, 89, 89, 92, 89,
724 89, 89, 89, 89, 89, 89, 89, -51
725 },
726
727 {
728 11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
729 -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
730
731 -52, -52, -52, -52, -52, -52, -52, -52, -52, -52,
732 -52, -52, -52, -52, -52, -52, -52, 93
733 },
734
735 {
736 11, -53, 53, 54, -53, -53, 55, -53, -53, -53,
737 -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
738 -53, -53, -53, -53, -53, -53, -53, -53, -53, -53,
739 -53, -53, -53, -53, -53, -53, -53, -53
740 },
741
742 {
743 11, -54, -54, -54, -54, -54, -54, -54, -54, -54,
744 -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
745 -54, -54, -54, -54, -54, -54, -54, -54, -54, -54,
746 -54, -54, -54, -54, -54, -54, -54, -54
747
748 },
749
750 {
751 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
752 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
753 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
754 56, 56, 56, 56, 56, 56, 56, 56
755 },
756
757 {
758 11, 56, 56, 57, 56, 56, 56, 56, 56, 56,
759 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
760 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
761 56, 56, 56, 56, 56, 56, 56, 56
762 },
763
764 {
765 11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
766 -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
767
768 -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
769 -57, -57, -57, -57, -57, -57, -57, -57
770 },
771
772 {
773 11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
774 -58, -58, -58, 58, -58, -58, 58, 58, 58, 58,
775 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
776 58, 58, 58, 58, 58, 58, 58, -58
777 },
778
779 {
780 11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
781 -59, -59, -59, 58, -59, -59, 58, 58, 58, 58,
782 58, 58, 58, 58, 58, 58, 58, 58, 58, 94,
783 58, 58, 58, 58, 58, 58, 58, -59
784
785 },
786
787 {
788 11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
789 -60, -60, -60, 58, -60, -60, 58, 58, 58, 58,
790 58, 58, 58, 58, 58, 58, 58, 58, 58, 95,
791 58, 58, 58, 58, 58, 58, 58, -60
792 },
793
794 {
795 11, -61, -61, -61, -61, -61, -61, -61, -61, -61,
796 -61, -61, -61, 58, -61, -61, 58, 58, 58, 58,
797 58, 58, 58, 58, 58, 58, 58, 96, 97, 58,
798 58, 58, 58, 58, 58, 58, 58, -61
799 },
800
801 {
802 11, -62, -62, -62, -62, -62, -62, -62, -62, -62,
803 -62, -62, -62, 58, -62, -62, 58, 58, 58, 58,
804
805 58, 58, 98, 58, 58, 58, 58, 58, 58, 58,
806 99, 58, 58, 58, 58, 58, 58, -62
807 },
808
809 {
810 11, -63, -63, -63, -63, -63, -63, -63, -63, -63,
811 -63, -63, -63, 58, -63, -63, 58, 100, 58, 58,
812 101, 58, 58, 58, 58, 58, 58, 58, 58, 58,
813 58, 58, 58, 58, 58, 58, 58, -63
814 },
815
816 {
817 11, -64, -64, -64, -64, -64, -64, -64, -64, -64,
818 -64, -64, -64, 58, -64, -64, 58, 58, 58, 58,
819 58, 58, 58, 58, 58, 58, 102, 58, 58, 58,
820 58, 58, 58, 58, 58, 58, 103, -64
821
822 },
823
824 {
825 11, -65, -65, -65, -65, -65, -65, -65, -65, -65,
826 -65, -65, -65, 58, -65, -65, 58, 58, 58, 58,
827 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
828 58, 58, 58, 58, 58, 58, 58, -65
829 },
830
831 {
832 11, -66, -66, -66, -66, -66, -66, -66, -66, -66,
833 -66, -66, -66, 58, -66, -66, 58, 58, 58, 58,
834 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
835 58, 58, 58, 58, 104, 58, 58, -66
836 },
837
838 {
839 11, -67, -67, -67, -67, -67, -67, -67, -67, -67,
840 -67, -67, -67, 58, -67, -67, 58, 58, 58, 58,
841
842 58, 58, 58, 58, 58, 105, 58, 58, 58, 58,
843 58, 58, 58, 58, 58, 58, 58, -67
844 },
845
846 {
847 11, -68, -68, -68, -68, -68, -68, -68, -68, -68,
848 -68, -68, -68, 58, -68, -68, 58, 58, 58, 58,
849 58, 58, 58, 58, 58, 58, 58, 58, 106, 58,
850 58, 58, 58, 58, 58, 58, 58, -68
851 },
852
853 {
854 11, -69, -69, -69, -69, -69, -69, -69, -69, -69,
855 -69, -69, -69, 58, -69, -69, 58, 58, 58, 58,
856 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
857 58, 58, 58, 58, 107, 58, 58, -69
858
859 },
860
861 {
862 11, -70, -70, -70, -70, -70, -70, -70, -70, -70,
863 -70, -70, -70, 58, -70, -70, 58, 58, 58, 58,
864 58, 58, 58, 58, 58, 58, 58, 58, 58, 108,
865 58, 58, 58, 58, 58, 58, 58, -70
866 },
867
868 {
869 11, -71, -71, -71, -71, -71, -71, -71, -71, -71,
870 -71, -71, -71, 58, -71, -71, 58, 58, 58, 58,
871 58, 58, 58, 58, 58, 58, 58, 58, 109, 58,
872 58, 58, 58, 58, 58, 58, 58, -71
873 },
874
875 {
876 11, -72, -72, -72, -72, -72, -72, -72, -72, -72,
877 -72, -72, -72, 58, -72, -72, 58, 58, 58, 58,
878
879 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
880 58, 110, 58, 58, 58, 58, 58, -72
881 },
882
883 {
884 11, -73, -73, -73, -73, -73, -73, -73, -73, -73,
885 -73, -73, -73, 58, -73, -73, 58, 58, 58, 58,
886 58, 58, 58, 58, 58, 58, 111, 58, 58, 58,
887 58, 58, 58, 58, 58, 58, 58, -73
888 },
889
890 {
891 11, -74, -74, -74, -74, -74, -74, -74, -74, -74,
892 -74, -74, -74, 58, -74, -74, 58, 58, 58, 58,
893 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
894 58, 58, 58, 58, 58, 112, 58, -74
895
896 },
897
898 {
899 11, -75, -75, -75, -75, -75, -75, -75, -75, -75,
900 -75, -75, -75, 58, -75, -75, 58, 58, 58, 58,
901 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
902 58, 58, 113, 58, 58, 58, 58, -75
903 },
904
905 {
906 11, -76, -76, -76, -76, -76, -76, -76, -76, -76,
907 -76, -76, -76, 58, -76, -76, 58, 58, 58, 58,
908 58, 58, 58, 58, 58, 114, 58, 58, 58, 58,
909 58, 58, 58, 58, 58, 58, 58, -76
910 },
911
912 {
913 11, 77, 77, -77, 77, 77, 77, 77, 77, 77,
914 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
915
916 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
917 77, 77, 77, 77, 77, 77, 77, 77
918 },
919
920 {
921 11, -78, 78, 79, -78, -78, -78, -78, -78, -78,
922 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
923 -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
924 -78, -78, -78, -78, -78, -78, -78, -78
925 },
926
927 {
928 11, 80, -79, -79, 80, 80, 80, 80, 80, 80,
929 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
930 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
931 80, 80, 80, 80, 80, 80, 80, 80
932
933 },
934
935 {
936 11, -80, -80, -80, -80, -80, -80, -80, -80, -80,
937 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
938 -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
939 -80, -80, -80, -80, -80, -80, -80, -80
940 },
941
942 {
943 11, 81, 81, 82, 81, -81, 81, 81, -81, 81,
944 81, 81, 81, 81, 81, -81, 81, 81, 81, 81,
945 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
946 81, 81, 81, 81, 81, 81, 81, 81
947 },
948
949 {
950 11, -82, -82, -82, -82, -82, -82, -82, -82, -82,
951 -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
952
953 -82, -82, -82, -82, -82, -82, -82, -82, -82, -82,
954 -82, -82, -82, -82, -82, -82, -82, -82
955 },
956
957 {
958 11, -83, -83, 84, -83, -83, -83, -83, -83, -83,
959 -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
960 -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
961 -83, -83, -83, -83, -83, -83, -83, -83
962 },
963
964 {
965 11, -84, -84, -84, -84, -84, -84, -84, -84, -84,
966 -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
967 -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
968 -84, -84, -84, -84, -84, -84, -84, -84
969
970 },
971
972 {
973 11, -85, -85, -85, -85, -85, -85, -85, -85, -85,
974 -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
975 -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
976 -85, -85, -85, -85, -85, -85, -85, -85
977 },
978
979 {
980 11, 86, 86, -86, 86, 86, 86, 86, 86, 86,
981 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
982 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
983 86, 86, 86, 86, 86, 86, 86, 86
984 },
985
986 {
987 11, -87, -87, -87, -87, -87, -87, -87, -87, -87,
988 -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
989
990 -87, -87, -87, -87, -87, -87, -87, -87, -87, -87,
991 -87, -87, -87, -87, -87, -87, -87, -87
992 },
993
994 {
995 11, -88, -88, -88, -88, -88, -88, -88, -88, -88,
996 -88, 115, 89, 89, -88, -88, 89, 89, 89, 89,
997 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
998 89, 89, 89, 89, 89, 89, 89, -88
999 },
1000
1001 {
1002 11, -89, -89, -89, -89, -89, -89, -89, -89, -89,
1003 -89, 89, 89, 89, -89, -89, 89, 89, 89, 89,
1004 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1005 89, 89, 89, 89, 89, 89, 89, -89
1006
1007 },
1008
1009 {
1010 11, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1011 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1012 -90, -90, -90, -90, -90, -90, -90, -90, -90, -90,
1013 -90, -90, -90, -90, -90, -90, -90, -90
1014 },
1015
1016 {
1017 11, -91, -91, -91, -91, -91, -91, -91, -91, -91,
1018 -91, 89, 89, 89, -91, -91, 89, 89, 89, 89,
1019 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1020 89, 89, 89, 89, 89, 89, 89, -91
1021 },
1022
1023 {
1024 11, -92, -92, -92, -92, -92, -92, -92, -92, -92,
1025 -92, 89, 89, 89, -92, -92, 89, 89, 89, 89,
1026
1027 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1028 89, 89, 89, 89, 89, 89, 89, -92
1029 },
1030
1031 {
1032 11, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1033 -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1034 -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1035 -93, -93, -93, -93, -93, -93, -93, -93
1036 },
1037
1038 {
1039 11, -94, -94, -94, -94, -94, -94, -94, -94, -94,
1040 -94, -94, -94, 58, -94, -94, 58, 58, 58, 58,
1041 58, 58, 58, 58, 58, 58, 116, 58, 58, 58,
1042 58, 58, 58, 58, 58, 58, 58, -94
1043
1044 },
1045
1046 {
1047 11, -95, -95, -95, -95, -95, -95, -95, -95, -95,
1048 -95, -95, -95, 58, -95, -95, 58, 58, 58, 58,
1049 58, 58, 58, 58, 58, 117, 58, 58, 58, 58,
1050 58, 58, 58, 58, 58, 58, 58, -95
1051 },
1052
1053 {
1054 11, -96, -96, -96, -96, -96, -96, -96, -96, -96,
1055 -96, -96, -96, 58, -96, -96, 58, 58, 58, 58,
1056 58, 58, 58, 58, 58, 58, 58, 118, 58, 58,
1057 58, 58, 58, 58, 58, 58, 58, -96
1058 },
1059
1060 {
1061 11, -97, -97, -97, -97, -97, -97, -97, -97, -97,
1062 -97, -97, -97, 58, -97, -97, 58, 58, 58, 58,
1063
1064 58, 58, 119, 58, 58, 58, 58, 58, 58, 58,
1065 58, 58, 58, 58, 58, 58, 58, -97
1066 },
1067
1068 {
1069 11, -98, -98, -98, -98, -98, -98, -98, -98, -98,
1070 -98, -98, -98, 58, -98, -98, 120, 121, 58, 58,
1071 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1072 58, 58, 58, 58, 58, 58, 58, -98
1073 },
1074
1075 {
1076 11, -99, -99, -99, -99, -99, -99, -99, -99, -99,
1077 -99, -99, -99, 58, -99, -99, 58, 58, 58, 58,
1078 58, 122, 58, 58, 58, 58, 58, 58, 58, 58,
1079 58, 58, 58, 58, 58, 58, 58, -99
1080
1081 },
1082
1083 {
1084 11, -100, -100, -100, -100, -100, -100, -100, -100, -100,
1085 -100, -100, -100, 58, -100, -100, 58, 58, 123, 58,
1086 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1087 58, 58, 58, 58, 58, 58, 58, -100
1088 },
1089
1090 {
1091 11, -101, -101, -101, -101, -101, -101, -101, -101, -101,
1092 -101, -101, -101, 58, -101, -101, 58, 58, 58, 124,
1093 58, 58, 58, 58, 58, 125, 58, 126, 58, 58,
1094 58, 58, 58, 58, 58, 58, 58, -101
1095 },
1096
1097 {
1098 11, -102, -102, -102, -102, -102, -102, -102, -102, -102,
1099 -102, -102, -102, 58, -102, -102, 58, 58, 58, 58,
1100
1101 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1102 127, 58, 58, 58, 58, 58, 58, -102
1103 },
1104
1105 {
1106 11, -103, -103, -103, -103, -103, -103, -103, -103, -103,
1107 -103, -103, -103, 58, -103, -103, 58, 58, 58, 58,
1108 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1109 58, 58, 58, 58, 58, 58, 58, -103
1110 },
1111
1112 {
1113 11, -104, -104, -104, -104, -104, -104, -104, -104, -104,
1114 -104, -104, -104, 58, -104, -104, 58, 58, 58, 58,
1115 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1116 58, 58, 58, 58, 58, 58, 58, -104
1117
1118 },
1119
1120 {
1121 11, -105, -105, -105, -105, -105, -105, -105, -105, -105,
1122 -105, -105, -105, 58, -105, -105, 58, 58, 58, 58,
1123 58, 58, 58, 58, 58, 58, 58, 58, 128, 58,
1124 58, 58, 58, 58, 58, 58, 58, -105
1125 },
1126
1127 {
1128 11, -106, -106, -106, -106, -106, -106, -106, -106, -106,
1129 -106, -106, -106, 58, -106, -106, 58, 58, 58, 58,
1130 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1131 58, 58, 58, 58, 58, 129, 58, -106
1132 },
1133
1134 {
1135 11, -107, -107, -107, -107, -107, -107, -107, -107, -107,
1136 -107, -107, -107, 58, -107, -107, 58, 58, 58, 58,
1137
1138 58, 58, 58, 58, 58, 130, 58, 58, 58, 58,
1139 58, 58, 58, 58, 58, 58, 58, -107
1140 },
1141
1142 {
1143 11, -108, -108, -108, -108, -108, -108, -108, -108, -108,
1144 -108, -108, -108, 58, -108, -108, 58, 58, 58, 58,
1145 58, 58, 58, 58, 58, 58, 58, 131, 58, 58,
1146 58, 58, 58, 58, 58, 58, 58, -108
1147 },
1148
1149 {
1150 11, -109, -109, -109, -109, -109, -109, -109, -109, -109,
1151 -109, -109, -109, 58, -109, -109, 58, 58, 58, 58,
1152 58, 58, 58, 132, 58, 58, 58, 58, 58, 58,
1153 58, 58, 58, 58, 58, 58, 58, -109
1154
1155 },
1156
1157 {
1158 11, -110, -110, -110, -110, -110, -110, -110, -110, -110,
1159 -110, -110, -110, 58, -110, -110, 58, 58, 58, 58,
1160 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1161 58, 58, 58, 58, 58, 133, 58, -110
1162 },
1163
1164 {
1165 11, -111, -111, -111, -111, -111, -111, -111, -111, -111,
1166 -111, -111, -111, 58, -111, -111, 58, 58, 58, 58,
1167 58, 134, 58, 58, 58, 58, 58, 58, 58, 58,
1168 58, 58, 58, 58, 58, 58, 58, -111
1169 },
1170
1171 {
1172 11, -112, -112, -112, -112, -112, -112, -112, -112, -112,
1173 -112, -112, -112, 58, -112, -112, 58, 58, 58, 58,
1174
1175 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1176 58, 58, 135, 58, 58, 58, 58, -112
1177 },
1178
1179 {
1180 11, -113, -113, -113, -113, -113, -113, -113, -113, -113,
1181 -113, -113, -113, 58, -113, -113, 58, 58, 58, 58,
1182 58, 58, 58, 58, 58, 136, 58, 58, 58, 58,
1183 58, 58, 58, 58, 58, 58, 58, -113
1184 },
1185
1186 {
1187 11, -114, -114, -114, -114, -114, -114, -114, -114, -114,
1188 -114, -114, -114, 58, -114, -114, 58, 58, 58, 58,
1189 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1190 58, 58, 58, 137, 58, 58, 58, -114
1191
1192 },
1193
1194 {
1195 11, -115, -115, -115, -115, -115, -115, -115, -115, -115,
1196 -115, 89, 89, 89, -115, -115, 89, 89, 89, 89,
1197 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
1198 89, 89, 89, 89, 89, 89, 89, -115
1199 },
1200
1201 {
1202 11, -116, -116, -116, -116, -116, -116, -116, -116, -116,
1203 -116, -116, -116, 58, -116, -116, 58, 58, 58, 58,
1204 58, 138, 58, 58, 58, 58, 58, 58, 58, 58,
1205 58, 58, 58, 58, 58, 58, 58, -116
1206 },
1207
1208 {
1209 11, -117, -117, -117, -117, -117, -117, -117, -117, -117,
1210 -117, -117, -117, 58, -117, -117, 58, 58, 58, 139,
1211
1212 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1213 58, 58, 58, 58, 58, 58, 58, -117
1214 },
1215
1216 {
1217 11, -118, -118, -118, -118, -118, -118, -118, -118, -118,
1218 -118, -118, -118, 58, -118, -118, 58, 58, 58, 58,
1219 58, 140, 58, 58, 58, 58, 58, 58, 58, 58,
1220 58, 58, 58, 58, 58, 58, 58, -118
1221 },
1222
1223 {
1224 11, -119, -119, -119, -119, -119, -119, -119, -119, -119,
1225 -119, -119, -119, 58, -119, -119, 58, 58, 58, 58,
1226 58, 58, 58, 58, 58, 141, 58, 58, 58, 58,
1227 58, 58, 58, 58, 58, 58, 58, -119
1228
1229 },
1230
1231 {
1232 11, -120, -120, -120, -120, -120, -120, -120, -120, -120,
1233 -120, -120, -120, 58, -120, -120, 58, 58, 142, 58,
1234 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1235 58, 58, 58, 58, 143, 58, 58, -120
1236 },
1237
1238 {
1239 11, -121, -121, -121, -121, -121, -121, -121, -121, -121,
1240 -121, -121, -121, 58, -121, -121, 58, 58, 58, 58,
1241 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1242 58, 58, 58, 58, 58, 144, 58, -121
1243 },
1244
1245 {
1246 11, -122, -122, -122, -122, -122, -122, -122, -122, -122,
1247 -122, -122, -122, 58, -122, -122, 58, 58, 58, 58,
1248
1249 58, 58, 58, 58, 58, 58, 58, 58, 145, 58,
1250 58, 58, 58, 58, 58, 58, 58, -122
1251 },
1252
1253 {
1254 11, -123, -123, -123, -123, -123, -123, -123, -123, -123,
1255 -123, -123, -123, 58, -123, -123, 58, 58, 58, 58,
1256 58, 58, 58, 58, 58, 58, 146, 58, 58, 58,
1257 58, 58, 58, 58, 58, 58, 58, -123
1258 },
1259
1260 {
1261 11, -124, -124, -124, -124, -124, -124, -124, -124, -124,
1262 -124, -124, -124, 58, -124, -124, 58, 58, 58, 58,
1263 58, 58, 58, 58, 147, 58, 58, 58, 58, 58,
1264 58, 58, 58, 58, 58, 58, 58, -124
1265
1266 },
1267
1268 {
1269 11, -125, -125, -125, -125, -125, -125, -125, -125, -125,
1270 -125, -125, -125, 58, -125, -125, 58, 58, 58, 58,
1271 58, 58, 148, 58, 58, 58, 58, 58, 58, 58,
1272 58, 58, 58, 58, 58, 58, 58, -125
1273 },
1274
1275 {
1276 11, -126, -126, -126, -126, -126, -126, -126, -126, -126,
1277 -126, -126, -126, 58, -126, -126, 58, 58, 58, 58,
1278 58, 149, 58, 58, 58, 58, 58, 58, 58, 58,
1279 58, 58, 58, 58, 58, 58, 58, -126
1280 },
1281
1282 {
1283 11, -127, -127, -127, -127, -127, -127, -127, -127, -127,
1284 -127, -127, -127, 58, -127, -127, 58, 58, 58, 58,
1285
1286 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1287 58, 58, 58, 58, 58, 58, 58, -127
1288 },
1289
1290 {
1291 11, -128, -128, -128, -128, -128, -128, -128, -128, -128,
1292 -128, -128, -128, 58, -128, -128, 58, 58, 58, 58,
1293 58, 58, 58, 58, 58, 58, 58, 150, 58, 58,
1294 58, 58, 58, 58, 58, 58, 58, -128
1295 },
1296
1297 {
1298 11, -129, -129, -129, -129, -129, -129, -129, -129, -129,
1299 -129, -129, -129, 58, -129, -129, 58, 58, 58, 151,
1300 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1301 58, 58, 58, 58, 58, 58, 58, -129
1302
1303 },
1304
1305 {
1306 11, -130, -130, -130, -130, -130, -130, -130, -130, -130,
1307 -130, -130, -130, 58, -130, -130, 58, 58, 58, 58,
1308 58, 58, 58, 58, 58, 58, 58, 58, 58, 152,
1309 58, 58, 58, 58, 58, 58, 58, -130
1310 },
1311
1312 {
1313 11, -131, -131, -131, -131, -131, -131, -131, -131, -131,
1314 -131, -131, -131, 58, -131, -131, 58, 58, 58, 58,
1315 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1316 153, 58, 58, 58, 58, 58, 58, -131
1317 },
1318
1319 {
1320 11, -132, -132, -132, -132, -132, -132, -132, -132, -132,
1321 -132, -132, -132, 58, -132, -132, 58, 58, 58, 58,
1322
1323 58, 154, 58, 58, 58, 58, 58, 58, 58, 58,
1324 58, 58, 58, 58, 58, 58, 58, -132
1325 },
1326
1327 {
1328 11, -133, -133, -133, -133, -133, -133, -133, -133, -133,
1329 -133, -133, -133, 58, -133, -133, 58, 58, 58, 58,
1330 58, 58, 58, 58, 58, 155, 58, 58, 58, 58,
1331 58, 58, 58, 58, 58, 58, 58, -133
1332 },
1333
1334 {
1335 11, -134, -134, -134, -134, -134, -134, -134, -134, -134,
1336 -134, -134, -134, 58, -134, -134, 58, 58, 58, 156,
1337 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1338 58, 58, 58, 58, 58, 58, 58, -134
1339
1340 },
1341
1342 {
1343 11, -135, -135, -135, -135, -135, -135, -135, -135, -135,
1344 -135, -135, -135, 58, -135, -135, 58, 58, 58, 157,
1345 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1346 58, 58, 58, 58, 58, 58, 58, -135
1347 },
1348
1349 {
1350 11, -136, -136, -136, -136, -136, -136, -136, -136, -136,
1351 -136, -136, -136, 58, -136, -136, 58, 58, 58, 58,
1352 58, 58, 58, 58, 58, 58, 58, 58, 158, 58,
1353 58, 58, 58, 58, 58, 58, 58, -136
1354 },
1355
1356 {
1357 11, -137, -137, -137, -137, -137, -137, -137, -137, -137,
1358 -137, -137, -137, 58, -137, -137, 58, 58, 58, 58,
1359
1360 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1361 58, 58, 58, 58, 159, 58, 58, -137
1362 },
1363
1364 {
1365 11, -138, -138, -138, -138, -138, -138, -138, -138, -138,
1366 -138, -138, -138, 58, -138, -138, 58, 160, 58, 58,
1367 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1368 58, 58, 58, 58, 58, 58, 58, -138
1369 },
1370
1371 {
1372 11, -139, -139, -139, -139, -139, -139, -139, -139, -139,
1373 -139, -139, -139, 58, -139, -139, 58, 58, 58, 58,
1374 58, 161, 58, 58, 58, 58, 58, 58, 58, 58,
1375 58, 58, 58, 58, 58, 58, 58, -139
1376
1377 },
1378
1379 {
1380 11, -140, -140, -140, -140, -140, -140, -140, -140, -140,
1381 -140, -140, -140, 58, -140, -140, 58, 58, 58, 58,
1382 58, 58, 58, 58, 58, 58, 58, 58, 162, 58,
1383 58, 58, 58, 58, 58, 58, 58, -140
1384 },
1385
1386 {
1387 11, -141, -141, -141, -141, -141, -141, -141, -141, -141,
1388 -141, -141, -141, 58, -141, -141, 58, 58, 58, 58,
1389 58, 58, 58, 163, 58, 58, 58, 58, 58, 58,
1390 58, 58, 58, 58, 58, 58, 58, -141
1391 },
1392
1393 {
1394 11, -142, -142, -142, -142, -142, -142, -142, -142, -142,
1395 -142, -142, -142, 58, -142, -142, 58, 58, 58, 58,
1396
1397 58, 58, 58, 58, 58, 58, 58, 58, 58, 164,
1398 58, 58, 58, 58, 58, 58, 58, -142
1399 },
1400
1401 {
1402 11, -143, -143, -143, -143, -143, -143, -143, -143, -143,
1403 -143, -143, -143, 58, -143, -143, 58, 58, 58, 58,
1404 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1405 58, 58, 165, 58, 58, 58, 58, -143
1406 },
1407
1408 {
1409 11, -144, -144, -144, -144, -144, -144, -144, -144, -144,
1410 -144, -144, -144, 58, -144, -144, 58, 58, 58, 58,
1411 58, 58, 58, 58, 58, 58, 166, 58, 58, 58,
1412 58, 58, 58, 58, 58, 58, 58, -144
1413
1414 },
1415
1416 {
1417 11, -145, -145, -145, -145, -145, -145, -145, -145, -145,
1418 -145, -145, -145, 58, -145, -145, 58, 58, 58, 58,
1419 167, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1420 58, 58, 58, 58, 58, 58, 58, -145
1421 },
1422
1423 {
1424 11, -146, -146, -146, -146, -146, -146, -146, -146, -146,
1425 -146, -146, -146, 58, -146, -146, 58, 58, 58, 58,
1426 58, 168, 58, 58, 58, 58, 58, 58, 58, 58,
1427 58, 58, 58, 58, 58, 58, 58, -146
1428 },
1429
1430 {
1431 11, -147, -147, -147, -147, -147, -147, -147, -147, -147,
1432 -147, -147, -147, 58, -147, -147, 58, 58, 58, 58,
1433
1434 58, 58, 58, 58, 58, 58, 58, 58, 58, 169,
1435 58, 58, 58, 58, 58, 58, 58, -147
1436 },
1437
1438 {
1439 11, -148, -148, -148, -148, -148, -148, -148, -148, -148,
1440 -148, -148, -148, 58, -148, -148, 58, 58, 58, 58,
1441 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1442 58, 58, 58, 58, 58, 58, 58, -148
1443 },
1444
1445 {
1446 11, -149, -149, -149, -149, -149, -149, -149, -149, -149,
1447 -149, -149, -149, 58, -149, -149, 58, 58, 58, 58,
1448 58, 58, 58, 58, 58, 58, 58, 58, 170, 58,
1449 58, 58, 58, 58, 58, 58, 58, -149
1450
1451 },
1452
1453 {
1454 11, -150, -150, -150, -150, -150, -150, -150, -150, -150,
1455 -150, -150, -150, 58, -150, -150, 58, 58, 58, 58,
1456 58, 171, 58, 58, 58, 58, 58, 58, 58, 58,
1457 58, 58, 58, 58, 58, 58, 58, -150
1458 },
1459
1460 {
1461 11, -151, -151, -151, -151, -151, -151, -151, -151, -151,
1462 -151, -151, -151, 58, -151, -151, 58, 58, 58, 58,
1463 58, 58, 58, 58, 58, 58, 58, 58, 58, 172,
1464 58, 58, 58, 58, 58, 58, 58, -151
1465 },
1466
1467 {
1468 11, -152, -152, -152, -152, -152, -152, -152, -152, -152,
1469 -152, -152, -152, 58, -152, -152, 58, 58, 58, 58,
1470
1471 58, 58, 58, 58, 58, 58, 58, 58, 173, 58,
1472 58, 58, 58, 58, 58, 58, 58, -152
1473 },
1474
1475 {
1476 11, -153, -153, -153, -153, -153, -153, -153, -153, -153,
1477 -153, -153, -153, 58, -153, -153, 58, 58, 58, 58,
1478 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1479 58, 58, 58, 58, 174, 58, 58, -153
1480 },
1481
1482 {
1483 11, -154, -154, -154, -154, -154, -154, -154, -154, -154,
1484 -154, -154, -154, 58, -154, -154, 58, 58, 58, 58,
1485 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1486 58, 58, 58, 58, 58, 58, 58, -154
1487
1488 },
1489
1490 {
1491 11, -155, -155, -155, -155, -155, -155, -155, -155, -155,
1492 -155, -155, -155, 58, -155, -155, 58, 58, 58, 58,
1493 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1494 58, 58, 175, 58, 58, 58, 58, -155
1495 },
1496
1497 {
1498 11, -156, -156, -156, -156, -156, -156, -156, -156, -156,
1499 -156, -156, -156, 58, -156, -156, 58, 58, 58, 58,
1500 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1501 58, 58, 58, 58, 176, 58, 58, -156
1502 },
1503
1504 {
1505 11, -157, -157, -157, -157, -157, -157, -157, -157, -157,
1506 -157, -157, -157, 58, -157, -157, 58, 58, 58, 58,
1507
1508 58, 177, 58, 58, 58, 58, 58, 58, 58, 58,
1509 58, 58, 58, 58, 58, 58, 58, -157
1510 },
1511
1512 {
1513 11, -158, -158, -158, -158, -158, -158, -158, -158, -158,
1514 -158, -158, -158, 58, -158, -158, 58, 58, 58, 58,
1515 58, 58, 58, 178, 58, 58, 58, 58, 58, 58,
1516 58, 58, 58, 58, 58, 58, 58, -158
1517 },
1518
1519 {
1520 11, -159, -159, -159, -159, -159, -159, -159, -159, -159,
1521 -159, -159, -159, 58, -159, -159, 58, 179, 58, 58,
1522 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1523 58, 58, 58, 58, 58, 58, 58, -159
1524
1525 },
1526
1527 {
1528 11, -160, -160, -160, -160, -160, -160, -160, -160, -160,
1529 -160, -160, -160, 58, -160, -160, 58, 58, 58, 58,
1530 58, 58, 58, 58, 58, 58, 58, 58, 180, 58,
1531 58, 58, 58, 58, 58, 58, 58, -160
1532 },
1533
1534 {
1535 11, -161, -161, -161, -161, -161, -161, -161, -161, -161,
1536 -161, -161, -161, 58, -161, -161, 58, 58, 58, 58,
1537 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1538 58, 58, 58, 58, 58, 58, 58, -161
1539 },
1540
1541 {
1542 11, -162, -162, -162, -162, -162, -162, -162, -162, -162,
1543 -162, -162, -162, 58, -162, -162, 58, 58, 58, 58,
1544
1545 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1546 58, 58, 58, 58, 181, 58, 58, -162
1547 },
1548
1549 {
1550 11, -163, -163, -163, -163, -163, -163, -163, -163, -163,
1551 -163, -163, -163, 58, -163, -163, 58, 58, 58, 58,
1552 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1553 58, 58, 58, 58, 58, 58, 58, -163
1554 },
1555
1556 {
1557 11, -164, -164, -164, -164, -164, -164, -164, -164, -164,
1558 -164, -164, -164, 58, -164, -164, 58, 58, 58, 58,
1559 58, 58, 58, 58, 58, 58, 58, 58, 58, 182,
1560 58, 58, 58, 58, 58, 58, 58, -164
1561
1562 },
1563
1564 {
1565 11, -165, -165, -165, -165, -165, -165, -165, -165, -165,
1566 -165, -165, -165, 58, -165, -165, 58, 58, 58, 58,
1567 58, 58, 58, 58, 58, 183, 58, 58, 58, 58,
1568 58, 58, 58, 58, 58, 58, 58, -165
1569 },
1570
1571 {
1572 11, -166, -166, -166, -166, -166, -166, -166, -166, -166,
1573 -166, -166, -166, 58, -166, -166, 58, 58, 58, 58,
1574 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1575 58, 58, 58, 58, 184, 58, 58, -166
1576 },
1577
1578 {
1579 11, -167, -167, -167, -167, -167, -167, -167, -167, -167,
1580 -167, -167, -167, 58, -167, -167, 58, 58, 58, 58,
1581
1582 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1583 58, 58, 58, 185, 58, 58, 58, -167
1584 },
1585
1586 {
1587 11, -168, -168, -168, -168, -168, -168, -168, -168, -168,
1588 -168, -168, -168, 58, -168, -168, 58, 58, 58, 58,
1589 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1590 58, 58, 58, 58, 58, 58, 58, -168
1591 },
1592
1593 {
1594 11, -169, -169, -169, -169, -169, -169, -169, -169, -169,
1595 -169, -169, -169, 58, -169, -169, 58, 58, 58, 58,
1596 58, 58, 58, 58, 58, 186, 58, 58, 58, 58,
1597 58, 58, 58, 58, 58, 58, 58, -169
1598
1599 },
1600
1601 {
1602 11, -170, -170, -170, -170, -170, -170, -170, -170, -170,
1603 -170, -170, -170, 58, -170, -170, 58, 58, 58, 58,
1604 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1605 58, 58, 58, 58, 58, 187, 58, -170
1606 },
1607
1608 {
1609 11, -171, -171, -171, -171, -171, -171, -171, -171, -171,
1610 -171, -171, -171, 58, -171, -171, 58, 58, 58, 58,
1611 58, 58, 58, 58, 58, 58, 58, 58, 188, 58,
1612 58, 58, 58, 58, 58, 58, 58, -171
1613 },
1614
1615 {
1616 11, -172, -172, -172, -172, -172, -172, -172, -172, -172,
1617 -172, -172, -172, 58, -172, -172, 58, 58, 58, 58,
1618
1619 58, 58, 58, 58, 58, 58, 58, 58, 189, 58,
1620 58, 58, 58, 58, 58, 58, 58, -172
1621 },
1622
1623 {
1624 11, -173, -173, -173, -173, -173, -173, -173, -173, -173,
1625 -173, -173, -173, 58, -173, -173, 58, 190, 58, 58,
1626 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1627 58, 58, 58, 58, 58, 58, 58, -173
1628 },
1629
1630 {
1631 11, -174, -174, -174, -174, -174, -174, -174, -174, -174,
1632 -174, -174, -174, 58, -174, -174, 58, 58, 58, 58,
1633 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1634 58, 58, 58, 58, 58, 58, 58, -174
1635
1636 },
1637
1638 {
1639 11, -175, -175, -175, -175, -175, -175, -175, -175, -175,
1640 -175, -175, -175, 58, -175, -175, 58, 58, 58, 58,
1641 58, 191, 58, 58, 58, 58, 58, 58, 58, 58,
1642 58, 58, 58, 58, 58, 58, 58, -175
1643 },
1644
1645 {
1646 11, -176, -176, -176, -176, -176, -176, -176, -176, -176,
1647 -176, -176, -176, 58, -176, -176, 58, 58, 58, 58,
1648 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1649 58, 58, 58, 58, 58, 58, 58, -176
1650 },
1651
1652 {
1653 11, -177, -177, -177, -177, -177, -177, -177, -177, -177,
1654 -177, -177, -177, 58, -177, -177, 58, 58, 58, 58,
1655
1656 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1657 58, 58, 58, 58, 58, 58, 58, -177
1658 },
1659
1660 {
1661 11, -178, -178, -178, -178, -178, -178, -178, -178, -178,
1662 -178, -178, -178, 58, -178, -178, 58, 58, 58, 58,
1663 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1664 58, 58, 58, 58, 58, 58, 58, -178
1665 },
1666
1667 {
1668 11, -179, -179, -179, -179, -179, -179, -179, -179, -179,
1669 -179, -179, -179, 58, -179, -179, 58, 58, 58, 58,
1670 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1671 58, 58, 58, 58, 192, 58, 58, -179
1672
1673 },
1674
1675 {
1676 11, -180, -180, -180, -180, -180, -180, -180, -180, -180,
1677 -180, -180, -180, 58, -180, -180, 58, 58, 58, 58,
1678 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1679 58, 58, 58, 58, 58, 58, 58, -180
1680 },
1681
1682 {
1683 11, -181, -181, -181, -181, -181, -181, -181, -181, -181,
1684 -181, -181, -181, 58, -181, -181, 58, 58, 58, 58,
1685 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1686 58, 58, 58, 58, 58, 58, 58, -181
1687 },
1688
1689 {
1690 11, -182, -182, -182, -182, -182, -182, -182, -182, -182,
1691 -182, -182, -182, 58, -182, -182, 58, 58, 58, 58,
1692
1693 58, 58, 58, 58, 58, 58, 193, 58, 58, 58,
1694 58, 58, 58, 58, 58, 58, 58, -182
1695 },
1696
1697 {
1698 11, -183, -183, -183, -183, -183, -183, -183, -183, -183,
1699 -183, -183, -183, 58, -183, -183, 58, 58, 58, 58,
1700 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1701 58, 58, 58, 194, 58, 58, 58, -183
1702 },
1703
1704 {
1705 11, -184, -184, -184, -184, -184, -184, -184, -184, -184,
1706 -184, -184, -184, 58, -184, -184, 58, 58, 58, 58,
1707 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1708 58, 58, 58, 58, 58, 58, 58, -184
1709
1710 },
1711
1712 {
1713 11, -185, -185, -185, -185, -185, -185, -185, -185, -185,
1714 -185, -185, -185, 58, -185, -185, 58, 58, 58, 58,
1715 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1716 58, 58, 58, 58, 58, 58, 58, -185
1717 },
1718
1719 {
1720 11, -186, -186, -186, -186, -186, -186, -186, -186, -186,
1721 -186, -186, -186, 58, -186, -186, 58, 58, 58, 195,
1722 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1723 58, 58, 58, 58, 58, 58, 58, -186
1724 },
1725
1726 {
1727 11, -187, -187, -187, -187, -187, -187, -187, -187, -187,
1728 -187, -187, -187, 58, -187, -187, 58, 58, 58, 58,
1729
1730 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1731 58, 58, 58, 58, 58, 58, 58, -187
1732 },
1733
1734 {
1735 11, -188, -188, -188, -188, -188, -188, -188, -188, -188,
1736 -188, -188, -188, 58, -188, -188, 58, 58, 58, 58,
1737 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1738 58, 58, 58, 58, 58, 196, 58, -188
1739 },
1740
1741 {
1742 11, -189, -189, -189, -189, -189, -189, -189, -189, -189,
1743 -189, -189, -189, 58, -189, -189, 58, 58, 58, 58,
1744 58, 58, 197, 58, 58, 58, 58, 58, 58, 58,
1745 58, 58, 58, 58, 58, 58, 58, -189
1746
1747 },
1748
1749 {
1750 11, -190, -190, -190, -190, -190, -190, -190, -190, -190,
1751 -190, -190, -190, 58, -190, -190, 58, 58, 58, 58,
1752 58, 58, 58, 58, 58, 58, 198, 58, 58, 58,
1753 58, 58, 58, 58, 58, 58, 58, -190
1754 },
1755
1756 {
1757 11, -191, -191, -191, -191, -191, -191, -191, -191, -191,
1758 -191, -191, -191, 58, -191, -191, 58, 58, 58, 58,
1759 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1760 58, 58, 58, 199, 58, 58, 58, -191
1761 },
1762
1763 {
1764 11, -192, -192, -192, -192, -192, -192, -192, -192, -192,
1765 -192, -192, -192, 58, -192, -192, 58, 58, 58, 58,
1766
1767 58, 200, 58, 58, 58, 58, 58, 58, 58, 58,
1768 58, 58, 58, 58, 58, 58, 58, -192
1769 },
1770
1771 {
1772 11, -193, -193, -193, -193, -193, -193, -193, -193, -193,
1773 -193, -193, -193, 58, -193, -193, 58, 58, 58, 58,
1774 58, 201, 58, 58, 58, 58, 58, 58, 58, 58,
1775 58, 58, 58, 58, 58, 58, 58, -193
1776 },
1777
1778 {
1779 11, -194, -194, -194, -194, -194, -194, -194, -194, -194,
1780 -194, -194, -194, 58, -194, -194, 58, 58, 58, 58,
1781 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1782 58, 58, 58, 58, 202, 58, 58, -194
1783
1784 },
1785
1786 {
1787 11, -195, -195, -195, -195, -195, -195, -195, -195, -195,
1788 -195, -195, -195, 58, -195, -195, 58, 58, 58, 58,
1789 58, 203, 58, 58, 58, 58, 58, 58, 58, 58,
1790 58, 58, 58, 58, 58, 58, 58, -195
1791 },
1792
1793 {
1794 11, -196, -196, -196, -196, -196, -196, -196, -196, -196,
1795 -196, -196, -196, 58, -196, -196, 58, 58, 58, 58,
1796 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1797 58, 58, 58, 58, 58, 58, 58, -196
1798 },
1799
1800 {
1801 11, -197, -197, -197, -197, -197, -197, -197, -197, -197,
1802 -197, -197, -197, 58, -197, -197, 58, 58, 58, 58,
1803
1804 58, 58, 58, 58, 58, 204, 58, 58, 58, 58,
1805 58, 58, 58, 58, 58, 58, 58, -197
1806 },
1807
1808 {
1809 11, -198, -198, -198, -198, -198, -198, -198, -198, -198,
1810 -198, -198, -198, 58, -198, -198, 58, 58, 58, 58,
1811 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1812 58, 58, 58, 58, 58, 58, 58, -198
1813 },
1814
1815 {
1816 11, -199, -199, -199, -199, -199, -199, -199, -199, -199,
1817 -199, -199, -199, 58, -199, -199, 58, 58, 58, 58,
1818 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1819 58, 58, 58, 58, 58, 58, 58, -199
1820
1821 },
1822
1823 {
1824 11, -200, -200, -200, -200, -200, -200, -200, -200, -200,
1825 -200, -200, -200, 58, -200, -200, 58, 58, 58, 58,
1826 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1827 58, 58, 58, 58, 58, 58, 58, -200
1828 },
1829
1830 {
1831 11, -201, -201, -201, -201, -201, -201, -201, -201, -201,
1832 -201, -201, -201, 58, -201, -201, 58, 205, 58, 58,
1833 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1834 58, 58, 58, 58, 58, 58, 58, -201
1835 },
1836
1837 {
1838 11, -202, -202, -202, -202, -202, -202, -202, -202, -202,
1839 -202, -202, -202, 58, -202, -202, 58, 206, 58, 58,
1840
1841 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1842 58, 58, 58, 58, 58, 58, 58, -202
1843 },
1844
1845 {
1846 11, -203, -203, -203, -203, -203, -203, -203, -203, -203,
1847 -203, -203, -203, 58, -203, -203, 58, 58, 58, 58,
1848 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1849 58, 58, 58, 58, 58, 58, 58, -203
1850 },
1851
1852 {
1853 11, -204, -204, -204, -204, -204, -204, -204, -204, -204,
1854 -204, -204, -204, 58, -204, -204, 58, 58, 58, 58,
1855 58, 58, 58, 207, 58, 58, 58, 58, 58, 58,
1856 58, 58, 58, 58, 58, 58, 58, -204
1857
1858 },
1859
1860 {
1861 11, -205, -205, -205, -205, -205, -205, -205, -205, -205,
1862 -205, -205, -205, 58, -205, -205, 58, 58, 58, 58,
1863 58, 58, 58, 58, 58, 58, 58, 58, 208, 58,
1864 58, 58, 58, 58, 58, 58, 58, -205
1865 },
1866
1867 {
1868 11, -206, -206, -206, -206, -206, -206, -206, -206, -206,
1869 -206, -206, -206, 58, -206, -206, 58, 58, 58, 58,
1870 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1871 58, 58, 58, 58, 209, 58, 58, -206
1872 },
1873
1874 {
1875 11, -207, -207, -207, -207, -207, -207, -207, -207, -207,
1876 -207, -207, -207, 58, -207, -207, 58, 58, 58, 58,
1877
1878 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1879 58, 58, 58, 58, 58, 58, 58, -207
1880 },
1881
1882 {
1883 11, -208, -208, -208, -208, -208, -208, -208, -208, -208,
1884 -208, -208, -208, 58, -208, -208, 58, 58, 58, 58,
1885 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1886 58, 58, 58, 58, 58, 58, 58, -208
1887 },
1888
1889 {
1890 11, -209, -209, -209, -209, -209, -209, -209, -209, -209,
1891 -209, -209, -209, 58, -209, -209, 58, 58, 58, 58,
1892 58, 210, 58, 58, 58, 58, 58, 58, 58, 58,
1893 58, 58, 58, 58, 58, 58, 58, -209
1894
1895 },
1896
1897 {
1898 11, -210, -210, -210, -210, -210, -210, -210, -210, -210,
1899 -210, -210, -210, 58, -210, -210, 58, 58, 58, 58,
1900 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
1901 58, 58, 58, 58, 58, 58, 58, -210
1902 },
1903
1904 } ;
1905
1906static yy_state_type yy_get_previous_state (void );
1907static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
1908static int yy_get_next_buffer (void );
1909static void yy_fatal_error (yyconst char msg[] );
1910
1911/* Done after the current pattern has been matched and before the
1912 * corresponding action - sets up zconftext.
1913 */
1914#define YY_DO_BEFORE_ACTION \
1915 (yytext_ptr) = yy_bp; \
1916 zconfleng = (size_t) (yy_cp - yy_bp); \
1917 (yy_hold_char) = *yy_cp; \
1918 *yy_cp = '\0'; \
1919 (yy_c_buf_p) = yy_cp;
1920
1921#define YY_NUM_RULES 64
1922#define YY_END_OF_BUFFER 65
1923/* This struct is not used in this scanner,
1924 but its presence is necessary. */
1925struct yy_trans_info
1926 {
1927 flex_int32_t yy_verify;
1928 flex_int32_t yy_nxt;
1929 };
1930static yyconst flex_int16_t yy_accept[211] =
1931 { 0,
1932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1933 65, 5, 4, 3, 2, 36, 37, 35, 35, 35,
1934 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
1935 63, 60, 62, 55, 59, 58, 57, 53, 48, 42,
1936 47, 51, 53, 40, 41, 50, 50, 43, 53, 50,
1937 50, 53, 4, 3, 2, 2, 1, 35, 35, 35,
1938 35, 35, 35, 35, 16, 35, 35, 35, 35, 35,
1939 35, 35, 35, 35, 35, 35, 63, 60, 62, 61,
1940 55, 54, 57, 56, 44, 51, 38, 50, 50, 52,
1941 45, 46, 39, 35, 35, 35, 35, 35, 35, 35,
1942
1943 35, 35, 30, 29, 35, 35, 35, 35, 35, 35,
1944 35, 35, 35, 35, 49, 25, 35, 35, 35, 35,
1945 35, 35, 35, 35, 35, 35, 15, 35, 7, 35,
1946 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
1947 35, 35, 35, 35, 35, 35, 35, 17, 35, 35,
1948 35, 35, 35, 34, 35, 35, 35, 35, 35, 35,
1949 10, 35, 13, 35, 35, 35, 35, 33, 35, 35,
1950 35, 35, 35, 22, 35, 32, 9, 31, 35, 26,
1951 12, 35, 35, 21, 18, 35, 8, 35, 35, 35,
1952 35, 35, 27, 35, 35, 6, 35, 20, 19, 23,
1953
1954 35, 35, 11, 35, 35, 35, 14, 28, 35, 24
1955 } ;
1956
1957static yyconst flex_int32_t yy_ec[256] =
1958 { 0,
1959 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1960 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1961 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1962 1, 2, 4, 5, 6, 1, 1, 7, 8, 9,
1963 10, 1, 1, 1, 11, 12, 12, 13, 13, 13,
1964 13, 13, 13, 13, 13, 13, 13, 1, 1, 1,
1965 14, 1, 1, 1, 13, 13, 13, 13, 13, 13,
1966 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1967 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
1968 1, 15, 1, 1, 16, 1, 17, 18, 19, 20,
1969
1970 21, 22, 23, 24, 25, 13, 13, 26, 27, 28,
1971 29, 30, 31, 32, 33, 34, 35, 13, 13, 36,
1972 13, 13, 1, 37, 1, 1, 1, 1, 1, 1,
1973 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1974 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1975 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1976 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1977 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1978 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1979 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1980
1981 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1982 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1983 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1984 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1985 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1986 1, 1, 1, 1, 1
1987 } ;
1988
1989extern int zconf_flex_debug;
1990int zconf_flex_debug = 0;
1991
1992/* The intent behind this definition is that it'll catch
1993 * any uses of REJECT which flex missed.
1994 */
1995#define REJECT reject_used_but_not_detected
1996#define yymore() yymore_used_but_not_detected
1997#define YY_MORE_ADJ 0
1998#define YY_RESTORE_YY_MORE_OFFSET
1999char *zconftext;
2000
2001/*
2002 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
2003 * Released under the terms of the GNU GPL v2.0.
2004 */
2005
2006#include <limits.h>
2007#include <stdio.h>
2008#include <stdlib.h>
2009#include <string.h>
2010#include <unistd.h>
2011
2012#define LKC_DIRECT_LINK
2013#include "lkc.h"
2014
2015#define START_STRSIZE 16
2016
2017char *text;
2018static char *text_ptr;
2019static int text_size, text_asize;
2020
2021struct buffer {
2022 struct buffer *parent;
2023 YY_BUFFER_STATE state;
2024};
2025
2026struct buffer *current_buf;
2027
2028static int last_ts, first_ts;
2029
2030static void zconf_endhelp(void);
2031static struct buffer *zconf_endfile(void);
2032
2033void new_string(void)
2034{
2035 text = malloc(START_STRSIZE);
2036 text_asize = START_STRSIZE;
2037 text_ptr = text;
2038 text_size = 0;
2039 *text_ptr = 0;
2040}
2041
2042void append_string(const char *str, int size)
2043{
2044 int new_size = text_size + size + 1;
2045 if (new_size > text_asize) {
2046 text = realloc(text, new_size);
2047 text_asize = new_size;
2048 text_ptr = text + text_size;
2049 }
2050 memcpy(text_ptr, str, size);
2051 text_ptr += size;
2052 text_size += size;
2053 *text_ptr = 0;
2054}
2055
2056void alloc_string(const char *str, int size)
2057{
2058 text = malloc(size + 1);
2059 memcpy(text, str, size);
2060 text[size] = 0;
2061}
2062
2063#define INITIAL 0
2064#define COMMAND 1
2065#define HELP 2
2066#define STRING 3
2067#define PARAM 4
2068
2069/* Special case for "unistd.h", since it is non-ANSI. We include it way
2070 * down here because we want the user's section 1 to have been scanned first.
2071 * The user has a chance to override it with an option.
2072 */
2073#include <unistd.h>
2074
2075#ifndef YY_EXTRA_TYPE
2076#define YY_EXTRA_TYPE void *
2077#endif
2078
2079/* Macros after this point can all be overridden by user definitions in
2080 * section 1.
2081 */
2082
2083#ifndef YY_SKIP_YYWRAP
2084#ifdef __cplusplus
2085extern "C" int zconfwrap (void );
2086#else
2087extern int zconfwrap (void );
2088#endif
2089#endif
2090
2091 static void yyunput (int c,char *buf_ptr );
2092
2093#ifndef yytext_ptr
2094static void yy_flex_strncpy (char *,yyconst char *,int );
2095#endif
2096
2097#ifdef YY_NEED_STRLEN
2098static int yy_flex_strlen (yyconst char * );
2099#endif
2100
2101#ifndef YY_NO_INPUT
2102
2103#ifdef __cplusplus
2104static int yyinput (void );
2105#else
2106static int input (void );
2107#endif
2108
2109#endif
2110
2111/* Amount of stuff to slurp up with each read. */
2112#ifndef YY_READ_BUF_SIZE
2113#define YY_READ_BUF_SIZE 8192
2114#endif
2115
2116/* Copy whatever the last rule matched to the standard output. */
2117#ifndef ECHO
2118/* This used to be an fputs(), but since the string might contain NUL's,
2119 * we now use fwrite().
2120 */
2121#define ECHO (void) fwrite( zconftext, zconfleng, 1, zconfout )
2122#endif
2123
2124/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
2125 * is returned in "result".
2126 */
2127#ifndef YY_INPUT
2128#define YY_INPUT(buf,result,max_size) \
2129 errno=0; \
2130 while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \
2131 { \
2132 if( errno != EINTR) \
2133 { \
2134 YY_FATAL_ERROR( "input in flex scanner failed" ); \
2135 break; \
2136 } \
2137 errno=0; \
2138 clearerr(zconfin); \
2139 }\
2140\
2141
2142#endif
2143
2144/* No semi-colon after return; correct usage is to write "yyterminate();" -
2145 * we don't want an extra ';' after the "return" because that will cause
2146 * some compilers to complain about unreachable statements.
2147 */
2148#ifndef yyterminate
2149#define yyterminate() return YY_NULL
2150#endif
2151
2152/* Number of entries by which start-condition stack grows. */
2153#ifndef YY_START_STACK_INCR
2154#define YY_START_STACK_INCR 25
2155#endif
2156
2157/* Report a fatal error. */
2158#ifndef YY_FATAL_ERROR
2159#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
2160#endif
2161
2162/* end tables serialization structures and prototypes */
2163
2164/* Default declaration of generated scanner - a define so the user can
2165 * easily add parameters.
2166 */
2167#ifndef YY_DECL
2168#define YY_DECL_IS_OURS 1
2169
2170extern int zconflex (void);
2171
2172#define YY_DECL int zconflex (void)
2173#endif /* !YY_DECL */
2174
2175/* Code executed at the beginning of each rule, after zconftext and zconfleng
2176 * have been set up.
2177 */
2178#ifndef YY_USER_ACTION
2179#define YY_USER_ACTION
2180#endif
2181
2182/* Code executed at the end of each rule. */
2183#ifndef YY_BREAK
2184#define YY_BREAK break;
2185#endif
2186
2187#define YY_RULE_SETUP \
2188 YY_USER_ACTION
2189
2190/** The main scanner function which does all the work.
2191 */
2192YY_DECL
2193{
2194 register yy_state_type yy_current_state;
2195 register char *yy_cp, *yy_bp;
2196 register int yy_act;
2197
2198 int str = 0;
2199 int ts, i;
2200
2201 if ( (yy_init) )
2202 {
2203 (yy_init) = 0;
2204
2205#ifdef YY_USER_INIT
2206 YY_USER_INIT;
2207#endif
2208
2209 if ( ! (yy_start) )
2210 (yy_start) = 1; /* first start state */
2211
2212 if ( ! zconfin )
2213 zconfin = stdin;
2214
2215 if ( ! zconfout )
2216 zconfout = stdout;
2217
2218 if ( ! YY_CURRENT_BUFFER ) {
2219 zconfensure_buffer_stack ();
2220 YY_CURRENT_BUFFER_LVALUE =
2221 zconf_create_buffer(zconfin,YY_BUF_SIZE );
2222 }
2223
2224 zconf_load_buffer_state( );
2225 }
2226
2227 while ( 1 ) /* loops until end-of-file is reached */
2228 {
2229 yy_cp = (yy_c_buf_p);
2230
2231 /* Support of zconftext. */
2232 *yy_cp = (yy_hold_char);
2233
2234 /* yy_bp points to the position in yy_ch_buf of the start of
2235 * the current run.
2236 */
2237 yy_bp = yy_cp;
2238
2239 yy_current_state = (yy_start);
2240yy_match:
2241 while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)] ]) > 0 )
2242 ++yy_cp;
2243
2244 yy_current_state = -yy_current_state;
2245
2246yy_find_action:
2247 yy_act = yy_accept[yy_current_state];
2248
2249 YY_DO_BEFORE_ACTION;
2250
2251do_action: /* This label is used only to access EOF actions. */
2252
2253 switch ( yy_act )
2254 { /* beginning of action switch */
2255case 1:
2256/* rule 1 can match eol */
2257YY_RULE_SETUP
2258current_file->lineno++;
2259 YY_BREAK
2260case 2:
2261YY_RULE_SETUP
2262
2263 YY_BREAK
2264case 3:
2265/* rule 3 can match eol */
2266YY_RULE_SETUP
2267current_file->lineno++; return T_EOL;
2268 YY_BREAK
2269case 4:
2270YY_RULE_SETUP
2271{
2272 BEGIN(COMMAND);
2273}
2274 YY_BREAK
2275case 5:
2276YY_RULE_SETUP
2277{
2278 unput(zconftext[0]);
2279 BEGIN(COMMAND);
2280}
2281 YY_BREAK
2282
2283case 6:
2284YY_RULE_SETUP
2285BEGIN(PARAM); return T_MAINMENU;
2286 YY_BREAK
2287case 7:
2288YY_RULE_SETUP
2289BEGIN(PARAM); return T_MENU;
2290 YY_BREAK
2291case 8:
2292YY_RULE_SETUP
2293BEGIN(PARAM); return T_ENDMENU;
2294 YY_BREAK
2295case 9:
2296YY_RULE_SETUP
2297BEGIN(PARAM); return T_SOURCE;
2298 YY_BREAK
2299case 10:
2300YY_RULE_SETUP
2301BEGIN(PARAM); return T_CHOICE;
2302 YY_BREAK
2303case 11:
2304YY_RULE_SETUP
2305BEGIN(PARAM); return T_ENDCHOICE;
2306 YY_BREAK
2307case 12:
2308YY_RULE_SETUP
2309BEGIN(PARAM); return T_COMMENT;
2310 YY_BREAK
2311case 13:
2312YY_RULE_SETUP
2313BEGIN(PARAM); return T_CONFIG;
2314 YY_BREAK
2315case 14:
2316YY_RULE_SETUP
2317BEGIN(PARAM); return T_MENUCONFIG;
2318 YY_BREAK
2319case 15:
2320YY_RULE_SETUP
2321BEGIN(PARAM); return T_HELP;
2322 YY_BREAK
2323case 16:
2324YY_RULE_SETUP
2325BEGIN(PARAM); return T_IF;
2326 YY_BREAK
2327case 17:
2328YY_RULE_SETUP
2329BEGIN(PARAM); return T_ENDIF;
2330 YY_BREAK
2331case 18:
2332YY_RULE_SETUP
2333BEGIN(PARAM); return T_DEPENDS;
2334 YY_BREAK
2335case 19:
2336YY_RULE_SETUP
2337BEGIN(PARAM); return T_REQUIRES;
2338 YY_BREAK
2339case 20:
2340YY_RULE_SETUP
2341BEGIN(PARAM); return T_OPTIONAL;
2342 YY_BREAK
2343case 21:
2344YY_RULE_SETUP
2345BEGIN(PARAM); return T_DEFAULT;
2346 YY_BREAK
2347case 22:
2348YY_RULE_SETUP
2349BEGIN(PARAM); return T_PROMPT;
2350 YY_BREAK
2351case 23:
2352YY_RULE_SETUP
2353BEGIN(PARAM); return T_TRISTATE;
2354 YY_BREAK
2355case 24:
2356YY_RULE_SETUP
2357BEGIN(PARAM); return T_DEF_TRISTATE;
2358 YY_BREAK
2359case 25:
2360YY_RULE_SETUP
2361BEGIN(PARAM); return T_BOOLEAN;
2362 YY_BREAK
2363case 26:
2364YY_RULE_SETUP
2365BEGIN(PARAM); return T_BOOLEAN;
2366 YY_BREAK
2367case 27:
2368YY_RULE_SETUP
2369BEGIN(PARAM); return T_DEF_BOOLEAN;
2370 YY_BREAK
2371case 28:
2372YY_RULE_SETUP
2373BEGIN(PARAM); return T_DEF_BOOLEAN;
2374 YY_BREAK
2375case 29:
2376YY_RULE_SETUP
2377BEGIN(PARAM); return T_INT;
2378 YY_BREAK
2379case 30:
2380YY_RULE_SETUP
2381BEGIN(PARAM); return T_HEX;
2382 YY_BREAK
2383case 31:
2384YY_RULE_SETUP
2385BEGIN(PARAM); return T_STRING;
2386 YY_BREAK
2387case 32:
2388YY_RULE_SETUP
2389BEGIN(PARAM); return T_SELECT;
2390 YY_BREAK
2391case 33:
2392YY_RULE_SETUP
2393BEGIN(PARAM); return T_SELECT;
2394 YY_BREAK
2395case 34:
2396YY_RULE_SETUP
2397BEGIN(PARAM); return T_RANGE;
2398 YY_BREAK
2399case 35:
2400YY_RULE_SETUP
2401{
2402 alloc_string(zconftext, zconfleng);
2403 zconflval.string = text;
2404 return T_WORD;
2405 }
2406 YY_BREAK
2407case 36:
2408YY_RULE_SETUP
2409
2410 YY_BREAK
2411case 37:
2412/* rule 37 can match eol */
2413YY_RULE_SETUP
2414current_file->lineno++; BEGIN(INITIAL);
2415 YY_BREAK
2416
2417case 38:
2418YY_RULE_SETUP
2419return T_AND;
2420 YY_BREAK
2421case 39:
2422YY_RULE_SETUP
2423return T_OR;
2424 YY_BREAK
2425case 40:
2426YY_RULE_SETUP
2427return T_OPEN_PAREN;
2428 YY_BREAK
2429case 41:
2430YY_RULE_SETUP
2431return T_CLOSE_PAREN;
2432 YY_BREAK
2433case 42:
2434YY_RULE_SETUP
2435return T_NOT;
2436 YY_BREAK
2437case 43:
2438YY_RULE_SETUP
2439return T_EQUAL;
2440 YY_BREAK
2441case 44:
2442YY_RULE_SETUP
2443return T_UNEQUAL;
2444 YY_BREAK
2445case 45:
2446YY_RULE_SETUP
2447return T_IF;
2448 YY_BREAK
2449case 46:
2450YY_RULE_SETUP
2451return T_ON;
2452 YY_BREAK
2453case 47:
2454YY_RULE_SETUP
2455{
2456 str = zconftext[0];
2457 new_string();
2458 BEGIN(STRING);
2459 }
2460 YY_BREAK
2461case 48:
2462/* rule 48 can match eol */
2463YY_RULE_SETUP
2464BEGIN(INITIAL); current_file->lineno++; return T_EOL;
2465 YY_BREAK
2466case 49:
2467YY_RULE_SETUP
2468/* ignore */
2469 YY_BREAK
2470case 50:
2471YY_RULE_SETUP
2472{
2473 alloc_string(zconftext, zconfleng);
2474 zconflval.string = text;
2475 return T_WORD;
2476 }
2477 YY_BREAK
2478case 51:
2479YY_RULE_SETUP
2480/* comment */
2481 YY_BREAK
2482case 52:
2483/* rule 52 can match eol */
2484YY_RULE_SETUP
2485current_file->lineno++;
2486 YY_BREAK
2487case 53:
2488YY_RULE_SETUP
2489
2490 YY_BREAK
2491case YY_STATE_EOF(PARAM):
2492{
2493 BEGIN(INITIAL);
2494 }
2495 YY_BREAK
2496
2497case 54:
2498/* rule 54 can match eol */
2499*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2500(yy_c_buf_p) = yy_cp -= 1;
2501YY_DO_BEFORE_ACTION; /* set up zconftext again */
2502YY_RULE_SETUP
2503{
2504 append_string(zconftext, zconfleng);
2505 zconflval.string = text;
2506 return T_WORD_QUOTE;
2507 }
2508 YY_BREAK
2509case 55:
2510YY_RULE_SETUP
2511{
2512 append_string(zconftext, zconfleng);
2513 }
2514 YY_BREAK
2515case 56:
2516/* rule 56 can match eol */
2517*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2518(yy_c_buf_p) = yy_cp -= 1;
2519YY_DO_BEFORE_ACTION; /* set up zconftext again */
2520YY_RULE_SETUP
2521{
2522 append_string(zconftext + 1, zconfleng - 1);
2523 zconflval.string = text;
2524 return T_WORD_QUOTE;
2525 }
2526 YY_BREAK
2527case 57:
2528YY_RULE_SETUP
2529{
2530 append_string(zconftext + 1, zconfleng - 1);
2531 }
2532 YY_BREAK
2533case 58:
2534YY_RULE_SETUP
2535{
2536 if (str == zconftext[0]) {
2537 BEGIN(PARAM);
2538 zconflval.string = text;
2539 return T_WORD_QUOTE;
2540 } else
2541 append_string(zconftext, 1);
2542 }
2543 YY_BREAK
2544case 59:
2545/* rule 59 can match eol */
2546YY_RULE_SETUP
2547{
2548 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
2549 current_file->lineno++;
2550 BEGIN(INITIAL);
2551 return T_EOL;
2552 }
2553 YY_BREAK
2554case YY_STATE_EOF(STRING):
2555{
2556 BEGIN(INITIAL);
2557 }
2558 YY_BREAK
2559
2560case 60:
2561YY_RULE_SETUP
2562{
2563 ts = 0;
2564 for (i = 0; i < zconfleng; i++) {
2565 if (zconftext[i] == '\t')
2566 ts = (ts & ~7) + 8;
2567 else
2568 ts++;
2569 }
2570 last_ts = ts;
2571 if (first_ts) {
2572 if (ts < first_ts) {
2573 zconf_endhelp();
2574 return T_HELPTEXT;
2575 }
2576 ts -= first_ts;
2577 while (ts > 8) {
2578 append_string(" ", 8);
2579 ts -= 8;
2580 }
2581 append_string(" ", ts);
2582 }
2583 }
2584 YY_BREAK
2585case 61:
2586/* rule 61 can match eol */
2587*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
2588(yy_c_buf_p) = yy_cp -= 1;
2589YY_DO_BEFORE_ACTION; /* set up zconftext again */
2590YY_RULE_SETUP
2591{
2592 current_file->lineno++;
2593 zconf_endhelp();
2594 return T_HELPTEXT;
2595 }
2596 YY_BREAK
2597case 62:
2598/* rule 62 can match eol */
2599YY_RULE_SETUP
2600{
2601 current_file->lineno++;
2602 append_string("\n", 1);
2603 }
2604 YY_BREAK
2605case 63:
2606YY_RULE_SETUP
2607{
2608 append_string(zconftext, zconfleng);
2609 if (!first_ts)
2610 first_ts = last_ts;
2611 }
2612 YY_BREAK
2613case YY_STATE_EOF(HELP):
2614{
2615 zconf_endhelp();
2616 return T_HELPTEXT;
2617 }
2618 YY_BREAK
2619
2620case YY_STATE_EOF(INITIAL):
2621case YY_STATE_EOF(COMMAND):
2622{
2623 if (current_buf) {
2624 zconf_endfile();
2625 return T_EOF;
2626 }
2627 fclose(zconfin);
2628 yyterminate();
2629}
2630 YY_BREAK
2631case 64:
2632YY_RULE_SETUP
2633YY_FATAL_ERROR( "flex scanner jammed" );
2634 YY_BREAK
2635
2636 case YY_END_OF_BUFFER:
2637 {
2638 /* Amount of text matched not including the EOB char. */
2639 int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
2640
2641 /* Undo the effects of YY_DO_BEFORE_ACTION. */
2642 *yy_cp = (yy_hold_char);
2643 YY_RESTORE_YY_MORE_OFFSET
2644
2645 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
2646 {
2647 /* We're scanning a new file or input source. It's
2648 * possible that this happened because the user
2649 * just pointed zconfin at a new source and called
2650 * zconflex(). If so, then we have to assure
2651 * consistency between YY_CURRENT_BUFFER and our
2652 * globals. Here is the right place to do so, because
2653 * this is the first action (other than possibly a
2654 * back-up) that will match for the new input source.
2655 */
2656 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
2657 YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin;
2658 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
2659 }
2660
2661 /* Note that here we test for yy_c_buf_p "<=" to the position
2662 * of the first EOB in the buffer, since yy_c_buf_p will
2663 * already have been incremented past the NUL character
2664 * (since all states make transitions on EOB to the
2665 * end-of-buffer state). Contrast this with the test
2666 * in input().
2667 */
2668 if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
2669 { /* This was really a NUL. */
2670 yy_state_type yy_next_state;
2671
2672 (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
2673
2674 yy_current_state = yy_get_previous_state( );
2675
2676 /* Okay, we're now positioned to make the NUL
2677 * transition. We couldn't have
2678 * yy_get_previous_state() go ahead and do it
2679 * for us because it doesn't know how to deal
2680 * with the possibility of jamming (and we don't
2681 * want to build jamming into it because then it
2682 * will run more slowly).
2683 */
2684
2685 yy_next_state = yy_try_NUL_trans( yy_current_state );
2686
2687 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
2688
2689 if ( yy_next_state )
2690 {
2691 /* Consume the NUL. */
2692 yy_cp = ++(yy_c_buf_p);
2693 yy_current_state = yy_next_state;
2694 goto yy_match;
2695 }
2696
2697 else
2698 {
2699 yy_cp = (yy_c_buf_p);
2700 goto yy_find_action;
2701 }
2702 }
2703
2704 else switch ( yy_get_next_buffer( ) )
2705 {
2706 case EOB_ACT_END_OF_FILE:
2707 {
2708 (yy_did_buffer_switch_on_eof) = 0;
2709
2710 if ( zconfwrap( ) )
2711 {
2712 /* Note: because we've taken care in
2713 * yy_get_next_buffer() to have set up
2714 * zconftext, we can now set up
2715 * yy_c_buf_p so that if some total
2716 * hoser (like flex itself) wants to
2717 * call the scanner after we return the
2718 * YY_NULL, it'll still work - another
2719 * YY_NULL will get returned.
2720 */
2721 (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
2722
2723 yy_act = YY_STATE_EOF(YY_START);
2724 goto do_action;
2725 }
2726
2727 else
2728 {
2729 if ( ! (yy_did_buffer_switch_on_eof) )
2730 YY_NEW_FILE;
2731 }
2732 break;
2733 }
2734
2735 case EOB_ACT_CONTINUE_SCAN:
2736 (yy_c_buf_p) =
2737 (yytext_ptr) + yy_amount_of_matched_text;
2738
2739 yy_current_state = yy_get_previous_state( );
2740
2741 yy_cp = (yy_c_buf_p);
2742 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
2743 goto yy_match;
2744
2745 case EOB_ACT_LAST_MATCH:
2746 (yy_c_buf_p) =
2747 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
2748
2749 yy_current_state = yy_get_previous_state( );
2750
2751 yy_cp = (yy_c_buf_p);
2752 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
2753 goto yy_find_action;
2754 }
2755 break;
2756 }
2757
2758 default:
2759 YY_FATAL_ERROR(
2760 "fatal flex scanner internal error--no action found" );
2761 } /* end of action switch */
2762 } /* end of scanning one token */
2763} /* end of zconflex */
2764
2765/* yy_get_next_buffer - try to read in a new buffer
2766 *
2767 * Returns a code representing an action:
2768 * EOB_ACT_LAST_MATCH -
2769 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
2770 * EOB_ACT_END_OF_FILE - end of file
2771 */
2772static int yy_get_next_buffer (void)
2773{
2774 register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
2775 register char *source = (yytext_ptr);
2776 register int number_to_move, i;
2777 int ret_val;
2778
2779 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
2780 YY_FATAL_ERROR(
2781 "fatal flex scanner internal error--end of buffer missed" );
2782
2783 if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
2784 { /* Don't try to fill the buffer, so this is an EOF. */
2785 if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
2786 {
2787 /* We matched a single character, the EOB, so
2788 * treat this as a final EOF.
2789 */
2790 return EOB_ACT_END_OF_FILE;
2791 }
2792
2793 else
2794 {
2795 /* We matched some text prior to the EOB, first
2796 * process it.
2797 */
2798 return EOB_ACT_LAST_MATCH;
2799 }
2800 }
2801
2802 /* Try to read more data. */
2803
2804 /* First move last chars to start of buffer. */
2805 number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
2806
2807 for ( i = 0; i < number_to_move; ++i )
2808 *(dest++) = *(source++);
2809
2810 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
2811 /* don't do the read, it's not guaranteed to return an EOF,
2812 * just force an EOF
2813 */
2814 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
2815
2816 else
2817 {
2818 size_t num_to_read =
2819 YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
2820
2821 while ( num_to_read <= 0 )
2822 { /* Not enough room in the buffer - grow it. */
2823
2824 /* just a shorter name for the current buffer */
2825 YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
2826
2827 int yy_c_buf_p_offset =
2828 (int) ((yy_c_buf_p) - b->yy_ch_buf);
2829
2830 if ( b->yy_is_our_buffer )
2831 {
2832 int new_size = b->yy_buf_size * 2;
2833
2834 if ( new_size <= 0 )
2835 b->yy_buf_size += b->yy_buf_size / 8;
2836 else
2837 b->yy_buf_size *= 2;
2838
2839 b->yy_ch_buf = (char *)
2840 /* Include room in for 2 EOB chars. */
2841 zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
2842 }
2843 else
2844 /* Can't grow it, we don't own it. */
2845 b->yy_ch_buf = 0;
2846
2847 if ( ! b->yy_ch_buf )
2848 YY_FATAL_ERROR(
2849 "fatal error - scanner input buffer overflow" );
2850
2851 (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
2852
2853 num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
2854 number_to_move - 1;
2855
2856 }
2857
2858 if ( num_to_read > YY_READ_BUF_SIZE )
2859 num_to_read = YY_READ_BUF_SIZE;
2860
2861 /* Read in more data. */
2862 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
2863 (yy_n_chars), num_to_read );
2864
2865 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
2866 }
2867
2868 if ( (yy_n_chars) == 0 )
2869 {
2870 if ( number_to_move == YY_MORE_ADJ )
2871 {
2872 ret_val = EOB_ACT_END_OF_FILE;
2873 zconfrestart(zconfin );
2874 }
2875
2876 else
2877 {
2878 ret_val = EOB_ACT_LAST_MATCH;
2879 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
2880 YY_BUFFER_EOF_PENDING;
2881 }
2882 }
2883
2884 else
2885 ret_val = EOB_ACT_CONTINUE_SCAN;
2886
2887 (yy_n_chars) += number_to_move;
2888 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
2889 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
2890
2891 (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
2892
2893 return ret_val;
2894}
2895
2896/* yy_get_previous_state - get the state just before the EOB char was reached */
2897
2898 static yy_state_type yy_get_previous_state (void)
2899{
2900 register yy_state_type yy_current_state;
2901 register char *yy_cp;
2902
2903 yy_current_state = (yy_start);
2904
2905 for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
2906 {
2907 yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
2908 }
2909
2910 return yy_current_state;
2911}
2912
2913/* yy_try_NUL_trans - try to make a transition on the NUL character
2914 *
2915 * synopsis
2916 * next_state = yy_try_NUL_trans( current_state );
2917 */
2918 static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
2919{
2920 register int yy_is_jam;
2921
2922 yy_current_state = yy_nxt[yy_current_state][1];
2923 yy_is_jam = (yy_current_state <= 0);
2924
2925 return yy_is_jam ? 0 : yy_current_state;
2926}
2927
2928 static void yyunput (int c, register char * yy_bp )
2929{
2930 register char *yy_cp;
2931
2932 yy_cp = (yy_c_buf_p);
2933
2934 /* undo effects of setting up zconftext */
2935 *yy_cp = (yy_hold_char);
2936
2937 if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
2938 { /* need to shift things up to make room */
2939 /* +2 for EOB chars. */
2940 register int number_to_move = (yy_n_chars) + 2;
2941 register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
2942 YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
2943 register char *source =
2944 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
2945
2946 while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
2947 *--dest = *--source;
2948
2949 yy_cp += (int) (dest - source);
2950 yy_bp += (int) (dest - source);
2951 YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
2952 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
2953
2954 if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
2955 YY_FATAL_ERROR( "flex scanner push-back overflow" );
2956 }
2957
2958 *--yy_cp = (char) c;
2959
2960 (yytext_ptr) = yy_bp;
2961 (yy_hold_char) = *yy_cp;
2962 (yy_c_buf_p) = yy_cp;
2963}
2964
2965#ifndef YY_NO_INPUT
2966#ifdef __cplusplus
2967 static int yyinput (void)
2968#else
2969 static int input (void)
2970#endif
2971
2972{
2973 int c;
2974
2975 *(yy_c_buf_p) = (yy_hold_char);
2976
2977 if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
2978 {
2979 /* yy_c_buf_p now points to the character we want to return.
2980 * If this occurs *before* the EOB characters, then it's a
2981 * valid NUL; if not, then we've hit the end of the buffer.
2982 */
2983 if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
2984 /* This was really a NUL. */
2985 *(yy_c_buf_p) = '\0';
2986
2987 else
2988 { /* need more input */
2989 int offset = (yy_c_buf_p) - (yytext_ptr);
2990 ++(yy_c_buf_p);
2991
2992 switch ( yy_get_next_buffer( ) )
2993 {
2994 case EOB_ACT_LAST_MATCH:
2995 /* This happens because yy_g_n_b()
2996 * sees that we've accumulated a
2997 * token and flags that we need to
2998 * try matching the token before
2999 * proceeding. But for input(),
3000 * there's no matching to consider.
3001 * So convert the EOB_ACT_LAST_MATCH
3002 * to EOB_ACT_END_OF_FILE.
3003 */
3004
3005 /* Reset buffer status. */
3006 zconfrestart(zconfin );
3007
3008 /*FALLTHROUGH*/
3009
3010 case EOB_ACT_END_OF_FILE:
3011 {
3012 if ( zconfwrap( ) )
3013 return EOF;
3014
3015 if ( ! (yy_did_buffer_switch_on_eof) )
3016 YY_NEW_FILE;
3017#ifdef __cplusplus
3018 return yyinput();
3019#else
3020 return input();
3021#endif
3022 }
3023
3024 case EOB_ACT_CONTINUE_SCAN:
3025 (yy_c_buf_p) = (yytext_ptr) + offset;
3026 break;
3027 }
3028 }
3029 }
3030
3031 c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
3032 *(yy_c_buf_p) = '\0'; /* preserve zconftext */
3033 (yy_hold_char) = *++(yy_c_buf_p);
3034
3035 return c;
3036}
3037#endif /* ifndef YY_NO_INPUT */
3038
3039/** Immediately switch to a different input stream.
3040 * @param input_file A readable stream.
3041 *
3042 * @note This function does not reset the start condition to @c INITIAL .
3043 */
3044 void zconfrestart (FILE * input_file )
3045{
3046
3047 if ( ! YY_CURRENT_BUFFER ){
3048 zconfensure_buffer_stack ();
3049 YY_CURRENT_BUFFER_LVALUE =
3050 zconf_create_buffer(zconfin,YY_BUF_SIZE );
3051 }
3052
3053 zconf_init_buffer(YY_CURRENT_BUFFER,input_file );
3054 zconf_load_buffer_state( );
3055}
3056
3057/** Switch to a different input buffer.
3058 * @param new_buffer The new input buffer.
3059 *
3060 */
3061 void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer )
3062{
3063
3064 /* TODO. We should be able to replace this entire function body
3065 * with
3066 * zconfpop_buffer_state();
3067 * zconfpush_buffer_state(new_buffer);
3068 */
3069 zconfensure_buffer_stack ();
3070 if ( YY_CURRENT_BUFFER == new_buffer )
3071 return;
3072
3073 if ( YY_CURRENT_BUFFER )
3074 {
3075 /* Flush out information for old buffer. */
3076 *(yy_c_buf_p) = (yy_hold_char);
3077 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
3078 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
3079 }
3080
3081 YY_CURRENT_BUFFER_LVALUE = new_buffer;
3082 zconf_load_buffer_state( );
3083
3084 /* We don't actually know whether we did this switch during
3085 * EOF (zconfwrap()) processing, but the only time this flag
3086 * is looked at is after zconfwrap() is called, so it's safe
3087 * to go ahead and always set it.
3088 */
3089 (yy_did_buffer_switch_on_eof) = 1;
3090}
3091
3092static void zconf_load_buffer_state (void)
3093{
3094 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
3095 (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
3096 zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
3097 (yy_hold_char) = *(yy_c_buf_p);
3098}
3099
3100/** Allocate and initialize an input buffer state.
3101 * @param file A readable stream.
3102 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
3103 *
3104 * @return the allocated buffer state.
3105 */
3106 YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size )
3107{
3108 YY_BUFFER_STATE b;
3109
3110 b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
3111 if ( ! b )
3112 YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
3113
3114 b->yy_buf_size = size;
3115
3116 /* yy_ch_buf has to be 2 characters longer than the size given because
3117 * we need to put in 2 end-of-buffer characters.
3118 */
3119 b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2 );
3120 if ( ! b->yy_ch_buf )
3121 YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
3122
3123 b->yy_is_our_buffer = 1;
3124
3125 zconf_init_buffer(b,file );
3126
3127 return b;
3128}
3129
3130/** Destroy the buffer.
3131 * @param b a buffer created with zconf_create_buffer()
3132 *
3133 */
3134 void zconf_delete_buffer (YY_BUFFER_STATE b )
3135{
3136
3137 if ( ! b )
3138 return;
3139
3140 if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
3141 YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
3142
3143 if ( b->yy_is_our_buffer )
3144 zconffree((void *) b->yy_ch_buf );
3145
3146 zconffree((void *) b );
3147}
3148
3149/* Initializes or reinitializes a buffer.
3150 * This function is sometimes called more than once on the same buffer,
3151 * such as during a zconfrestart() or at EOF.
3152 */
3153 static void zconf_init_buffer (YY_BUFFER_STATE b, FILE * file )
3154
3155{
3156 int oerrno = errno;
3157
3158 zconf_flush_buffer(b );
3159
3160 b->yy_input_file = file;
3161 b->yy_fill_buffer = 1;
3162
3163 /* If b is the current buffer, then zconf_init_buffer was _probably_
3164 * called from zconfrestart() or through yy_get_next_buffer.
3165 * In that case, we don't want to reset the lineno or column.
3166 */
3167 if (b != YY_CURRENT_BUFFER){
3168 b->yy_bs_lineno = 1;
3169 b->yy_bs_column = 0;
3170 }
3171
3172 b->yy_is_interactive = 0;
3173
3174 errno = oerrno;
3175}
3176
3177/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
3178 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
3179 *
3180 */
3181 void zconf_flush_buffer (YY_BUFFER_STATE b )
3182{
3183 if ( ! b )
3184 return;
3185
3186 b->yy_n_chars = 0;
3187
3188 /* We always need two end-of-buffer characters. The first causes
3189 * a transition to the end-of-buffer state. The second causes
3190 * a jam in that state.
3191 */
3192 b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
3193 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
3194
3195 b->yy_buf_pos = &b->yy_ch_buf[0];
3196
3197 b->yy_at_bol = 1;
3198 b->yy_buffer_status = YY_BUFFER_NEW;
3199
3200 if ( b == YY_CURRENT_BUFFER )
3201 zconf_load_buffer_state( );
3202}
3203
3204/** Pushes the new state onto the stack. The new state becomes
3205 * the current state. This function will allocate the stack
3206 * if necessary.
3207 * @param new_buffer The new state.
3208 *
3209 */
3210void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
3211{
3212 if (new_buffer == NULL)
3213 return;
3214
3215 zconfensure_buffer_stack();
3216
3217 /* This block is copied from zconf_switch_to_buffer. */
3218 if ( YY_CURRENT_BUFFER )
3219 {
3220 /* Flush out information for old buffer. */
3221 *(yy_c_buf_p) = (yy_hold_char);
3222 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
3223 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
3224 }
3225
3226 /* Only push if top exists. Otherwise, replace top. */
3227 if (YY_CURRENT_BUFFER)
3228 (yy_buffer_stack_top)++;
3229 YY_CURRENT_BUFFER_LVALUE = new_buffer;
3230
3231 /* copied from zconf_switch_to_buffer. */
3232 zconf_load_buffer_state( );
3233 (yy_did_buffer_switch_on_eof) = 1;
3234}
3235
3236/** Removes and deletes the top of the stack, if present.
3237 * The next element becomes the new top.
3238 *
3239 */
3240void zconfpop_buffer_state (void)
3241{
3242 if (!YY_CURRENT_BUFFER)
3243 return;
3244
3245 zconf_delete_buffer(YY_CURRENT_BUFFER );
3246 YY_CURRENT_BUFFER_LVALUE = NULL;
3247 if ((yy_buffer_stack_top) > 0)
3248 --(yy_buffer_stack_top);
3249
3250 if (YY_CURRENT_BUFFER) {
3251 zconf_load_buffer_state( );
3252 (yy_did_buffer_switch_on_eof) = 1;
3253 }
3254}
3255
3256/* Allocates the stack if it does not exist.
3257 * Guarantees space for at least one push.
3258 */
3259static void zconfensure_buffer_stack (void)
3260{
3261 int num_to_alloc;
3262
3263 if (!(yy_buffer_stack)) {
3264
3265 /* First allocation is just for 2 elements, since we don't know if this
3266 * scanner will even need a stack. We use 2 instead of 1 to avoid an
3267 * immediate realloc on the next call.
3268 */
3269 num_to_alloc = 1;
3270 (yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
3271 (num_to_alloc * sizeof(struct yy_buffer_state*)
3272 );
3273
3274 memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
3275
3276 (yy_buffer_stack_max) = num_to_alloc;
3277 (yy_buffer_stack_top) = 0;
3278 return;
3279 }
3280
3281 if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
3282
3283 /* Increase the buffer to prepare for a possible push. */
3284 int grow_size = 8 /* arbitrary grow size */;
3285
3286 num_to_alloc = (yy_buffer_stack_max) + grow_size;
3287 (yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc
3288 ((yy_buffer_stack),
3289 num_to_alloc * sizeof(struct yy_buffer_state*)
3290 );
3291
3292 /* zero only the new slots.*/
3293 memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
3294 (yy_buffer_stack_max) = num_to_alloc;
3295 }
3296}
3297
3298/** Setup the input buffer state to scan directly from a user-specified character buffer.
3299 * @param base the character buffer
3300 * @param size the size in bytes of the character buffer
3301 *
3302 * @return the newly allocated buffer state object.
3303 */
3304YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
3305{
3306 YY_BUFFER_STATE b;
3307
3308 if ( size < 2 ||
3309 base[size-2] != YY_END_OF_BUFFER_CHAR ||
3310 base[size-1] != YY_END_OF_BUFFER_CHAR )
3311 /* They forgot to leave room for the EOB's. */
3312 return 0;
3313
3314 b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
3315 if ( ! b )
3316 YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" );
3317
3318 b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
3319 b->yy_buf_pos = b->yy_ch_buf = base;
3320 b->yy_is_our_buffer = 0;
3321 b->yy_input_file = 0;
3322 b->yy_n_chars = b->yy_buf_size;
3323 b->yy_is_interactive = 0;
3324 b->yy_at_bol = 1;
3325 b->yy_fill_buffer = 0;
3326 b->yy_buffer_status = YY_BUFFER_NEW;
3327
3328 zconf_switch_to_buffer(b );
3329
3330 return b;
3331}
3332
3333/** Setup the input buffer state to scan a string. The next call to zconflex() will
3334 * scan from a @e copy of @a str.
3335 * @param str a NUL-terminated string to scan
3336 *
3337 * @return the newly allocated buffer state object.
3338 * @note If you want to scan bytes that may contain NUL values, then use
3339 * zconf_scan_bytes() instead.
3340 */
3341YY_BUFFER_STATE zconf_scan_string (yyconst char * str )
3342{
3343
3344 return zconf_scan_bytes(str,strlen(str) );
3345}
3346
3347/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
3348 * scan from a @e copy of @a bytes.
3349 * @param bytes the byte buffer to scan
3350 * @param len the number of bytes in the buffer pointed to by @a bytes.
3351 *
3352 * @return the newly allocated buffer state object.
3353 */
3354YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len )
3355{
3356 YY_BUFFER_STATE b;
3357 char *buf;
3358 yy_size_t n;
3359 int i;
3360
3361 /* Get memory for full buffer, including space for trailing EOB's. */
3362 n = len + 2;
3363 buf = (char *) zconfalloc(n );
3364 if ( ! buf )
3365 YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
3366
3367 for ( i = 0; i < len; ++i )
3368 buf[i] = bytes[i];
3369
3370 buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
3371
3372 b = zconf_scan_buffer(buf,n );
3373 if ( ! b )
3374 YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" );
3375
3376 /* It's okay to grow etc. this buffer, and we should throw it
3377 * away when we're done.
3378 */
3379 b->yy_is_our_buffer = 1;
3380
3381 return b;
3382}
3383
3384#ifndef YY_EXIT_FAILURE
3385#define YY_EXIT_FAILURE 2
3386#endif
3387
3388static void yy_fatal_error (yyconst char* msg )
3389{
3390 (void) fprintf( stderr, "%s\n", msg );
3391 exit( YY_EXIT_FAILURE );
3392}
3393
3394/* Redefine yyless() so it works in section 3 code. */
3395
3396#undef yyless
3397#define yyless(n) \
3398 do \
3399 { \
3400 /* Undo effects of setting up zconftext. */ \
3401 int yyless_macro_arg = (n); \
3402 YY_LESS_LINENO(yyless_macro_arg);\
3403 zconftext[zconfleng] = (yy_hold_char); \
3404 (yy_c_buf_p) = zconftext + yyless_macro_arg; \
3405 (yy_hold_char) = *(yy_c_buf_p); \
3406 *(yy_c_buf_p) = '\0'; \
3407 zconfleng = yyless_macro_arg; \
3408 } \
3409 while ( 0 )
3410
3411/* Accessor methods (get/set functions) to struct members. */
3412
3413/** Get the current line number.
3414 *
3415 */
3416int zconfget_lineno (void)
3417{
3418
3419 return zconflineno;
3420}
3421
3422/** Get the input stream.
3423 *
3424 */
3425FILE *zconfget_in (void)
3426{
3427 return zconfin;
3428}
3429
3430/** Get the output stream.
3431 *
3432 */
3433FILE *zconfget_out (void)
3434{
3435 return zconfout;
3436}
3437
3438/** Get the length of the current token.
3439 *
3440 */
3441int zconfget_leng (void)
3442{
3443 return zconfleng;
3444}
3445
3446/** Get the current token.
3447 *
3448 */
3449
3450char *zconfget_text (void)
3451{
3452 return zconftext;
3453}
3454
3455/** Set the current line number.
3456 * @param line_number
3457 *
3458 */
3459void zconfset_lineno (int line_number )
3460{
3461
3462 zconflineno = line_number;
3463}
3464
3465/** Set the input stream. This does not discard the current
3466 * input buffer.
3467 * @param in_str A readable stream.
3468 *
3469 * @see zconf_switch_to_buffer
3470 */
3471void zconfset_in (FILE * in_str )
3472{
3473 zconfin = in_str ;
3474}
3475
3476void zconfset_out (FILE * out_str )
3477{
3478 zconfout = out_str ;
3479}
3480
3481int zconfget_debug (void)
3482{
3483 return zconf_flex_debug;
3484}
3485
3486void zconfset_debug (int bdebug )
3487{
3488 zconf_flex_debug = bdebug ;
3489}
3490
3491/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
3492int zconflex_destroy (void)
3493{
3494
3495 /* Pop the buffer stack, destroying each element. */
3496 while(YY_CURRENT_BUFFER){
3497 zconf_delete_buffer(YY_CURRENT_BUFFER );
3498 YY_CURRENT_BUFFER_LVALUE = NULL;
3499 zconfpop_buffer_state();
3500 }
3501
3502 /* Destroy the stack itself. */
3503 zconffree((yy_buffer_stack) );
3504 (yy_buffer_stack) = NULL;
3505
3506 return 0;
3507}
3508
3509/*
3510 * Internal utility routines.
3511 */
3512
3513#ifndef yytext_ptr
3514static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
3515{
3516 register int i;
3517 for ( i = 0; i < n; ++i )
3518 s1[i] = s2[i];
3519}
3520#endif
3521
3522#ifdef YY_NEED_STRLEN
3523static int yy_flex_strlen (yyconst char * s )
3524{
3525 register int n;
3526 for ( n = 0; s[n]; ++n )
3527 ;
3528
3529 return n;
3530}
3531#endif
3532
3533void *zconfalloc (yy_size_t size )
3534{
3535 return (void *) malloc( size );
3536}
3537
3538void *zconfrealloc (void * ptr, yy_size_t size )
3539{
3540 /* The cast to (char *) in the following accommodates both
3541 * implementations that use char* generic pointers, and those
3542 * that use void* generic pointers. It works with the latter
3543 * because both ANSI C and C++ allow castless assignment from
3544 * any pointer type to void*, and deal with argument conversions
3545 * as though doing an assignment.
3546 */
3547 return (void *) realloc( (char *) ptr, size );
3548}
3549
3550void zconffree (void * ptr )
3551{
3552 free( (char *) ptr ); /* see zconfrealloc() for (char *) cast */
3553}
3554
3555#define YYTABLES_NAME "yytables"
3556
3557#undef YY_NEW_FILE
3558#undef YY_FLUSH_BUFFER
3559#undef yy_set_bol
3560#undef yy_new_buffer
3561#undef yy_set_interactive
3562#undef yytext_ptr
3563#undef YY_DO_BEFORE_ACTION
3564
3565#ifdef YY_DECL_IS_OURS
3566#undef YY_DECL_IS_OURS
3567#undef YY_DECL
3568#endif
3569
3570void zconf_starthelp(void)
3571{
3572 new_string();
3573 last_ts = first_ts = 0;
3574 BEGIN(HELP);
3575}
3576
3577static void zconf_endhelp(void)
3578{
3579 zconflval.string = text;
3580 BEGIN(INITIAL);
3581}
3582
3583/*
3584 * Try to open specified file with following names:
3585 * ./name
3586 * $(srctree)/name
3587 * The latter is used when srctree is separate from objtree
3588 * when compiling the kernel.
3589 * Return NULL if file is not found.
3590 */
3591FILE *zconf_fopen(const char *name)
3592{
3593 char *env, fullname[PATH_MAX+1];
3594 FILE *f;
3595
3596 f = fopen(name, "r");
3597 if (!f && name[0] != '/') {
3598 env = getenv(SRCTREE);
3599 if (env) {
3600 sprintf(fullname, "%s/%s", env, name);
3601 f = fopen(fullname, "r");
3602 }
3603 }
3604 return f;
3605}
3606
3607void zconf_initscan(const char *name)
3608{
3609 zconfin = zconf_fopen(name);
3610 if (!zconfin) {
3611 printf("can't find file %s\n", name);
3612 exit(1);
3613 }
3614
3615 current_buf = malloc(sizeof(*current_buf));
3616 memset(current_buf, 0, sizeof(*current_buf));
3617
3618 current_file = file_lookup(name);
3619 current_file->lineno = 1;
3620 current_file->flags = FILE_BUSY;
3621}
3622
3623void zconf_nextfile(const char *name)
3624{
3625 struct file *file = file_lookup(name);
3626 struct buffer *buf = malloc(sizeof(*buf));
3627 memset(buf, 0, sizeof(*buf));
3628
3629 current_buf->state = YY_CURRENT_BUFFER;
3630 zconfin = zconf_fopen(name);
3631 if (!zconfin) {
3632 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
3633 exit(1);
3634 }
3635 zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
3636 buf->parent = current_buf;
3637 current_buf = buf;
3638
3639 if (file->flags & FILE_BUSY) {
3640 printf("recursive scan (%s)?\n", name);
3641 exit(1);
3642 }
3643 if (file->flags & FILE_SCANNED) {
3644 printf("file %s already scanned?\n", name);
3645 exit(1);
3646 }
3647 file->flags |= FILE_BUSY;
3648 file->lineno = 1;
3649 file->parent = current_file;
3650 current_file = file;
3651}
3652
3653static struct buffer *zconf_endfile(void)
3654{
3655 struct buffer *parent;
3656
3657 current_file->flags |= FILE_SCANNED;
3658 current_file->flags &= ~FILE_BUSY;
3659 current_file = current_file->parent;
3660
3661 parent = current_buf->parent;
3662 if (parent) {
3663 fclose(zconfin);
3664 zconf_delete_buffer(YY_CURRENT_BUFFER);
3665 zconf_switch_to_buffer(parent->state);
3666 }
3667 free(current_buf);
3668 current_buf = parent;
3669
3670 return parent;
3671}
3672
3673int zconf_lineno(void)
3674{
3675 if (current_buf)
3676 return current_file->lineno - 1;
3677 else
3678 return 0;
3679}
3680
3681char *zconf_curname(void)
3682{
3683 if (current_buf)
3684 return current_file->name;
3685 else
3686 return "<none>";
3687}
3688
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
new file mode 100644
index 000000000000..b8a67fc9d647
--- /dev/null
+++ b/scripts/kconfig/lkc.h
@@ -0,0 +1,123 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#ifndef LKC_H
7#define LKC_H
8
9#include "expr.h"
10
11#ifdef __cplusplus
12extern "C" {
13#endif
14
15#ifdef LKC_DIRECT_LINK
16#define P(name,type,arg) extern type name arg
17#else
18#include "lkc_defs.h"
19#define P(name,type,arg) extern type (*name ## _p) arg
20#endif
21#include "lkc_proto.h"
22#undef P
23
24#define SRCTREE "srctree"
25
26int zconfparse(void);
27void zconfdump(FILE *out);
28
29extern int zconfdebug;
30void zconf_starthelp(void);
31FILE *zconf_fopen(const char *name);
32void zconf_initscan(const char *name);
33void zconf_nextfile(const char *name);
34int zconf_lineno(void);
35char *zconf_curname(void);
36
37/* confdata.c */
38extern const char conf_def_filename[];
39extern char conf_filename[];
40
41char *conf_get_default_confname(void);
42
43/* kconfig_load.c */
44void kconfig_load(void);
45
46/* menu.c */
47void menu_init(void);
48void menu_add_menu(void);
49void menu_end_menu(void);
50void menu_add_entry(struct symbol *sym);
51void menu_end_entry(void);
52void menu_add_dep(struct expr *dep);
53struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
54void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
55void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
56void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
57void menu_finalize(struct menu *parent);
58void menu_set_type(int type);
59
60/* util.c */
61struct file *file_lookup(const char *name);
62int file_write_dep(const char *name);
63
64struct gstr {
65 size_t len;
66 char *s;
67};
68struct gstr str_new(void);
69struct gstr str_assign(const char *s);
70void str_free(struct gstr *gs);
71void str_append(struct gstr *gs, const char *s);
72void str_printf(struct gstr *gs, const char *fmt, ...);
73const char *str_get(struct gstr *gs);
74
75/* symbol.c */
76void sym_init(void);
77void sym_clear_all_valid(void);
78void sym_set_changed(struct symbol *sym);
79struct symbol *sym_check_deps(struct symbol *sym);
80struct property *prop_alloc(enum prop_type type, struct symbol *sym);
81struct symbol *prop_get_symbol(struct property *prop);
82
83static inline tristate sym_get_tristate_value(struct symbol *sym)
84{
85 return sym->curr.tri;
86}
87
88
89static inline struct symbol *sym_get_choice_value(struct symbol *sym)
90{
91 return (struct symbol *)sym->curr.val;
92}
93
94static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
95{
96 return sym_set_tristate_value(chval, yes);
97}
98
99static inline bool sym_is_choice(struct symbol *sym)
100{
101 return sym->flags & SYMBOL_CHOICE ? true : false;
102}
103
104static inline bool sym_is_choice_value(struct symbol *sym)
105{
106 return sym->flags & SYMBOL_CHOICEVAL ? true : false;
107}
108
109static inline bool sym_is_optional(struct symbol *sym)
110{
111 return sym->flags & SYMBOL_OPTIONAL ? true : false;
112}
113
114static inline bool sym_has_value(struct symbol *sym)
115{
116 return sym->flags & SYMBOL_NEW ? false : true;
117}
118
119#ifdef __cplusplus
120}
121#endif
122
123#endif /* LKC_H */
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
new file mode 100644
index 000000000000..6dc6d0c48e7a
--- /dev/null
+++ b/scripts/kconfig/lkc_proto.h
@@ -0,0 +1,40 @@
1
2/* confdata.c */
3P(conf_parse,void,(const char *name));
4P(conf_read,int,(const char *name));
5P(conf_write,int,(const char *name));
6
7/* menu.c */
8P(rootmenu,struct menu,);
9
10P(menu_is_visible,bool,(struct menu *menu));
11P(menu_get_prompt,const char *,(struct menu *menu));
12P(menu_get_root_menu,struct menu *,(struct menu *menu));
13P(menu_get_parent_menu,struct menu *,(struct menu *menu));
14
15/* symbol.c */
16P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
17P(sym_change_count,int,);
18
19P(sym_lookup,struct symbol *,(const char *name, int isconst));
20P(sym_find,struct symbol *,(const char *name));
21P(sym_re_search,struct symbol **,(const char *pattern));
22P(sym_type_name,const char *,(enum symbol_type type));
23P(sym_calc_value,void,(struct symbol *sym));
24P(sym_get_type,enum symbol_type,(struct symbol *sym));
25P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
26P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
27P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
28P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
29P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
30P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
31P(sym_is_changable,bool,(struct symbol *sym));
32P(sym_get_choice_prop,struct property *,(struct symbol *sym));
33P(sym_get_default_prop,struct property *,(struct symbol *sym));
34P(sym_get_string_value,const char *,(struct symbol *sym));
35
36P(prop_get_type_name,const char *,(enum prop_type type));
37
38/* expr.c */
39P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
40P(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
new file mode 100644
index 000000000000..730d316fe7fe
--- /dev/null
+++ b/scripts/kconfig/mconf.c
@@ -0,0 +1,1090 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Introduced single menu mode (show all sub-menus in one large tree).
6 * 2002-11-06 Petr Baudis <pasky@ucw.cz>
7 */
8
9#include <sys/ioctl.h>
10#include <sys/wait.h>
11#include <ctype.h>
12#include <errno.h>
13#include <fcntl.h>
14#include <limits.h>
15#include <signal.h>
16#include <stdarg.h>
17#include <stdlib.h>
18#include <string.h>
19#include <termios.h>
20#include <unistd.h>
21
22#define LKC_DIRECT_LINK
23#include "lkc.h"
24
25static char menu_backtitle[128];
26static const char mconf_readme[] =
27"Overview\n"
28"--------\n"
29"Some kernel features may be built directly into the kernel.\n"
30"Some may be made into loadable runtime modules. Some features\n"
31"may be completely removed altogether. There are also certain\n"
32"kernel parameters which are not really features, but must be\n"
33"entered in as decimal or hexadecimal numbers or possibly text.\n"
34"\n"
35"Menu items beginning with [*], <M> or [ ] represent features\n"
36"configured to be built in, modularized or removed respectively.\n"
37"Pointed brackets <> represent module capable features.\n"
38"\n"
39"To change any of these features, highlight it with the cursor\n"
40"keys and press <Y> to build it in, <M> to make it a module or\n"
41"<N> to removed it. You may also press the <Space Bar> to cycle\n"
42"through the available options (ie. Y->N->M->Y).\n"
43"\n"
44"Some additional keyboard hints:\n"
45"\n"
46"Menus\n"
47"----------\n"
48"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
49" you wish to change or submenu wish to select and press <Enter>.\n"
50" Submenus are designated by \"--->\".\n"
51"\n"
52" Shortcut: Press the option's highlighted letter (hotkey).\n"
53" Pressing a hotkey more than once will sequence\n"
54" through all visible items which use that hotkey.\n"
55"\n"
56" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
57" unseen options into view.\n"
58"\n"
59"o To exit a menu use the cursor keys to highlight the <Exit> button\n"
60" and press <ENTER>.\n"
61"\n"
62" Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
63" using those letters. You may press a single <ESC>, but\n"
64" there is a delayed response which you may find annoying.\n"
65"\n"
66" Also, the <TAB> and cursor keys will cycle between <Select>,\n"
67" <Exit> and <Help>\n"
68"\n"
69"o To get help with an item, use the cursor keys to highlight <Help>\n"
70" and Press <ENTER>.\n"
71"\n"
72" Shortcut: Press <H> or <?>.\n"
73"\n"
74"\n"
75"Radiolists (Choice lists)\n"
76"-----------\n"
77"o Use the cursor keys to select the option you wish to set and press\n"
78" <S> or the <SPACE BAR>.\n"
79"\n"
80" Shortcut: Press the first letter of the option you wish to set then\n"
81" press <S> or <SPACE BAR>.\n"
82"\n"
83"o To see available help for the item, use the cursor keys to highlight\n"
84" <Help> and Press <ENTER>.\n"
85"\n"
86" Shortcut: Press <H> or <?>.\n"
87"\n"
88" Also, the <TAB> and cursor keys will cycle between <Select> and\n"
89" <Help>\n"
90"\n"
91"\n"
92"Data Entry\n"
93"-----------\n"
94"o Enter the requested information and press <ENTER>\n"
95" If you are entering hexadecimal values, it is not necessary to\n"
96" add the '0x' prefix to the entry.\n"
97"\n"
98"o For help, use the <TAB> or cursor keys to highlight the help option\n"
99" and press <ENTER>. You can try <TAB><H> as well.\n"
100"\n"
101"\n"
102"Text Box (Help Window)\n"
103"--------\n"
104"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
105" keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
106" who are familiar with less and lynx.\n"
107"\n"
108"o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
109"\n"
110"\n"
111"Alternate Configuration Files\n"
112"-----------------------------\n"
113"Menuconfig supports the use of alternate configuration files for\n"
114"those who, for various reasons, find it necessary to switch\n"
115"between different kernel configurations.\n"
116"\n"
117"At the end of the main menu you will find two options. One is\n"
118"for saving the current configuration to a file of your choosing.\n"
119"The other option is for loading a previously saved alternate\n"
120"configuration.\n"
121"\n"
122"Even if you don't use alternate configuration files, but you\n"
123"find during a Menuconfig session that you have completely messed\n"
124"up your settings, you may use the \"Load Alternate...\" option to\n"
125"restore your previously saved settings from \".config\" without\n"
126"restarting Menuconfig.\n"
127"\n"
128"Other information\n"
129"-----------------\n"
130"If you use Menuconfig in an XTERM window make sure you have your\n"
131"$TERM variable set to point to a xterm definition which supports color.\n"
132"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n"
133"display correctly in a RXVT window because rxvt displays only one\n"
134"intensity of color, bright.\n"
135"\n"
136"Menuconfig will display larger menus on screens or xterms which are\n"
137"set to display more than the standard 25 row by 80 column geometry.\n"
138"In order for this to work, the \"stty size\" command must be able to\n"
139"display the screen's current row and column geometry. I STRONGLY\n"
140"RECOMMEND that you make sure you do NOT have the shell variables\n"
141"LINES and COLUMNS exported into your environment. Some distributions\n"
142"export those variables via /etc/profile. Some ncurses programs can\n"
143"become confused when those variables (LINES & COLUMNS) don't reflect\n"
144"the true screen size.\n"
145"\n"
146"Optional personality available\n"
147"------------------------------\n"
148"If you prefer to have all of the kernel options listed in a single\n"
149"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
150"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
151"\n"
152"make MENUCONFIG_MODE=single_menu menuconfig\n"
153"\n"
154"<Enter> will then unroll the appropriate category, or enfold it if it\n"
155"is already unrolled.\n"
156"\n"
157"Note that this mode can eventually be a little more CPU expensive\n"
158"(especially with a larger number of unrolled categories) than the\n"
159"default mode.\n",
160menu_instructions[] =
161 "Arrow keys navigate the menu. "
162 "<Enter> selects submenus --->. "
163 "Highlighted letters are hotkeys. "
164 "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
165 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
166 "Legend: [*] built-in [ ] excluded <M> module < > module capable",
167radiolist_instructions[] =
168 "Use the arrow keys to navigate this window or "
169 "press the hotkey of the item you wish to select "
170 "followed by the <SPACE BAR>. "
171 "Press <?> for additional information about this option.",
172inputbox_instructions_int[] =
173 "Please enter a decimal value. "
174 "Fractions will not be accepted. "
175 "Use the <TAB> key to move from the input field to the buttons below it.",
176inputbox_instructions_hex[] =
177 "Please enter a hexadecimal value. "
178 "Use the <TAB> key to move from the input field to the buttons below it.",
179inputbox_instructions_string[] =
180 "Please enter a string value. "
181 "Use the <TAB> key to move from the input field to the buttons below it.",
182setmod_text[] =
183 "This feature depends on another which has been configured as a module.\n"
184 "As a result, this feature will be built as a module.",
185nohelp_text[] =
186 "There is no help available for this kernel option.\n",
187load_config_text[] =
188 "Enter the name of the configuration file you wish to load. "
189 "Accept the name shown to restore the configuration you "
190 "last retrieved. Leave blank to abort.",
191load_config_help[] =
192 "\n"
193 "For various reasons, one may wish to keep several different kernel\n"
194 "configurations available on a single machine.\n"
195 "\n"
196 "If you have saved a previous configuration in a file other than the\n"
197 "kernel's default, entering the name of the file here will allow you\n"
198 "to modify that configuration.\n"
199 "\n"
200 "If you are uncertain, then you have probably never used alternate\n"
201 "configuration files. You should therefor leave this blank to abort.\n",
202save_config_text[] =
203 "Enter a filename to which this configuration should be saved "
204 "as an alternate. Leave blank to abort.",
205save_config_help[] =
206 "\n"
207 "For various reasons, one may wish to keep different kernel\n"
208 "configurations available on a single machine.\n"
209 "\n"
210 "Entering a file name here will allow you to later retrieve, modify\n"
211 "and use the current configuration as an alternate to whatever\n"
212 "configuration options you have selected at that time.\n"
213 "\n"
214 "If you are uncertain what all this means then you should probably\n"
215 "leave this blank.\n",
216search_help[] =
217 "\n"
218 "Search for CONFIG_ symbols and display their relations.\n"
219 "Example: search for \"^FOO\"\n"
220 "Result:\n"
221 "-----------------------------------------------------------------\n"
222 "Symbol: FOO [=m]\n"
223 "Prompt: Foo bus is used to drive the bar HW\n"
224 "Defined at drivers/pci/Kconfig:47\n"
225 "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
226 "Location:\n"
227 " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
228 " -> PCI support (PCI [=y])\n"
229 " -> PCI access mode (<choice> [=y])\n"
230 "Selects: LIBCRC32\n"
231 "Selected by: BAR\n"
232 "-----------------------------------------------------------------\n"
233 "o The line 'Prompt:' shows the text used in the menu structure for\n"
234 " this CONFIG_ symbol\n"
235 "o The 'Defined at' line tell at what file / line number the symbol\n"
236 " is defined\n"
237 "o The 'Depends on:' line tell what symbols needs to be defined for\n"
238 " this symbol to be visible in the menu (selectable)\n"
239 "o The 'Location:' lines tell where in the menu structure this symbol\n"
240 " is located\n"
241 " A location followed by a [=y] indicate that this is a selectable\n"
242 " menu item - and current value is displayed inside brackets.\n"
243 "o The 'Selects:' line tell what symbol will be automatically\n"
244 " selected if this symbol is selected (y or m)\n"
245 "o The 'Selected by' line tell what symbol has selected this symbol\n"
246 "\n"
247 "Only relevant lines are shown.\n"
248 "\n\n"
249 "Search examples:\n"
250 "Examples: USB => find all CONFIG_ symbols containing USB\n"
251 " ^USB => find all CONFIG_ symbols starting with USB\n"
252 " USB$ => find all CONFIG_ symbols ending with USB\n"
253 "\n";
254
255static signed char buf[4096], *bufptr = buf;
256static signed char input_buf[4096];
257static char filename[PATH_MAX+1] = ".config";
258static char *args[1024], **argptr = args;
259static int indent;
260static struct termios ios_org;
261static int rows = 0, cols = 0;
262static struct menu *current_menu;
263static int child_count;
264static int do_resize;
265static int single_menu_mode;
266
267static void conf(struct menu *menu);
268static void conf_choice(struct menu *menu);
269static void conf_string(struct menu *menu);
270static void conf_load(void);
271static void conf_save(void);
272static void show_textbox(const char *title, const char *text, int r, int c);
273static void show_helptext(const char *title, const char *text);
274static void show_help(struct menu *menu);
275static void show_file(const char *filename, const char *title, int r, int c);
276
277static void cprint_init(void);
278static int cprint1(const char *fmt, ...);
279static void cprint_done(void);
280static int cprint(const char *fmt, ...);
281
282static void init_wsize(void)
283{
284 struct winsize ws;
285 char *env;
286
287 if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
288 rows = ws.ws_row;
289 cols = ws.ws_col;
290 }
291
292 if (!rows) {
293 env = getenv("LINES");
294 if (env)
295 rows = atoi(env);
296 if (!rows)
297 rows = 24;
298 }
299 if (!cols) {
300 env = getenv("COLUMNS");
301 if (env)
302 cols = atoi(env);
303 if (!cols)
304 cols = 80;
305 }
306
307 if (rows < 19 || cols < 80) {
308 fprintf(stderr, "Your display is too small to run Menuconfig!\n");
309 fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
310 exit(1);
311 }
312
313 rows -= 4;
314 cols -= 5;
315}
316
317static void cprint_init(void)
318{
319 bufptr = buf;
320 argptr = args;
321 memset(args, 0, sizeof(args));
322 indent = 0;
323 child_count = 0;
324 cprint("./scripts/lxdialog/lxdialog");
325 cprint("--backtitle");
326 cprint(menu_backtitle);
327}
328
329static int cprint1(const char *fmt, ...)
330{
331 va_list ap;
332 int res;
333
334 if (!*argptr)
335 *argptr = bufptr;
336 va_start(ap, fmt);
337 res = vsprintf(bufptr, fmt, ap);
338 va_end(ap);
339 bufptr += res;
340
341 return res;
342}
343
344static void cprint_done(void)
345{
346 *bufptr++ = 0;
347 argptr++;
348}
349
350static int cprint(const char *fmt, ...)
351{
352 va_list ap;
353 int res;
354
355 *argptr++ = bufptr;
356 va_start(ap, fmt);
357 res = vsprintf(bufptr, fmt, ap);
358 va_end(ap);
359 bufptr += res;
360 *bufptr++ = 0;
361
362 return res;
363}
364
365static void get_prompt_str(struct gstr *r, struct property *prop)
366{
367 int i, j;
368 struct menu *submenu[8], *menu;
369
370 str_printf(r, "Prompt: %s\n", prop->text);
371 str_printf(r, " Defined at %s:%d\n", prop->menu->file->name,
372 prop->menu->lineno);
373 if (!expr_is_yes(prop->visible.expr)) {
374 str_append(r, " Depends on: ");
375 expr_gstr_print(prop->visible.expr, r);
376 str_append(r, "\n");
377 }
378 menu = prop->menu->parent;
379 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
380 submenu[i++] = menu;
381 if (i > 0) {
382 str_printf(r, " Location:\n");
383 for (j = 4; --i >= 0; j += 2) {
384 menu = submenu[i];
385 str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
386 if (menu->sym) {
387 str_printf(r, " (%s [=%s])", menu->sym->name ?
388 menu->sym->name : "<choice>",
389 sym_get_string_value(menu->sym));
390 }
391 str_append(r, "\n");
392 }
393 }
394}
395
396static void get_symbol_str(struct gstr *r, struct symbol *sym)
397{
398 bool hit;
399 struct property *prop;
400
401 str_printf(r, "Symbol: %s [=%s]\n", sym->name,
402 sym_get_string_value(sym));
403 for_all_prompts(sym, prop)
404 get_prompt_str(r, prop);
405 hit = false;
406 for_all_properties(sym, prop, P_SELECT) {
407 if (!hit) {
408 str_append(r, " Selects: ");
409 hit = true;
410 } else
411 str_printf(r, " && ");
412 expr_gstr_print(prop->expr, r);
413 }
414 if (hit)
415 str_append(r, "\n");
416 if (sym->rev_dep.expr) {
417 str_append(r, " Selected by: ");
418 expr_gstr_print(sym->rev_dep.expr, r);
419 str_append(r, "\n");
420 }
421 str_append(r, "\n\n");
422}
423
424static struct gstr get_relations_str(struct symbol **sym_arr)
425{
426 struct symbol *sym;
427 struct gstr res = str_new();
428 int i;
429
430 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
431 get_symbol_str(&res, sym);
432 if (!i)
433 str_append(&res, "No matches found.\n");
434 return res;
435}
436
437pid_t pid;
438
439static void winch_handler(int sig)
440{
441 if (!do_resize) {
442 kill(pid, SIGINT);
443 do_resize = 1;
444 }
445}
446
447static int exec_conf(void)
448{
449 int pipefd[2], stat, size;
450 struct sigaction sa;
451 sigset_t sset, osset;
452
453 sigemptyset(&sset);
454 sigaddset(&sset, SIGINT);
455 sigprocmask(SIG_BLOCK, &sset, &osset);
456
457 signal(SIGINT, SIG_DFL);
458
459 sa.sa_handler = winch_handler;
460 sigemptyset(&sa.sa_mask);
461 sa.sa_flags = SA_RESTART;
462 sigaction(SIGWINCH, &sa, NULL);
463
464 *argptr++ = NULL;
465
466 pipe(pipefd);
467 pid = fork();
468 if (pid == 0) {
469 sigprocmask(SIG_SETMASK, &osset, NULL);
470 dup2(pipefd[1], 2);
471 close(pipefd[0]);
472 close(pipefd[1]);
473 execv(args[0], args);
474 _exit(EXIT_FAILURE);
475 }
476
477 close(pipefd[1]);
478 bufptr = input_buf;
479 while (1) {
480 size = input_buf + sizeof(input_buf) - bufptr;
481 size = read(pipefd[0], bufptr, size);
482 if (size <= 0) {
483 if (size < 0) {
484 if (errno == EINTR || errno == EAGAIN)
485 continue;
486 perror("read");
487 }
488 break;
489 }
490 bufptr += size;
491 }
492 *bufptr++ = 0;
493 close(pipefd[0]);
494 waitpid(pid, &stat, 0);
495
496 if (do_resize) {
497 init_wsize();
498 do_resize = 0;
499 sigprocmask(SIG_SETMASK, &osset, NULL);
500 return -1;
501 }
502 if (WIFSIGNALED(stat)) {
503 printf("\finterrupted(%d)\n", WTERMSIG(stat));
504 exit(1);
505 }
506#if 0
507 printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf);
508 sleep(1);
509#endif
510 sigpending(&sset);
511 if (sigismember(&sset, SIGINT)) {
512 printf("\finterrupted\n");
513 exit(1);
514 }
515 sigprocmask(SIG_SETMASK, &osset, NULL);
516
517 return WEXITSTATUS(stat);
518}
519
520static void search_conf(void)
521{
522 struct symbol **sym_arr;
523 int stat;
524 struct gstr res;
525
526again:
527 cprint_init();
528 cprint("--title");
529 cprint("Search Configuration Parameter");
530 cprint("--inputbox");
531 cprint("Enter Keyword");
532 cprint("10");
533 cprint("75");
534 cprint("");
535 stat = exec_conf();
536 if (stat < 0)
537 goto again;
538 switch (stat) {
539 case 0:
540 break;
541 case 1:
542 show_helptext("Search Configuration", search_help);
543 goto again;
544 default:
545 return;
546 }
547
548 sym_arr = sym_re_search(input_buf);
549 res = get_relations_str(sym_arr);
550 free(sym_arr);
551 show_textbox("Search Results", str_get(&res), 0, 0);
552 str_free(&res);
553}
554
555static void build_conf(struct menu *menu)
556{
557 struct symbol *sym;
558 struct property *prop;
559 struct menu *child;
560 int type, tmp, doint = 2;
561 tristate val;
562 char ch;
563
564 if (!menu_is_visible(menu))
565 return;
566
567 sym = menu->sym;
568 prop = menu->prompt;
569 if (!sym) {
570 if (prop && menu != current_menu) {
571 const char *prompt = menu_get_prompt(menu);
572 switch (prop->type) {
573 case P_MENU:
574 child_count++;
575 cprint("m%p", menu);
576
577 if (single_menu_mode) {
578 cprint1("%s%*c%s",
579 menu->data ? "-->" : "++>",
580 indent + 1, ' ', prompt);
581 } else
582 cprint1(" %*c%s --->", indent + 1, ' ', prompt);
583
584 cprint_done();
585 if (single_menu_mode && menu->data)
586 goto conf_childs;
587 return;
588 default:
589 if (prompt) {
590 child_count++;
591 cprint(":%p", menu);
592 cprint("---%*c%s", indent + 1, ' ', prompt);
593 }
594 }
595 } else
596 doint = 0;
597 goto conf_childs;
598 }
599
600 type = sym_get_type(sym);
601 if (sym_is_choice(sym)) {
602 struct symbol *def_sym = sym_get_choice_value(sym);
603 struct menu *def_menu = NULL;
604
605 child_count++;
606 for (child = menu->list; child; child = child->next) {
607 if (menu_is_visible(child) && child->sym == def_sym)
608 def_menu = child;
609 }
610
611 val = sym_get_tristate_value(sym);
612 if (sym_is_changable(sym)) {
613 cprint("t%p", menu);
614 switch (type) {
615 case S_BOOLEAN:
616 cprint1("[%c]", val == no ? ' ' : '*');
617 break;
618 case S_TRISTATE:
619 switch (val) {
620 case yes: ch = '*'; break;
621 case mod: ch = 'M'; break;
622 default: ch = ' '; break;
623 }
624 cprint1("<%c>", ch);
625 break;
626 }
627 } else {
628 cprint("%c%p", def_menu ? 't' : ':', menu);
629 cprint1(" ");
630 }
631
632 cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
633 if (val == yes) {
634 if (def_menu) {
635 cprint1(" (%s)", menu_get_prompt(def_menu));
636 cprint1(" --->");
637 cprint_done();
638 if (def_menu->list) {
639 indent += 2;
640 build_conf(def_menu);
641 indent -= 2;
642 }
643 } else
644 cprint_done();
645 return;
646 }
647 cprint_done();
648 } else {
649 if (menu == current_menu) {
650 cprint(":%p", menu);
651 cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
652 goto conf_childs;
653 }
654 child_count++;
655 val = sym_get_tristate_value(sym);
656 if (sym_is_choice_value(sym) && val == yes) {
657 cprint(":%p", menu);
658 cprint1(" ");
659 } else {
660 switch (type) {
661 case S_BOOLEAN:
662 cprint("t%p", menu);
663 if (sym_is_changable(sym))
664 cprint1("[%c]", val == no ? ' ' : '*');
665 else
666 cprint1("---");
667 break;
668 case S_TRISTATE:
669 cprint("t%p", menu);
670 switch (val) {
671 case yes: ch = '*'; break;
672 case mod: ch = 'M'; break;
673 default: ch = ' '; break;
674 }
675 if (sym_is_changable(sym))
676 cprint1("<%c>", ch);
677 else
678 cprint1("---");
679 break;
680 default:
681 cprint("s%p", menu);
682 tmp = cprint1("(%s)", sym_get_string_value(sym));
683 tmp = indent - tmp + 4;
684 if (tmp < 0)
685 tmp = 0;
686 cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
687 (sym_has_value(sym) || !sym_is_changable(sym)) ?
688 "" : " (NEW)");
689 cprint_done();
690 goto conf_childs;
691 }
692 }
693 cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
694 (sym_has_value(sym) || !sym_is_changable(sym)) ?
695 "" : " (NEW)");
696 if (menu->prompt->type == P_MENU) {
697 cprint1(" --->");
698 cprint_done();
699 return;
700 }
701 cprint_done();
702 }
703
704conf_childs:
705 indent += doint;
706 for (child = menu->list; child; child = child->next)
707 build_conf(child);
708 indent -= doint;
709}
710
711static void conf(struct menu *menu)
712{
713 struct menu *submenu;
714 const char *prompt = menu_get_prompt(menu);
715 struct symbol *sym;
716 char active_entry[40];
717 int stat, type, i;
718
719 unlink("lxdialog.scrltmp");
720 active_entry[0] = 0;
721 while (1) {
722 cprint_init();
723 cprint("--title");
724 cprint("%s", prompt ? prompt : "Main Menu");
725 cprint("--menu");
726 cprint(menu_instructions);
727 cprint("%d", rows);
728 cprint("%d", cols);
729 cprint("%d", rows - 10);
730 cprint("%s", active_entry);
731 current_menu = menu;
732 build_conf(menu);
733 if (!child_count)
734 break;
735 if (menu == &rootmenu) {
736 cprint(":");
737 cprint("--- ");
738 cprint("L");
739 cprint(" Load an Alternate Configuration File");
740 cprint("S");
741 cprint(" Save Configuration to an Alternate File");
742 }
743 stat = exec_conf();
744 if (stat < 0)
745 continue;
746
747 if (stat == 1 || stat == 255)
748 break;
749
750 type = input_buf[0];
751 if (!type)
752 continue;
753
754 for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++)
755 ;
756 if (i >= sizeof(active_entry))
757 i = sizeof(active_entry) - 1;
758 input_buf[i] = 0;
759 strcpy(active_entry, input_buf);
760
761 sym = NULL;
762 submenu = NULL;
763 if (sscanf(input_buf + 1, "%p", &submenu) == 1)
764 sym = submenu->sym;
765
766 switch (stat) {
767 case 0:
768 switch (type) {
769 case 'm':
770 if (single_menu_mode)
771 submenu->data = (void *) (long) !submenu->data;
772 else
773 conf(submenu);
774 break;
775 case 't':
776 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
777 conf_choice(submenu);
778 else if (submenu->prompt->type == P_MENU)
779 conf(submenu);
780 break;
781 case 's':
782 conf_string(submenu);
783 break;
784 case 'L':
785 conf_load();
786 break;
787 case 'S':
788 conf_save();
789 break;
790 }
791 break;
792 case 2:
793 if (sym)
794 show_help(submenu);
795 else
796 show_helptext("README", mconf_readme);
797 break;
798 case 3:
799 if (type == 't') {
800 if (sym_set_tristate_value(sym, yes))
801 break;
802 if (sym_set_tristate_value(sym, mod))
803 show_textbox(NULL, setmod_text, 6, 74);
804 }
805 break;
806 case 4:
807 if (type == 't')
808 sym_set_tristate_value(sym, no);
809 break;
810 case 5:
811 if (type == 't')
812 sym_set_tristate_value(sym, mod);
813 break;
814 case 6:
815 if (type == 't')
816 sym_toggle_tristate_value(sym);
817 else if (type == 'm')
818 conf(submenu);
819 break;
820 case 7:
821 search_conf();
822 break;
823 }
824 }
825}
826
827static void show_textbox(const char *title, const char *text, int r, int c)
828{
829 int fd;
830
831 fd = creat(".help.tmp", 0777);
832 write(fd, text, strlen(text));
833 close(fd);
834 show_file(".help.tmp", title, r, c);
835 unlink(".help.tmp");
836}
837
838static void show_helptext(const char *title, const char *text)
839{
840 show_textbox(title, text, 0, 0);
841}
842
843static void show_help(struct menu *menu)
844{
845 struct gstr help = str_new();
846 struct symbol *sym = menu->sym;
847
848 if (sym->help)
849 {
850 if (sym->name) {
851 str_printf(&help, "CONFIG_%s:\n\n", sym->name);
852 str_append(&help, sym->help);
853 str_append(&help, "\n");
854 }
855 } else {
856 str_append(&help, nohelp_text);
857 }
858 get_symbol_str(&help, sym);
859 show_helptext(menu_get_prompt(menu), str_get(&help));
860 str_free(&help);
861}
862
863static void show_file(const char *filename, const char *title, int r, int c)
864{
865 do {
866 cprint_init();
867 if (title) {
868 cprint("--title");
869 cprint("%s", title);
870 }
871 cprint("--textbox");
872 cprint("%s", filename);
873 cprint("%d", r ? r : rows);
874 cprint("%d", c ? c : cols);
875 } while (exec_conf() < 0);
876}
877
878static void conf_choice(struct menu *menu)
879{
880 const char *prompt = menu_get_prompt(menu);
881 struct menu *child;
882 struct symbol *active;
883 int stat;
884
885 active = sym_get_choice_value(menu->sym);
886 while (1) {
887 cprint_init();
888 cprint("--title");
889 cprint("%s", prompt ? prompt : "Main Menu");
890 cprint("--radiolist");
891 cprint(radiolist_instructions);
892 cprint("15");
893 cprint("70");
894 cprint("6");
895
896 current_menu = menu;
897 for (child = menu->list; child; child = child->next) {
898 if (!menu_is_visible(child))
899 continue;
900 cprint("%p", child);
901 cprint("%s", menu_get_prompt(child));
902 if (child->sym == sym_get_choice_value(menu->sym))
903 cprint("ON");
904 else if (child->sym == active)
905 cprint("SELECTED");
906 else
907 cprint("OFF");
908 }
909
910 stat = exec_conf();
911 switch (stat) {
912 case 0:
913 if (sscanf(input_buf, "%p", &child) != 1)
914 break;
915 sym_set_tristate_value(child->sym, yes);
916 return;
917 case 1:
918 if (sscanf(input_buf, "%p", &child) == 1) {
919 show_help(child);
920 active = child->sym;
921 } else
922 show_help(menu);
923 break;
924 case 255:
925 return;
926 }
927 }
928}
929
930static void conf_string(struct menu *menu)
931{
932 const char *prompt = menu_get_prompt(menu);
933 int stat;
934
935 while (1) {
936 cprint_init();
937 cprint("--title");
938 cprint("%s", prompt ? prompt : "Main Menu");
939 cprint("--inputbox");
940 switch (sym_get_type(menu->sym)) {
941 case S_INT:
942 cprint(inputbox_instructions_int);
943 break;
944 case S_HEX:
945 cprint(inputbox_instructions_hex);
946 break;
947 case S_STRING:
948 cprint(inputbox_instructions_string);
949 break;
950 default:
951 /* panic? */;
952 }
953 cprint("10");
954 cprint("75");
955 cprint("%s", sym_get_string_value(menu->sym));
956 stat = exec_conf();
957 switch (stat) {
958 case 0:
959 if (sym_set_string_value(menu->sym, input_buf))
960 return;
961 show_textbox(NULL, "You have made an invalid entry.", 5, 43);
962 break;
963 case 1:
964 show_help(menu);
965 break;
966 case 255:
967 return;
968 }
969 }
970}
971
972static void conf_load(void)
973{
974 int stat;
975
976 while (1) {
977 cprint_init();
978 cprint("--inputbox");
979 cprint(load_config_text);
980 cprint("11");
981 cprint("55");
982 cprint("%s", filename);
983 stat = exec_conf();
984 switch(stat) {
985 case 0:
986 if (!input_buf[0])
987 return;
988 if (!conf_read(input_buf))
989 return;
990 show_textbox(NULL, "File does not exist!", 5, 38);
991 break;
992 case 1:
993 show_helptext("Load Alternate Configuration", load_config_help);
994 break;
995 case 255:
996 return;
997 }
998 }
999}
1000
1001static void conf_save(void)
1002{
1003 int stat;
1004
1005 while (1) {
1006 cprint_init();
1007 cprint("--inputbox");
1008 cprint(save_config_text);
1009 cprint("11");
1010 cprint("55");
1011 cprint("%s", filename);
1012 stat = exec_conf();
1013 switch(stat) {
1014 case 0:
1015 if (!input_buf[0])
1016 return;
1017 if (!conf_write(input_buf))
1018 return;
1019 show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
1020 break;
1021 case 1:
1022 show_helptext("Save Alternate Configuration", save_config_help);
1023 break;
1024 case 255:
1025 return;
1026 }
1027 }
1028}
1029
1030static void conf_cleanup(void)
1031{
1032 tcsetattr(1, TCSAFLUSH, &ios_org);
1033 unlink(".help.tmp");
1034 unlink("lxdialog.scrltmp");
1035}
1036
1037int main(int ac, char **av)
1038{
1039 struct symbol *sym;
1040 char *mode;
1041 int stat;
1042
1043 conf_parse(av[1]);
1044 conf_read(NULL);
1045
1046 sym = sym_lookup("KERNELRELEASE", 0);
1047 sym_calc_value(sym);
1048 sprintf(menu_backtitle, "Linux Kernel v%s Configuration",
1049 sym_get_string_value(sym));
1050
1051 mode = getenv("MENUCONFIG_MODE");
1052 if (mode) {
1053 if (!strcasecmp(mode, "single_menu"))
1054 single_menu_mode = 1;
1055 }
1056
1057 tcgetattr(1, &ios_org);
1058 atexit(conf_cleanup);
1059 init_wsize();
1060 conf(&rootmenu);
1061
1062 do {
1063 cprint_init();
1064 cprint("--yesno");
1065 cprint("Do you wish to save your new kernel configuration?");
1066 cprint("5");
1067 cprint("60");
1068 stat = exec_conf();
1069 } while (stat < 0);
1070
1071 if (stat == 0) {
1072 if (conf_write(NULL)) {
1073 fprintf(stderr, "\n\n"
1074 "Error during writing of the kernel configuration.\n"
1075 "Your kernel configuration changes were NOT saved."
1076 "\n\n");
1077 return 1;
1078 }
1079 printf("\n\n"
1080 "*** End of Linux kernel configuration.\n"
1081 "*** Execute 'make' to build the kernel or try 'make help'."
1082 "\n\n");
1083 } else {
1084 fprintf(stderr, "\n\n"
1085 "Your kernel configuration changes were NOT saved."
1086 "\n\n");
1087 }
1088
1089 return 0;
1090}
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
new file mode 100644
index 000000000000..0c13156f3344
--- /dev/null
+++ b/scripts/kconfig/menu.c
@@ -0,0 +1,390 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <stdlib.h>
7#include <string.h>
8
9#define LKC_DIRECT_LINK
10#include "lkc.h"
11
12struct menu rootmenu;
13static struct menu **last_entry_ptr;
14
15struct file *file_list;
16struct file *current_file;
17
18static void menu_warn(struct menu *menu, const char *fmt, ...)
19{
20 va_list ap;
21 va_start(ap, fmt);
22 fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
23 vfprintf(stderr, fmt, ap);
24 fprintf(stderr, "\n");
25 va_end(ap);
26}
27
28static void prop_warn(struct property *prop, const char *fmt, ...)
29{
30 va_list ap;
31 va_start(ap, fmt);
32 fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
33 vfprintf(stderr, fmt, ap);
34 fprintf(stderr, "\n");
35 va_end(ap);
36}
37
38void menu_init(void)
39{
40 current_entry = current_menu = &rootmenu;
41 last_entry_ptr = &rootmenu.list;
42}
43
44void menu_add_entry(struct symbol *sym)
45{
46 struct menu *menu;
47
48 menu = malloc(sizeof(*menu));
49 memset(menu, 0, sizeof(*menu));
50 menu->sym = sym;
51 menu->parent = current_menu;
52 menu->file = current_file;
53 menu->lineno = zconf_lineno();
54
55 *last_entry_ptr = menu;
56 last_entry_ptr = &menu->next;
57 current_entry = menu;
58}
59
60void menu_end_entry(void)
61{
62}
63
64void menu_add_menu(void)
65{
66 current_menu = current_entry;
67 last_entry_ptr = &current_entry->list;
68}
69
70void menu_end_menu(void)
71{
72 last_entry_ptr = &current_menu->next;
73 current_menu = current_menu->parent;
74}
75
76struct expr *menu_check_dep(struct expr *e)
77{
78 if (!e)
79 return e;
80
81 switch (e->type) {
82 case E_NOT:
83 e->left.expr = menu_check_dep(e->left.expr);
84 break;
85 case E_OR:
86 case E_AND:
87 e->left.expr = menu_check_dep(e->left.expr);
88 e->right.expr = menu_check_dep(e->right.expr);
89 break;
90 case E_SYMBOL:
91 /* change 'm' into 'm' && MODULES */
92 if (e->left.sym == &symbol_mod)
93 return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
94 break;
95 default:
96 break;
97 }
98 return e;
99}
100
101void menu_add_dep(struct expr *dep)
102{
103 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
104}
105
106void menu_set_type(int type)
107{
108 struct symbol *sym = current_entry->sym;
109
110 if (sym->type == type)
111 return;
112 if (sym->type == S_UNKNOWN) {
113 sym->type = type;
114 return;
115 }
116 menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n",
117 sym->name ? sym->name : "<choice>",
118 sym_type_name(sym->type), sym_type_name(type));
119}
120
121struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
122{
123 struct property *prop = prop_alloc(type, current_entry->sym);
124
125 prop->menu = current_entry;
126 prop->text = prompt;
127 prop->expr = expr;
128 prop->visible.expr = menu_check_dep(dep);
129
130 if (prompt) {
131 if (current_entry->prompt)
132 menu_warn(current_entry, "prompt redefined\n");
133 current_entry->prompt = prop;
134 }
135
136 return prop;
137}
138
139void menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
140{
141 menu_add_prop(type, prompt, NULL, dep);
142}
143
144void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
145{
146 menu_add_prop(type, NULL, expr, dep);
147}
148
149void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
150{
151 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
152}
153
154void sym_check_prop(struct symbol *sym)
155{
156 struct property *prop;
157 struct symbol *sym2;
158 for (prop = sym->prop; prop; prop = prop->next) {
159 switch (prop->type) {
160 case P_DEFAULT:
161 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
162 prop->expr->type != E_SYMBOL)
163 prop_warn(prop,
164 "default for config symbol '%'"
165 " must be a single symbol", sym->name);
166 break;
167 case P_SELECT:
168 sym2 = prop_get_symbol(prop);
169 if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
170 prop_warn(prop,
171 "config symbol '%s' uses select, but is "
172 "not boolean or tristate", sym->name);
173 else if (sym2->type == S_UNKNOWN)
174 prop_warn(prop,
175 "'select' used by config symbol '%s' "
176 "refer to undefined symbol '%s'",
177 sym->name, sym2->name);
178 else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
179 prop_warn(prop,
180 "'%s' has wrong type. 'select' only "
181 "accept arguments of boolean and "
182 "tristate type", sym2->name);
183 break;
184 case P_RANGE:
185 if (sym->type != S_INT && sym->type != S_HEX)
186 prop_warn(prop, "range is only allowed "
187 "for int or hex symbols");
188 if (!sym_string_valid(sym, prop->expr->left.sym->name) ||
189 !sym_string_valid(sym, prop->expr->right.sym->name))
190 prop_warn(prop, "range is invalid");
191 break;
192 default:
193 ;
194 }
195 }
196}
197
198void menu_finalize(struct menu *parent)
199{
200 struct menu *menu, *last_menu;
201 struct symbol *sym;
202 struct property *prop;
203 struct expr *parentdep, *basedep, *dep, *dep2, **ep;
204
205 sym = parent->sym;
206 if (parent->list) {
207 if (sym && sym_is_choice(sym)) {
208 /* find the first choice value and find out choice type */
209 for (menu = parent->list; menu; menu = menu->next) {
210 if (menu->sym) {
211 current_entry = parent;
212 menu_set_type(menu->sym->type);
213 current_entry = menu;
214 menu_set_type(sym->type);
215 break;
216 }
217 }
218 parentdep = expr_alloc_symbol(sym);
219 } else if (parent->prompt)
220 parentdep = parent->prompt->visible.expr;
221 else
222 parentdep = parent->dep;
223
224 for (menu = parent->list; menu; menu = menu->next) {
225 basedep = expr_transform(menu->dep);
226 basedep = expr_alloc_and(expr_copy(parentdep), basedep);
227 basedep = expr_eliminate_dups(basedep);
228 menu->dep = basedep;
229 if (menu->sym)
230 prop = menu->sym->prop;
231 else
232 prop = menu->prompt;
233 for (; prop; prop = prop->next) {
234 if (prop->menu != menu)
235 continue;
236 dep = expr_transform(prop->visible.expr);
237 dep = expr_alloc_and(expr_copy(basedep), dep);
238 dep = expr_eliminate_dups(dep);
239 if (menu->sym && menu->sym->type != S_TRISTATE)
240 dep = expr_trans_bool(dep);
241 prop->visible.expr = dep;
242 if (prop->type == P_SELECT) {
243 struct symbol *es = prop_get_symbol(prop);
244 es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
245 expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
246 }
247 }
248 }
249 for (menu = parent->list; menu; menu = menu->next)
250 menu_finalize(menu);
251 } else if (sym) {
252 basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
253 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
254 basedep = expr_eliminate_dups(expr_transform(basedep));
255 last_menu = NULL;
256 for (menu = parent->next; menu; menu = menu->next) {
257 dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
258 if (!expr_contains_symbol(dep, sym))
259 break;
260 if (expr_depends_symbol(dep, sym))
261 goto next;
262 dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
263 dep = expr_eliminate_dups(expr_transform(dep));
264 dep2 = expr_copy(basedep);
265 expr_eliminate_eq(&dep, &dep2);
266 expr_free(dep);
267 if (!expr_is_yes(dep2)) {
268 expr_free(dep2);
269 break;
270 }
271 expr_free(dep2);
272 next:
273 menu_finalize(menu);
274 menu->parent = parent;
275 last_menu = menu;
276 }
277 if (last_menu) {
278 parent->list = parent->next;
279 parent->next = last_menu->next;
280 last_menu->next = NULL;
281 }
282 }
283 for (menu = parent->list; menu; menu = menu->next) {
284 if (sym && sym_is_choice(sym) && menu->sym) {
285 menu->sym->flags |= SYMBOL_CHOICEVAL;
286 if (!menu->prompt)
287 menu_warn(menu, "choice value must have a prompt");
288 for (prop = menu->sym->prop; prop; prop = prop->next) {
289 if (prop->type == P_PROMPT && prop->menu != menu) {
290 prop_warn(prop, "choice values "
291 "currently only support a "
292 "single prompt");
293 }
294 if (prop->type == P_DEFAULT)
295 prop_warn(prop, "defaults for choice "
296 "values not supported");
297 }
298 current_entry = menu;
299 menu_set_type(sym->type);
300 menu_add_symbol(P_CHOICE, sym, NULL);
301 prop = sym_get_choice_prop(sym);
302 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
303 ;
304 *ep = expr_alloc_one(E_CHOICE, NULL);
305 (*ep)->right.sym = menu->sym;
306 }
307 if (menu->list && (!menu->prompt || !menu->prompt->text)) {
308 for (last_menu = menu->list; ; last_menu = last_menu->next) {
309 last_menu->parent = parent;
310 if (!last_menu->next)
311 break;
312 }
313 last_menu->next = menu->next;
314 menu->next = menu->list;
315 menu->list = NULL;
316 }
317 }
318
319 if (sym && !(sym->flags & SYMBOL_WARNED)) {
320 if (sym->type == S_UNKNOWN)
321 menu_warn(parent, "config symbol defined "
322 "without type\n");
323
324 if (sym_is_choice(sym) && !parent->prompt)
325 menu_warn(parent, "choice must have a prompt\n");
326
327 /* Check properties connected to this symbol */
328 sym_check_prop(sym);
329 sym->flags |= SYMBOL_WARNED;
330 }
331
332 if (sym && !sym_is_optional(sym) && parent->prompt) {
333 sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
334 expr_alloc_and(parent->prompt->visible.expr,
335 expr_alloc_symbol(&symbol_mod)));
336 }
337}
338
339bool menu_is_visible(struct menu *menu)
340{
341 struct menu *child;
342 struct symbol *sym;
343 tristate visible;
344
345 if (!menu->prompt)
346 return false;
347 sym = menu->sym;
348 if (sym) {
349 sym_calc_value(sym);
350 visible = menu->prompt->visible.tri;
351 } else
352 visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
353
354 if (visible != no)
355 return true;
356 if (!sym || sym_get_tristate_value(menu->sym) == no)
357 return false;
358
359 for (child = menu->list; child; child = child->next)
360 if (menu_is_visible(child))
361 return true;
362 return false;
363}
364
365const char *menu_get_prompt(struct menu *menu)
366{
367 if (menu->prompt)
368 return menu->prompt->text;
369 else if (menu->sym)
370 return menu->sym->name;
371 return NULL;
372}
373
374struct menu *menu_get_root_menu(struct menu *menu)
375{
376 return &rootmenu;
377}
378
379struct menu *menu_get_parent_menu(struct menu *menu)
380{
381 enum prop_type type;
382
383 for (; menu != &rootmenu; menu = menu->parent) {
384 type = menu->prompt ? menu->prompt->type : 0;
385 if (type == P_MENU)
386 break;
387 }
388 return menu;
389}
390
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
new file mode 100644
index 000000000000..0cdbf9dbbd51
--- /dev/null
+++ b/scripts/kconfig/qconf.cc
@@ -0,0 +1,1407 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <qapplication.h>
7#include <qmainwindow.h>
8#include <qtoolbar.h>
9#include <qvbox.h>
10#include <qsplitter.h>
11#include <qlistview.h>
12#include <qtextview.h>
13#include <qlineedit.h>
14#include <qmenubar.h>
15#include <qmessagebox.h>
16#include <qaction.h>
17#include <qheader.h>
18#include <qfiledialog.h>
19#include <qregexp.h>
20
21#include <stdlib.h>
22
23#include "lkc.h"
24#include "qconf.h"
25
26#include "qconf.moc"
27#include "images.c"
28
29static QApplication *configApp;
30
31ConfigSettings::ConfigSettings()
32 : showAll(false), showName(false), showRange(false), showData(false)
33{
34}
35
36#if QT_VERSION >= 300
37/**
38 * Reads the list column settings from the application settings.
39 */
40void ConfigSettings::readListSettings()
41{
42 showAll = readBoolEntry("/kconfig/qconf/showAll", false);
43 showName = readBoolEntry("/kconfig/qconf/showName", false);
44 showRange = readBoolEntry("/kconfig/qconf/showRange", false);
45 showData = readBoolEntry("/kconfig/qconf/showData", false);
46}
47
48/**
49 * Reads a list of integer values from the application settings.
50 */
51QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
52{
53 QValueList<int> result;
54 QStringList entryList = readListEntry(key, ok);
55 if (ok) {
56 QStringList::Iterator it;
57 for (it = entryList.begin(); it != entryList.end(); ++it)
58 result.push_back((*it).toInt());
59 }
60
61 return result;
62}
63
64/**
65 * Writes a list of integer values to the application settings.
66 */
67bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
68{
69 QStringList stringList;
70 QValueList<int>::ConstIterator it;
71
72 for (it = value.begin(); it != value.end(); ++it)
73 stringList.push_back(QString::number(*it));
74 return writeEntry(key, stringList);
75}
76#endif
77
78
79/*
80 * update all the children of a menu entry
81 * removes/adds the entries from the parent widget as necessary
82 *
83 * parent: either the menu list widget or a menu entry widget
84 * menu: entry to be updated
85 */
86template <class P>
87void ConfigList::updateMenuList(P* parent, struct menu* menu)
88{
89 struct menu* child;
90 ConfigItem* item;
91 ConfigItem* last;
92 bool visible;
93 enum prop_type type;
94
95 if (!menu) {
96 while ((item = parent->firstChild()))
97 delete item;
98 return;
99 }
100
101 last = parent->firstChild();
102 if (last && !last->goParent)
103 last = 0;
104 for (child = menu->list; child; child = child->next) {
105 item = last ? last->nextSibling() : parent->firstChild();
106 type = child->prompt ? child->prompt->type : P_UNKNOWN;
107
108 switch (mode) {
109 case menuMode:
110 if (!(child->flags & MENU_ROOT))
111 goto hide;
112 break;
113 case symbolMode:
114 if (child->flags & MENU_ROOT)
115 goto hide;
116 break;
117 default:
118 break;
119 }
120
121 visible = menu_is_visible(child);
122 if (showAll || visible) {
123 if (!item || item->menu != child)
124 item = new ConfigItem(parent, last, child, visible);
125 else
126 item->testUpdateMenu(visible);
127
128 if (mode == fullMode || mode == menuMode || type != P_MENU)
129 updateMenuList(item, child);
130 else
131 updateMenuList(item, 0);
132 last = item;
133 continue;
134 }
135 hide:
136 if (item && item->menu == child) {
137 last = parent->firstChild();
138 if (last == item)
139 last = 0;
140 else while (last->nextSibling() != item)
141 last = last->nextSibling();
142 delete item;
143 }
144 }
145}
146
147#if QT_VERSION >= 300
148/*
149 * set the new data
150 * TODO check the value
151 */
152void ConfigItem::okRename(int col)
153{
154 Parent::okRename(col);
155 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
156}
157#endif
158
159/*
160 * update the displayed of a menu entry
161 */
162void ConfigItem::updateMenu(void)
163{
164 ConfigList* list;
165 struct symbol* sym;
166 struct property *prop;
167 QString prompt;
168 int type;
169 tristate expr;
170
171 list = listView();
172 if (goParent) {
173 setPixmap(promptColIdx, list->menuBackPix);
174 prompt = "..";
175 goto set_prompt;
176 }
177
178 sym = menu->sym;
179 prop = menu->prompt;
180 prompt = menu_get_prompt(menu);
181
182 if (prop) switch (prop->type) {
183 case P_MENU:
184 if (list->mode == singleMode || list->mode == symbolMode) {
185 /* a menuconfig entry is displayed differently
186 * depending whether it's at the view root or a child.
187 */
188 if (sym && list->rootEntry == menu)
189 break;
190 setPixmap(promptColIdx, list->menuPix);
191 } else {
192 if (sym)
193 break;
194 setPixmap(promptColIdx, 0);
195 }
196 goto set_prompt;
197 case P_COMMENT:
198 setPixmap(promptColIdx, 0);
199 goto set_prompt;
200 default:
201 ;
202 }
203 if (!sym)
204 goto set_prompt;
205
206 setText(nameColIdx, sym->name);
207
208 type = sym_get_type(sym);
209 switch (type) {
210 case S_BOOLEAN:
211 case S_TRISTATE:
212 char ch;
213
214 if (!sym_is_changable(sym) && !list->showAll) {
215 setPixmap(promptColIdx, 0);
216 setText(noColIdx, 0);
217 setText(modColIdx, 0);
218 setText(yesColIdx, 0);
219 break;
220 }
221 expr = sym_get_tristate_value(sym);
222 switch (expr) {
223 case yes:
224 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
225 setPixmap(promptColIdx, list->choiceYesPix);
226 else
227 setPixmap(promptColIdx, list->symbolYesPix);
228 setText(yesColIdx, "Y");
229 ch = 'Y';
230 break;
231 case mod:
232 setPixmap(promptColIdx, list->symbolModPix);
233 setText(modColIdx, "M");
234 ch = 'M';
235 break;
236 default:
237 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
238 setPixmap(promptColIdx, list->choiceNoPix);
239 else
240 setPixmap(promptColIdx, list->symbolNoPix);
241 setText(noColIdx, "N");
242 ch = 'N';
243 break;
244 }
245 if (expr != no)
246 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
247 if (expr != mod)
248 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
249 if (expr != yes)
250 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
251
252 setText(dataColIdx, QChar(ch));
253 break;
254 case S_INT:
255 case S_HEX:
256 case S_STRING:
257 const char* data;
258
259 data = sym_get_string_value(sym);
260#if QT_VERSION >= 300
261 int i = list->mapIdx(dataColIdx);
262 if (i >= 0)
263 setRenameEnabled(i, TRUE);
264#endif
265 setText(dataColIdx, data);
266 if (type == S_STRING)
267 prompt.sprintf("%s: %s", prompt.latin1(), data);
268 else
269 prompt.sprintf("(%s) %s", data, prompt.latin1());
270 break;
271 }
272 if (!sym_has_value(sym) && visible)
273 prompt += " (NEW)";
274set_prompt:
275 setText(promptColIdx, prompt);
276}
277
278void ConfigItem::testUpdateMenu(bool v)
279{
280 ConfigItem* i;
281
282 visible = v;
283 if (!menu)
284 return;
285
286 sym_calc_value(menu->sym);
287 if (menu->flags & MENU_CHANGED) {
288 /* the menu entry changed, so update all list items */
289 menu->flags &= ~MENU_CHANGED;
290 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
291 i->updateMenu();
292 } else if (listView()->updateAll)
293 updateMenu();
294}
295
296void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
297{
298 ConfigList* list = listView();
299
300 if (visible) {
301 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
302 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
303 else
304 Parent::paintCell(p, cg, column, width, align);
305 } else
306 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
307}
308
309/*
310 * construct a menu entry
311 */
312void ConfigItem::init(void)
313{
314 if (menu) {
315 ConfigList* list = listView();
316 nextItem = (ConfigItem*)menu->data;
317 menu->data = this;
318
319 if (list->mode != fullMode)
320 setOpen(TRUE);
321 sym_calc_value(menu->sym);
322 }
323 updateMenu();
324}
325
326/*
327 * destruct a menu entry
328 */
329ConfigItem::~ConfigItem(void)
330{
331 if (menu) {
332 ConfigItem** ip = (ConfigItem**)&menu->data;
333 for (; *ip; ip = &(*ip)->nextItem) {
334 if (*ip == this) {
335 *ip = nextItem;
336 break;
337 }
338 }
339 }
340}
341
342void ConfigLineEdit::show(ConfigItem* i)
343{
344 item = i;
345 if (sym_get_string_value(item->menu->sym))
346 setText(sym_get_string_value(item->menu->sym));
347 else
348 setText(0);
349 Parent::show();
350 setFocus();
351}
352
353void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
354{
355 switch (e->key()) {
356 case Key_Escape:
357 break;
358 case Key_Return:
359 case Key_Enter:
360 sym_set_string_value(item->menu->sym, text().latin1());
361 parent()->updateList(item);
362 break;
363 default:
364 Parent::keyPressEvent(e);
365 return;
366 }
367 e->accept();
368 parent()->list->setFocus();
369 hide();
370}
371
372ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv, ConfigSettings* configSettings)
373 : Parent(p), cview(cv),
374 updateAll(false),
375 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
376 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
377 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
378 showAll(false), showName(false), showRange(false), showData(false),
379 rootEntry(0)
380{
381 int i;
382
383 setSorting(-1);
384 setRootIsDecorated(TRUE);
385 disabledColorGroup = palette().active();
386 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
387 inactivedColorGroup = palette().active();
388 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
389
390 connect(this, SIGNAL(selectionChanged(void)),
391 SLOT(updateSelection(void)));
392
393 if (configSettings) {
394 showAll = configSettings->showAll;
395 showName = configSettings->showName;
396 showRange = configSettings->showRange;
397 showData = configSettings->showData;
398 }
399
400 for (i = 0; i < colNr; i++)
401 colMap[i] = colRevMap[i] = -1;
402 addColumn(promptColIdx, "Option");
403
404 reinit();
405}
406
407void ConfigList::reinit(void)
408{
409 removeColumn(dataColIdx);
410 removeColumn(yesColIdx);
411 removeColumn(modColIdx);
412 removeColumn(noColIdx);
413 removeColumn(nameColIdx);
414
415 if (showName)
416 addColumn(nameColIdx, "Name");
417 if (showRange) {
418 addColumn(noColIdx, "N");
419 addColumn(modColIdx, "M");
420 addColumn(yesColIdx, "Y");
421 }
422 if (showData)
423 addColumn(dataColIdx, "Value");
424
425 updateListAll();
426}
427
428void ConfigList::updateSelection(void)
429{
430 struct menu *menu;
431 enum prop_type type;
432
433 ConfigItem* item = (ConfigItem*)selectedItem();
434 if (!item)
435 return;
436
437 cview->setHelp(item);
438
439 menu = item->menu;
440 if (!menu)
441 return;
442 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
443 if (mode == menuMode && type == P_MENU)
444 emit menuSelected(menu);
445}
446
447void ConfigList::updateList(ConfigItem* item)
448{
449 ConfigItem* last = 0;
450
451 if (!rootEntry)
452 goto update;
453
454 if (rootEntry != &rootmenu && (mode == singleMode ||
455 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
456 item = firstChild();
457 if (!item)
458 item = new ConfigItem(this, 0, true);
459 last = item;
460 }
461 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
462 rootEntry->sym && rootEntry->prompt) {
463 item = last ? last->nextSibling() : firstChild();
464 if (!item)
465 item = new ConfigItem(this, last, rootEntry, true);
466 else
467 item->testUpdateMenu(true);
468
469 updateMenuList(item, rootEntry);
470 triggerUpdate();
471 return;
472 }
473update:
474 updateMenuList(this, rootEntry);
475 triggerUpdate();
476}
477
478void ConfigList::setAllOpen(bool open)
479{
480 QListViewItemIterator it(this);
481
482 for (; it.current(); it++)
483 it.current()->setOpen(open);
484}
485
486void ConfigList::setValue(ConfigItem* item, tristate val)
487{
488 struct symbol* sym;
489 int type;
490 tristate oldval;
491
492 sym = item->menu ? item->menu->sym : 0;
493 if (!sym)
494 return;
495
496 type = sym_get_type(sym);
497 switch (type) {
498 case S_BOOLEAN:
499 case S_TRISTATE:
500 oldval = sym_get_tristate_value(sym);
501
502 if (!sym_set_tristate_value(sym, val))
503 return;
504 if (oldval == no && item->menu->list)
505 item->setOpen(TRUE);
506 parent()->updateList(item);
507 break;
508 }
509}
510
511void ConfigList::changeValue(ConfigItem* item)
512{
513 struct symbol* sym;
514 struct menu* menu;
515 int type, oldexpr, newexpr;
516
517 menu = item->menu;
518 if (!menu)
519 return;
520 sym = menu->sym;
521 if (!sym) {
522 if (item->menu->list)
523 item->setOpen(!item->isOpen());
524 return;
525 }
526
527 type = sym_get_type(sym);
528 switch (type) {
529 case S_BOOLEAN:
530 case S_TRISTATE:
531 oldexpr = sym_get_tristate_value(sym);
532 newexpr = sym_toggle_tristate_value(sym);
533 if (item->menu->list) {
534 if (oldexpr == newexpr)
535 item->setOpen(!item->isOpen());
536 else if (oldexpr == no)
537 item->setOpen(TRUE);
538 }
539 if (oldexpr != newexpr)
540 parent()->updateList(item);
541 break;
542 case S_INT:
543 case S_HEX:
544 case S_STRING:
545#if QT_VERSION >= 300
546 if (colMap[dataColIdx] >= 0)
547 item->startRename(colMap[dataColIdx]);
548 else
549#endif
550 parent()->lineEdit->show(item);
551 break;
552 }
553}
554
555void ConfigList::setRootMenu(struct menu *menu)
556{
557 enum prop_type type;
558
559 if (rootEntry == menu)
560 return;
561 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
562 if (type != P_MENU)
563 return;
564 updateMenuList(this, 0);
565 rootEntry = menu;
566 updateListAll();
567 setSelected(currentItem(), hasFocus());
568}
569
570void ConfigList::setParentMenu(void)
571{
572 ConfigItem* item;
573 struct menu *oldroot;
574
575 oldroot = rootEntry;
576 if (rootEntry == &rootmenu)
577 return;
578 setRootMenu(menu_get_parent_menu(rootEntry->parent));
579
580 QListViewItemIterator it(this);
581 for (; (item = (ConfigItem*)it.current()); it++) {
582 if (item->menu == oldroot) {
583 setCurrentItem(item);
584 ensureItemVisible(item);
585 break;
586 }
587 }
588}
589
590void ConfigList::keyPressEvent(QKeyEvent* ev)
591{
592 QListViewItem* i = currentItem();
593 ConfigItem* item;
594 struct menu *menu;
595 enum prop_type type;
596
597 if (ev->key() == Key_Escape && mode != fullMode) {
598 emit parentSelected();
599 ev->accept();
600 return;
601 }
602
603 if (!i) {
604 Parent::keyPressEvent(ev);
605 return;
606 }
607 item = (ConfigItem*)i;
608
609 switch (ev->key()) {
610 case Key_Return:
611 case Key_Enter:
612 if (item->goParent) {
613 emit parentSelected();
614 break;
615 }
616 menu = item->menu;
617 if (!menu)
618 break;
619 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
620 if (type == P_MENU && rootEntry != menu &&
621 mode != fullMode && mode != menuMode) {
622 emit menuSelected(menu);
623 break;
624 }
625 case Key_Space:
626 changeValue(item);
627 break;
628 case Key_N:
629 setValue(item, no);
630 break;
631 case Key_M:
632 setValue(item, mod);
633 break;
634 case Key_Y:
635 setValue(item, yes);
636 break;
637 default:
638 Parent::keyPressEvent(ev);
639 return;
640 }
641 ev->accept();
642}
643
644void ConfigList::contentsMousePressEvent(QMouseEvent* e)
645{
646 //QPoint p(contentsToViewport(e->pos()));
647 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
648 Parent::contentsMousePressEvent(e);
649}
650
651void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
652{
653 QPoint p(contentsToViewport(e->pos()));
654 ConfigItem* item = (ConfigItem*)itemAt(p);
655 struct menu *menu;
656 enum prop_type ptype;
657 const QPixmap* pm;
658 int idx, x;
659
660 if (!item)
661 goto skip;
662
663 menu = item->menu;
664 x = header()->offset() + p.x();
665 idx = colRevMap[header()->sectionAt(x)];
666 switch (idx) {
667 case promptColIdx:
668 pm = item->pixmap(promptColIdx);
669 if (pm) {
670 int off = header()->sectionPos(0) + itemMargin() +
671 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
672 if (x >= off && x < off + pm->width()) {
673 if (item->goParent) {
674 emit parentSelected();
675 break;
676 } else if (!menu)
677 break;
678 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
679 if (ptype == P_MENU && rootEntry != menu &&
680 mode != fullMode && mode != menuMode)
681 emit menuSelected(menu);
682 else
683 changeValue(item);
684 }
685 }
686 break;
687 case noColIdx:
688 setValue(item, no);
689 break;
690 case modColIdx:
691 setValue(item, mod);
692 break;
693 case yesColIdx:
694 setValue(item, yes);
695 break;
696 case dataColIdx:
697 changeValue(item);
698 break;
699 }
700
701skip:
702 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
703 Parent::contentsMouseReleaseEvent(e);
704}
705
706void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
707{
708 //QPoint p(contentsToViewport(e->pos()));
709 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
710 Parent::contentsMouseMoveEvent(e);
711}
712
713void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
714{
715 QPoint p(contentsToViewport(e->pos()));
716 ConfigItem* item = (ConfigItem*)itemAt(p);
717 struct menu *menu;
718 enum prop_type ptype;
719
720 if (!item)
721 goto skip;
722 if (item->goParent) {
723 emit parentSelected();
724 goto skip;
725 }
726 menu = item->menu;
727 if (!menu)
728 goto skip;
729 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
730 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
731 emit menuSelected(menu);
732 else if (menu->sym)
733 changeValue(item);
734
735skip:
736 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
737 Parent::contentsMouseDoubleClickEvent(e);
738}
739
740void ConfigList::focusInEvent(QFocusEvent *e)
741{
742 Parent::focusInEvent(e);
743
744 QListViewItem* item = currentItem();
745 if (!item)
746 return;
747
748 setSelected(item, TRUE);
749 emit gotFocus();
750}
751
752ConfigView* ConfigView::viewList;
753
754ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview,
755 ConfigSettings *configSettings)
756 : Parent(parent)
757{
758 list = new ConfigList(this, cview, configSettings);
759 lineEdit = new ConfigLineEdit(this);
760 lineEdit->hide();
761
762 this->nextView = viewList;
763 viewList = this;
764}
765
766ConfigView::~ConfigView(void)
767{
768 ConfigView** vp;
769
770 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
771 if (*vp == this) {
772 *vp = nextView;
773 break;
774 }
775 }
776}
777
778void ConfigView::updateList(ConfigItem* item)
779{
780 ConfigView* v;
781
782 for (v = viewList; v; v = v->nextView)
783 v->list->updateList(item);
784}
785
786void ConfigView::updateListAll(void)
787{
788 ConfigView* v;
789
790 for (v = viewList; v; v = v->nextView)
791 v->list->updateListAll();
792}
793
794/*
795 * Construct the complete config widget
796 */
797ConfigMainWindow::ConfigMainWindow(void)
798{
799 QMenuBar* menu;
800 bool ok;
801 int x, y, width, height;
802
803 QWidget *d = configApp->desktop();
804
805 ConfigSettings* configSettings = new ConfigSettings();
806#if QT_VERSION >= 300
807 width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64);
808 height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64);
809 resize(width, height);
810 x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok);
811 if (ok)
812 y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok);
813 if (ok)
814 move(x, y);
815 showDebug = configSettings->readBoolEntry("/kconfig/qconf/showDebug", false);
816
817 // read list settings into configSettings, will be used later for ConfigList setup
818 configSettings->readListSettings();
819#else
820 width = d->width() - 64;
821 height = d->height() - 64;
822 resize(width, height);
823 showDebug = false;
824#endif
825
826 split1 = new QSplitter(this);
827 split1->setOrientation(QSplitter::Horizontal);
828 setCentralWidget(split1);
829
830 menuView = new ConfigView(split1, this, configSettings);
831 menuList = menuView->list;
832
833 split2 = new QSplitter(split1);
834 split2->setOrientation(QSplitter::Vertical);
835
836 // create config tree
837 configView = new ConfigView(split2, this, configSettings);
838 configList = configView->list;
839
840 helpText = new QTextView(split2);
841 helpText->setTextFormat(Qt::RichText);
842
843 setTabOrder(configList, helpText);
844 configList->setFocus();
845
846 menu = menuBar();
847 toolBar = new QToolBar("Tools", this);
848
849 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
850 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
851 backAction->setEnabled(FALSE);
852 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
853 connect(quitAction, SIGNAL(activated()), SLOT(close()));
854 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
855 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
856 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
857 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
858 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
859 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
860 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
861 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
862 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
863 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
864 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
865 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
866
867 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
868 showNameAction->setToggleAction(TRUE);
869 showNameAction->setOn(configList->showName);
870 connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool)));
871 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
872 showRangeAction->setToggleAction(TRUE);
873 showRangeAction->setOn(configList->showRange);
874 connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool)));
875 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
876 showDataAction->setToggleAction(TRUE);
877 showDataAction->setOn(configList->showData);
878 connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool)));
879 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
880 showAllAction->setToggleAction(TRUE);
881 showAllAction->setOn(configList->showAll);
882 connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool)));
883 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
884 showDebugAction->setToggleAction(TRUE);
885 showDebugAction->setOn(showDebug);
886 connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
887
888 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
889 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
890 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
891 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
892
893 // init tool bar
894 backAction->addTo(toolBar);
895 toolBar->addSeparator();
896 loadAction->addTo(toolBar);
897 saveAction->addTo(toolBar);
898 toolBar->addSeparator();
899 singleViewAction->addTo(toolBar);
900 splitViewAction->addTo(toolBar);
901 fullViewAction->addTo(toolBar);
902
903 // create config menu
904 QPopupMenu* config = new QPopupMenu(this);
905 menu->insertItem("&File", config);
906 loadAction->addTo(config);
907 saveAction->addTo(config);
908 saveAsAction->addTo(config);
909 config->insertSeparator();
910 quitAction->addTo(config);
911
912 // create options menu
913 QPopupMenu* optionMenu = new QPopupMenu(this);
914 menu->insertItem("&Option", optionMenu);
915 showNameAction->addTo(optionMenu);
916 showRangeAction->addTo(optionMenu);
917 showDataAction->addTo(optionMenu);
918 optionMenu->insertSeparator();
919 showAllAction->addTo(optionMenu);
920 showDebugAction->addTo(optionMenu);
921
922 // create help menu
923 QPopupMenu* helpMenu = new QPopupMenu(this);
924 menu->insertSeparator();
925 menu->insertItem("&Help", helpMenu);
926 showIntroAction->addTo(helpMenu);
927 showAboutAction->addTo(helpMenu);
928
929 connect(configList, SIGNAL(menuSelected(struct menu *)),
930 SLOT(changeMenu(struct menu *)));
931 connect(configList, SIGNAL(parentSelected()),
932 SLOT(goBack()));
933 connect(menuList, SIGNAL(menuSelected(struct menu *)),
934 SLOT(changeMenu(struct menu *)));
935
936 connect(configList, SIGNAL(gotFocus(void)),
937 SLOT(listFocusChanged(void)));
938 connect(menuList, SIGNAL(gotFocus(void)),
939 SLOT(listFocusChanged(void)));
940
941#if QT_VERSION >= 300
942 QString listMode = configSettings->readEntry("/kconfig/qconf/listMode", "symbol");
943 if (listMode == "single")
944 showSingleView();
945 else if (listMode == "full")
946 showFullView();
947 else /*if (listMode == "split")*/
948 showSplitView();
949
950 // UI setup done, restore splitter positions
951 QValueList<int> sizes = configSettings->readSizes("/kconfig/qconf/split1", &ok);
952 if (ok)
953 split1->setSizes(sizes);
954
955 sizes = configSettings->readSizes("/kconfig/qconf/split2", &ok);
956 if (ok)
957 split2->setSizes(sizes);
958#else
959 showSplitView();
960#endif
961 delete configSettings;
962}
963
964static QString print_filter(const char *str)
965{
966 QRegExp re("[<>&\"\\n]");
967 QString res = str;
968 for (int i = 0; (i = res.find(re, i)) >= 0;) {
969 switch (res[i].latin1()) {
970 case '<':
971 res.replace(i, 1, "&lt;");
972 i += 4;
973 break;
974 case '>':
975 res.replace(i, 1, "&gt;");
976 i += 4;
977 break;
978 case '&':
979 res.replace(i, 1, "&amp;");
980 i += 5;
981 break;
982 case '"':
983 res.replace(i, 1, "&quot;");
984 i += 6;
985 break;
986 case '\n':
987 res.replace(i, 1, "<br>");
988 i += 4;
989 break;
990 }
991 }
992 return res;
993}
994
995static void expr_print_help(void *data, const char *str)
996{
997 ((QString*)data)->append(print_filter(str));
998}
999
1000/*
1001 * display a new help entry as soon as a new menu entry is selected
1002 */
1003void ConfigMainWindow::setHelp(QListViewItem* item)
1004{
1005 struct symbol* sym;
1006 struct menu* menu = 0;
1007
1008 configList->parent()->lineEdit->hide();
1009 if (item)
1010 menu = ((ConfigItem*)item)->menu;
1011 if (!menu) {
1012 helpText->setText(NULL);
1013 return;
1014 }
1015
1016 QString head, debug, help;
1017 menu = ((ConfigItem*)item)->menu;
1018 sym = menu->sym;
1019 if (sym) {
1020 if (menu->prompt) {
1021 head += "<big><b>";
1022 head += print_filter(menu->prompt->text);
1023 head += "</b></big>";
1024 if (sym->name) {
1025 head += " (";
1026 head += print_filter(sym->name);
1027 head += ")";
1028 }
1029 } else if (sym->name) {
1030 head += "<big><b>";
1031 head += print_filter(sym->name);
1032 head += "</b></big>";
1033 }
1034 head += "<br><br>";
1035
1036 if (showDebug) {
1037 debug += "type: ";
1038 debug += print_filter(sym_type_name(sym->type));
1039 if (sym_is_choice(sym))
1040 debug += " (choice)";
1041 debug += "<br>";
1042 if (sym->rev_dep.expr) {
1043 debug += "reverse dep: ";
1044 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1045 debug += "<br>";
1046 }
1047 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1048 switch (prop->type) {
1049 case P_PROMPT:
1050 case P_MENU:
1051 debug += "prompt: ";
1052 debug += print_filter(prop->text);
1053 debug += "<br>";
1054 break;
1055 case P_DEFAULT:
1056 debug += "default: ";
1057 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1058 debug += "<br>";
1059 break;
1060 case P_CHOICE:
1061 if (sym_is_choice(sym)) {
1062 debug += "choice: ";
1063 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1064 debug += "<br>";
1065 }
1066 break;
1067 case P_SELECT:
1068 debug += "select: ";
1069 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1070 debug += "<br>";
1071 break;
1072 case P_RANGE:
1073 debug += "range: ";
1074 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1075 debug += "<br>";
1076 break;
1077 default:
1078 debug += "unknown property: ";
1079 debug += prop_get_type_name(prop->type);
1080 debug += "<br>";
1081 }
1082 if (prop->visible.expr) {
1083 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1084 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1085 debug += "<br>";
1086 }
1087 }
1088 debug += "<br>";
1089 }
1090
1091 help = print_filter(sym->help);
1092 } else if (menu->prompt) {
1093 head += "<big><b>";
1094 head += print_filter(menu->prompt->text);
1095 head += "</b></big><br><br>";
1096 if (showDebug) {
1097 if (menu->prompt->visible.expr) {
1098 debug += "&nbsp;&nbsp;dep: ";
1099 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1100 debug += "<br><br>";
1101 }
1102 }
1103 }
1104 if (showDebug)
1105 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1106 helpText->setText(head + debug + help);
1107}
1108
1109void ConfigMainWindow::loadConfig(void)
1110{
1111 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1112 if (s.isNull())
1113 return;
1114 if (conf_read(s.latin1()))
1115 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1116 ConfigView::updateListAll();
1117}
1118
1119void ConfigMainWindow::saveConfig(void)
1120{
1121 if (conf_write(NULL))
1122 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1123}
1124
1125void ConfigMainWindow::saveConfigAs(void)
1126{
1127 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1128 if (s.isNull())
1129 return;
1130 if (conf_write(s.latin1()))
1131 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1132}
1133
1134void ConfigMainWindow::changeMenu(struct menu *menu)
1135{
1136 configList->setRootMenu(menu);
1137 backAction->setEnabled(TRUE);
1138}
1139
1140void ConfigMainWindow::listFocusChanged(void)
1141{
1142 if (menuList->hasFocus()) {
1143 if (menuList->mode == menuMode)
1144 configList->clearSelection();
1145 setHelp(menuList->selectedItem());
1146 } else if (configList->hasFocus()) {
1147 setHelp(configList->selectedItem());
1148 }
1149}
1150
1151void ConfigMainWindow::goBack(void)
1152{
1153 ConfigItem* item;
1154
1155 configList->setParentMenu();
1156 if (configList->rootEntry == &rootmenu)
1157 backAction->setEnabled(FALSE);
1158 item = (ConfigItem*)menuList->selectedItem();
1159 while (item) {
1160 if (item->menu == configList->rootEntry) {
1161 menuList->setSelected(item, TRUE);
1162 break;
1163 }
1164 item = (ConfigItem*)item->parent();
1165 }
1166}
1167
1168void ConfigMainWindow::showSingleView(void)
1169{
1170 menuView->hide();
1171 menuList->setRootMenu(0);
1172 configList->mode = singleMode;
1173 if (configList->rootEntry == &rootmenu)
1174 configList->updateListAll();
1175 else
1176 configList->setRootMenu(&rootmenu);
1177 configList->setAllOpen(TRUE);
1178 configList->setFocus();
1179}
1180
1181void ConfigMainWindow::showSplitView(void)
1182{
1183 configList->mode = symbolMode;
1184 if (configList->rootEntry == &rootmenu)
1185 configList->updateListAll();
1186 else
1187 configList->setRootMenu(&rootmenu);
1188 configList->setAllOpen(TRUE);
1189 configApp->processEvents();
1190 menuList->mode = menuMode;
1191 menuList->setRootMenu(&rootmenu);
1192 menuList->setAllOpen(TRUE);
1193 menuView->show();
1194 menuList->setFocus();
1195}
1196
1197void ConfigMainWindow::showFullView(void)
1198{
1199 menuView->hide();
1200 menuList->setRootMenu(0);
1201 configList->mode = fullMode;
1202 if (configList->rootEntry == &rootmenu)
1203 configList->updateListAll();
1204 else
1205 configList->setRootMenu(&rootmenu);
1206 configList->setAllOpen(FALSE);
1207 configList->setFocus();
1208}
1209
1210void ConfigMainWindow::setShowAll(bool b)
1211{
1212 if (configList->showAll == b)
1213 return;
1214 configList->showAll = b;
1215 configList->updateListAll();
1216 menuList->showAll = b;
1217 menuList->updateListAll();
1218}
1219
1220void ConfigMainWindow::setShowDebug(bool b)
1221{
1222 if (showDebug == b)
1223 return;
1224 showDebug = b;
1225}
1226
1227void ConfigMainWindow::setShowName(bool b)
1228{
1229 if (configList->showName == b)
1230 return;
1231 configList->showName = b;
1232 configList->reinit();
1233 menuList->showName = b;
1234 menuList->reinit();
1235}
1236
1237void ConfigMainWindow::setShowRange(bool b)
1238{
1239 if (configList->showRange == b)
1240 return;
1241 configList->showRange = b;
1242 configList->reinit();
1243 menuList->showRange = b;
1244 menuList->reinit();
1245}
1246
1247void ConfigMainWindow::setShowData(bool b)
1248{
1249 if (configList->showData == b)
1250 return;
1251 configList->showData = b;
1252 configList->reinit();
1253 menuList->showData = b;
1254 menuList->reinit();
1255}
1256
1257/*
1258 * ask for saving configuration before quitting
1259 * TODO ask only when something changed
1260 */
1261void ConfigMainWindow::closeEvent(QCloseEvent* e)
1262{
1263 if (!sym_change_count) {
1264 e->accept();
1265 return;
1266 }
1267 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1268 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1269 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1270 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1271 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1272 switch (mb.exec()) {
1273 case QMessageBox::Yes:
1274 conf_write(NULL);
1275 case QMessageBox::No:
1276 e->accept();
1277 break;
1278 case QMessageBox::Cancel:
1279 e->ignore();
1280 break;
1281 }
1282}
1283
1284void ConfigMainWindow::showIntro(void)
1285{
1286 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1287 "For each option, a blank box indicates the feature is disabled, a check\n"
1288 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1289 "as a module. Clicking on the box will cycle through the three states.\n\n"
1290 "If you do not see an option (e.g., a device driver) that you believe\n"
1291 "should be present, try turning on Show All Options under the Options menu.\n"
1292 "Although there is no cross reference yet to help you figure out what other\n"
1293 "options must be enabled to support the option you are interested in, you can\n"
1294 "still view the help of a grayed-out option.\n\n"
1295 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1296 "which you can then match by examining other options.\n\n";
1297
1298 QMessageBox::information(this, "qconf", str);
1299}
1300
1301void ConfigMainWindow::showAbout(void)
1302{
1303 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1304 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1305
1306 QMessageBox::information(this, "qconf", str);
1307}
1308
1309void ConfigMainWindow::saveSettings(void)
1310{
1311#if QT_VERSION >= 300
1312 ConfigSettings *configSettings = new ConfigSettings;
1313 configSettings->writeEntry("/kconfig/qconf/window x", pos().x());
1314 configSettings->writeEntry("/kconfig/qconf/window y", pos().y());
1315 configSettings->writeEntry("/kconfig/qconf/window width", size().width());
1316 configSettings->writeEntry("/kconfig/qconf/window height", size().height());
1317 configSettings->writeEntry("/kconfig/qconf/showName", configList->showName);
1318 configSettings->writeEntry("/kconfig/qconf/showRange", configList->showRange);
1319 configSettings->writeEntry("/kconfig/qconf/showData", configList->showData);
1320 configSettings->writeEntry("/kconfig/qconf/showAll", configList->showAll);
1321 configSettings->writeEntry("/kconfig/qconf/showDebug", showDebug);
1322
1323 QString entry;
1324 switch(configList->mode) {
1325 case singleMode :
1326 entry = "single";
1327 break;
1328
1329 case symbolMode :
1330 entry = "split";
1331 break;
1332
1333 case fullMode :
1334 entry = "full";
1335 break;
1336 }
1337 configSettings->writeEntry("/kconfig/qconf/listMode", entry);
1338
1339 configSettings->writeSizes("/kconfig/qconf/split1", split1->sizes());
1340 configSettings->writeSizes("/kconfig/qconf/split2", split2->sizes());
1341
1342 delete configSettings;
1343#endif
1344}
1345
1346void fixup_rootmenu(struct menu *menu)
1347{
1348 struct menu *child;
1349 static int menu_cnt = 0;
1350
1351 menu->flags |= MENU_ROOT;
1352 for (child = menu->list; child; child = child->next) {
1353 if (child->prompt && child->prompt->type == P_MENU) {
1354 menu_cnt++;
1355 fixup_rootmenu(child);
1356 menu_cnt--;
1357 } else if (!menu_cnt)
1358 fixup_rootmenu(child);
1359 }
1360}
1361
1362static const char *progname;
1363
1364static void usage(void)
1365{
1366 printf("%s <config>\n", progname);
1367 exit(0);
1368}
1369
1370int main(int ac, char** av)
1371{
1372 ConfigMainWindow* v;
1373 const char *name;
1374
1375#ifndef LKC_DIRECT_LINK
1376 kconfig_load();
1377#endif
1378
1379 progname = av[0];
1380 configApp = new QApplication(ac, av);
1381 if (ac > 1 && av[1][0] == '-') {
1382 switch (av[1][1]) {
1383 case 'h':
1384 case '?':
1385 usage();
1386 }
1387 name = av[2];
1388 } else
1389 name = av[1];
1390 if (!name)
1391 usage();
1392
1393 conf_parse(name);
1394 fixup_rootmenu(&rootmenu);
1395 conf_read(NULL);
1396 //zconfdump(stdout);
1397
1398 v = new ConfigMainWindow();
1399
1400 //zconfdump(stdout);
1401 v->show();
1402 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1403 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1404 configApp->exec();
1405
1406 return 0;
1407}
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
new file mode 100644
index 000000000000..7c03927d4c7c
--- /dev/null
+++ b/scripts/kconfig/qconf.h
@@ -0,0 +1,263 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <qlistview.h>
7#if QT_VERSION >= 300
8#include <qsettings.h>
9#else
10class QSettings { };
11#endif
12
13class ConfigList;
14class ConfigItem;
15class ConfigLineEdit;
16class ConfigMainWindow;
17
18
19class ConfigSettings : public QSettings {
20public:
21 ConfigSettings();
22
23#if QT_VERSION >= 300
24 void readListSettings();
25 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok);
26 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value);
27#endif
28
29 bool showAll;
30 bool showName;
31 bool showRange;
32 bool showData;
33};
34
35class ConfigView : public QVBox {
36 Q_OBJECT
37 typedef class QVBox Parent;
38public:
39 ConfigView(QWidget* parent, ConfigMainWindow* cview, ConfigSettings* configSettings);
40 ~ConfigView(void);
41 static void updateList(ConfigItem* item);
42 static void updateListAll(void);
43
44public:
45 ConfigList* list;
46 ConfigLineEdit* lineEdit;
47
48 static ConfigView* viewList;
49 ConfigView* nextView;
50};
51
52enum colIdx {
53 promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
54};
55enum listMode {
56 singleMode, menuMode, symbolMode, fullMode
57};
58
59class ConfigList : public QListView {
60 Q_OBJECT
61 typedef class QListView Parent;
62public:
63 ConfigList(ConfigView* p, ConfigMainWindow* cview, ConfigSettings *configSettings);
64 void reinit(void);
65 ConfigView* parent(void) const
66 {
67 return (ConfigView*)Parent::parent();
68 }
69
70protected:
71 ConfigMainWindow* cview;
72
73 void keyPressEvent(QKeyEvent *e);
74 void contentsMousePressEvent(QMouseEvent *e);
75 void contentsMouseReleaseEvent(QMouseEvent *e);
76 void contentsMouseMoveEvent(QMouseEvent *e);
77 void contentsMouseDoubleClickEvent(QMouseEvent *e);
78 void focusInEvent(QFocusEvent *e);
79public slots:
80 void setRootMenu(struct menu *menu);
81
82 void updateList(ConfigItem *item);
83 void setValue(ConfigItem* item, tristate val);
84 void changeValue(ConfigItem* item);
85 void updateSelection(void);
86signals:
87 void menuSelected(struct menu *menu);
88 void parentSelected(void);
89 void gotFocus(void);
90
91public:
92 void updateListAll(void)
93 {
94 updateAll = true;
95 updateList(NULL);
96 updateAll = false;
97 }
98 ConfigList* listView()
99 {
100 return this;
101 }
102 ConfigItem* firstChild() const
103 {
104 return (ConfigItem *)Parent::firstChild();
105 }
106 int mapIdx(colIdx idx)
107 {
108 return colMap[idx];
109 }
110 void addColumn(colIdx idx, const QString& label)
111 {
112 colMap[idx] = Parent::addColumn(label);
113 colRevMap[colMap[idx]] = idx;
114 }
115 void removeColumn(colIdx idx)
116 {
117 int col = colMap[idx];
118 if (col >= 0) {
119 Parent::removeColumn(col);
120 colRevMap[col] = colMap[idx] = -1;
121 }
122 }
123 void setAllOpen(bool open);
124 void setParentMenu(void);
125
126 template <class P>
127 void ConfigList::updateMenuList(P*, struct menu*);
128
129 bool updateAll;
130
131 QPixmap symbolYesPix, symbolModPix, symbolNoPix;
132 QPixmap choiceYesPix, choiceNoPix;
133 QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
134
135 bool showAll, showName, showRange, showData;
136 enum listMode mode;
137 struct menu *rootEntry;
138 QColorGroup disabledColorGroup;
139 QColorGroup inactivedColorGroup;
140
141private:
142 int colMap[colNr];
143 int colRevMap[colNr];
144};
145
146class ConfigItem : public QListViewItem {
147 typedef class QListViewItem Parent;
148public:
149 ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v)
150 : Parent(parent, after), menu(m), visible(v), goParent(false)
151 {
152 init();
153 }
154 ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
155 : Parent(parent, after), menu(m), visible(v), goParent(false)
156 {
157 init();
158 }
159 ConfigItem(QListView *parent, ConfigItem *after, bool v)
160 : Parent(parent, after), menu(0), visible(v), goParent(true)
161 {
162 init();
163 }
164 ~ConfigItem(void);
165 void init(void);
166#if QT_VERSION >= 300
167 void okRename(int col);
168#endif
169 void updateMenu(void);
170 void testUpdateMenu(bool v);
171 ConfigList* listView() const
172 {
173 return (ConfigList*)Parent::listView();
174 }
175 ConfigItem* firstChild() const
176 {
177 return (ConfigItem *)Parent::firstChild();
178 }
179 ConfigItem* nextSibling() const
180 {
181 return (ConfigItem *)Parent::nextSibling();
182 }
183 void setText(colIdx idx, const QString& text)
184 {
185 Parent::setText(listView()->mapIdx(idx), text);
186 }
187 QString text(colIdx idx) const
188 {
189 return Parent::text(listView()->mapIdx(idx));
190 }
191 void setPixmap(colIdx idx, const QPixmap& pm)
192 {
193 Parent::setPixmap(listView()->mapIdx(idx), pm);
194 }
195 const QPixmap* pixmap(colIdx idx) const
196 {
197 return Parent::pixmap(listView()->mapIdx(idx));
198 }
199 void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
200
201 ConfigItem* nextItem;
202 struct menu *menu;
203 bool visible;
204 bool goParent;
205};
206
207class ConfigLineEdit : public QLineEdit {
208 Q_OBJECT
209 typedef class QLineEdit Parent;
210public:
211 ConfigLineEdit(ConfigView* parent)
212 : Parent(parent)
213 { }
214 ConfigView* parent(void) const
215 {
216 return (ConfigView*)Parent::parent();
217 }
218 void show(ConfigItem *i);
219 void keyPressEvent(QKeyEvent *e);
220
221public:
222 ConfigItem *item;
223};
224
225class ConfigMainWindow : public QMainWindow {
226 Q_OBJECT
227public:
228 ConfigMainWindow(void);
229public slots:
230 void setHelp(QListViewItem* item);
231 void changeMenu(struct menu *);
232 void listFocusChanged(void);
233 void goBack(void);
234 void loadConfig(void);
235 void saveConfig(void);
236 void saveConfigAs(void);
237 void showSingleView(void);
238 void showSplitView(void);
239 void showFullView(void);
240 void setShowAll(bool);
241 void setShowDebug(bool);
242 void setShowRange(bool);
243 void setShowName(bool);
244 void setShowData(bool);
245 void showIntro(void);
246 void showAbout(void);
247 void saveSettings(void);
248
249protected:
250 void closeEvent(QCloseEvent *e);
251
252 ConfigView *menuView;
253 ConfigList *menuList;
254 ConfigView *configView;
255 ConfigList *configList;
256 QTextView *helpText;
257 QToolBar *toolBar;
258 QAction *backAction;
259 QSplitter* split1;
260 QSplitter* split2;
261
262 bool showDebug;
263};
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
new file mode 100644
index 000000000000..affa52f5c651
--- /dev/null
+++ b/scripts/kconfig/symbol.c
@@ -0,0 +1,816 @@
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <ctype.h>
7#include <stdlib.h>
8#include <string.h>
9#include <regex.h>
10#include <sys/utsname.h>
11
12#define LKC_DIRECT_LINK
13#include "lkc.h"
14
15struct symbol symbol_yes = {
16 .name = "y",
17 .curr = { "y", yes },
18 .flags = SYMBOL_YES|SYMBOL_VALID,
19}, symbol_mod = {
20 .name = "m",
21 .curr = { "m", mod },
22 .flags = SYMBOL_MOD|SYMBOL_VALID,
23}, symbol_no = {
24 .name = "n",
25 .curr = { "n", no },
26 .flags = SYMBOL_NO|SYMBOL_VALID,
27}, symbol_empty = {
28 .name = "",
29 .curr = { "", no },
30 .flags = SYMBOL_VALID,
31};
32
33int sym_change_count;
34struct symbol *modules_sym;
35tristate modules_val;
36
37void sym_add_default(struct symbol *sym, const char *def)
38{
39 struct property *prop = prop_alloc(P_DEFAULT, sym);
40
41 prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
42}
43
44void sym_init(void)
45{
46 struct symbol *sym;
47 struct utsname uts;
48 char *p;
49 static bool inited = false;
50
51 if (inited)
52 return;
53 inited = true;
54
55 uname(&uts);
56
57 sym = sym_lookup("ARCH", 0);
58 sym->type = S_STRING;
59 sym->flags |= SYMBOL_AUTO;
60 p = getenv("ARCH");
61 if (p)
62 sym_add_default(sym, p);
63
64 sym = sym_lookup("KERNELRELEASE", 0);
65 sym->type = S_STRING;
66 sym->flags |= SYMBOL_AUTO;
67 p = getenv("KERNELRELEASE");
68 if (p)
69 sym_add_default(sym, p);
70
71 sym = sym_lookup("UNAME_RELEASE", 0);
72 sym->type = S_STRING;
73 sym->flags |= SYMBOL_AUTO;
74 sym_add_default(sym, uts.release);
75}
76
77enum symbol_type sym_get_type(struct symbol *sym)
78{
79 enum symbol_type type = sym->type;
80
81 if (type == S_TRISTATE) {
82 if (sym_is_choice_value(sym) && sym->visible == yes)
83 type = S_BOOLEAN;
84 else if (modules_val == no)
85 type = S_BOOLEAN;
86 }
87 return type;
88}
89
90const char *sym_type_name(enum symbol_type type)
91{
92 switch (type) {
93 case S_BOOLEAN:
94 return "boolean";
95 case S_TRISTATE:
96 return "tristate";
97 case S_INT:
98 return "integer";
99 case S_HEX:
100 return "hex";
101 case S_STRING:
102 return "string";
103 case S_UNKNOWN:
104 return "unknown";
105 case S_OTHER:
106 break;
107 }
108 return "???";
109}
110
111struct property *sym_get_choice_prop(struct symbol *sym)
112{
113 struct property *prop;
114
115 for_all_choices(sym, prop)
116 return prop;
117 return NULL;
118}
119
120struct property *sym_get_default_prop(struct symbol *sym)
121{
122 struct property *prop;
123
124 for_all_defaults(sym, prop) {
125 prop->visible.tri = expr_calc_value(prop->visible.expr);
126 if (prop->visible.tri != no)
127 return prop;
128 }
129 return NULL;
130}
131
132struct property *sym_get_range_prop(struct symbol *sym)
133{
134 struct property *prop;
135
136 for_all_properties(sym, prop, P_RANGE) {
137 prop->visible.tri = expr_calc_value(prop->visible.expr);
138 if (prop->visible.tri != no)
139 return prop;
140 }
141 return NULL;
142}
143
144static void sym_calc_visibility(struct symbol *sym)
145{
146 struct property *prop;
147 tristate tri;
148
149 /* any prompt visible? */
150 tri = no;
151 for_all_prompts(sym, prop) {
152 prop->visible.tri = expr_calc_value(prop->visible.expr);
153 tri = E_OR(tri, prop->visible.tri);
154 }
155 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
156 tri = yes;
157 if (sym->visible != tri) {
158 sym->visible = tri;
159 sym_set_changed(sym);
160 }
161 if (sym_is_choice_value(sym))
162 return;
163 tri = no;
164 if (sym->rev_dep.expr)
165 tri = expr_calc_value(sym->rev_dep.expr);
166 if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
167 tri = yes;
168 if (sym->rev_dep.tri != tri) {
169 sym->rev_dep.tri = tri;
170 sym_set_changed(sym);
171 }
172}
173
174static struct symbol *sym_calc_choice(struct symbol *sym)
175{
176 struct symbol *def_sym;
177 struct property *prop;
178 struct expr *e;
179
180 /* is the user choice visible? */
181 def_sym = sym->user.val;
182 if (def_sym) {
183 sym_calc_visibility(def_sym);
184 if (def_sym->visible != no)
185 return def_sym;
186 }
187
188 /* any of the defaults visible? */
189 for_all_defaults(sym, prop) {
190 prop->visible.tri = expr_calc_value(prop->visible.expr);
191 if (prop->visible.tri == no)
192 continue;
193 def_sym = prop_get_symbol(prop);
194 sym_calc_visibility(def_sym);
195 if (def_sym->visible != no)
196 return def_sym;
197 }
198
199 /* just get the first visible value */
200 prop = sym_get_choice_prop(sym);
201 for (e = prop->expr; e; e = e->left.expr) {
202 def_sym = e->right.sym;
203 sym_calc_visibility(def_sym);
204 if (def_sym->visible != no)
205 return def_sym;
206 }
207
208 /* no choice? reset tristate value */
209 sym->curr.tri = no;
210 return NULL;
211}
212
213void sym_calc_value(struct symbol *sym)
214{
215 struct symbol_value newval, oldval;
216 struct property *prop;
217 struct expr *e;
218
219 if (!sym)
220 return;
221
222 if (sym->flags & SYMBOL_VALID)
223 return;
224 sym->flags |= SYMBOL_VALID;
225
226 oldval = sym->curr;
227
228 switch (sym->type) {
229 case S_INT:
230 case S_HEX:
231 case S_STRING:
232 newval = symbol_empty.curr;
233 break;
234 case S_BOOLEAN:
235 case S_TRISTATE:
236 newval = symbol_no.curr;
237 break;
238 default:
239 sym->curr.val = sym->name;
240 sym->curr.tri = no;
241 return;
242 }
243 if (!sym_is_choice_value(sym))
244 sym->flags &= ~SYMBOL_WRITE;
245
246 sym_calc_visibility(sym);
247
248 /* set default if recursively called */
249 sym->curr = newval;
250
251 switch (sym_get_type(sym)) {
252 case S_BOOLEAN:
253 case S_TRISTATE:
254 if (sym_is_choice_value(sym) && sym->visible == yes) {
255 prop = sym_get_choice_prop(sym);
256 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
257 } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
258 sym->flags |= SYMBOL_WRITE;
259 if (sym_has_value(sym))
260 newval.tri = sym->user.tri;
261 else if (!sym_is_choice(sym)) {
262 prop = sym_get_default_prop(sym);
263 if (prop)
264 newval.tri = expr_calc_value(prop->expr);
265 }
266 newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
267 } else if (!sym_is_choice(sym)) {
268 prop = sym_get_default_prop(sym);
269 if (prop) {
270 sym->flags |= SYMBOL_WRITE;
271 newval.tri = expr_calc_value(prop->expr);
272 }
273 }
274 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
275 newval.tri = yes;
276 break;
277 case S_STRING:
278 case S_HEX:
279 case S_INT:
280 if (sym->visible != no) {
281 sym->flags |= SYMBOL_WRITE;
282 if (sym_has_value(sym)) {
283 newval.val = sym->user.val;
284 break;
285 }
286 }
287 prop = sym_get_default_prop(sym);
288 if (prop) {
289 struct symbol *ds = prop_get_symbol(prop);
290 if (ds) {
291 sym->flags |= SYMBOL_WRITE;
292 sym_calc_value(ds);
293 newval.val = ds->curr.val;
294 }
295 }
296 break;
297 default:
298 ;
299 }
300
301 sym->curr = newval;
302 if (sym_is_choice(sym) && newval.tri == yes)
303 sym->curr.val = sym_calc_choice(sym);
304
305 if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
306 sym_set_changed(sym);
307 if (modules_sym == sym)
308 modules_val = modules_sym->curr.tri;
309
310 if (sym_is_choice(sym)) {
311 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
312 prop = sym_get_choice_prop(sym);
313 for (e = prop->expr; e; e = e->left.expr) {
314 e->right.sym->flags |= flags;
315 if (flags & SYMBOL_CHANGED)
316 sym_set_changed(e->right.sym);
317 }
318 }
319}
320
321void sym_clear_all_valid(void)
322{
323 struct symbol *sym;
324 int i;
325
326 for_all_symbols(i, sym)
327 sym->flags &= ~SYMBOL_VALID;
328 sym_change_count++;
329 if (modules_sym)
330 sym_calc_value(modules_sym);
331}
332
333void sym_set_changed(struct symbol *sym)
334{
335 struct property *prop;
336
337 sym->flags |= SYMBOL_CHANGED;
338 for (prop = sym->prop; prop; prop = prop->next) {
339 if (prop->menu)
340 prop->menu->flags |= MENU_CHANGED;
341 }
342}
343
344void sym_set_all_changed(void)
345{
346 struct symbol *sym;
347 int i;
348
349 for_all_symbols(i, sym)
350 sym_set_changed(sym);
351}
352
353bool sym_tristate_within_range(struct symbol *sym, tristate val)
354{
355 int type = sym_get_type(sym);
356
357 if (sym->visible == no)
358 return false;
359
360 if (type != S_BOOLEAN && type != S_TRISTATE)
361 return false;
362
363 if (type == S_BOOLEAN && val == mod)
364 return false;
365 if (sym->visible <= sym->rev_dep.tri)
366 return false;
367 if (sym_is_choice_value(sym) && sym->visible == yes)
368 return val == yes;
369 return val >= sym->rev_dep.tri && val <= sym->visible;
370}
371
372bool sym_set_tristate_value(struct symbol *sym, tristate val)
373{
374 tristate oldval = sym_get_tristate_value(sym);
375
376 if (oldval != val && !sym_tristate_within_range(sym, val))
377 return false;
378
379 if (sym->flags & SYMBOL_NEW) {
380 sym->flags &= ~SYMBOL_NEW;
381 sym_set_changed(sym);
382 }
383 if (sym_is_choice_value(sym) && val == yes) {
384 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
385
386 cs->user.val = sym;
387 cs->flags &= ~SYMBOL_NEW;
388 }
389
390 sym->user.tri = val;
391 if (oldval != val) {
392 sym_clear_all_valid();
393 if (sym == modules_sym)
394 sym_set_all_changed();
395 }
396
397 return true;
398}
399
400tristate sym_toggle_tristate_value(struct symbol *sym)
401{
402 tristate oldval, newval;
403
404 oldval = newval = sym_get_tristate_value(sym);
405 do {
406 switch (newval) {
407 case no:
408 newval = mod;
409 break;
410 case mod:
411 newval = yes;
412 break;
413 case yes:
414 newval = no;
415 break;
416 }
417 if (sym_set_tristate_value(sym, newval))
418 break;
419 } while (oldval != newval);
420 return newval;
421}
422
423bool sym_string_valid(struct symbol *sym, const char *str)
424{
425 signed char ch;
426
427 switch (sym->type) {
428 case S_STRING:
429 return true;
430 case S_INT:
431 ch = *str++;
432 if (ch == '-')
433 ch = *str++;
434 if (!isdigit(ch))
435 return false;
436 if (ch == '0' && *str != 0)
437 return false;
438 while ((ch = *str++)) {
439 if (!isdigit(ch))
440 return false;
441 }
442 return true;
443 case S_HEX:
444 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
445 str += 2;
446 ch = *str++;
447 do {
448 if (!isxdigit(ch))
449 return false;
450 } while ((ch = *str++));
451 return true;
452 case S_BOOLEAN:
453 case S_TRISTATE:
454 switch (str[0]) {
455 case 'y': case 'Y':
456 case 'm': case 'M':
457 case 'n': case 'N':
458 return true;
459 }
460 return false;
461 default:
462 return false;
463 }
464}
465
466bool sym_string_within_range(struct symbol *sym, const char *str)
467{
468 struct property *prop;
469 int val;
470
471 switch (sym->type) {
472 case S_STRING:
473 return sym_string_valid(sym, str);
474 case S_INT:
475 if (!sym_string_valid(sym, str))
476 return false;
477 prop = sym_get_range_prop(sym);
478 if (!prop)
479 return true;
480 val = strtol(str, NULL, 10);
481 return val >= strtol(prop->expr->left.sym->name, NULL, 10) &&
482 val <= strtol(prop->expr->right.sym->name, NULL, 10);
483 case S_HEX:
484 if (!sym_string_valid(sym, str))
485 return false;
486 prop = sym_get_range_prop(sym);
487 if (!prop)
488 return true;
489 val = strtol(str, NULL, 16);
490 return val >= strtol(prop->expr->left.sym->name, NULL, 16) &&
491 val <= strtol(prop->expr->right.sym->name, NULL, 16);
492 case S_BOOLEAN:
493 case S_TRISTATE:
494 switch (str[0]) {
495 case 'y': case 'Y':
496 return sym_tristate_within_range(sym, yes);
497 case 'm': case 'M':
498 return sym_tristate_within_range(sym, mod);
499 case 'n': case 'N':
500 return sym_tristate_within_range(sym, no);
501 }
502 return false;
503 default:
504 return false;
505 }
506}
507
508bool sym_set_string_value(struct symbol *sym, const char *newval)
509{
510 const char *oldval;
511 char *val;
512 int size;
513
514 switch (sym->type) {
515 case S_BOOLEAN:
516 case S_TRISTATE:
517 switch (newval[0]) {
518 case 'y': case 'Y':
519 return sym_set_tristate_value(sym, yes);
520 case 'm': case 'M':
521 return sym_set_tristate_value(sym, mod);
522 case 'n': case 'N':
523 return sym_set_tristate_value(sym, no);
524 }
525 return false;
526 default:
527 ;
528 }
529
530 if (!sym_string_within_range(sym, newval))
531 return false;
532
533 if (sym->flags & SYMBOL_NEW) {
534 sym->flags &= ~SYMBOL_NEW;
535 sym_set_changed(sym);
536 }
537
538 oldval = sym->user.val;
539 size = strlen(newval) + 1;
540 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
541 size += 2;
542 sym->user.val = val = malloc(size);
543 *val++ = '0';
544 *val++ = 'x';
545 } else if (!oldval || strcmp(oldval, newval))
546 sym->user.val = val = malloc(size);
547 else
548 return true;
549
550 strcpy(val, newval);
551 free((void *)oldval);
552 sym_clear_all_valid();
553
554 return true;
555}
556
557const char *sym_get_string_value(struct symbol *sym)
558{
559 tristate val;
560
561 switch (sym->type) {
562 case S_BOOLEAN:
563 case S_TRISTATE:
564 val = sym_get_tristate_value(sym);
565 switch (val) {
566 case no:
567 return "n";
568 case mod:
569 return "m";
570 case yes:
571 return "y";
572 }
573 break;
574 default:
575 ;
576 }
577 return (const char *)sym->curr.val;
578}
579
580bool sym_is_changable(struct symbol *sym)
581{
582 return sym->visible > sym->rev_dep.tri;
583}
584
585struct symbol *sym_lookup(const char *name, int isconst)
586{
587 struct symbol *symbol;
588 const char *ptr;
589 char *new_name;
590 int hash = 0;
591
592 if (name) {
593 if (name[0] && !name[1]) {
594 switch (name[0]) {
595 case 'y': return &symbol_yes;
596 case 'm': return &symbol_mod;
597 case 'n': return &symbol_no;
598 }
599 }
600 for (ptr = name; *ptr; ptr++)
601 hash += *ptr;
602 hash &= 0xff;
603
604 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
605 if (!strcmp(symbol->name, name)) {
606 if ((isconst && symbol->flags & SYMBOL_CONST) ||
607 (!isconst && !(symbol->flags & SYMBOL_CONST)))
608 return symbol;
609 }
610 }
611 new_name = strdup(name);
612 } else {
613 new_name = NULL;
614 hash = 256;
615 }
616
617 symbol = malloc(sizeof(*symbol));
618 memset(symbol, 0, sizeof(*symbol));
619 symbol->name = new_name;
620 symbol->type = S_UNKNOWN;
621 symbol->flags = SYMBOL_NEW;
622 if (isconst)
623 symbol->flags |= SYMBOL_CONST;
624
625 symbol->next = symbol_hash[hash];
626 symbol_hash[hash] = symbol;
627
628 return symbol;
629}
630
631struct symbol *sym_find(const char *name)
632{
633 struct symbol *symbol = NULL;
634 const char *ptr;
635 int hash = 0;
636
637 if (!name)
638 return NULL;
639
640 if (name[0] && !name[1]) {
641 switch (name[0]) {
642 case 'y': return &symbol_yes;
643 case 'm': return &symbol_mod;
644 case 'n': return &symbol_no;
645 }
646 }
647 for (ptr = name; *ptr; ptr++)
648 hash += *ptr;
649 hash &= 0xff;
650
651 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
652 if (!strcmp(symbol->name, name) &&
653 !(symbol->flags & SYMBOL_CONST))
654 break;
655 }
656
657 return symbol;
658}
659
660struct symbol **sym_re_search(const char *pattern)
661{
662 struct symbol *sym, **sym_arr = NULL;
663 int i, cnt, size;
664 regex_t re;
665
666 cnt = size = 0;
667 /* Skip if empty */
668 if (strlen(pattern) == 0)
669 return NULL;
670 if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
671 return NULL;
672
673 for_all_symbols(i, sym) {
674 if (sym->flags & SYMBOL_CONST || !sym->name)
675 continue;
676 if (regexec(&re, sym->name, 0, NULL, 0))
677 continue;
678 if (cnt + 1 >= size) {
679 void *tmp = sym_arr;
680 size += 16;
681 sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
682 if (!sym_arr) {
683 free(tmp);
684 return NULL;
685 }
686 }
687 sym_arr[cnt++] = sym;
688 }
689 if (sym_arr)
690 sym_arr[cnt] = NULL;
691 regfree(&re);
692
693 return sym_arr;
694}
695
696
697struct symbol *sym_check_deps(struct symbol *sym);
698
699static struct symbol *sym_check_expr_deps(struct expr *e)
700{
701 struct symbol *sym;
702
703 if (!e)
704 return NULL;
705 switch (e->type) {
706 case E_OR:
707 case E_AND:
708 sym = sym_check_expr_deps(e->left.expr);
709 if (sym)
710 return sym;
711 return sym_check_expr_deps(e->right.expr);
712 case E_NOT:
713 return sym_check_expr_deps(e->left.expr);
714 case E_EQUAL:
715 case E_UNEQUAL:
716 sym = sym_check_deps(e->left.sym);
717 if (sym)
718 return sym;
719 return sym_check_deps(e->right.sym);
720 case E_SYMBOL:
721 return sym_check_deps(e->left.sym);
722 default:
723 break;
724 }
725 printf("Oops! How to check %d?\n", e->type);
726 return NULL;
727}
728
729struct symbol *sym_check_deps(struct symbol *sym)
730{
731 struct symbol *sym2;
732 struct property *prop;
733
734 if (sym->flags & SYMBOL_CHECK_DONE)
735 return NULL;
736 if (sym->flags & SYMBOL_CHECK) {
737 printf("Warning! Found recursive dependency: %s", sym->name);
738 return sym;
739 }
740
741 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
742 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
743 if (sym2)
744 goto out;
745
746 for (prop = sym->prop; prop; prop = prop->next) {
747 if (prop->type == P_CHOICE || prop->type == P_SELECT)
748 continue;
749 sym2 = sym_check_expr_deps(prop->visible.expr);
750 if (sym2)
751 goto out;
752 if (prop->type != P_DEFAULT || sym_is_choice(sym))
753 continue;
754 sym2 = sym_check_expr_deps(prop->expr);
755 if (sym2)
756 goto out;
757 }
758out:
759 if (sym2)
760 printf(" %s", sym->name);
761 sym->flags &= ~SYMBOL_CHECK;
762 return sym2;
763}
764
765struct property *prop_alloc(enum prop_type type, struct symbol *sym)
766{
767 struct property *prop;
768 struct property **propp;
769
770 prop = malloc(sizeof(*prop));
771 memset(prop, 0, sizeof(*prop));
772 prop->type = type;
773 prop->sym = sym;
774 prop->file = current_file;
775 prop->lineno = zconf_lineno();
776
777 /* append property to the prop list of symbol */
778 if (sym) {
779 for (propp = &sym->prop; *propp; propp = &(*propp)->next)
780 ;
781 *propp = prop;
782 }
783
784 return prop;
785}
786
787struct symbol *prop_get_symbol(struct property *prop)
788{
789 if (prop->expr && (prop->expr->type == E_SYMBOL ||
790 prop->expr->type == E_CHOICE))
791 return prop->expr->left.sym;
792 return NULL;
793}
794
795const char *prop_get_type_name(enum prop_type type)
796{
797 switch (type) {
798 case P_PROMPT:
799 return "prompt";
800 case P_COMMENT:
801 return "comment";
802 case P_MENU:
803 return "menu";
804 case P_DEFAULT:
805 return "default";
806 case P_CHOICE:
807 return "choice";
808 case P_SELECT:
809 return "select";
810 case P_RANGE:
811 return "range";
812 case P_UNKNOWN:
813 break;
814 }
815 return "unknown";
816}
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
new file mode 100644
index 000000000000..1fa4c0b801b3
--- /dev/null
+++ b/scripts/kconfig/util.c
@@ -0,0 +1,109 @@
1/*
2 * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
3 * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
4 *
5 * Released under the terms of the GNU GPL v2.0.
6 */
7
8#include <string.h>
9#include "lkc.h"
10
11/* file already present in list? If not add it */
12struct file *file_lookup(const char *name)
13{
14 struct file *file;
15
16 for (file = file_list; file; file = file->next) {
17 if (!strcmp(name, file->name))
18 return file;
19 }
20
21 file = malloc(sizeof(*file));
22 memset(file, 0, sizeof(*file));
23 file->name = strdup(name);
24 file->next = file_list;
25 file_list = file;
26 return file;
27}
28
29/* write a dependency file as used by kbuild to track dependencies */
30int file_write_dep(const char *name)
31{
32 struct file *file;
33 FILE *out;
34
35 if (!name)
36 name = ".config.cmd";
37 out = fopen("..config.tmp", "w");
38 if (!out)
39 return 1;
40 fprintf(out, "deps_config := \\\n");
41 for (file = file_list; file; file = file->next) {
42 if (file->next)
43 fprintf(out, "\t%s \\\n", file->name);
44 else
45 fprintf(out, "\t%s\n", file->name);
46 }
47 fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
48 fclose(out);
49 rename("..config.tmp", name);
50 return 0;
51}
52
53
54/* Allocate initial growable sting */
55struct gstr str_new(void)
56{
57 struct gstr gs;
58 gs.s = malloc(sizeof(char) * 64);
59 gs.len = 16;
60 strcpy(gs.s, "\0");
61 return gs;
62}
63
64/* Allocate and assign growable string */
65struct gstr str_assign(const char *s)
66{
67 struct gstr gs;
68 gs.s = strdup(s);
69 gs.len = strlen(s) + 1;
70 return gs;
71}
72
73/* Free storage for growable string */
74void str_free(struct gstr *gs)
75{
76 if (gs->s)
77 free(gs->s);
78 gs->s = NULL;
79 gs->len = 0;
80}
81
82/* Append to growable string */
83void str_append(struct gstr *gs, const char *s)
84{
85 size_t l = strlen(gs->s) + strlen(s) + 1;
86 if (l > gs->len) {
87 gs->s = realloc(gs->s, l);
88 gs->len = l;
89 }
90 strcat(gs->s, s);
91}
92
93/* Append printf formatted string to growable string */
94void str_printf(struct gstr *gs, const char *fmt, ...)
95{
96 va_list ap;
97 char s[10000]; /* big enough... */
98 va_start(ap, fmt);
99 vsnprintf(s, sizeof(s), fmt, ap);
100 str_append(gs, s);
101 va_end(ap);
102}
103
104/* Retreive value of growable string */
105const char *str_get(struct gstr *gs)
106{
107 return gs->s;
108}
109
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
new file mode 100644
index 000000000000..55517b2877cd
--- /dev/null
+++ b/scripts/kconfig/zconf.l
@@ -0,0 +1,366 @@
1%option backup nostdinit noyywrap never-interactive full ecs
2%option 8bit backup nodefault perf-report perf-report
3%x COMMAND HELP STRING PARAM
4%{
5/*
6 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
7 * Released under the terms of the GNU GPL v2.0.
8 */
9
10#include <limits.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15
16#define LKC_DIRECT_LINK
17#include "lkc.h"
18
19#define START_STRSIZE 16
20
21char *text;
22static char *text_ptr;
23static int text_size, text_asize;
24
25struct buffer {
26 struct buffer *parent;
27 YY_BUFFER_STATE state;
28};
29
30struct buffer *current_buf;
31
32static int last_ts, first_ts;
33
34static void zconf_endhelp(void);
35static struct buffer *zconf_endfile(void);
36
37void new_string(void)
38{
39 text = malloc(START_STRSIZE);
40 text_asize = START_STRSIZE;
41 text_ptr = text;
42 text_size = 0;
43 *text_ptr = 0;
44}
45
46void append_string(const char *str, int size)
47{
48 int new_size = text_size + size + 1;
49 if (new_size > text_asize) {
50 text = realloc(text, new_size);
51 text_asize = new_size;
52 text_ptr = text + text_size;
53 }
54 memcpy(text_ptr, str, size);
55 text_ptr += size;
56 text_size += size;
57 *text_ptr = 0;
58}
59
60void alloc_string(const char *str, int size)
61{
62 text = malloc(size + 1);
63 memcpy(text, str, size);
64 text[size] = 0;
65}
66%}
67
68ws [ \n\t]
69n [A-Za-z0-9_]
70
71%%
72 int str = 0;
73 int ts, i;
74
75[ \t]*#.*\n current_file->lineno++;
76[ \t]*#.*
77
78[ \t]*\n current_file->lineno++; return T_EOL;
79
80[ \t]+ {
81 BEGIN(COMMAND);
82}
83
84. {
85 unput(yytext[0]);
86 BEGIN(COMMAND);
87}
88
89
90<COMMAND>{
91 "mainmenu" BEGIN(PARAM); return T_MAINMENU;
92 "menu" BEGIN(PARAM); return T_MENU;
93 "endmenu" BEGIN(PARAM); return T_ENDMENU;
94 "source" BEGIN(PARAM); return T_SOURCE;
95 "choice" BEGIN(PARAM); return T_CHOICE;
96 "endchoice" BEGIN(PARAM); return T_ENDCHOICE;
97 "comment" BEGIN(PARAM); return T_COMMENT;
98 "config" BEGIN(PARAM); return T_CONFIG;
99 "menuconfig" BEGIN(PARAM); return T_MENUCONFIG;
100 "help" BEGIN(PARAM); return T_HELP;
101 "if" BEGIN(PARAM); return T_IF;
102 "endif" BEGIN(PARAM); return T_ENDIF;
103 "depends" BEGIN(PARAM); return T_DEPENDS;
104 "requires" BEGIN(PARAM); return T_REQUIRES;
105 "optional" BEGIN(PARAM); return T_OPTIONAL;
106 "default" BEGIN(PARAM); return T_DEFAULT;
107 "prompt" BEGIN(PARAM); return T_PROMPT;
108 "tristate" BEGIN(PARAM); return T_TRISTATE;
109 "def_tristate" BEGIN(PARAM); return T_DEF_TRISTATE;
110 "bool" 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;
114 "int" BEGIN(PARAM); return T_INT;
115 "hex" BEGIN(PARAM); return T_HEX;
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;
120 {n}+ {
121 alloc_string(yytext, yyleng);
122 zconflval.string = text;
123 return T_WORD;
124 }
125 .
126 \n current_file->lineno++; BEGIN(INITIAL);
127}
128
129<PARAM>{
130 "&&" return T_AND;
131 "||" return T_OR;
132 "(" return T_OPEN_PAREN;
133 ")" return T_CLOSE_PAREN;
134 "!" return T_NOT;
135 "=" return T_EQUAL;
136 "!=" return T_UNEQUAL;
137 "if" return T_IF;
138 "on" return T_ON;
139 \"|\' {
140 str = yytext[0];
141 new_string();
142 BEGIN(STRING);
143 }
144 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
145 --- /* ignore */
146 ({n}|[-/.])+ {
147 alloc_string(yytext, yyleng);
148 zconflval.string = text;
149 return T_WORD;
150 }
151 #.* /* comment */
152 \\\n current_file->lineno++;
153 .
154 <<EOF>> {
155 BEGIN(INITIAL);
156 }
157}
158
159<STRING>{
160 [^'"\\\n]+/\n {
161 append_string(yytext, yyleng);
162 zconflval.string = text;
163 return T_WORD_QUOTE;
164 }
165 [^'"\\\n]+ {
166 append_string(yytext, yyleng);
167 }
168 \\.?/\n {
169 append_string(yytext + 1, yyleng - 1);
170 zconflval.string = text;
171 return T_WORD_QUOTE;
172 }
173 \\.? {
174 append_string(yytext + 1, yyleng - 1);
175 }
176 \'|\" {
177 if (str == yytext[0]) {
178 BEGIN(PARAM);
179 zconflval.string = text;
180 return T_WORD_QUOTE;
181 } else
182 append_string(yytext, 1);
183 }
184 \n {
185 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
186 current_file->lineno++;
187 BEGIN(INITIAL);
188 return T_EOL;
189 }
190 <<EOF>> {
191 BEGIN(INITIAL);
192 }
193}
194
195<HELP>{
196 [ \t]+ {
197 ts = 0;
198 for (i = 0; i < yyleng; i++) {
199 if (yytext[i] == '\t')
200 ts = (ts & ~7) + 8;
201 else
202 ts++;
203 }
204 last_ts = ts;
205 if (first_ts) {
206 if (ts < first_ts) {
207 zconf_endhelp();
208 return T_HELPTEXT;
209 }
210 ts -= first_ts;
211 while (ts > 8) {
212 append_string(" ", 8);
213 ts -= 8;
214 }
215 append_string(" ", ts);
216 }
217 }
218 [ \t]*\n/[^ \t\n] {
219 current_file->lineno++;
220 zconf_endhelp();
221 return T_HELPTEXT;
222 }
223 [ \t]*\n {
224 current_file->lineno++;
225 append_string("\n", 1);
226 }
227 [^ \t\n].* {
228 append_string(yytext, yyleng);
229 if (!first_ts)
230 first_ts = last_ts;
231 }
232 <<EOF>> {
233 zconf_endhelp();
234 return T_HELPTEXT;
235 }
236}
237
238<<EOF>> {
239 if (current_buf) {
240 zconf_endfile();
241 return T_EOF;
242 }
243 fclose(yyin);
244 yyterminate();
245}
246
247%%
248void zconf_starthelp(void)
249{
250 new_string();
251 last_ts = first_ts = 0;
252 BEGIN(HELP);
253}
254
255static void zconf_endhelp(void)
256{
257 zconflval.string = text;
258 BEGIN(INITIAL);
259}
260
261
262/*
263 * Try to open specified file with following names:
264 * ./name
265 * $(srctree)/name
266 * The latter is used when srctree is separate from objtree
267 * when compiling the kernel.
268 * Return NULL if file is not found.
269 */
270FILE *zconf_fopen(const char *name)
271{
272 char *env, fullname[PATH_MAX+1];
273 FILE *f;
274
275 f = fopen(name, "r");
276 if (!f && name[0] != '/') {
277 env = getenv(SRCTREE);
278 if (env) {
279 sprintf(fullname, "%s/%s", env, name);
280 f = fopen(fullname, "r");
281 }
282 }
283 return f;
284}
285
286void zconf_initscan(const char *name)
287{
288 yyin = zconf_fopen(name);
289 if (!yyin) {
290 printf("can't find file %s\n", name);
291 exit(1);
292 }
293
294 current_buf = malloc(sizeof(*current_buf));
295 memset(current_buf, 0, sizeof(*current_buf));
296
297 current_file = file_lookup(name);
298 current_file->lineno = 1;
299 current_file->flags = FILE_BUSY;
300}
301
302void zconf_nextfile(const char *name)
303{
304 struct file *file = file_lookup(name);
305 struct buffer *buf = malloc(sizeof(*buf));
306 memset(buf, 0, sizeof(*buf));
307
308 current_buf->state = YY_CURRENT_BUFFER;
309 yyin = zconf_fopen(name);
310 if (!yyin) {
311 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
312 exit(1);
313 }
314 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
315 buf->parent = current_buf;
316 current_buf = buf;
317
318 if (file->flags & FILE_BUSY) {
319 printf("recursive scan (%s)?\n", name);
320 exit(1);
321 }
322 if (file->flags & FILE_SCANNED) {
323 printf("file %s already scanned?\n", name);
324 exit(1);
325 }
326 file->flags |= FILE_BUSY;
327 file->lineno = 1;
328 file->parent = current_file;
329 current_file = file;
330}
331
332static struct buffer *zconf_endfile(void)
333{
334 struct buffer *parent;
335
336 current_file->flags |= FILE_SCANNED;
337 current_file->flags &= ~FILE_BUSY;
338 current_file = current_file->parent;
339
340 parent = current_buf->parent;
341 if (parent) {
342 fclose(yyin);
343 yy_delete_buffer(YY_CURRENT_BUFFER);
344 yy_switch_to_buffer(parent->state);
345 }
346 free(current_buf);
347 current_buf = parent;
348
349 return parent;
350}
351
352int zconf_lineno(void)
353{
354 if (current_buf)
355 return current_file->lineno - 1;
356 else
357 return 0;
358}
359
360char *zconf_curname(void)
361{
362 if (current_buf)
363 return current_file->name;
364 else
365 return "<none>";
366}
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
new file mode 100644
index 000000000000..f163d8d2d9ef
--- /dev/null
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -0,0 +1,2130 @@
1/* A Bison parser, made by GNU Bison 1.875a. */
2
3/* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21/* As a special exception, when this file is copied by Bison into a
22 Bison output file, you may use that output file without restriction.
23 This special exception was added by the Free Software Foundation
24 in version 1.24 of Bison. */
25
26/* Written by Richard Stallman by simplifying the original so called
27 ``semantic'' parser. */
28
29/* All symbols defined below should begin with yy or YY, to avoid
30 infringing on user name space. This should be done even for local
31 variables, as they might otherwise be expanded by user macros.
32 There are some unavoidable exceptions within include files to
33 define necessary library symbols; they are noted "INFRINGES ON
34 USER NAME SPACE" below. */
35
36/* Identify Bison output. */
37#define YYBISON 1
38
39/* Skeleton name. */
40#define YYSKELETON_NAME "yacc.c"
41
42/* Pure parsers. */
43#define YYPURE 0
44
45/* Using locations. */
46#define YYLSP_NEEDED 0
47
48/* If NAME_PREFIX is specified substitute the variables and functions
49 names. */
50#define yyparse zconfparse
51#define yylex zconflex
52#define yyerror zconferror
53#define yylval zconflval
54#define yychar zconfchar
55#define yydebug zconfdebug
56#define yynerrs zconfnerrs
57
58
59/* Tokens. */
60#ifndef YYTOKENTYPE
61# define YYTOKENTYPE
62 /* Put the tokens into the symbol table, so that GDB and other debuggers
63 know about them. */
64 enum yytokentype {
65 T_MAINMENU = 258,
66 T_MENU = 259,
67 T_ENDMENU = 260,
68 T_SOURCE = 261,
69 T_CHOICE = 262,
70 T_ENDCHOICE = 263,
71 T_COMMENT = 264,
72 T_CONFIG = 265,
73 T_MENUCONFIG = 266,
74 T_HELP = 267,
75 T_HELPTEXT = 268,
76 T_IF = 269,
77 T_ENDIF = 270,
78 T_DEPENDS = 271,
79 T_REQUIRES = 272,
80 T_OPTIONAL = 273,
81 T_PROMPT = 274,
82 T_DEFAULT = 275,
83 T_TRISTATE = 276,
84 T_DEF_TRISTATE = 277,
85 T_BOOLEAN = 278,
86 T_DEF_BOOLEAN = 279,
87 T_STRING = 280,
88 T_INT = 281,
89 T_HEX = 282,
90 T_WORD = 283,
91 T_WORD_QUOTE = 284,
92 T_UNEQUAL = 285,
93 T_EOF = 286,
94 T_EOL = 287,
95 T_CLOSE_PAREN = 288,
96 T_OPEN_PAREN = 289,
97 T_ON = 290,
98 T_SELECT = 291,
99 T_RANGE = 292,
100 T_OR = 293,
101 T_AND = 294,
102 T_EQUAL = 295,
103 T_NOT = 296
104 };
105#endif
106#define T_MAINMENU 258
107#define T_MENU 259
108#define T_ENDMENU 260
109#define T_SOURCE 261
110#define T_CHOICE 262
111#define T_ENDCHOICE 263
112#define T_COMMENT 264
113#define T_CONFIG 265
114#define T_MENUCONFIG 266
115#define T_HELP 267
116#define T_HELPTEXT 268
117#define T_IF 269
118#define T_ENDIF 270
119#define T_DEPENDS 271
120#define T_REQUIRES 272
121#define T_OPTIONAL 273
122#define T_PROMPT 274
123#define T_DEFAULT 275
124#define T_TRISTATE 276
125#define T_DEF_TRISTATE 277
126#define T_BOOLEAN 278
127#define T_DEF_BOOLEAN 279
128#define T_STRING 280
129#define T_INT 281
130#define T_HEX 282
131#define T_WORD 283
132#define T_WORD_QUOTE 284
133#define T_UNEQUAL 285
134#define T_EOF 286
135#define T_EOL 287
136#define T_CLOSE_PAREN 288
137#define T_OPEN_PAREN 289
138#define T_ON 290
139#define T_SELECT 291
140#define T_RANGE 292
141#define T_OR 293
142#define T_AND 294
143#define T_EQUAL 295
144#define T_NOT 296
145
146
147
148
149/* Copy the first part of user declarations. */
150
151
152/*
153 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
154 * Released under the terms of the GNU GPL v2.0.
155 */
156
157#include <ctype.h>
158#include <stdarg.h>
159#include <stdio.h>
160#include <stdlib.h>
161#include <string.h>
162#include <stdbool.h>
163
164#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
165
166#define PRINTD 0x0001
167#define DEBUG_PARSE 0x0002
168
169int cdebug = PRINTD;
170
171extern int zconflex(void);
172static void zconfprint(const char *err, ...);
173static void zconferror(const char *err);
174static bool zconf_endtoken(int token, int starttoken, int endtoken);
175
176struct symbol *symbol_hash[257];
177
178static struct menu *current_menu, *current_entry;
179
180#define YYERROR_VERBOSE
181
182
183/* Enabling traces. */
184#ifndef YYDEBUG
185# define YYDEBUG 0
186#endif
187
188/* Enabling verbose error messages. */
189#ifdef YYERROR_VERBOSE
190# undef YYERROR_VERBOSE
191# define YYERROR_VERBOSE 1
192#else
193# define YYERROR_VERBOSE 0
194#endif
195
196#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
197
198typedef union YYSTYPE {
199 int token;
200 char *string;
201 struct symbol *symbol;
202 struct expr *expr;
203 struct menu *menu;
204} YYSTYPE;
205/* Line 191 of yacc.c. */
206
207# define yystype YYSTYPE /* obsolescent; will be withdrawn */
208# define YYSTYPE_IS_DECLARED 1
209# define YYSTYPE_IS_TRIVIAL 1
210#endif
211
212
213
214/* Copy the second part of user declarations. */
215
216
217#define LKC_DIRECT_LINK
218#include "lkc.h"
219
220
221/* Line 214 of yacc.c. */
222
223
224#if ! defined (yyoverflow) || YYERROR_VERBOSE
225
226/* The parser invokes alloca or malloc; define the necessary symbols. */
227
228# if YYSTACK_USE_ALLOCA
229# define YYSTACK_ALLOC alloca
230# else
231# ifndef YYSTACK_USE_ALLOCA
232# if defined (alloca) || defined (_ALLOCA_H)
233# define YYSTACK_ALLOC alloca
234# else
235# ifdef __GNUC__
236# define YYSTACK_ALLOC __builtin_alloca
237# endif
238# endif
239# endif
240# endif
241
242# ifdef YYSTACK_ALLOC
243 /* Pacify GCC's `empty if-body' warning. */
244# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
245# else
246# if defined (__STDC__) || defined (__cplusplus)
247# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
248# define YYSIZE_T size_t
249# endif
250# define YYSTACK_ALLOC malloc
251# define YYSTACK_FREE free
252# endif
253#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
254
255
256#if (! defined (yyoverflow) \
257 && (! defined (__cplusplus) \
258 || (YYSTYPE_IS_TRIVIAL)))
259
260/* A type that is properly aligned for any stack member. */
261union yyalloc
262{
263 short yyss;
264 YYSTYPE yyvs;
265 };
266
267/* The size of the maximum gap between one aligned stack and the next. */
268# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
269
270/* The size of an array large to enough to hold all stacks, each with
271 N elements. */
272# define YYSTACK_BYTES(N) \
273 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
274 + YYSTACK_GAP_MAXIMUM)
275
276/* Copy COUNT objects from FROM to TO. The source and destination do
277 not overlap. */
278# ifndef YYCOPY
279# if 1 < __GNUC__
280# define YYCOPY(To, From, Count) \
281 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
282# else
283# define YYCOPY(To, From, Count) \
284 do \
285 { \
286 register YYSIZE_T yyi; \
287 for (yyi = 0; yyi < (Count); yyi++) \
288 (To)[yyi] = (From)[yyi]; \
289 } \
290 while (0)
291# endif
292# endif
293
294/* Relocate STACK from its old location to the new one. The
295 local variables YYSIZE and YYSTACKSIZE give the old and new number of
296 elements in the stack, and YYPTR gives the new location of the
297 stack. Advance YYPTR to a properly aligned location for the next
298 stack. */
299# define YYSTACK_RELOCATE(Stack) \
300 do \
301 { \
302 YYSIZE_T yynewbytes; \
303 YYCOPY (&yyptr->Stack, Stack, yysize); \
304 Stack = &yyptr->Stack; \
305 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
306 yyptr += yynewbytes / sizeof (*yyptr); \
307 } \
308 while (0)
309
310#endif
311
312#if defined (__STDC__) || defined (__cplusplus)
313 typedef signed char yysigned_char;
314#else
315 typedef short yysigned_char;
316#endif
317
318/* YYFINAL -- State number of the termination state. */
319#define YYFINAL 2
320/* YYLAST -- Last index in YYTABLE. */
321#define YYLAST 201
322
323/* YYNTOKENS -- Number of terminals. */
324#define YYNTOKENS 42
325/* YYNNTS -- Number of nonterminals. */
326#define YYNNTS 41
327/* YYNRULES -- Number of rules. */
328#define YYNRULES 104
329/* YYNRULES -- Number of states. */
330#define YYNSTATES 182
331
332/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
333#define YYUNDEFTOK 2
334#define YYMAXUTOK 296
335
336#define YYTRANSLATE(YYX) \
337 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
338
339/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
340static const unsigned char yytranslate[] =
341{
342 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
343 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
344 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
345 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
346 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
347 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
348 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
349 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
350 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
351 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
352 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
353 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
354 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
355 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
356 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
357 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
358 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
359 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
360 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
361 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
362 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
363 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
364 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
365 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
366 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
367 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
368 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
369 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
370 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
371 35, 36, 37, 38, 39, 40, 41
372};
373
374#if YYDEBUG
375/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
376 YYRHS. */
377static const unsigned short yyprhs[] =
378{
379 0, 0, 3, 4, 7, 9, 11, 13, 17, 19,
380 21, 23, 26, 28, 30, 32, 34, 36, 38, 42,
381 45, 49, 52, 53, 56, 59, 62, 65, 69, 74,
382 78, 83, 87, 91, 95, 100, 105, 110, 116, 119,
383 122, 124, 128, 131, 132, 135, 138, 141, 144, 149,
384 153, 157, 160, 165, 166, 169, 173, 175, 179, 182,
385 183, 186, 189, 192, 196, 199, 201, 205, 208, 209,
386 212, 215, 218, 222, 226, 228, 232, 235, 238, 241,
387 242, 245, 248, 253, 257, 261, 262, 265, 267, 269,
388 272, 275, 278, 280, 282, 283, 286, 288, 292, 296,
389 300, 303, 307, 311, 313
390};
391
392/* YYRHS -- A `-1'-separated list of the rules' RHS. */
393static const yysigned_char yyrhs[] =
394{
395 43, 0, -1, -1, 43, 44, -1, 45, -1, 55,
396 -1, 66, -1, 3, 77, 79, -1, 5, -1, 15,
397 -1, 8, -1, 1, 79, -1, 61, -1, 71, -1,
398 47, -1, 49, -1, 69, -1, 79, -1, 10, 28,
399 32, -1, 46, 50, -1, 11, 28, 32, -1, 48,
400 50, -1, -1, 50, 51, -1, 50, 75, -1, 50,
401 73, -1, 50, 32, -1, 21, 76, 32, -1, 22,
402 81, 80, 32, -1, 23, 76, 32, -1, 24, 81,
403 80, 32, -1, 26, 76, 32, -1, 27, 76, 32,
404 -1, 25, 76, 32, -1, 19, 77, 80, 32, -1,
405 20, 81, 80, 32, -1, 36, 28, 80, 32, -1,
406 37, 82, 82, 80, 32, -1, 7, 32, -1, 52,
407 56, -1, 78, -1, 53, 58, 54, -1, 53, 58,
408 -1, -1, 56, 57, -1, 56, 75, -1, 56, 73,
409 -1, 56, 32, -1, 19, 77, 80, 32, -1, 21,
410 76, 32, -1, 23, 76, 32, -1, 18, 32, -1,
411 20, 28, 80, 32, -1, -1, 58, 45, -1, 14,
412 81, 32, -1, 78, -1, 59, 62, 60, -1, 59,
413 62, -1, -1, 62, 45, -1, 62, 66, -1, 62,
414 55, -1, 4, 77, 32, -1, 63, 74, -1, 78,
415 -1, 64, 67, 65, -1, 64, 67, -1, -1, 67,
416 45, -1, 67, 66, -1, 67, 55, -1, 67, 1,
417 32, -1, 6, 77, 32, -1, 68, -1, 9, 77,
418 32, -1, 70, 74, -1, 12, 32, -1, 72, 13,
419 -1, -1, 74, 75, -1, 74, 32, -1, 16, 35,
420 81, 32, -1, 16, 81, 32, -1, 17, 81, 32,
421 -1, -1, 77, 80, -1, 28, -1, 29, -1, 5,
422 79, -1, 8, 79, -1, 15, 79, -1, 32, -1,
423 31, -1, -1, 14, 81, -1, 82, -1, 82, 40,
424 82, -1, 82, 30, 82, -1, 34, 81, 33, -1,
425 41, 81, -1, 81, 38, 81, -1, 81, 39, 81,
426 -1, 28, -1, 29, -1
427};
428
429/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
430static const unsigned short yyrline[] =
431{
432 0, 94, 94, 95, 98, 99, 100, 101, 102, 103,
433 104, 105, 109, 110, 111, 112, 113, 114, 120, 128,
434 134, 142, 152, 154, 155, 156, 157, 160, 166, 173,
435 179, 186, 192, 198, 204, 210, 216, 222, 230, 239,
436 245, 254, 255, 261, 263, 264, 265, 266, 269, 275,
437 281, 287, 293, 299, 301, 306, 315, 324, 325, 331,
438 333, 334, 335, 340, 347, 353, 362, 363, 369, 371,
439 372, 373, 374, 377, 383, 390, 397, 404, 410, 417,
440 418, 419, 422, 427, 432, 440, 442, 447, 448, 451,
441 452, 453, 457, 457, 459, 460, 463, 464, 465, 466,
442 467, 468, 469, 472, 473
443};
444#endif
445
446#if YYDEBUG || YYERROR_VERBOSE
447/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
448 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
449static const char *const yytname[] =
450{
451 "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
452 "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
453 "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
454 "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_DEFAULT", "T_TRISTATE",
455 "T_DEF_TRISTATE", "T_BOOLEAN", "T_DEF_BOOLEAN", "T_STRING", "T_INT",
456 "T_HEX", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL", "T_EOF", "T_EOL",
457 "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_ON", "T_SELECT", "T_RANGE", "T_OR",
458 "T_AND", "T_EQUAL", "T_NOT", "$accept", "input", "block",
459 "common_block", "config_entry_start", "config_stmt",
460 "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
461 "config_option", "choice", "choice_entry", "choice_end", "choice_stmt",
462 "choice_option_list", "choice_option", "choice_block", "if", "if_end",
463 "if_stmt", "if_block", "menu", "menu_entry", "menu_end", "menu_stmt",
464 "menu_block", "source", "source_stmt", "comment", "comment_stmt",
465 "help_start", "help", "depends_list", "depends", "prompt_stmt_opt",
466 "prompt", "end", "nl_or_eof", "if_expr", "expr", "symbol", 0
467};
468#endif
469
470# ifdef YYPRINT
471/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
472 token YYLEX-NUM. */
473static const unsigned short yytoknum[] =
474{
475 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
476 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
477 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
478 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
479 295, 296
480};
481# endif
482
483/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
484static const unsigned char yyr1[] =
485{
486 0, 42, 43, 43, 44, 44, 44, 44, 44, 44,
487 44, 44, 45, 45, 45, 45, 45, 45, 46, 47,
488 48, 49, 50, 50, 50, 50, 50, 51, 51, 51,
489 51, 51, 51, 51, 51, 51, 51, 51, 52, 53,
490 54, 55, 55, 56, 56, 56, 56, 56, 57, 57,
491 57, 57, 57, 58, 58, 59, 60, 61, 61, 62,
492 62, 62, 62, 63, 64, 65, 66, 66, 67, 67,
493 67, 67, 67, 68, 69, 70, 71, 72, 73, 74,
494 74, 74, 75, 75, 75, 76, 76, 77, 77, 78,
495 78, 78, 79, 79, 80, 80, 81, 81, 81, 81,
496 81, 81, 81, 82, 82
497};
498
499/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
500static const unsigned char yyr2[] =
501{
502 0, 2, 0, 2, 1, 1, 1, 3, 1, 1,
503 1, 2, 1, 1, 1, 1, 1, 1, 3, 2,
504 3, 2, 0, 2, 2, 2, 2, 3, 4, 3,
505 4, 3, 3, 3, 4, 4, 4, 5, 2, 2,
506 1, 3, 2, 0, 2, 2, 2, 2, 4, 3,
507 3, 2, 4, 0, 2, 3, 1, 3, 2, 0,
508 2, 2, 2, 3, 2, 1, 3, 2, 0, 2,
509 2, 2, 3, 3, 1, 3, 2, 2, 2, 0,
510 2, 2, 4, 3, 3, 0, 2, 1, 1, 2,
511 2, 2, 1, 1, 0, 2, 1, 3, 3, 3,
512 2, 3, 3, 1, 1
513};
514
515/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
516 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
517 means the default is an error. */
518static const unsigned char yydefact[] =
519{
520 2, 0, 1, 0, 0, 0, 8, 0, 0, 10,
521 0, 0, 0, 0, 9, 93, 92, 3, 4, 22,
522 14, 22, 15, 43, 53, 5, 59, 12, 79, 68,
523 6, 74, 16, 79, 13, 17, 11, 87, 88, 0,
524 0, 0, 38, 0, 0, 0, 103, 104, 0, 0,
525 0, 96, 19, 21, 39, 42, 58, 64, 0, 76,
526 7, 63, 73, 75, 18, 20, 0, 100, 55, 0,
527 0, 0, 0, 0, 0, 0, 0, 0, 85, 0,
528 85, 0, 85, 85, 85, 26, 0, 0, 23, 0,
529 25, 24, 0, 0, 0, 85, 85, 47, 44, 46,
530 45, 0, 0, 0, 54, 41, 40, 60, 62, 57,
531 61, 56, 81, 80, 0, 69, 71, 66, 70, 65,
532 99, 101, 102, 98, 97, 77, 0, 0, 0, 94,
533 94, 0, 94, 94, 0, 94, 0, 0, 0, 94,
534 0, 78, 51, 94, 94, 0, 0, 89, 90, 91,
535 72, 0, 83, 84, 0, 0, 0, 27, 86, 0,
536 29, 0, 33, 31, 32, 0, 94, 0, 0, 49,
537 50, 82, 95, 34, 35, 28, 30, 36, 0, 48,
538 52, 37
539};
540
541/* YYDEFGOTO[NTERM-NUM]. */
542static const short yydefgoto[] =
543{
544 -1, 1, 17, 18, 19, 20, 21, 22, 52, 88,
545 23, 24, 105, 25, 54, 98, 55, 26, 109, 27,
546 56, 28, 29, 117, 30, 58, 31, 32, 33, 34,
547 89, 90, 57, 91, 131, 132, 106, 35, 155, 50,
548 51
549};
550
551/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
552 STATE-NUM. */
553#define YYPACT_NINF -99
554static const short yypact[] =
555{
556 -99, 48, -99, 38, 46, 46, -99, 46, -29, -99,
557 46, -17, -3, -11, -99, -99, -99, -99, -99, -99,
558 -99, -99, -99, -99, -99, -99, -99, -99, -99, -99,
559 -99, -99, -99, -99, -99, -99, -99, -99, -99, 38,
560 12, 15, -99, 18, 51, 62, -99, -99, -11, -11,
561 4, -24, 138, 138, 160, 121, 110, -4, 81, -4,
562 -99, -99, -99, -99, -99, -99, -19, -99, -99, -11,
563 -11, 70, 70, 73, 32, -11, 46, -11, 46, -11,
564 46, -11, 46, 46, 46, -99, 36, 70, -99, 95,
565 -99, -99, 96, 46, 106, 46, 46, -99, -99, -99,
566 -99, 38, 38, 38, -99, -99, -99, -99, -99, -99,
567 -99, -99, -99, -99, 112, -99, -99, -99, -99, -99,
568 -99, 117, -99, -99, -99, -99, -11, 33, 65, 131,
569 1, 119, 131, 1, 136, 1, 153, 154, 155, 131,
570 70, -99, -99, 131, 131, 156, 157, -99, -99, -99,
571 -99, 101, -99, -99, -11, 158, 159, -99, -99, 161,
572 -99, 162, -99, -99, -99, 163, 131, 164, 165, -99,
573 -99, -99, 99, -99, -99, -99, -99, -99, 166, -99,
574 -99, -99
575};
576
577/* YYPGOTO[NTERM-NUM]. */
578static const short yypgoto[] =
579{
580 -99, -99, -99, 111, -99, -99, -99, -99, 178, -99,
581 -99, -99, -99, 91, -99, -99, -99, -99, -99, -99,
582 -99, -99, -99, -99, 115, -99, -99, -99, -99, -99,
583 -99, 146, 168, 89, 27, 0, 126, -1, -98, -48,
584 -63
585};
586
587/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
588 positive, shift that token. If negative, reduce the rule which
589 number is the opposite. If zero, do what YYDEFACT says.
590 If YYTABLE_NINF, syntax error. */
591#define YYTABLE_NINF -68
592static const short yytable[] =
593{
594 66, 67, 36, 42, 39, 40, 71, 41, 123, 124,
595 43, 44, 74, 75, 120, 154, 72, 46, 47, 69,
596 70, 121, 122, 48, 140, 45, 127, 128, 112, 130,
597 49, 133, 156, 135, 158, 159, 68, 161, 60, 69,
598 70, 165, 69, 70, 61, 167, 168, 62, 2, 3,
599 63, 4, 5, 6, 7, 8, 9, 10, 11, 12,
600 46, 47, 13, 14, 139, 152, 48, 126, 178, 15,
601 16, 69, 70, 49, 37, 38, 129, 166, 151, 15,
602 16, -67, 114, 64, -67, 5, 101, 7, 8, 102,
603 10, 11, 12, 143, 65, 13, 103, 153, 46, 47,
604 147, 148, 149, 69, 70, 125, 172, 134, 141, 136,
605 137, 138, 15, 16, 5, 101, 7, 8, 102, 10,
606 11, 12, 145, 146, 13, 103, 101, 7, 142, 102,
607 10, 11, 12, 171, 144, 13, 103, 69, 70, 69,
608 70, 15, 16, 100, 150, 154, 113, 108, 113, 116,
609 73, 157, 15, 16, 74, 75, 70, 76, 77, 78,
610 79, 80, 81, 82, 83, 84, 104, 107, 160, 115,
611 85, 110, 73, 118, 86, 87, 74, 75, 92, 93,
612 94, 95, 111, 96, 119, 162, 163, 164, 169, 170,
613 173, 174, 97, 175, 176, 177, 179, 180, 181, 53,
614 99, 59
615};
616
617static const unsigned char yycheck[] =
618{
619 48, 49, 3, 32, 4, 5, 30, 7, 71, 72,
620 10, 28, 16, 17, 33, 14, 40, 28, 29, 38,
621 39, 69, 70, 34, 87, 28, 74, 75, 32, 77,
622 41, 79, 130, 81, 132, 133, 32, 135, 39, 38,
623 39, 139, 38, 39, 32, 143, 144, 32, 0, 1,
624 32, 3, 4, 5, 6, 7, 8, 9, 10, 11,
625 28, 29, 14, 15, 28, 32, 34, 35, 166, 31,
626 32, 38, 39, 41, 28, 29, 76, 140, 126, 31,
627 32, 0, 1, 32, 3, 4, 5, 6, 7, 8,
628 9, 10, 11, 93, 32, 14, 15, 32, 28, 29,
629 101, 102, 103, 38, 39, 32, 154, 80, 13, 82,
630 83, 84, 31, 32, 4, 5, 6, 7, 8, 9,
631 10, 11, 95, 96, 14, 15, 5, 6, 32, 8,
632 9, 10, 11, 32, 28, 14, 15, 38, 39, 38,
633 39, 31, 32, 54, 32, 14, 57, 56, 59, 58,
634 12, 32, 31, 32, 16, 17, 39, 19, 20, 21,
635 22, 23, 24, 25, 26, 27, 55, 56, 32, 58,
636 32, 56, 12, 58, 36, 37, 16, 17, 18, 19,
637 20, 21, 56, 23, 58, 32, 32, 32, 32, 32,
638 32, 32, 32, 32, 32, 32, 32, 32, 32, 21,
639 54, 33
640};
641
642/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
643 symbol of state STATE-NUM. */
644static const unsigned char yystos[] =
645{
646 0, 43, 0, 1, 3, 4, 5, 6, 7, 8,
647 9, 10, 11, 14, 15, 31, 32, 44, 45, 46,
648 47, 48, 49, 52, 53, 55, 59, 61, 63, 64,
649 66, 68, 69, 70, 71, 79, 79, 28, 29, 77,
650 77, 77, 32, 77, 28, 28, 28, 29, 34, 41,
651 81, 82, 50, 50, 56, 58, 62, 74, 67, 74,
652 79, 32, 32, 32, 32, 32, 81, 81, 32, 38,
653 39, 30, 40, 12, 16, 17, 19, 20, 21, 22,
654 23, 24, 25, 26, 27, 32, 36, 37, 51, 72,
655 73, 75, 18, 19, 20, 21, 23, 32, 57, 73,
656 75, 5, 8, 15, 45, 54, 78, 45, 55, 60,
657 66, 78, 32, 75, 1, 45, 55, 65, 66, 78,
658 33, 81, 81, 82, 82, 32, 35, 81, 81, 77,
659 81, 76, 77, 81, 76, 81, 76, 76, 76, 28,
660 82, 13, 32, 77, 28, 76, 76, 79, 79, 79,
661 32, 81, 32, 32, 14, 80, 80, 32, 80, 80,
662 32, 80, 32, 32, 32, 80, 82, 80, 80, 32,
663 32, 32, 81, 32, 32, 32, 32, 32, 80, 32,
664 32, 32
665};
666
667#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
668# define YYSIZE_T __SIZE_TYPE__
669#endif
670#if ! defined (YYSIZE_T) && defined (size_t)
671# define YYSIZE_T size_t
672#endif
673#if ! defined (YYSIZE_T)
674# if defined (__STDC__) || defined (__cplusplus)
675# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
676# define YYSIZE_T size_t
677# endif
678#endif
679#if ! defined (YYSIZE_T)
680# define YYSIZE_T unsigned int
681#endif
682
683#define yyerrok (yyerrstatus = 0)
684#define yyclearin (yychar = YYEMPTY)
685#define YYEMPTY (-2)
686#define YYEOF 0
687
688#define YYACCEPT goto yyacceptlab
689#define YYABORT goto yyabortlab
690#define YYERROR goto yyerrlab1
691
692
693/* Like YYERROR except do call yyerror. This remains here temporarily
694 to ease the transition to the new meaning of YYERROR, for GCC.
695 Once GCC version 2 has supplanted version 1, this can go. */
696
697#define YYFAIL goto yyerrlab
698
699#define YYRECOVERING() (!!yyerrstatus)
700
701#define YYBACKUP(Token, Value) \
702do \
703 if (yychar == YYEMPTY && yylen == 1) \
704 { \
705 yychar = (Token); \
706 yylval = (Value); \
707 yytoken = YYTRANSLATE (yychar); \
708 YYPOPSTACK; \
709 goto yybackup; \
710 } \
711 else \
712 { \
713 yyerror ("syntax error: cannot back up");\
714 YYERROR; \
715 } \
716while (0)
717
718#define YYTERROR 1
719#define YYERRCODE 256
720
721/* YYLLOC_DEFAULT -- Compute the default location (before the actions
722 are run). */
723
724#ifndef YYLLOC_DEFAULT
725# define YYLLOC_DEFAULT(Current, Rhs, N) \
726 Current.first_line = Rhs[1].first_line; \
727 Current.first_column = Rhs[1].first_column; \
728 Current.last_line = Rhs[N].last_line; \
729 Current.last_column = Rhs[N].last_column;
730#endif
731
732/* YYLEX -- calling `yylex' with the right arguments. */
733
734#ifdef YYLEX_PARAM
735# define YYLEX yylex (YYLEX_PARAM)
736#else
737# define YYLEX yylex ()
738#endif
739
740/* Enable debugging if requested. */
741#if YYDEBUG
742
743# ifndef YYFPRINTF
744# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
745# define YYFPRINTF fprintf
746# endif
747
748# define YYDPRINTF(Args) \
749do { \
750 if (yydebug) \
751 YYFPRINTF Args; \
752} while (0)
753
754# define YYDSYMPRINT(Args) \
755do { \
756 if (yydebug) \
757 yysymprint Args; \
758} while (0)
759
760# define YYDSYMPRINTF(Title, Token, Value, Location) \
761do { \
762 if (yydebug) \
763 { \
764 YYFPRINTF (stderr, "%s ", Title); \
765 yysymprint (stderr, \
766 Token, Value); \
767 YYFPRINTF (stderr, "\n"); \
768 } \
769} while (0)
770
771/*------------------------------------------------------------------.
772| yy_stack_print -- Print the state stack from its BOTTOM up to its |
773| TOP (cinluded). |
774`------------------------------------------------------------------*/
775
776#if defined (__STDC__) || defined (__cplusplus)
777static void
778yy_stack_print (short *bottom, short *top)
779#else
780static void
781yy_stack_print (bottom, top)
782 short *bottom;
783 short *top;
784#endif
785{
786 YYFPRINTF (stderr, "Stack now");
787 for (/* Nothing. */; bottom <= top; ++bottom)
788 YYFPRINTF (stderr, " %d", *bottom);
789 YYFPRINTF (stderr, "\n");
790}
791
792# define YY_STACK_PRINT(Bottom, Top) \
793do { \
794 if (yydebug) \
795 yy_stack_print ((Bottom), (Top)); \
796} while (0)
797
798
799/*------------------------------------------------.
800| Report that the YYRULE is going to be reduced. |
801`------------------------------------------------*/
802
803#if defined (__STDC__) || defined (__cplusplus)
804static void
805yy_reduce_print (int yyrule)
806#else
807static void
808yy_reduce_print (yyrule)
809 int yyrule;
810#endif
811{
812 int yyi;
813 unsigned int yylineno = yyrline[yyrule];
814 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
815 yyrule - 1, yylineno);
816 /* Print the symbols being reduced, and their result. */
817 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
818 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
819 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
820}
821
822# define YY_REDUCE_PRINT(Rule) \
823do { \
824 if (yydebug) \
825 yy_reduce_print (Rule); \
826} while (0)
827
828/* Nonzero means print parse trace. It is left uninitialized so that
829 multiple parsers can coexist. */
830int yydebug;
831#else /* !YYDEBUG */
832# define YYDPRINTF(Args)
833# define YYDSYMPRINT(Args)
834# define YYDSYMPRINTF(Title, Token, Value, Location)
835# define YY_STACK_PRINT(Bottom, Top)
836# define YY_REDUCE_PRINT(Rule)
837#endif /* !YYDEBUG */
838
839
840/* YYINITDEPTH -- initial size of the parser's stacks. */
841#ifndef YYINITDEPTH
842# define YYINITDEPTH 200
843#endif
844
845/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
846 if the built-in stack extension method is used).
847
848 Do not make this value too large; the results are undefined if
849 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
850 evaluated with infinite-precision integer arithmetic. */
851
852#if YYMAXDEPTH == 0
853# undef YYMAXDEPTH
854#endif
855
856#ifndef YYMAXDEPTH
857# define YYMAXDEPTH 10000
858#endif
859
860
861
862#if YYERROR_VERBOSE
863
864# ifndef yystrlen
865# if defined (__GLIBC__) && defined (_STRING_H)
866# define yystrlen strlen
867# else
868/* Return the length of YYSTR. */
869static YYSIZE_T
870# if defined (__STDC__) || defined (__cplusplus)
871yystrlen (const char *yystr)
872# else
873yystrlen (yystr)
874 const char *yystr;
875# endif
876{
877 register const char *yys = yystr;
878
879 while (*yys++ != '\0')
880 continue;
881
882 return yys - yystr - 1;
883}
884# endif
885# endif
886
887# ifndef yystpcpy
888# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
889# define yystpcpy stpcpy
890# else
891/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
892 YYDEST. */
893static char *
894# if defined (__STDC__) || defined (__cplusplus)
895yystpcpy (char *yydest, const char *yysrc)
896# else
897yystpcpy (yydest, yysrc)
898 char *yydest;
899 const char *yysrc;
900# endif
901{
902 register char *yyd = yydest;
903 register const char *yys = yysrc;
904
905 while ((*yyd++ = *yys++) != '\0')
906 continue;
907
908 return yyd - 1;
909}
910# endif
911# endif
912
913#endif /* !YYERROR_VERBOSE */
914
915
916
917#if YYDEBUG
918/*--------------------------------.
919| Print this symbol on YYOUTPUT. |
920`--------------------------------*/
921
922#if defined (__STDC__) || defined (__cplusplus)
923static void
924yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
925#else
926static void
927yysymprint (yyoutput, yytype, yyvaluep)
928 FILE *yyoutput;
929 int yytype;
930 YYSTYPE *yyvaluep;
931#endif
932{
933 /* Pacify ``unused variable'' warnings. */
934 (void) yyvaluep;
935
936 if (yytype < YYNTOKENS)
937 {
938 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
939# ifdef YYPRINT
940 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
941# endif
942 }
943 else
944 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
945
946 switch (yytype)
947 {
948 default:
949 break;
950 }
951 YYFPRINTF (yyoutput, ")");
952}
953
954#endif /* ! YYDEBUG */
955/*-----------------------------------------------.
956| Release the memory associated to this symbol. |
957`-----------------------------------------------*/
958
959#if defined (__STDC__) || defined (__cplusplus)
960static void
961yydestruct (int yytype, YYSTYPE *yyvaluep)
962#else
963static void
964yydestruct (yytype, yyvaluep)
965 int yytype;
966 YYSTYPE *yyvaluep;
967#endif
968{
969 /* Pacify ``unused variable'' warnings. */
970 (void) yyvaluep;
971
972 switch (yytype)
973 {
974
975 default:
976 break;
977 }
978}
979
980
981/* Prevent warnings from -Wmissing-prototypes. */
982
983#ifdef YYPARSE_PARAM
984# if defined (__STDC__) || defined (__cplusplus)
985int yyparse (void *YYPARSE_PARAM);
986# else
987int yyparse ();
988# endif
989#else /* ! YYPARSE_PARAM */
990#if defined (__STDC__) || defined (__cplusplus)
991int yyparse (void);
992#else
993int yyparse ();
994#endif
995#endif /* ! YYPARSE_PARAM */
996
997
998
999/* The lookahead symbol. */
1000int yychar;
1001
1002/* The semantic value of the lookahead symbol. */
1003YYSTYPE yylval;
1004
1005/* Number of syntax errors so far. */
1006int yynerrs;
1007
1008
1009
1010/*----------.
1011| yyparse. |
1012`----------*/
1013
1014#ifdef YYPARSE_PARAM
1015# if defined (__STDC__) || defined (__cplusplus)
1016int yyparse (void *YYPARSE_PARAM)
1017# else
1018int yyparse (YYPARSE_PARAM)
1019 void *YYPARSE_PARAM;
1020# endif
1021#else /* ! YYPARSE_PARAM */
1022#if defined (__STDC__) || defined (__cplusplus)
1023int
1024yyparse (void)
1025#else
1026int
1027yyparse ()
1028
1029#endif
1030#endif
1031{
1032
1033 register int yystate;
1034 register int yyn;
1035 int yyresult;
1036 /* Number of tokens to shift before error messages enabled. */
1037 int yyerrstatus;
1038 /* Lookahead token as an internal (translated) token number. */
1039 int yytoken = 0;
1040
1041 /* Three stacks and their tools:
1042 `yyss': related to states,
1043 `yyvs': related to semantic values,
1044 `yyls': related to locations.
1045
1046 Refer to the stacks thru separate pointers, to allow yyoverflow
1047 to reallocate them elsewhere. */
1048
1049 /* The state stack. */
1050 short yyssa[YYINITDEPTH];
1051 short *yyss = yyssa;
1052 register short *yyssp;
1053
1054 /* The semantic value stack. */
1055 YYSTYPE yyvsa[YYINITDEPTH];
1056 YYSTYPE *yyvs = yyvsa;
1057 register YYSTYPE *yyvsp;
1058
1059
1060
1061#define YYPOPSTACK (yyvsp--, yyssp--)
1062
1063 YYSIZE_T yystacksize = YYINITDEPTH;
1064
1065 /* The variables used to return semantic value and location from the
1066 action routines. */
1067 YYSTYPE yyval;
1068
1069
1070 /* When reducing, the number of symbols on the RHS of the reduced
1071 rule. */
1072 int yylen;
1073
1074 YYDPRINTF ((stderr, "Starting parse\n"));
1075
1076 yystate = 0;
1077 yyerrstatus = 0;
1078 yynerrs = 0;
1079 yychar = YYEMPTY; /* Cause a token to be read. */
1080
1081 /* Initialize stack pointers.
1082 Waste one element of value and location stack
1083 so that they stay on the same level as the state stack.
1084 The wasted elements are never initialized. */
1085
1086 yyssp = yyss;
1087 yyvsp = yyvs;
1088
1089 goto yysetstate;
1090
1091/*------------------------------------------------------------.
1092| yynewstate -- Push a new state, which is found in yystate. |
1093`------------------------------------------------------------*/
1094 yynewstate:
1095 /* In all cases, when you get here, the value and location stacks
1096 have just been pushed. so pushing a state here evens the stacks.
1097 */
1098 yyssp++;
1099
1100 yysetstate:
1101 *yyssp = yystate;
1102
1103 if (yyss + yystacksize - 1 <= yyssp)
1104 {
1105 /* Get the current used size of the three stacks, in elements. */
1106 YYSIZE_T yysize = yyssp - yyss + 1;
1107
1108#ifdef yyoverflow
1109 {
1110 /* Give user a chance to reallocate the stack. Use copies of
1111 these so that the &'s don't force the real ones into
1112 memory. */
1113 YYSTYPE *yyvs1 = yyvs;
1114 short *yyss1 = yyss;
1115
1116
1117 /* Each stack pointer address is followed by the size of the
1118 data in use in that stack, in bytes. This used to be a
1119 conditional around just the two extra args, but that might
1120 be undefined if yyoverflow is a macro. */
1121 yyoverflow ("parser stack overflow",
1122 &yyss1, yysize * sizeof (*yyssp),
1123 &yyvs1, yysize * sizeof (*yyvsp),
1124
1125 &yystacksize);
1126
1127 yyss = yyss1;
1128 yyvs = yyvs1;
1129 }
1130#else /* no yyoverflow */
1131# ifndef YYSTACK_RELOCATE
1132 goto yyoverflowlab;
1133# else
1134 /* Extend the stack our own way. */
1135 if (YYMAXDEPTH <= yystacksize)
1136 goto yyoverflowlab;
1137 yystacksize *= 2;
1138 if (YYMAXDEPTH < yystacksize)
1139 yystacksize = YYMAXDEPTH;
1140
1141 {
1142 short *yyss1 = yyss;
1143 union yyalloc *yyptr =
1144 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1145 if (! yyptr)
1146 goto yyoverflowlab;
1147 YYSTACK_RELOCATE (yyss);
1148 YYSTACK_RELOCATE (yyvs);
1149
1150# undef YYSTACK_RELOCATE
1151 if (yyss1 != yyssa)
1152 YYSTACK_FREE (yyss1);
1153 }
1154# endif
1155#endif /* no yyoverflow */
1156
1157 yyssp = yyss + yysize - 1;
1158 yyvsp = yyvs + yysize - 1;
1159
1160
1161 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1162 (unsigned long int) yystacksize));
1163
1164 if (yyss + yystacksize - 1 <= yyssp)
1165 YYABORT;
1166 }
1167
1168 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1169
1170 goto yybackup;
1171
1172/*-----------.
1173| yybackup. |
1174`-----------*/
1175yybackup:
1176
1177/* Do appropriate processing given the current state. */
1178/* Read a lookahead token if we need one and don't already have one. */
1179/* yyresume: */
1180
1181 /* First try to decide what to do without reference to lookahead token. */
1182
1183 yyn = yypact[yystate];
1184 if (yyn == YYPACT_NINF)
1185 goto yydefault;
1186
1187 /* Not known => get a lookahead token if don't already have one. */
1188
1189 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1190 if (yychar == YYEMPTY)
1191 {
1192 YYDPRINTF ((stderr, "Reading a token: "));
1193 yychar = YYLEX;
1194 }
1195
1196 if (yychar <= YYEOF)
1197 {
1198 yychar = yytoken = YYEOF;
1199 YYDPRINTF ((stderr, "Now at end of input.\n"));
1200 }
1201 else
1202 {
1203 yytoken = YYTRANSLATE (yychar);
1204 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1205 }
1206
1207 /* If the proper action on seeing token YYTOKEN is to reduce or to
1208 detect an error, take that action. */
1209 yyn += yytoken;
1210 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1211 goto yydefault;
1212 yyn = yytable[yyn];
1213 if (yyn <= 0)
1214 {
1215 if (yyn == 0 || yyn == YYTABLE_NINF)
1216 goto yyerrlab;
1217 yyn = -yyn;
1218 goto yyreduce;
1219 }
1220
1221 if (yyn == YYFINAL)
1222 YYACCEPT;
1223
1224 /* Shift the lookahead token. */
1225 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1226
1227 /* Discard the token being shifted unless it is eof. */
1228 if (yychar != YYEOF)
1229 yychar = YYEMPTY;
1230
1231 *++yyvsp = yylval;
1232
1233
1234 /* Count tokens shifted since error; after three, turn off error
1235 status. */
1236 if (yyerrstatus)
1237 yyerrstatus--;
1238
1239 yystate = yyn;
1240 goto yynewstate;
1241
1242
1243/*-----------------------------------------------------------.
1244| yydefault -- do the default action for the current state. |
1245`-----------------------------------------------------------*/
1246yydefault:
1247 yyn = yydefact[yystate];
1248 if (yyn == 0)
1249 goto yyerrlab;
1250 goto yyreduce;
1251
1252
1253/*-----------------------------.
1254| yyreduce -- Do a reduction. |
1255`-----------------------------*/
1256yyreduce:
1257 /* yyn is the number of a rule to reduce with. */
1258 yylen = yyr2[yyn];
1259
1260 /* If YYLEN is nonzero, implement the default value of the action:
1261 `$$ = $1'.
1262
1263 Otherwise, the following line sets YYVAL to garbage.
1264 This behavior is undocumented and Bison
1265 users should not rely upon it. Assigning to YYVAL
1266 unconditionally makes the parser a bit smaller, and it avoids a
1267 GCC warning that YYVAL may be used uninitialized. */
1268 yyval = yyvsp[1-yylen];
1269
1270
1271 YY_REDUCE_PRINT (yyn);
1272 switch (yyn)
1273 {
1274 case 8:
1275
1276 { zconfprint("unexpected 'endmenu' statement"); ;}
1277 break;
1278
1279 case 9:
1280
1281 { zconfprint("unexpected 'endif' statement"); ;}
1282 break;
1283
1284 case 10:
1285
1286 { zconfprint("unexpected 'endchoice' statement"); ;}
1287 break;
1288
1289 case 11:
1290
1291 { zconfprint("syntax error"); yyerrok; ;}
1292 break;
1293
1294 case 18:
1295
1296 {
1297 struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
1298 sym->flags |= SYMBOL_OPTIONAL;
1299 menu_add_entry(sym);
1300 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
1301;}
1302 break;
1303
1304 case 19:
1305
1306 {
1307 menu_end_entry();
1308 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
1309;}
1310 break;
1311
1312 case 20:
1313
1314 {
1315 struct symbol *sym = sym_lookup(yyvsp[-1].string, 0);
1316 sym->flags |= SYMBOL_OPTIONAL;
1317 menu_add_entry(sym);
1318 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
1319;}
1320 break;
1321
1322 case 21:
1323
1324 {
1325 if (current_entry->prompt)
1326 current_entry->prompt->type = P_MENU;
1327 else
1328 zconfprint("warning: menuconfig statement without prompt");
1329 menu_end_entry();
1330 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
1331;}
1332 break;
1333
1334 case 27:
1335
1336 {
1337 menu_set_type(S_TRISTATE);
1338 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
1339;}
1340 break;
1341
1342 case 28:
1343
1344 {
1345 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
1346 menu_set_type(S_TRISTATE);
1347 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
1348;}
1349 break;
1350
1351 case 29:
1352
1353 {
1354 menu_set_type(S_BOOLEAN);
1355 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
1356;}
1357 break;
1358
1359 case 30:
1360
1361 {
1362 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
1363 menu_set_type(S_BOOLEAN);
1364 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
1365;}
1366 break;
1367
1368 case 31:
1369
1370 {
1371 menu_set_type(S_INT);
1372 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
1373;}
1374 break;
1375
1376 case 32:
1377
1378 {
1379 menu_set_type(S_HEX);
1380 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
1381;}
1382 break;
1383
1384 case 33:
1385
1386 {
1387 menu_set_type(S_STRING);
1388 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
1389;}
1390 break;
1391
1392 case 34:
1393
1394 {
1395 menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
1396 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
1397;}
1398 break;
1399
1400 case 35:
1401
1402 {
1403 menu_add_expr(P_DEFAULT, yyvsp[-2].expr, yyvsp[-1].expr);
1404 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
1405;}
1406 break;
1407
1408 case 36:
1409
1410 {
1411 menu_add_symbol(P_SELECT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
1412 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
1413;}
1414 break;
1415
1416 case 37:
1417
1418 {
1419 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,yyvsp[-3].symbol, yyvsp[-2].symbol), yyvsp[-1].expr);
1420 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
1421;}
1422 break;
1423
1424 case 38:
1425
1426 {
1427 struct symbol *sym = sym_lookup(NULL, 0);
1428 sym->flags |= SYMBOL_CHOICE;
1429 menu_add_entry(sym);
1430 menu_add_expr(P_CHOICE, NULL, NULL);
1431 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
1432;}
1433 break;
1434
1435 case 39:
1436
1437 {
1438 menu_end_entry();
1439 menu_add_menu();
1440;}
1441 break;
1442
1443 case 40:
1444
1445 {
1446 if (zconf_endtoken(yyvsp[0].token, T_CHOICE, T_ENDCHOICE)) {
1447 menu_end_menu();
1448 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
1449 }
1450;}
1451 break;
1452
1453 case 42:
1454
1455 {
1456 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
1457 zconfnerrs++;
1458;}
1459 break;
1460
1461 case 48:
1462
1463 {
1464 menu_add_prompt(P_PROMPT, yyvsp[-2].string, yyvsp[-1].expr);
1465 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
1466;}
1467 break;
1468
1469 case 49:
1470
1471 {
1472 menu_set_type(S_TRISTATE);
1473 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
1474;}
1475 break;
1476
1477 case 50:
1478
1479 {
1480 menu_set_type(S_BOOLEAN);
1481 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
1482;}
1483 break;
1484
1485 case 51:
1486
1487 {
1488 current_entry->sym->flags |= SYMBOL_OPTIONAL;
1489 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
1490;}
1491 break;
1492
1493 case 52:
1494
1495 {
1496 menu_add_symbol(P_DEFAULT, sym_lookup(yyvsp[-2].string, 0), yyvsp[-1].expr);
1497 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
1498;}
1499 break;
1500
1501 case 55:
1502
1503 {
1504 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
1505 menu_add_entry(NULL);
1506 menu_add_dep(yyvsp[-1].expr);
1507 menu_end_entry();
1508 menu_add_menu();
1509;}
1510 break;
1511
1512 case 56:
1513
1514 {
1515 if (zconf_endtoken(yyvsp[0].token, T_IF, T_ENDIF)) {
1516 menu_end_menu();
1517 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
1518 }
1519;}
1520 break;
1521
1522 case 58:
1523
1524 {
1525 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
1526 zconfnerrs++;
1527;}
1528 break;
1529
1530 case 63:
1531
1532 {
1533 menu_add_entry(NULL);
1534 menu_add_prop(P_MENU, yyvsp[-1].string, NULL, NULL);
1535 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
1536;}
1537 break;
1538
1539 case 64:
1540
1541 {
1542 menu_end_entry();
1543 menu_add_menu();
1544;}
1545 break;
1546
1547 case 65:
1548
1549 {
1550 if (zconf_endtoken(yyvsp[0].token, T_MENU, T_ENDMENU)) {
1551 menu_end_menu();
1552 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
1553 }
1554;}
1555 break;
1556
1557 case 67:
1558
1559 {
1560 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
1561 zconfnerrs++;
1562;}
1563 break;
1564
1565 case 72:
1566
1567 { zconfprint("invalid menu option"); yyerrok; ;}
1568 break;
1569
1570 case 73:
1571
1572 {
1573 yyval.string = yyvsp[-1].string;
1574 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), yyvsp[-1].string);
1575;}
1576 break;
1577
1578 case 74:
1579
1580 {
1581 zconf_nextfile(yyvsp[0].string);
1582;}
1583 break;
1584
1585 case 75:
1586
1587 {
1588 menu_add_entry(NULL);
1589 menu_add_prop(P_COMMENT, yyvsp[-1].string, NULL, NULL);
1590 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
1591;}
1592 break;
1593
1594 case 76:
1595
1596 {
1597 menu_end_entry();
1598;}
1599 break;
1600
1601 case 77:
1602
1603 {
1604 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
1605 zconf_starthelp();
1606;}
1607 break;
1608
1609 case 78:
1610
1611 {
1612 current_entry->sym->help = yyvsp[0].string;
1613;}
1614 break;
1615
1616 case 82:
1617
1618 {
1619 menu_add_dep(yyvsp[-1].expr);
1620 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
1621;}
1622 break;
1623
1624 case 83:
1625
1626 {
1627 menu_add_dep(yyvsp[-1].expr);
1628 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
1629;}
1630 break;
1631
1632 case 84:
1633
1634 {
1635 menu_add_dep(yyvsp[-1].expr);
1636 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
1637;}
1638 break;
1639
1640 case 86:
1641
1642 {
1643 menu_add_prop(P_PROMPT, yyvsp[-1].string, NULL, yyvsp[0].expr);
1644;}
1645 break;
1646
1647 case 89:
1648
1649 { yyval.token = T_ENDMENU; ;}
1650 break;
1651
1652 case 90:
1653
1654 { yyval.token = T_ENDCHOICE; ;}
1655 break;
1656
1657 case 91:
1658
1659 { yyval.token = T_ENDIF; ;}
1660 break;
1661
1662 case 94:
1663
1664 { yyval.expr = NULL; ;}
1665 break;
1666
1667 case 95:
1668
1669 { yyval.expr = yyvsp[0].expr; ;}
1670 break;
1671
1672 case 96:
1673
1674 { yyval.expr = expr_alloc_symbol(yyvsp[0].symbol); ;}
1675 break;
1676
1677 case 97:
1678
1679 { yyval.expr = expr_alloc_comp(E_EQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
1680 break;
1681
1682 case 98:
1683
1684 { yyval.expr = expr_alloc_comp(E_UNEQUAL, yyvsp[-2].symbol, yyvsp[0].symbol); ;}
1685 break;
1686
1687 case 99:
1688
1689 { yyval.expr = yyvsp[-1].expr; ;}
1690 break;
1691
1692 case 100:
1693
1694 { yyval.expr = expr_alloc_one(E_NOT, yyvsp[0].expr); ;}
1695 break;
1696
1697 case 101:
1698
1699 { yyval.expr = expr_alloc_two(E_OR, yyvsp[-2].expr, yyvsp[0].expr); ;}
1700 break;
1701
1702 case 102:
1703
1704 { yyval.expr = expr_alloc_two(E_AND, yyvsp[-2].expr, yyvsp[0].expr); ;}
1705 break;
1706
1707 case 103:
1708
1709 { yyval.symbol = sym_lookup(yyvsp[0].string, 0); free(yyvsp[0].string); ;}
1710 break;
1711
1712 case 104:
1713
1714 { yyval.symbol = sym_lookup(yyvsp[0].string, 1); free(yyvsp[0].string); ;}
1715 break;
1716
1717
1718 }
1719
1720/* Line 999 of yacc.c. */
1721
1722
1723 yyvsp -= yylen;
1724 yyssp -= yylen;
1725
1726
1727 YY_STACK_PRINT (yyss, yyssp);
1728
1729 *++yyvsp = yyval;
1730
1731
1732 /* Now `shift' the result of the reduction. Determine what state
1733 that goes to, based on the state we popped back to and the rule
1734 number reduced by. */
1735
1736 yyn = yyr1[yyn];
1737
1738 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1739 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1740 yystate = yytable[yystate];
1741 else
1742 yystate = yydefgoto[yyn - YYNTOKENS];
1743
1744 goto yynewstate;
1745
1746
1747/*------------------------------------.
1748| yyerrlab -- here on detecting error |
1749`------------------------------------*/
1750yyerrlab:
1751 /* If not already recovering from an error, report this error. */
1752 if (!yyerrstatus)
1753 {
1754 ++yynerrs;
1755#if YYERROR_VERBOSE
1756 yyn = yypact[yystate];
1757
1758 if (YYPACT_NINF < yyn && yyn < YYLAST)
1759 {
1760 YYSIZE_T yysize = 0;
1761 int yytype = YYTRANSLATE (yychar);
1762 char *yymsg;
1763 int yyx, yycount;
1764
1765 yycount = 0;
1766 /* Start YYX at -YYN if negative to avoid negative indexes in
1767 YYCHECK. */
1768 for (yyx = yyn < 0 ? -yyn : 0;
1769 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1770 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1771 yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1772 yysize += yystrlen ("syntax error, unexpected ") + 1;
1773 yysize += yystrlen (yytname[yytype]);
1774 yymsg = (char *) YYSTACK_ALLOC (yysize);
1775 if (yymsg != 0)
1776 {
1777 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1778 yyp = yystpcpy (yyp, yytname[yytype]);
1779
1780 if (yycount < 5)
1781 {
1782 yycount = 0;
1783 for (yyx = yyn < 0 ? -yyn : 0;
1784 yyx < (int) (sizeof (yytname) / sizeof (char *));
1785 yyx++)
1786 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1787 {
1788 const char *yyq = ! yycount ? ", expecting " : " or ";
1789 yyp = yystpcpy (yyp, yyq);
1790 yyp = yystpcpy (yyp, yytname[yyx]);
1791 yycount++;
1792 }
1793 }
1794 yyerror (yymsg);
1795 YYSTACK_FREE (yymsg);
1796 }
1797 else
1798 yyerror ("syntax error; also virtual memory exhausted");
1799 }
1800 else
1801#endif /* YYERROR_VERBOSE */
1802 yyerror ("syntax error");
1803 }
1804
1805
1806
1807 if (yyerrstatus == 3)
1808 {
1809 /* If just tried and failed to reuse lookahead token after an
1810 error, discard it. */
1811
1812 /* Return failure if at end of input. */
1813 if (yychar == YYEOF)
1814 {
1815 /* Pop the error token. */
1816 YYPOPSTACK;
1817 /* Pop the rest of the stack. */
1818 while (yyss < yyssp)
1819 {
1820 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1821 yydestruct (yystos[*yyssp], yyvsp);
1822 YYPOPSTACK;
1823 }
1824 YYABORT;
1825 }
1826
1827 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1828 yydestruct (yytoken, &yylval);
1829 yychar = YYEMPTY;
1830
1831 }
1832
1833 /* Else will try to reuse lookahead token after shifting the error
1834 token. */
1835 goto yyerrlab1;
1836
1837
1838/*----------------------------------------------------.
1839| yyerrlab1 -- error raised explicitly by an action. |
1840`----------------------------------------------------*/
1841yyerrlab1:
1842 yyerrstatus = 3; /* Each real token shifted decrements this. */
1843
1844 for (;;)
1845 {
1846 yyn = yypact[yystate];
1847 if (yyn != YYPACT_NINF)
1848 {
1849 yyn += YYTERROR;
1850 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1851 {
1852 yyn = yytable[yyn];
1853 if (0 < yyn)
1854 break;
1855 }
1856 }
1857
1858 /* Pop the current state because it cannot handle the error token. */
1859 if (yyssp == yyss)
1860 YYABORT;
1861
1862 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1863 yydestruct (yystos[yystate], yyvsp);
1864 yyvsp--;
1865 yystate = *--yyssp;
1866
1867 YY_STACK_PRINT (yyss, yyssp);
1868 }
1869
1870 if (yyn == YYFINAL)
1871 YYACCEPT;
1872
1873 YYDPRINTF ((stderr, "Shifting error token, "));
1874
1875 *++yyvsp = yylval;
1876
1877
1878 yystate = yyn;
1879 goto yynewstate;
1880
1881
1882/*-------------------------------------.
1883| yyacceptlab -- YYACCEPT comes here. |
1884`-------------------------------------*/
1885yyacceptlab:
1886 yyresult = 0;
1887 goto yyreturn;
1888
1889/*-----------------------------------.
1890| yyabortlab -- YYABORT comes here. |
1891`-----------------------------------*/
1892yyabortlab:
1893 yyresult = 1;
1894 goto yyreturn;
1895
1896#ifndef yyoverflow
1897/*----------------------------------------------.
1898| yyoverflowlab -- parser overflow comes here. |
1899`----------------------------------------------*/
1900yyoverflowlab:
1901 yyerror ("parser stack overflow");
1902 yyresult = 2;
1903 /* Fall through. */
1904#endif
1905
1906yyreturn:
1907#ifndef yyoverflow
1908 if (yyss != yyssa)
1909 YYSTACK_FREE (yyss);
1910#endif
1911 return yyresult;
1912}
1913
1914
1915
1916
1917
1918void conf_parse(const char *name)
1919{
1920 struct symbol *sym;
1921 int i;
1922
1923 zconf_initscan(name);
1924
1925 sym_init();
1926 menu_init();
1927 modules_sym = sym_lookup("MODULES", 0);
1928 rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
1929
1930 //zconfdebug = 1;
1931 zconfparse();
1932 if (zconfnerrs)
1933 exit(1);
1934 menu_finalize(&rootmenu);
1935 for_all_symbols(i, sym) {
1936 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
1937 printf("\n");
1938 else
1939 sym->flags |= SYMBOL_CHECK_DONE;
1940 }
1941
1942 sym_change_count = 1;
1943}
1944
1945const char *zconf_tokenname(int token)
1946{
1947 switch (token) {
1948 case T_MENU: return "menu";
1949 case T_ENDMENU: return "endmenu";
1950 case T_CHOICE: return "choice";
1951 case T_ENDCHOICE: return "endchoice";
1952 case T_IF: return "if";
1953 case T_ENDIF: return "endif";
1954 }
1955 return "<token>";
1956}
1957
1958static bool zconf_endtoken(int token, int starttoken, int endtoken)
1959{
1960 if (token != endtoken) {
1961 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
1962 zconfnerrs++;
1963 return false;
1964 }
1965 if (current_menu->file != current_file) {
1966 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
1967 zconfprint("location of the '%s'", zconf_tokenname(starttoken));
1968 zconfnerrs++;
1969 return false;
1970 }
1971 return true;
1972}
1973
1974static void zconfprint(const char *err, ...)
1975{
1976 va_list ap;
1977
1978 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
1979 va_start(ap, err);
1980 vfprintf(stderr, err, ap);
1981 va_end(ap);
1982 fprintf(stderr, "\n");
1983}
1984
1985static void zconferror(const char *err)
1986{
1987 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
1988}
1989
1990void print_quoted_string(FILE *out, const char *str)
1991{
1992 const char *p;
1993 int len;
1994
1995 putc('"', out);
1996 while ((p = strchr(str, '"'))) {
1997 len = p - str;
1998 if (len)
1999 fprintf(out, "%.*s", len, str);
2000 fputs("\\\"", out);
2001 str = p + 1;
2002 }
2003 fputs(str, out);
2004 putc('"', out);
2005}
2006
2007void print_symbol(FILE *out, struct menu *menu)
2008{
2009 struct symbol *sym = menu->sym;
2010 struct property *prop;
2011
2012 if (sym_is_choice(sym))
2013 fprintf(out, "choice\n");
2014 else
2015 fprintf(out, "config %s\n", sym->name);
2016 switch (sym->type) {
2017 case S_BOOLEAN:
2018 fputs(" boolean\n", out);
2019 break;
2020 case S_TRISTATE:
2021 fputs(" tristate\n", out);
2022 break;
2023 case S_STRING:
2024 fputs(" string\n", out);
2025 break;
2026 case S_INT:
2027 fputs(" integer\n", out);
2028 break;
2029 case S_HEX:
2030 fputs(" hex\n", out);
2031 break;
2032 default:
2033 fputs(" ???\n", out);
2034 break;
2035 }
2036 for (prop = sym->prop; prop; prop = prop->next) {
2037 if (prop->menu != menu)
2038 continue;
2039 switch (prop->type) {
2040 case P_PROMPT:
2041 fputs(" prompt ", out);
2042 print_quoted_string(out, prop->text);
2043 if (!expr_is_yes(prop->visible.expr)) {
2044 fputs(" if ", out);
2045 expr_fprint(prop->visible.expr, out);
2046 }
2047 fputc('\n', out);
2048 break;
2049 case P_DEFAULT:
2050 fputs( " default ", out);
2051 expr_fprint(prop->expr, out);
2052 if (!expr_is_yes(prop->visible.expr)) {
2053 fputs(" if ", out);
2054 expr_fprint(prop->visible.expr, out);
2055 }
2056 fputc('\n', out);
2057 break;
2058 case P_CHOICE:
2059 fputs(" #choice value\n", out);
2060 break;
2061 default:
2062 fprintf(out, " unknown prop %d!\n", prop->type);
2063 break;
2064 }
2065 }
2066 if (sym->help) {
2067 int len = strlen(sym->help);
2068 while (sym->help[--len] == '\n')
2069 sym->help[len] = 0;
2070 fprintf(out, " help\n%s\n", sym->help);
2071 }
2072 fputc('\n', out);
2073}
2074
2075void zconfdump(FILE *out)
2076{
2077 struct property *prop;
2078 struct symbol *sym;
2079 struct menu *menu;
2080
2081 menu = rootmenu.list;
2082 while (menu) {
2083 if ((sym = menu->sym))
2084 print_symbol(out, menu);
2085 else if ((prop = menu->prompt)) {
2086 switch (prop->type) {
2087 case P_COMMENT:
2088 fputs("\ncomment ", out);
2089 print_quoted_string(out, prop->text);
2090 fputs("\n", out);
2091 break;
2092 case P_MENU:
2093 fputs("\nmenu ", out);
2094 print_quoted_string(out, prop->text);
2095 fputs("\n", out);
2096 break;
2097 default:
2098 ;
2099 }
2100 if (!expr_is_yes(prop->visible.expr)) {
2101 fputs(" depends ", out);
2102 expr_fprint(prop->visible.expr, out);
2103 fputc('\n', out);
2104 }
2105 fputs("\n", out);
2106 }
2107
2108 if (menu->list)
2109 menu = menu->list;
2110 else if (menu->next)
2111 menu = menu->next;
2112 else while ((menu = menu->parent)) {
2113 if (menu->prompt && menu->prompt->type == P_MENU)
2114 fputs("\nendmenu\n", out);
2115 if (menu->next) {
2116 menu = menu->next;
2117 break;
2118 }
2119 }
2120 }
2121}
2122
2123#include "lex.zconf.c"
2124#include "util.c"
2125#include "confdata.c"
2126#include "expr.c"
2127#include "symbol.c"
2128#include "menu.c"
2129
2130
diff --git a/scripts/kconfig/zconf.tab.h_shipped b/scripts/kconfig/zconf.tab.h_shipped
new file mode 100644
index 000000000000..3b191ef59985
--- /dev/null
+++ b/scripts/kconfig/zconf.tab.h_shipped
@@ -0,0 +1,125 @@
1/* A Bison parser, made from zconf.y, by GNU bison 1.75. */
2
3/* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21/* As a special exception, when this file is copied by Bison into a
22 Bison output file, you may use that output file without restriction.
23 This special exception was added by the Free Software Foundation
24 in version 1.24 of Bison. */
25
26#ifndef BISON_ZCONF_TAB_H
27# define BISON_ZCONF_TAB_H
28
29/* Tokens. */
30#ifndef YYTOKENTYPE
31# define YYTOKENTYPE
32 /* Put the tokens into the symbol table, so that GDB and other debuggers
33 know about them. */
34 enum yytokentype {
35 T_MAINMENU = 258,
36 T_MENU = 259,
37 T_ENDMENU = 260,
38 T_SOURCE = 261,
39 T_CHOICE = 262,
40 T_ENDCHOICE = 263,
41 T_COMMENT = 264,
42 T_CONFIG = 265,
43 T_HELP = 266,
44 T_HELPTEXT = 267,
45 T_IF = 268,
46 T_ENDIF = 269,
47 T_DEPENDS = 270,
48 T_REQUIRES = 271,
49 T_OPTIONAL = 272,
50 T_PROMPT = 273,
51 T_DEFAULT = 274,
52 T_TRISTATE = 275,
53 T_BOOLEAN = 276,
54 T_INT = 277,
55 T_HEX = 278,
56 T_WORD = 279,
57 T_STRING = 280,
58 T_UNEQUAL = 281,
59 T_EOF = 282,
60 T_EOL = 283,
61 T_CLOSE_PAREN = 284,
62 T_OPEN_PAREN = 285,
63 T_ON = 286,
64 T_OR = 287,
65 T_AND = 288,
66 T_EQUAL = 289,
67 T_NOT = 290
68 };
69#endif
70#define T_MAINMENU 258
71#define T_MENU 259
72#define T_ENDMENU 260
73#define T_SOURCE 261
74#define T_CHOICE 262
75#define T_ENDCHOICE 263
76#define T_COMMENT 264
77#define T_CONFIG 265
78#define T_HELP 266
79#define T_HELPTEXT 267
80#define T_IF 268
81#define T_ENDIF 269
82#define T_DEPENDS 270
83#define T_REQUIRES 271
84#define T_OPTIONAL 272
85#define T_PROMPT 273
86#define T_DEFAULT 274
87#define T_TRISTATE 275
88#define T_BOOLEAN 276
89#define T_INT 277
90#define T_HEX 278
91#define T_WORD 279
92#define T_STRING 280
93#define T_UNEQUAL 281
94#define T_EOF 282
95#define T_EOL 283
96#define T_CLOSE_PAREN 284
97#define T_OPEN_PAREN 285
98#define T_ON 286
99#define T_OR 287
100#define T_AND 288
101#define T_EQUAL 289
102#define T_NOT 290
103
104
105
106
107#ifndef YYSTYPE
108#line 33 "zconf.y"
109typedef union {
110 int token;
111 char *string;
112 struct symbol *symbol;
113 struct expr *expr;
114 struct menu *menu;
115} yystype;
116/* Line 1281 of /usr/share/bison/yacc.c. */
117#line 118 "zconf.tab.h"
118# define YYSTYPE yystype
119#endif
120
121extern YYSTYPE zconflval;
122
123
124#endif /* not BISON_ZCONF_TAB_H */
125
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
new file mode 100644
index 000000000000..54460f8d3696
--- /dev/null
+++ b/scripts/kconfig/zconf.y
@@ -0,0 +1,690 @@
1%{
2/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 * Released under the terms of the GNU GPL v2.0.
5 */
6
7#include <ctype.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <stdbool.h>
13
14#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
15
16#define PRINTD 0x0001
17#define DEBUG_PARSE 0x0002
18
19int cdebug = PRINTD;
20
21extern int zconflex(void);
22static void zconfprint(const char *err, ...);
23static void zconferror(const char *err);
24static bool zconf_endtoken(int token, int starttoken, int endtoken);
25
26struct symbol *symbol_hash[257];
27
28static struct menu *current_menu, *current_entry;
29
30#define YYERROR_VERBOSE
31%}
32%expect 40
33
34%union
35{
36 int token;
37 char *string;
38 struct symbol *symbol;
39 struct expr *expr;
40 struct menu *menu;
41}
42
43%token T_MAINMENU
44%token T_MENU
45%token T_ENDMENU
46%token T_SOURCE
47%token T_CHOICE
48%token T_ENDCHOICE
49%token T_COMMENT
50%token T_CONFIG
51%token T_MENUCONFIG
52%token T_HELP
53%token <string> T_HELPTEXT
54%token T_IF
55%token T_ENDIF
56%token T_DEPENDS
57%token T_REQUIRES
58%token T_OPTIONAL
59%token T_PROMPT
60%token T_DEFAULT
61%token T_TRISTATE
62%token T_DEF_TRISTATE
63%token T_BOOLEAN
64%token T_DEF_BOOLEAN
65%token T_STRING
66%token T_INT
67%token T_HEX
68%token <string> T_WORD
69%token <string> T_WORD_QUOTE
70%token T_UNEQUAL
71%token T_EOF
72%token T_EOL
73%token T_CLOSE_PAREN
74%token T_OPEN_PAREN
75%token T_ON
76%token T_SELECT
77%token T_RANGE
78
79%left T_OR
80%left T_AND
81%left T_EQUAL T_UNEQUAL
82%nonassoc T_NOT
83
84%type <string> prompt
85%type <string> source
86%type <symbol> symbol
87%type <expr> expr
88%type <expr> if_expr
89%type <token> end
90
91%{
92#define LKC_DIRECT_LINK
93#include "lkc.h"
94%}
95%%
96input: /* empty */
97 | input block
98;
99
100block: common_block
101 | choice_stmt
102 | menu_stmt
103 | T_MAINMENU prompt nl_or_eof
104 | T_ENDMENU { zconfprint("unexpected 'endmenu' statement"); }
105 | T_ENDIF { zconfprint("unexpected 'endif' statement"); }
106 | T_ENDCHOICE { zconfprint("unexpected 'endchoice' statement"); }
107 | error nl_or_eof { zconfprint("syntax error"); yyerrok; }
108;
109
110common_block:
111 if_stmt
112 | comment_stmt
113 | config_stmt
114 | menuconfig_stmt
115 | source_stmt
116 | nl_or_eof
117;
118
119
120/* config/menuconfig entry */
121
122config_entry_start: T_CONFIG T_WORD T_EOL
123{
124 struct symbol *sym = sym_lookup($2, 0);
125 sym->flags |= SYMBOL_OPTIONAL;
126 menu_add_entry(sym);
127 printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
128};
129
130config_stmt: config_entry_start config_option_list
131{
132 menu_end_entry();
133 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
134};
135
136menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
137{
138 struct symbol *sym = sym_lookup($2, 0);
139 sym->flags |= SYMBOL_OPTIONAL;
140 menu_add_entry(sym);
141 printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
142};
143
144menuconfig_stmt: menuconfig_entry_start config_option_list
145{
146 if (current_entry->prompt)
147 current_entry->prompt->type = P_MENU;
148 else
149 zconfprint("warning: menuconfig statement without prompt");
150 menu_end_entry();
151 printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
152};
153
154config_option_list:
155 /* empty */
156 | config_option_list config_option
157 | config_option_list depends
158 | config_option_list help
159 | config_option_list T_EOL
160;
161
162config_option: T_TRISTATE prompt_stmt_opt T_EOL
163{
164 menu_set_type(S_TRISTATE);
165 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
166};
167
168config_option: T_DEF_TRISTATE expr if_expr T_EOL
169{
170 menu_add_expr(P_DEFAULT, $2, $3);
171 menu_set_type(S_TRISTATE);
172 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
173};
174
175config_option: T_BOOLEAN prompt_stmt_opt T_EOL
176{
177 menu_set_type(S_BOOLEAN);
178 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
179};
180
181config_option: T_DEF_BOOLEAN expr if_expr T_EOL
182{
183 menu_add_expr(P_DEFAULT, $2, $3);
184 menu_set_type(S_BOOLEAN);
185 printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
186};
187
188config_option: T_INT prompt_stmt_opt T_EOL
189{
190 menu_set_type(S_INT);
191 printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
192};
193
194config_option: T_HEX prompt_stmt_opt T_EOL
195{
196 menu_set_type(S_HEX);
197 printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
198};
199
200config_option: T_STRING prompt_stmt_opt T_EOL
201{
202 menu_set_type(S_STRING);
203 printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
204};
205
206config_option: T_PROMPT prompt if_expr T_EOL
207{
208 menu_add_prompt(P_PROMPT, $2, $3);
209 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
210};
211
212config_option: T_DEFAULT expr if_expr T_EOL
213{
214 menu_add_expr(P_DEFAULT, $2, $3);
215 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
216};
217
218config_option: T_SELECT T_WORD if_expr T_EOL
219{
220 menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
221 printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
222};
223
224config_option: T_RANGE symbol symbol if_expr T_EOL
225{
226 menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
227 printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
228};
229
230/* choice entry */
231
232choice: T_CHOICE T_EOL
233{
234 struct symbol *sym = sym_lookup(NULL, 0);
235 sym->flags |= SYMBOL_CHOICE;
236 menu_add_entry(sym);
237 menu_add_expr(P_CHOICE, NULL, NULL);
238 printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
239};
240
241choice_entry: choice choice_option_list
242{
243 menu_end_entry();
244 menu_add_menu();
245};
246
247choice_end: end
248{
249 if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
250 menu_end_menu();
251 printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
252 }
253};
254
255choice_stmt:
256 choice_entry choice_block choice_end
257 | choice_entry choice_block
258{
259 printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
260 zconfnerrs++;
261};
262
263choice_option_list:
264 /* empty */
265 | choice_option_list choice_option
266 | choice_option_list depends
267 | choice_option_list help
268 | choice_option_list T_EOL
269;
270
271choice_option: T_PROMPT prompt if_expr T_EOL
272{
273 menu_add_prompt(P_PROMPT, $2, $3);
274 printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
275};
276
277choice_option: T_TRISTATE prompt_stmt_opt T_EOL
278{
279 menu_set_type(S_TRISTATE);
280 printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
281};
282
283choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
284{
285 menu_set_type(S_BOOLEAN);
286 printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
287};
288
289choice_option: T_OPTIONAL T_EOL
290{
291 current_entry->sym->flags |= SYMBOL_OPTIONAL;
292 printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
293};
294
295choice_option: T_DEFAULT T_WORD if_expr T_EOL
296{
297 menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
298 printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
299};
300
301choice_block:
302 /* empty */
303 | choice_block common_block
304;
305
306/* if entry */
307
308if: T_IF expr T_EOL
309{
310 printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
311 menu_add_entry(NULL);
312 menu_add_dep($2);
313 menu_end_entry();
314 menu_add_menu();
315};
316
317if_end: end
318{
319 if (zconf_endtoken($1, T_IF, T_ENDIF)) {
320 menu_end_menu();
321 printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
322 }
323};
324
325if_stmt:
326 if if_block if_end
327 | if if_block
328{
329 printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
330 zconfnerrs++;
331};
332
333if_block:
334 /* empty */
335 | if_block common_block
336 | if_block menu_stmt
337 | if_block choice_stmt
338;
339
340/* menu entry */
341
342menu: T_MENU prompt T_EOL
343{
344 menu_add_entry(NULL);
345 menu_add_prop(P_MENU, $2, NULL, NULL);
346 printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
347};
348
349menu_entry: menu depends_list
350{
351 menu_end_entry();
352 menu_add_menu();
353};
354
355menu_end: end
356{
357 if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
358 menu_end_menu();
359 printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
360 }
361};
362
363menu_stmt:
364 menu_entry menu_block menu_end
365 | menu_entry menu_block
366{
367 printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
368 zconfnerrs++;
369};
370
371menu_block:
372 /* empty */
373 | menu_block common_block
374 | menu_block menu_stmt
375 | menu_block choice_stmt
376 | menu_block error T_EOL { zconfprint("invalid menu option"); yyerrok; }
377;
378
379source: T_SOURCE prompt T_EOL
380{
381 $$ = $2;
382 printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
383};
384
385source_stmt: source
386{
387 zconf_nextfile($1);
388};
389
390/* comment entry */
391
392comment: T_COMMENT prompt T_EOL
393{
394 menu_add_entry(NULL);
395 menu_add_prop(P_COMMENT, $2, NULL, NULL);
396 printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
397};
398
399comment_stmt: comment depends_list
400{
401 menu_end_entry();
402};
403
404/* help option */
405
406help_start: T_HELP T_EOL
407{
408 printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
409 zconf_starthelp();
410};
411
412help: help_start T_HELPTEXT
413{
414 current_entry->sym->help = $2;
415};
416
417/* depends option */
418
419depends_list: /* empty */
420 | depends_list depends
421 | depends_list T_EOL
422;
423
424depends: T_DEPENDS T_ON expr T_EOL
425{
426 menu_add_dep($3);
427 printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
428}
429 | T_DEPENDS expr T_EOL
430{
431 menu_add_dep($2);
432 printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
433}
434 | T_REQUIRES expr T_EOL
435{
436 menu_add_dep($2);
437 printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
438};
439
440/* prompt statement */
441
442prompt_stmt_opt:
443 /* empty */
444 | prompt if_expr
445{
446 menu_add_prop(P_PROMPT, $1, NULL, $2);
447};
448
449prompt: T_WORD
450 | T_WORD_QUOTE
451;
452
453end: T_ENDMENU nl_or_eof { $$ = T_ENDMENU; }
454 | T_ENDCHOICE nl_or_eof { $$ = T_ENDCHOICE; }
455 | T_ENDIF nl_or_eof { $$ = T_ENDIF; }
456;
457
458nl_or_eof:
459 T_EOL | T_EOF;
460
461if_expr: /* empty */ { $$ = NULL; }
462 | T_IF expr { $$ = $2; }
463;
464
465expr: symbol { $$ = expr_alloc_symbol($1); }
466 | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
467 | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
468 | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; }
469 | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); }
470 | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); }
471 | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); }
472;
473
474symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); }
475 | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); }
476;
477
478%%
479
480void conf_parse(const char *name)
481{
482 struct symbol *sym;
483 int i;
484
485 zconf_initscan(name);
486
487 sym_init();
488 menu_init();
489 modules_sym = sym_lookup("MODULES", 0);
490 rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
491
492 //zconfdebug = 1;
493 zconfparse();
494 if (zconfnerrs)
495 exit(1);
496 menu_finalize(&rootmenu);
497 for_all_symbols(i, sym) {
498 if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
499 printf("\n");
500 else
501 sym->flags |= SYMBOL_CHECK_DONE;
502 }
503
504 sym_change_count = 1;
505}
506
507const char *zconf_tokenname(int token)
508{
509 switch (token) {
510 case T_MENU: return "menu";
511 case T_ENDMENU: return "endmenu";
512 case T_CHOICE: return "choice";
513 case T_ENDCHOICE: return "endchoice";
514 case T_IF: return "if";
515 case T_ENDIF: return "endif";
516 }
517 return "<token>";
518}
519
520static bool zconf_endtoken(int token, int starttoken, int endtoken)
521{
522 if (token != endtoken) {
523 zconfprint("unexpected '%s' within %s block", zconf_tokenname(token), zconf_tokenname(starttoken));
524 zconfnerrs++;
525 return false;
526 }
527 if (current_menu->file != current_file) {
528 zconfprint("'%s' in different file than '%s'", zconf_tokenname(token), zconf_tokenname(starttoken));
529 zconfprint("location of the '%s'", zconf_tokenname(starttoken));
530 zconfnerrs++;
531 return false;
532 }
533 return true;
534}
535
536static void zconfprint(const char *err, ...)
537{
538 va_list ap;
539
540 fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
541 va_start(ap, err);
542 vfprintf(stderr, err, ap);
543 va_end(ap);
544 fprintf(stderr, "\n");
545}
546
547static void zconferror(const char *err)
548{
549 fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
550}
551
552void print_quoted_string(FILE *out, const char *str)
553{
554 const char *p;
555 int len;
556
557 putc('"', out);
558 while ((p = strchr(str, '"'))) {
559 len = p - str;
560 if (len)
561 fprintf(out, "%.*s", len, str);
562 fputs("\\\"", out);
563 str = p + 1;
564 }
565 fputs(str, out);
566 putc('"', out);
567}
568
569void print_symbol(FILE *out, struct menu *menu)
570{
571 struct symbol *sym = menu->sym;
572 struct property *prop;
573
574 if (sym_is_choice(sym))
575 fprintf(out, "choice\n");
576 else
577 fprintf(out, "config %s\n", sym->name);
578 switch (sym->type) {
579 case S_BOOLEAN:
580 fputs(" boolean\n", out);
581 break;
582 case S_TRISTATE:
583 fputs(" tristate\n", out);
584 break;
585 case S_STRING:
586 fputs(" string\n", out);
587 break;
588 case S_INT:
589 fputs(" integer\n", out);
590 break;
591 case S_HEX:
592 fputs(" hex\n", out);
593 break;
594 default:
595 fputs(" ???\n", out);
596 break;
597 }
598 for (prop = sym->prop; prop; prop = prop->next) {
599 if (prop->menu != menu)
600 continue;
601 switch (prop->type) {
602 case P_PROMPT:
603 fputs(" prompt ", out);
604 print_quoted_string(out, prop->text);
605 if (!expr_is_yes(prop->visible.expr)) {
606 fputs(" if ", out);
607 expr_fprint(prop->visible.expr, out);
608 }
609 fputc('\n', out);
610 break;
611 case P_DEFAULT:
612 fputs( " default ", out);
613 expr_fprint(prop->expr, out);
614 if (!expr_is_yes(prop->visible.expr)) {
615 fputs(" if ", out);
616 expr_fprint(prop->visible.expr, out);
617 }
618 fputc('\n', out);
619 break;
620 case P_CHOICE:
621 fputs(" #choice value\n", out);
622 break;
623 default:
624 fprintf(out, " unknown prop %d!\n", prop->type);
625 break;
626 }
627 }
628 if (sym->help) {
629 int len = strlen(sym->help);
630 while (sym->help[--len] == '\n')
631 sym->help[len] = 0;
632 fprintf(out, " help\n%s\n", sym->help);
633 }
634 fputc('\n', out);
635}
636
637void zconfdump(FILE *out)
638{
639 struct property *prop;
640 struct symbol *sym;
641 struct menu *menu;
642
643 menu = rootmenu.list;
644 while (menu) {
645 if ((sym = menu->sym))
646 print_symbol(out, menu);
647 else if ((prop = menu->prompt)) {
648 switch (prop->type) {
649 case P_COMMENT:
650 fputs("\ncomment ", out);
651 print_quoted_string(out, prop->text);
652 fputs("\n", out);
653 break;
654 case P_MENU:
655 fputs("\nmenu ", out);
656 print_quoted_string(out, prop->text);
657 fputs("\n", out);
658 break;
659 default:
660 ;
661 }
662 if (!expr_is_yes(prop->visible.expr)) {
663 fputs(" depends ", out);
664 expr_fprint(prop->visible.expr, out);
665 fputc('\n', out);
666 }
667 fputs("\n", out);
668 }
669
670 if (menu->list)
671 menu = menu->list;
672 else if (menu->next)
673 menu = menu->next;
674 else while ((menu = menu->parent)) {
675 if (menu->prompt && menu->prompt->type == P_MENU)
676 fputs("\nendmenu\n", out);
677 if (menu->next) {
678 menu = menu->next;
679 break;
680 }
681 }
682 }
683}
684
685#include "lex.zconf.c"
686#include "util.c"
687#include "confdata.c"
688#include "expr.c"
689#include "symbol.c"
690#include "menu.c"
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
new file mode 100755
index 000000000000..8b1dab63f11c
--- /dev/null
+++ b/scripts/kernel-doc
@@ -0,0 +1,1831 @@
1#!/usr/bin/perl -w
2
3use strict;
4
5## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
6## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
7## Copyright (C) 2001 Simon Huggins ##
8## ##
9## #define enhancements by Armin Kuster <akuster@mvista.com> ##
10## Copyright (c) 2000 MontaVista Software, Inc. ##
11## ##
12## This software falls under the GNU General Public License. ##
13## Please read the COPYING file for more information ##
14
15# w.o. 03-11-2000: added the '-filelist' option.
16
17# 18/01/2001 - Cleanups
18# Functions prototyped as foo(void) same as foo()
19# Stop eval'ing where we don't need to.
20# -- huggie@earth.li
21
22# 27/06/2001 - Allowed whitespace after initial "/**" and
23# allowed comments before function declarations.
24# -- Christian Kreibich <ck@whoop.org>
25
26# Still to do:
27# - add perldoc documentation
28# - Look more closely at some of the scarier bits :)
29
30# 26/05/2001 - Support for separate source and object trees.
31# Return error code.
32# Keith Owens <kaos@ocs.com.au>
33
34# 23/09/2001 - Added support for typedefs, structs, enums and unions
35# Support for Context section; can be terminated using empty line
36# Small fixes (like spaces vs. \s in regex)
37# -- Tim Jansen <tim@tjansen.de>
38
39
40#
41# This will read a 'c' file and scan for embedded comments in the
42# style of gnome comments (+minor extensions - see below).
43#
44
45# Note: This only supports 'c'.
46
47# usage:
48# kerneldoc [ -docbook | -html | -text | -man ]
49# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
50# or
51# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
52#
53# Set output format using one of -docbook -html -text or -man. Default is man.
54#
55# -function funcname
56# If set, then only generate documentation for the given function(s). All
57# other functions are ignored.
58#
59# -nofunction funcname
60# If set, then only generate documentation for the other function(s). All
61# other functions are ignored. Cannot be used with -function together
62# (yes thats a bug - perl hackers can fix it 8))
63#
64# c files - list of 'c' files to process
65#
66# All output goes to stdout, with errors to stderr.
67
68#
69# format of comments.
70# In the following table, (...)? signifies optional structure.
71# (...)* signifies 0 or more structure elements
72# /**
73# * function_name(:)? (- short description)?
74# (* @parameterx: (description of parameter x)?)*
75# (* a blank line)?
76# * (Description:)? (Description of function)?
77# * (section header: (section description)? )*
78# (*)?*/
79#
80# So .. the trivial example would be:
81#
82# /**
83# * my_function
84# **/
85#
86# If the Description: header tag is ommitted, then there must be a blank line
87# after the last parameter specification.
88# e.g.
89# /**
90# * my_function - does my stuff
91# * @my_arg: its mine damnit
92# *
93# * Does my stuff explained.
94# */
95#
96# or, could also use:
97# /**
98# * my_function - does my stuff
99# * @my_arg: its mine damnit
100# * Description: Does my stuff explained.
101# */
102# etc.
103#
104# Beside functions you can also write documentation for structs, unions,
105# enums and typedefs. Instead of the function name you must write the name
106# of the declaration; the struct/union/enum/typedef must always precede
107# the name. Nesting of declarations is not supported.
108# Use the argument mechanism to document members or constants.
109# e.g.
110# /**
111# * struct my_struct - short description
112# * @a: first member
113# * @b: second member
114# *
115# * Longer description
116# */
117# struct my_struct {
118# int a;
119# int b;
120# };
121#
122# All descriptions can be multiline, except the short function description.
123#
124# You can also add additional sections. When documenting kernel functions you
125# should document the "Context:" of the function, e.g. whether the functions
126# can be called form interrupts. Unlike other sections you can end it with an
127# empty line.
128# Example-sections should contain the string EXAMPLE so that they are marked
129# appropriately in DocBook.
130#
131# Example:
132# /**
133# * user_function - function that can only be called in user context
134# * @a: some argument
135# * Context: !in_interrupt()
136# *
137# * Some description
138# * Example:
139# * user_function(22);
140# */
141# ...
142#
143#
144# All descriptive text is further processed, scanning for the following special
145# patterns, which are highlighted appropriately.
146#
147# 'funcname()' - function
148# '$ENVVAR' - environmental variable
149# '&struct_name' - name of a structure (up to two words including 'struct')
150# '@parameter' - name of a parameter
151# '%CONST' - name of a constant.
152
153my $errors = 0;
154my $warnings = 0;
155
156# match expressions used to find embedded type information
157my $type_constant = '\%([-_\w]+)';
158my $type_func = '(\w+)\(\)';
159my $type_param = '\@(\w+)';
160my $type_struct = '\&((struct\s*)?[_\w]+)';
161my $type_env = '(\$\w+)';
162
163# Output conversion substitutions.
164# One for each output format
165
166# these work fairly well
167my %highlights_html = ( $type_constant, "<i>\$1</i>",
168 $type_func, "<b>\$1</b>",
169 $type_struct, "<i>\$1</i>",
170 $type_param, "<tt><b>\$1</b></tt>" );
171my $blankline_html = "<p>";
172
173# XML, docbook format
174my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
175 $type_constant, "<constant>\$1</constant>",
176 $type_func, "<function>\$1</function>",
177 $type_struct, "<structname>\$1</structname>",
178 $type_env, "<envar>\$1</envar>",
179 $type_param, "<parameter>\$1</parameter>" );
180my $blankline_xml = "</para><para>\n";
181
182# gnome, docbook format
183my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
184 $type_func, "<function>\$1</function>",
185 $type_struct, "<structname>\$1</structname>",
186 $type_env, "<envar>\$1</envar>",
187 $type_param, "<parameter>\$1</parameter>" );
188my $blankline_gnome = "</para><para>\n";
189
190# these are pretty rough
191my %highlights_man = ( $type_constant, "\$1",
192 $type_func, "\\\\fB\$1\\\\fP",
193 $type_struct, "\\\\fI\$1\\\\fP",
194 $type_param, "\\\\fI\$1\\\\fP" );
195my $blankline_man = "";
196
197# text-mode
198my %highlights_text = ( $type_constant, "\$1",
199 $type_func, "\$1",
200 $type_struct, "\$1",
201 $type_param, "\$1" );
202my $blankline_text = "";
203
204
205sub usage {
206 print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
207 print " [ -function funcname [ -function funcname ...] ]\n";
208 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
209 print " c source file(s) > outputfile\n";
210 exit 1;
211}
212
213# read arguments
214if ($#ARGV==-1) {
215 usage();
216}
217
218my $verbose = 0;
219my $output_mode = "man";
220my %highlights = %highlights_man;
221my $blankline = $blankline_man;
222my $modulename = "Kernel API";
223my $function_only = 0;
224my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
225 'July', 'August', 'September', 'October',
226 'November', 'December')[(localtime)[4]] .
227 " " . ((localtime)[5]+1900);
228
229# Essentially these are globals
230# They probably want to be tidied up made more localised or summat.
231# CAVEAT EMPTOR! Some of the others I localised may not want to be which
232# could cause "use of undefined value" or other bugs.
233my ($function, %function_table,%parametertypes,$declaration_purpose);
234my ($type,$declaration_name,$return_type);
235my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
236
237# Generated docbook code is inserted in a template at a point where
238# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
239# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
240# We keep track of number of generated entries and generate a dummy
241# if needs be to ensure the expanded template can be postprocessed
242# into html.
243my $section_counter = 0;
244
245my $lineprefix="";
246
247# states
248# 0 - normal code
249# 1 - looking for function name
250# 2 - scanning field start.
251# 3 - scanning prototype.
252# 4 - documentation block
253my $state;
254
255#declaration types: can be
256# 'function', 'struct', 'union', 'enum', 'typedef'
257my $decl_type;
258
259my $doc_special = "\@\%\$\&";
260
261my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
262my $doc_end = '\*/';
263my $doc_com = '\s*\*\s*';
264my $doc_decl = $doc_com.'(\w+)';
265my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)';
266my $doc_content = $doc_com.'(.*)';
267my $doc_block = $doc_com.'DOC:\s*(.*)?';
268
269my %constants;
270my %parameterdescs;
271my @parameterlist;
272my %sections;
273my @sectionlist;
274
275my $contents = "";
276my $section_default = "Description"; # default section
277my $section_intro = "Introduction";
278my $section = $section_default;
279my $section_context = "Context";
280
281my $undescribed = "-- undescribed --";
282
283reset_state();
284
285while ($ARGV[0] =~ m/^-(.*)/) {
286 my $cmd = shift @ARGV;
287 if ($cmd eq "-html") {
288 $output_mode = "html";
289 %highlights = %highlights_html;
290 $blankline = $blankline_html;
291 } elsif ($cmd eq "-man") {
292 $output_mode = "man";
293 %highlights = %highlights_man;
294 $blankline = $blankline_man;
295 } elsif ($cmd eq "-text") {
296 $output_mode = "text";
297 %highlights = %highlights_text;
298 $blankline = $blankline_text;
299 } elsif ($cmd eq "-docbook") {
300 $output_mode = "xml";
301 %highlights = %highlights_xml;
302 $blankline = $blankline_xml;
303 } elsif ($cmd eq "-gnome") {
304 $output_mode = "gnome";
305 %highlights = %highlights_gnome;
306 $blankline = $blankline_gnome;
307 } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
308 $modulename = shift @ARGV;
309 } elsif ($cmd eq "-function") { # to only output specific functions
310 $function_only = 1;
311 $function = shift @ARGV;
312 $function_table{$function} = 1;
313 } elsif ($cmd eq "-nofunction") { # to only output specific functions
314 $function_only = 2;
315 $function = shift @ARGV;
316 $function_table{$function} = 1;
317 } elsif ($cmd eq "-v") {
318 $verbose = 1;
319 } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
320 usage();
321 } elsif ($cmd eq '-filelist') {
322 $filelist = shift @ARGV;
323 }
324}
325
326
327# generate a sequence of code that will splice in highlighting information
328# using the s// operator.
329my $dohighlight = "";
330foreach my $pattern (keys %highlights) {
331# print "scanning pattern $pattern ($highlights{$pattern})\n";
332 $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
333}
334
335##
336# dumps section contents to arrays/hashes intended for that purpose.
337#
338sub dump_section {
339 my $name = shift;
340 my $contents = join "\n", @_;
341
342 if ($name =~ m/$type_constant/) {
343 $name = $1;
344# print STDERR "constant section '$1' = '$contents'\n";
345 $constants{$name} = $contents;
346 } elsif ($name =~ m/$type_param/) {
347# print STDERR "parameter def '$1' = '$contents'\n";
348 $name = $1;
349 $parameterdescs{$name} = $contents;
350 } else {
351# print STDERR "other section '$name' = '$contents'\n";
352 $sections{$name} = $contents;
353 push @sectionlist, $name;
354 }
355}
356
357##
358# output function
359#
360# parameterdescs, a hash.
361# function => "function name"
362# parameterlist => @list of parameters
363# parameterdescs => %parameter descriptions
364# sectionlist => @list of sections
365# sections => %descriont descriptions
366#
367
368sub output_highlight {
369 my $contents = join "\n",@_;
370 my $line;
371
372# DEBUG
373# if (!defined $contents) {
374# use Carp;
375# confess "output_highlight got called with no args?\n";
376# }
377
378 eval $dohighlight;
379 die $@ if $@;
380 foreach $line (split "\n", $contents) {
381 if ($line eq ""){
382 print $lineprefix, $blankline;
383 } else {
384 $line =~ s/\\\\\\/\&/g;
385 print $lineprefix, $line;
386 }
387 print "\n";
388 }
389}
390
391#output sections in html
392sub output_section_html(%) {
393 my %args = %{$_[0]};
394 my $section;
395
396 foreach $section (@{$args{'sectionlist'}}) {
397 print "<h3>$section</h3>\n";
398 print "<blockquote>\n";
399 output_highlight($args{'sections'}{$section});
400 print "</blockquote>\n";
401 }
402}
403
404# output enum in html
405sub output_enum_html(%) {
406 my %args = %{$_[0]};
407 my ($parameter);
408 my $count;
409 print "<h2>enum ".$args{'enum'}."</h2>\n";
410
411 print "<b>enum ".$args{'enum'}."</b> {<br>\n";
412 $count = 0;
413 foreach $parameter (@{$args{'parameterlist'}}) {
414 print " <b>".$parameter."</b>";
415 if ($count != $#{$args{'parameterlist'}}) {
416 $count++;
417 print ",\n";
418 }
419 print "<br>";
420 }
421 print "};<br>\n";
422
423 print "<h3>Constants</h3>\n";
424 print "<dl>\n";
425 foreach $parameter (@{$args{'parameterlist'}}) {
426 print "<dt><b>".$parameter."</b>\n";
427 print "<dd>";
428 output_highlight($args{'parameterdescs'}{$parameter});
429 }
430 print "</dl>\n";
431 output_section_html(@_);
432 print "<hr>\n";
433}
434
435# output tyepdef in html
436sub output_typedef_html(%) {
437 my %args = %{$_[0]};
438 my ($parameter);
439 my $count;
440 print "<h2>typedef ".$args{'typedef'}."</h2>\n";
441
442 print "<b>typedef ".$args{'typedef'}."</b>\n";
443 output_section_html(@_);
444 print "<hr>\n";
445}
446
447# output struct in html
448sub output_struct_html(%) {
449 my %args = %{$_[0]};
450 my ($parameter);
451
452 print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n";
453 print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n";
454 foreach $parameter (@{$args{'parameterlist'}}) {
455 if ($parameter =~ /^#/) {
456 print "$parameter<br>\n";
457 next;
458 }
459 my $parameter_name = $parameter;
460 $parameter_name =~ s/\[.*//;
461
462 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
463 $type = $args{'parametertypes'}{$parameter};
464 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
465 # pointer-to-function
466 print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
467 } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
468 print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
469 } else {
470 print " <i>$type</i> <b>$parameter</b>;<br>\n";
471 }
472 }
473 print "};<br>\n";
474
475 print "<h3>Members</h3>\n";
476 print "<dl>\n";
477 foreach $parameter (@{$args{'parameterlist'}}) {
478 ($parameter =~ /^#/) && next;
479
480 my $parameter_name = $parameter;
481 $parameter_name =~ s/\[.*//;
482
483 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
484 print "<dt><b>".$parameter."</b>\n";
485 print "<dd>";
486 output_highlight($args{'parameterdescs'}{$parameter_name});
487 }
488 print "</dl>\n";
489 output_section_html(@_);
490 print "<hr>\n";
491}
492
493# output function in html
494sub output_function_html(%) {
495 my %args = %{$_[0]};
496 my ($parameter, $section);
497 my $count;
498 print "<h2>Function</h2>\n";
499
500 print "<i>".$args{'functiontype'}."</i>\n";
501 print "<b>".$args{'function'}."</b>\n";
502 print "(";
503 $count = 0;
504 foreach $parameter (@{$args{'parameterlist'}}) {
505 $type = $args{'parametertypes'}{$parameter};
506 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
507 # pointer-to-function
508 print "<i>$1</i><b>$parameter</b>) <i>($2)</i>";
509 } else {
510 print "<i>".$type."</i> <b>".$parameter."</b>";
511 }
512 if ($count != $#{$args{'parameterlist'}}) {
513 $count++;
514 print ",\n";
515 }
516 }
517 print ")\n";
518
519 print "<h3>Arguments</h3>\n";
520 print "<dl>\n";
521 foreach $parameter (@{$args{'parameterlist'}}) {
522 my $parameter_name = $parameter;
523 $parameter_name =~ s/\[.*//;
524
525 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
526 print "<dt><b>".$parameter."</b>\n";
527 print "<dd>";
528 output_highlight($args{'parameterdescs'}{$parameter_name});
529 }
530 print "</dl>\n";
531 output_section_html(@_);
532 print "<hr>\n";
533}
534
535# output intro in html
536sub output_intro_html(%) {
537 my %args = %{$_[0]};
538 my ($parameter, $section);
539 my $count;
540
541 foreach $section (@{$args{'sectionlist'}}) {
542 print "<h3>$section</h3>\n";
543 print "<ul>\n";
544 output_highlight($args{'sections'}{$section});
545 print "</ul>\n";
546 }
547 print "<hr>\n";
548}
549
550sub output_section_xml(%) {
551 my %args = %{$_[0]};
552 my $section;
553 # print out each section
554 $lineprefix=" ";
555 foreach $section (@{$args{'sectionlist'}}) {
556 print "<refsect1>\n <title>$section</title>\n <para>\n";
557 if ($section =~ m/EXAMPLE/i) {
558 print "<example><para>\n";
559 }
560 output_highlight($args{'sections'}{$section});
561 if ($section =~ m/EXAMPLE/i) {
562 print "</para></example>\n";
563 }
564 print " </para>\n</refsect1>\n";
565 }
566}
567
568# output function in XML DocBook
569sub output_function_xml(%) {
570 my %args = %{$_[0]};
571 my ($parameter, $section);
572 my $count;
573 my $id;
574
575 $id = "API-".$args{'function'};
576 $id =~ s/[^A-Za-z0-9]/-/g;
577
578 print "<refentry>\n";
579 print "<refmeta>\n";
580 print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
581 print "</refmeta>\n";
582 print "<refnamediv>\n";
583 print " <refname>".$args{'function'}."</refname>\n";
584 print " <refpurpose>\n";
585 print " ";
586 output_highlight ($args{'purpose'});
587 print " </refpurpose>\n";
588 print "</refnamediv>\n";
589
590 print "<refsynopsisdiv>\n";
591 print " <title>Synopsis</title>\n";
592 print " <funcsynopsis><funcprototype>\n";
593 print " <funcdef>".$args{'functiontype'}." ";
594 print "<function>".$args{'function'}." </function></funcdef>\n";
595
596 $count = 0;
597 if ($#{$args{'parameterlist'}} >= 0) {
598 foreach $parameter (@{$args{'parameterlist'}}) {
599 $type = $args{'parametertypes'}{$parameter};
600 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
601 # pointer-to-function
602 print " <paramdef>$1<parameter>$parameter</parameter>)\n";
603 print " <funcparams>$2</funcparams></paramdef>\n";
604 } else {
605 print " <paramdef>".$type;
606 print " <parameter>$parameter</parameter></paramdef>\n";
607 }
608 }
609 } else {
610 print " <void>\n";
611 }
612 print " </funcprototype></funcsynopsis>\n";
613 print "</refsynopsisdiv>\n";
614
615 # print parameters
616 print "<refsect1>\n <title>Arguments</title>\n";
617 if ($#{$args{'parameterlist'}} >= 0) {
618 print " <variablelist>\n";
619 foreach $parameter (@{$args{'parameterlist'}}) {
620 my $parameter_name = $parameter;
621 $parameter_name =~ s/\[.*//;
622
623 print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n";
624 print " <listitem>\n <para>\n";
625 $lineprefix=" ";
626 output_highlight($args{'parameterdescs'}{$parameter_name});
627 print " </para>\n </listitem>\n </varlistentry>\n";
628 }
629 print " </variablelist>\n";
630 } else {
631 print " <para>\n None\n </para>\n";
632 }
633 print "</refsect1>\n";
634
635 output_section_xml(@_);
636 print "</refentry>\n\n";
637}
638
639# output struct in XML DocBook
640sub output_struct_xml(%) {
641 my %args = %{$_[0]};
642 my ($parameter, $section);
643 my $id;
644
645 $id = "API-struct-".$args{'struct'};
646 $id =~ s/[^A-Za-z0-9]/-/g;
647
648 print "<refentry>\n";
649 print "<refmeta>\n";
650 print "<refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n";
651 print "</refmeta>\n";
652 print "<refnamediv>\n";
653 print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n";
654 print " <refpurpose>\n";
655 print " ";
656 output_highlight ($args{'purpose'});
657 print " </refpurpose>\n";
658 print "</refnamediv>\n";
659
660 print "<refsynopsisdiv>\n";
661 print " <title>Synopsis</title>\n";
662 print " <programlisting>\n";
663 print $args{'type'}." ".$args{'struct'}." {\n";
664 foreach $parameter (@{$args{'parameterlist'}}) {
665 if ($parameter =~ /^#/) {
666 print "$parameter\n";
667 next;
668 }
669
670 my $parameter_name = $parameter;
671 $parameter_name =~ s/\[.*//;
672
673 defined($args{'parameterdescs'}{$parameter_name}) || next;
674 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
675 $type = $args{'parametertypes'}{$parameter};
676 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
677 # pointer-to-function
678 print " $1 $parameter) ($2);\n";
679 } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
680 print " $1 $parameter$2;\n";
681 } else {
682 print " ".$type." ".$parameter.";\n";
683 }
684 }
685 print "};";
686 print " </programlisting>\n";
687 print "</refsynopsisdiv>\n";
688
689 print " <refsect1>\n";
690 print " <title>Members</title>\n";
691
692 print " <variablelist>\n";
693 foreach $parameter (@{$args{'parameterlist'}}) {
694 ($parameter =~ /^#/) && next;
695
696 my $parameter_name = $parameter;
697 $parameter_name =~ s/\[.*//;
698
699 defined($args{'parameterdescs'}{$parameter_name}) || next;
700 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
701 print " <varlistentry>";
702 print " <term>$parameter</term>\n";
703 print " <listitem><para>\n";
704 output_highlight($args{'parameterdescs'}{$parameter_name});
705 print " </para></listitem>\n";
706 print " </varlistentry>\n";
707 }
708 print " </variablelist>\n";
709 print " </refsect1>\n";
710
711 output_section_xml(@_);
712
713 print "</refentry>\n\n";
714}
715
716# output enum in XML DocBook
717sub output_enum_xml(%) {
718 my %args = %{$_[0]};
719 my ($parameter, $section);
720 my $count;
721 my $id;
722
723 $id = "API-enum-".$args{'enum'};
724 $id =~ s/[^A-Za-z0-9]/-/g;
725
726 print "<refentry>\n";
727 print "<refmeta>\n";
728 print "<refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n";
729 print "</refmeta>\n";
730 print "<refnamediv>\n";
731 print " <refname>enum ".$args{'enum'}."</refname>\n";
732 print " <refpurpose>\n";
733 print " ";
734 output_highlight ($args{'purpose'});
735 print " </refpurpose>\n";
736 print "</refnamediv>\n";
737
738 print "<refsynopsisdiv>\n";
739 print " <title>Synopsis</title>\n";
740 print " <programlisting>\n";
741 print "enum ".$args{'enum'}." {\n";
742 $count = 0;
743 foreach $parameter (@{$args{'parameterlist'}}) {
744 print " $parameter";
745 if ($count != $#{$args{'parameterlist'}}) {
746 $count++;
747 print ",";
748 }
749 print "\n";
750 }
751 print "};";
752 print " </programlisting>\n";
753 print "</refsynopsisdiv>\n";
754
755 print "<refsect1>\n";
756 print " <title>Constants</title>\n";
757 print " <variablelist>\n";
758 foreach $parameter (@{$args{'parameterlist'}}) {
759 my $parameter_name = $parameter;
760 $parameter_name =~ s/\[.*//;
761
762 print " <varlistentry>";
763 print " <term>$parameter</term>\n";
764 print " <listitem><para>\n";
765 output_highlight($args{'parameterdescs'}{$parameter_name});
766 print " </para></listitem>\n";
767 print " </varlistentry>\n";
768 }
769 print " </variablelist>\n";
770 print "</refsect1>\n";
771
772 output_section_xml(@_);
773
774 print "</refentry>\n\n";
775}
776
777# output typedef in XML DocBook
778sub output_typedef_xml(%) {
779 my %args = %{$_[0]};
780 my ($parameter, $section);
781 my $id;
782
783 $id = "API-typedef-".$args{'typedef'};
784 $id =~ s/[^A-Za-z0-9]/-/g;
785
786 print "<refentry>\n";
787 print "<refmeta>\n";
788 print "<refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n";
789 print "</refmeta>\n";
790 print "<refnamediv>\n";
791 print " <refname>typedef ".$args{'typedef'}."</refname>\n";
792 print " <refpurpose>\n";
793 print " ";
794 output_highlight ($args{'purpose'});
795 print " </refpurpose>\n";
796 print "</refnamediv>\n";
797
798 print "<refsynopsisdiv>\n";
799 print " <title>Synopsis</title>\n";
800 print " <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n";
801 print "</refsynopsisdiv>\n";
802
803 output_section_xml(@_);
804
805 print "</refentry>\n\n";
806}
807
808# output in XML DocBook
809sub output_intro_xml(%) {
810 my %args = %{$_[0]};
811 my ($parameter, $section);
812 my $count;
813
814 my $id = $args{'module'};
815 $id =~ s/[^A-Za-z0-9]/-/g;
816
817 # print out each section
818 $lineprefix=" ";
819 foreach $section (@{$args{'sectionlist'}}) {
820 print "<refsect1>\n <title>$section</title>\n <para>\n";
821 if ($section =~ m/EXAMPLE/i) {
822 print "<example><para>\n";
823 }
824 output_highlight($args{'sections'}{$section});
825 if ($section =~ m/EXAMPLE/i) {
826 print "</para></example>\n";
827 }
828 print " </para>\n</refsect1>\n";
829 }
830
831 print "\n\n";
832}
833
834# output in XML DocBook
835sub output_function_gnome {
836 my %args = %{$_[0]};
837 my ($parameter, $section);
838 my $count;
839 my $id;
840
841 $id = $args{'module'}."-".$args{'function'};
842 $id =~ s/[^A-Za-z0-9]/-/g;
843
844 print "<sect2>\n";
845 print " <title id=\"$id\">".$args{'function'}."</title>\n";
846
847 print " <funcsynopsis>\n";
848 print " <funcdef>".$args{'functiontype'}." ";
849 print "<function>".$args{'function'}." ";
850 print "</function></funcdef>\n";
851
852 $count = 0;
853 if ($#{$args{'parameterlist'}} >= 0) {
854 foreach $parameter (@{$args{'parameterlist'}}) {
855 $type = $args{'parametertypes'}{$parameter};
856 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
857 # pointer-to-function
858 print " <paramdef>$1 <parameter>$parameter</parameter>)\n";
859 print " <funcparams>$2</funcparams></paramdef>\n";
860 } else {
861 print " <paramdef>".$type;
862 print " <parameter>$parameter</parameter></paramdef>\n";
863 }
864 }
865 } else {
866 print " <void>\n";
867 }
868 print " </funcsynopsis>\n";
869 if ($#{$args{'parameterlist'}} >= 0) {
870 print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n";
871 print "<tgroup cols=\"2\">\n";
872 print "<colspec colwidth=\"2*\">\n";
873 print "<colspec colwidth=\"8*\">\n";
874 print "<tbody>\n";
875 foreach $parameter (@{$args{'parameterlist'}}) {
876 my $parameter_name = $parameter;
877 $parameter_name =~ s/\[.*//;
878
879 print " <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
880 print " <entry>\n";
881 $lineprefix=" ";
882 output_highlight($args{'parameterdescs'}{$parameter_name});
883 print " </entry></row>\n";
884 }
885 print " </tbody></tgroup></informaltable>\n";
886 } else {
887 print " <para>\n None\n </para>\n";
888 }
889
890 # print out each section
891 $lineprefix=" ";
892 foreach $section (@{$args{'sectionlist'}}) {
893 print "<simplesect>\n <title>$section</title>\n";
894 if ($section =~ m/EXAMPLE/i) {
895 print "<example><programlisting>\n";
896 } else {
897 }
898 print "<para>\n";
899 output_highlight($args{'sections'}{$section});
900 print "</para>\n";
901 if ($section =~ m/EXAMPLE/i) {
902 print "</programlisting></example>\n";
903 } else {
904 }
905 print " </simplesect>\n";
906 }
907
908 print "</sect2>\n\n";
909}
910
911##
912# output function in man
913sub output_function_man(%) {
914 my %args = %{$_[0]};
915 my ($parameter, $section);
916 my $count;
917
918 print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
919
920 print ".SH NAME\n";
921 print $args{'function'}." \\- ".$args{'purpose'}."\n";
922
923 print ".SH SYNOPSIS\n";
924 print ".B \"".$args{'functiontype'}."\" ".$args{'function'}."\n";
925 $count = 0;
926 my $parenth = "(";
927 my $post = ",";
928 foreach my $parameter (@{$args{'parameterlist'}}) {
929 if ($count == $#{$args{'parameterlist'}}) {
930 $post = ");";
931 }
932 $type = $args{'parametertypes'}{$parameter};
933 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
934 # pointer-to-function
935 print ".BI \"".$parenth.$1."\" ".$parameter." \") (".$2.")".$post."\"\n";
936 } else {
937 $type =~ s/([^\*])$/$1 /;
938 print ".BI \"".$parenth.$type."\" ".$parameter." \"".$post."\"\n";
939 }
940 $count++;
941 $parenth = "";
942 }
943
944 print ".SH ARGUMENTS\n";
945 foreach $parameter (@{$args{'parameterlist'}}) {
946 my $parameter_name = $parameter;
947 $parameter_name =~ s/\[.*//;
948
949 print ".IP \"".$parameter."\" 12\n";
950 output_highlight($args{'parameterdescs'}{$parameter_name});
951 }
952 foreach $section (@{$args{'sectionlist'}}) {
953 print ".SH \"", uc $section, "\"\n";
954 output_highlight($args{'sections'}{$section});
955 }
956}
957
958##
959# output enum in man
960sub output_enum_man(%) {
961 my %args = %{$_[0]};
962 my ($parameter, $section);
963 my $count;
964
965 print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
966
967 print ".SH NAME\n";
968 print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n";
969
970 print ".SH SYNOPSIS\n";
971 print "enum ".$args{'enum'}." {\n";
972 $count = 0;
973 foreach my $parameter (@{$args{'parameterlist'}}) {
974 print ".br\n.BI \" $parameter\"\n";
975 if ($count == $#{$args{'parameterlist'}}) {
976 print "\n};\n";
977 last;
978 }
979 else {
980 print ", \n.br\n";
981 }
982 $count++;
983 }
984
985 print ".SH Constants\n";
986 foreach $parameter (@{$args{'parameterlist'}}) {
987 my $parameter_name = $parameter;
988 $parameter_name =~ s/\[.*//;
989
990 print ".IP \"".$parameter."\" 12\n";
991 output_highlight($args{'parameterdescs'}{$parameter_name});
992 }
993 foreach $section (@{$args{'sectionlist'}}) {
994 print ".SH \"$section\"\n";
995 output_highlight($args{'sections'}{$section});
996 }
997}
998
999##
1000# output struct in man
1001sub output_struct_man(%) {
1002 my %args = %{$_[0]};
1003 my ($parameter, $section);
1004
1005 print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n";
1006
1007 print ".SH NAME\n";
1008 print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n";
1009
1010 print ".SH SYNOPSIS\n";
1011 print $args{'type'}." ".$args{'struct'}." {\n.br\n";
1012
1013 foreach my $parameter (@{$args{'parameterlist'}}) {
1014 if ($parameter =~ /^#/) {
1015 print ".BI \"$parameter\"\n.br\n";
1016 next;
1017 }
1018 my $parameter_name = $parameter;
1019 $parameter_name =~ s/\[.*//;
1020
1021 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1022 $type = $args{'parametertypes'}{$parameter};
1023 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1024 # pointer-to-function
1025 print ".BI \" ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n";
1026 } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
1027 print ".BI \" ".$1."\" ".$parameter.$2." \""."\"\n;\n";
1028 } else {
1029 $type =~ s/([^\*])$/$1 /;
1030 print ".BI \" ".$type."\" ".$parameter." \""."\"\n;\n";
1031 }
1032 print "\n.br\n";
1033 }
1034 print "};\n.br\n";
1035
1036 print ".SH Arguments\n";
1037 foreach $parameter (@{$args{'parameterlist'}}) {
1038 ($parameter =~ /^#/) && next;
1039
1040 my $parameter_name = $parameter;
1041 $parameter_name =~ s/\[.*//;
1042
1043 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1044 print ".IP \"".$parameter."\" 12\n";
1045 output_highlight($args{'parameterdescs'}{$parameter_name});
1046 }
1047 foreach $section (@{$args{'sectionlist'}}) {
1048 print ".SH \"$section\"\n";
1049 output_highlight($args{'sections'}{$section});
1050 }
1051}
1052
1053##
1054# output typedef in man
1055sub output_typedef_man(%) {
1056 my %args = %{$_[0]};
1057 my ($parameter, $section);
1058
1059 print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
1060
1061 print ".SH NAME\n";
1062 print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n";
1063
1064 foreach $section (@{$args{'sectionlist'}}) {
1065 print ".SH \"$section\"\n";
1066 output_highlight($args{'sections'}{$section});
1067 }
1068}
1069
1070sub output_intro_man(%) {
1071 my %args = %{$_[0]};
1072 my ($parameter, $section);
1073 my $count;
1074
1075 print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
1076
1077 foreach $section (@{$args{'sectionlist'}}) {
1078 print ".SH \"$section\"\n";
1079 output_highlight($args{'sections'}{$section});
1080 }
1081}
1082
1083##
1084# output in text
1085sub output_function_text(%) {
1086 my %args = %{$_[0]};
1087 my ($parameter, $section);
1088
1089 print "Function:\n\n";
1090 my $start=$args{'functiontype'}." ".$args{'function'}." (";
1091 print $start;
1092 my $count = 0;
1093 foreach my $parameter (@{$args{'parameterlist'}}) {
1094 $type = $args{'parametertypes'}{$parameter};
1095 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1096 # pointer-to-function
1097 print $1.$parameter.") (".$2;
1098 } else {
1099 print $type." ".$parameter;
1100 }
1101 if ($count != $#{$args{'parameterlist'}}) {
1102 $count++;
1103 print ",\n";
1104 print " " x length($start);
1105 } else {
1106 print ");\n\n";
1107 }
1108 }
1109
1110 print "Arguments:\n\n";
1111 foreach $parameter (@{$args{'parameterlist'}}) {
1112 my $parameter_name = $parameter;
1113 $parameter_name =~ s/\[.*//;
1114
1115 print $parameter."\n\t".$args{'parameterdescs'}{$parameter_name}."\n";
1116 }
1117 output_section_text(@_);
1118}
1119
1120#output sections in text
1121sub output_section_text(%) {
1122 my %args = %{$_[0]};
1123 my $section;
1124
1125 print "\n";
1126 foreach $section (@{$args{'sectionlist'}}) {
1127 print "$section:\n\n";
1128 output_highlight($args{'sections'}{$section});
1129 }
1130 print "\n\n";
1131}
1132
1133# output enum in text
1134sub output_enum_text(%) {
1135 my %args = %{$_[0]};
1136 my ($parameter);
1137 my $count;
1138 print "Enum:\n\n";
1139
1140 print "enum ".$args{'enum'}." {\n";
1141 $count = 0;
1142 foreach $parameter (@{$args{'parameterlist'}}) {
1143 print "\t$parameter";
1144 if ($count != $#{$args{'parameterlist'}}) {
1145 $count++;
1146 print ",";
1147 }
1148 print "\n";
1149 }
1150 print "};\n\n";
1151
1152 print "Constants:\n\n";
1153 foreach $parameter (@{$args{'parameterlist'}}) {
1154 print "$parameter\n\t";
1155 print $args{'parameterdescs'}{$parameter}."\n";
1156 }
1157
1158 output_section_text(@_);
1159}
1160
1161# output typedef in text
1162sub output_typedef_text(%) {
1163 my %args = %{$_[0]};
1164 my ($parameter);
1165 my $count;
1166 print "Typedef:\n\n";
1167
1168 print "typedef ".$args{'typedef'}."\n";
1169 output_section_text(@_);
1170}
1171
1172# output struct as text
1173sub output_struct_text(%) {
1174 my %args = %{$_[0]};
1175 my ($parameter);
1176
1177 print $args{'type'}." ".$args{'struct'}.":\n\n";
1178 print $args{'type'}." ".$args{'struct'}." {\n";
1179 foreach $parameter (@{$args{'parameterlist'}}) {
1180 if ($parameter =~ /^#/) {
1181 print "$parameter\n";
1182 next;
1183 }
1184
1185 my $parameter_name = $parameter;
1186 $parameter_name =~ s/\[.*//;
1187
1188 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1189 $type = $args{'parametertypes'}{$parameter};
1190 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
1191 # pointer-to-function
1192 print "\t$1 $parameter) ($2);\n";
1193 } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
1194 print "\t$1 $parameter$2;\n";
1195 } else {
1196 print "\t".$type." ".$parameter.";\n";
1197 }
1198 }
1199 print "};\n\n";
1200
1201 print "Members:\n\n";
1202 foreach $parameter (@{$args{'parameterlist'}}) {
1203 ($parameter =~ /^#/) && next;
1204
1205 my $parameter_name = $parameter;
1206 $parameter_name =~ s/\[.*//;
1207
1208 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1209 print "$parameter\n\t";
1210 print $args{'parameterdescs'}{$parameter_name}."\n";
1211 }
1212 print "\n";
1213 output_section_text(@_);
1214}
1215
1216sub output_intro_text(%) {
1217 my %args = %{$_[0]};
1218 my ($parameter, $section);
1219
1220 foreach $section (@{$args{'sectionlist'}}) {
1221 print " $section:\n";
1222 print " -> ";
1223 output_highlight($args{'sections'}{$section});
1224 }
1225}
1226
1227##
1228# generic output function for typedefs
1229sub output_declaration {
1230 no strict 'refs';
1231 my $name = shift;
1232 my $functype = shift;
1233 my $func = "output_${functype}_$output_mode";
1234 if (($function_only==0) ||
1235 ( $function_only == 1 && defined($function_table{$name})) ||
1236 ( $function_only == 2 && !defined($function_table{$name})))
1237 {
1238 &$func(@_);
1239 $section_counter++;
1240 }
1241}
1242
1243##
1244# generic output function - calls the right one based
1245# on current output mode.
1246sub output_intro {
1247 no strict 'refs';
1248 my $func = "output_intro_".$output_mode;
1249 &$func(@_);
1250 $section_counter++;
1251}
1252
1253##
1254# takes a declaration (struct, union, enum, typedef) and
1255# invokes the right handler. NOT called for functions.
1256sub dump_declaration($$) {
1257 no strict 'refs';
1258 my ($prototype, $file) = @_;
1259 my $func = "dump_".$decl_type;
1260 &$func(@_);
1261}
1262
1263sub dump_union($$) {
1264 dump_struct(@_);
1265}
1266
1267sub dump_struct($$) {
1268 my $x = shift;
1269 my $file = shift;
1270
1271 if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
1272 $declaration_name = $2;
1273 my $members = $3;
1274
1275 # ignore embedded structs or unions
1276 $members =~ s/{.*?}//g;
1277
1278 create_parameterlist($members, ';', $file);
1279
1280 output_declaration($declaration_name,
1281 'struct',
1282 {'struct' => $declaration_name,
1283 'module' => $modulename,
1284 'parameterlist' => \@parameterlist,
1285 'parameterdescs' => \%parameterdescs,
1286 'parametertypes' => \%parametertypes,
1287 'sectionlist' => \@sectionlist,
1288 'sections' => \%sections,
1289 'purpose' => $declaration_purpose,
1290 'type' => $decl_type
1291 });
1292 }
1293 else {
1294 print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
1295 ++$errors;
1296 }
1297}
1298
1299sub dump_enum($$) {
1300 my $x = shift;
1301 my $file = shift;
1302
1303 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
1304 $declaration_name = $1;
1305 my $members = $2;
1306
1307 foreach my $arg (split ',', $members) {
1308 $arg =~ s/^\s*(\w+).*/$1/;
1309 push @parameterlist, $arg;
1310 if (!$parameterdescs{$arg}) {
1311 $parameterdescs{$arg} = $undescribed;
1312 print STDERR "Warning(${file}:$.): Enum value '$arg' ".
1313 "not described in enum '$declaration_name'\n";
1314 }
1315
1316 }
1317
1318 output_declaration($declaration_name,
1319 'enum',
1320 {'enum' => $declaration_name,
1321 'module' => $modulename,
1322 'parameterlist' => \@parameterlist,
1323 'parameterdescs' => \%parameterdescs,
1324 'sectionlist' => \@sectionlist,
1325 'sections' => \%sections,
1326 'purpose' => $declaration_purpose
1327 });
1328 }
1329 else {
1330 print STDERR "Error(${file}:$.): Cannot parse enum!\n";
1331 ++$errors;
1332 }
1333}
1334
1335sub dump_typedef($$) {
1336 my $x = shift;
1337 my $file = shift;
1338
1339 while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
1340 $x =~ s/\(*.\)\s*;$/;/;
1341 $x =~ s/\[*.\]\s*;$/;/;
1342 }
1343
1344 if ($x =~ /typedef.*\s+(\w+)\s*;/) {
1345 $declaration_name = $1;
1346
1347 output_declaration($declaration_name,
1348 'typedef',
1349 {'typedef' => $declaration_name,
1350 'module' => $modulename,
1351 'sectionlist' => \@sectionlist,
1352 'sections' => \%sections,
1353 'purpose' => $declaration_purpose
1354 });
1355 }
1356 else {
1357 print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
1358 ++$errors;
1359 }
1360}
1361
1362sub create_parameterlist($$$) {
1363 my $args = shift;
1364 my $splitter = shift;
1365 my $file = shift;
1366 my $type;
1367 my $param;
1368
1369 while ($args =~ /(\([^\),]+),/) {
1370 $args =~ s/(\([^\),]+),/$1#/g;
1371 }
1372
1373 foreach my $arg (split($splitter, $args)) {
1374 # strip comments
1375 $arg =~ s/\/\*.*\*\///;
1376 # strip leading/trailing spaces
1377 $arg =~ s/^\s*//;
1378 $arg =~ s/\s*$//;
1379 $arg =~ s/\s+/ /;
1380
1381 if ($arg =~ /^#/) {
1382 # Treat preprocessor directive as a typeless variable just to fill
1383 # corresponding data structures "correctly". Catch it later in
1384 # output_* subs.
1385 push_parameter($arg, "", $file);
1386 } elsif ($arg =~ m/\(/) {
1387 # pointer-to-function
1388 $arg =~ tr/#/,/;
1389 $arg =~ m/[^\(]+\(\*([^\)]+)\)/;
1390 $param = $1;
1391 $type = $arg;
1392 $type =~ s/([^\(]+\(\*)$param/$1/;
1393 push_parameter($param, $type, $file);
1394 } else {
1395 $arg =~ s/\s*:\s*/:/g;
1396 $arg =~ s/\s*\[/\[/g;
1397
1398 my @args = split('\s*,\s*', $arg);
1399 if ($args[0] =~ m/\*/) {
1400 $args[0] =~ s/(\*+)\s*/ $1/;
1401 }
1402 my @first_arg = split('\s+', shift @args);
1403 unshift(@args, pop @first_arg);
1404 $type = join " ", @first_arg;
1405
1406 foreach $param (@args) {
1407 if ($param =~ m/^(\*+)\s*(.*)/) {
1408 push_parameter($2, "$type $1", $file);
1409 }
1410 elsif ($param =~ m/(.*?):(\d+)/) {
1411 push_parameter($1, "$type:$2", $file)
1412 }
1413 else {
1414 push_parameter($param, $type, $file);
1415 }
1416 }
1417 }
1418 }
1419}
1420
1421sub push_parameter($$$) {
1422 my $param = shift;
1423 my $type = shift;
1424 my $file = shift;
1425
1426 my $param_name = $param;
1427 $param_name =~ s/\[.*//;
1428
1429 if ($type eq "" && $param eq "...")
1430 {
1431 $type="";
1432 $param="...";
1433 $parameterdescs{"..."} = "variable arguments";
1434 }
1435 elsif ($type eq "" && ($param eq "" or $param eq "void"))
1436 {
1437 $type="";
1438 $param="void";
1439 $parameterdescs{void} = "no arguments";
1440 }
1441 if (defined $type && $type && !defined $parameterdescs{$param_name}) {
1442 $parameterdescs{$param_name} = $undescribed;
1443
1444 if (($type eq 'function') || ($type eq 'enum')) {
1445 print STDERR "Warning(${file}:$.): Function parameter ".
1446 "or member '$param' not " .
1447 "described in '$declaration_name'\n";
1448 }
1449 print STDERR "Warning(${file}:$.):".
1450 " No description found for parameter '$param'\n";
1451 ++$warnings;
1452 }
1453
1454 push @parameterlist, $param;
1455 $parametertypes{$param} = $type;
1456}
1457
1458##
1459# takes a function prototype and the name of the current file being
1460# processed and spits out all the details stored in the global
1461# arrays/hashes.
1462sub dump_function($$) {
1463 my $prototype = shift;
1464 my $file = shift;
1465
1466 $prototype =~ s/^static +//;
1467 $prototype =~ s/^extern +//;
1468 $prototype =~ s/^inline +//;
1469 $prototype =~ s/^__inline__ +//;
1470 $prototype =~ s/^#define +//; #ak added
1471 $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//;
1472
1473 # Yes, this truly is vile. We are looking for:
1474 # 1. Return type (may be nothing if we're looking at a macro)
1475 # 2. Function name
1476 # 3. Function parameters.
1477 #
1478 # All the while we have to watch out for function pointer parameters
1479 # (which IIRC is what the two sections are for), C types (these
1480 # regexps don't even start to express all the possibilities), and
1481 # so on.
1482 #
1483 # If you mess with these regexps, it's a good idea to check that
1484 # the following functions' documentation still comes out right:
1485 # - parport_register_device (function pointer parameters)
1486 # - atomic_set (macro)
1487 # - pci_match_device (long return type)
1488
1489 if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1490 $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1491 $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1492 $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1493 $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1494 $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1495 $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
1496 $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1497 $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1498 $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1499 $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1500 $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1501 $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
1502 $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) {
1503 $return_type = $1;
1504 $declaration_name = $2;
1505 my $args = $3;
1506
1507 create_parameterlist($args, ',', $file);
1508 } else {
1509 print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n";
1510 ++$errors;
1511 return;
1512 }
1513
1514 output_declaration($declaration_name,
1515 'function',
1516 {'function' => $declaration_name,
1517 'module' => $modulename,
1518 'functiontype' => $return_type,
1519 'parameterlist' => \@parameterlist,
1520 'parameterdescs' => \%parameterdescs,
1521 'parametertypes' => \%parametertypes,
1522 'sectionlist' => \@sectionlist,
1523 'sections' => \%sections,
1524 'purpose' => $declaration_purpose
1525 });
1526}
1527
1528sub process_file($);
1529
1530# Read the file that maps relative names to absolute names for
1531# separate source and object directories and for shadow trees.
1532if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
1533 my ($relname, $absname);
1534 while(<SOURCE_MAP>) {
1535 chop();
1536 ($relname, $absname) = (split())[0..1];
1537 $relname =~ s:^/+::;
1538 $source_map{$relname} = $absname;
1539 }
1540 close(SOURCE_MAP);
1541}
1542
1543if ($filelist) {
1544 open(FLIST,"<$filelist") or die "Can't open file list $filelist";
1545 while(<FLIST>) {
1546 chop;
1547 process_file($_);
1548 }
1549}
1550
1551foreach (@ARGV) {
1552 chomp;
1553 process_file($_);
1554}
1555if ($verbose && $errors) {
1556 print STDERR "$errors errors\n";
1557}
1558if ($verbose && $warnings) {
1559 print STDERR "$warnings warnings\n";
1560}
1561
1562exit($errors);
1563
1564sub reset_state {
1565 $function = "";
1566 %constants = ();
1567 %parameterdescs = ();
1568 %parametertypes = ();
1569 @parameterlist = ();
1570 %sections = ();
1571 @sectionlist = ();
1572 $prototype = "";
1573
1574 $state = 0;
1575}
1576
1577sub process_state3_function($$) {
1578 my $x = shift;
1579 my $file = shift;
1580
1581 if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#define/)) {
1582 # do nothing
1583 }
1584 elsif ($x =~ /([^\{]*)/) {
1585 $prototype .= $1;
1586 }
1587 if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) {
1588 $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
1589 $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1590 $prototype =~ s@^\s+@@gos; # strip leading spaces
1591 dump_function($prototype,$file);
1592 reset_state();
1593 }
1594}
1595
1596sub process_state3_type($$) {
1597 my $x = shift;
1598 my $file = shift;
1599
1600 $x =~ s@/\*.*?\*/@@gos; # strip comments.
1601 $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1602 $x =~ s@^\s+@@gos; # strip leading spaces
1603 $x =~ s@\s+$@@gos; # strip trailing spaces
1604 if ($x =~ /^#/) {
1605 # To distinguish preprocessor directive from regular declaration later.
1606 $x .= ";";
1607 }
1608
1609 while (1) {
1610 if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
1611 $prototype .= $1 . $2;
1612 ($2 eq '{') && $brcount++;
1613 ($2 eq '}') && $brcount--;
1614 if (($2 eq ';') && ($brcount == 0)) {
1615 dump_declaration($prototype,$file);
1616 reset_state();
1617 last;
1618 }
1619 $x = $3;
1620 } else {
1621 $prototype .= $x;
1622 last;
1623 }
1624 }
1625}
1626
1627# replace <, >, and &
1628sub xml_escape($) {
1629 my $text = shift;
1630 $text =~ s/\&/\\\\\\amp;/g;
1631 $text =~ s/\</\\\\\\lt;/g;
1632 $text =~ s/\>/\\\\\\gt;/g;
1633 return $text;
1634}
1635
1636sub process_file($) {
1637 my ($file) = "$ENV{'SRCTREE'}@_";
1638 my $identifier;
1639 my $func;
1640 my $initial_section_counter = $section_counter;
1641
1642 if (defined($source_map{$file})) {
1643 $file = $source_map{$file};
1644 }
1645
1646 if (!open(IN,"<$file")) {
1647 print STDERR "Error: Cannot open file $file\n";
1648 ++$errors;
1649 return;
1650 }
1651
1652 $section_counter = 0;
1653 while (<IN>) {
1654 if ($state == 0) {
1655 if (/$doc_start/o) {
1656 $state = 1; # next line is always the function name
1657 }
1658 } elsif ($state == 1) { # this line is the function name (always)
1659 if (/$doc_block/o) {
1660 $state = 4;
1661 $contents = "";
1662 if ( $1 eq "" ) {
1663 $section = $section_intro;
1664 } else {
1665 $section = $1;
1666 }
1667 }
1668 elsif (/$doc_decl/o) {
1669 $identifier = $1;
1670 if (/\s*([\w\s]+?)\s*-/) {
1671 $identifier = $1;
1672 }
1673
1674 $state = 2;
1675 if (/-(.*)/) {
1676 $declaration_purpose = xml_escape($1);
1677 } else {
1678 $declaration_purpose = "";
1679 }
1680 if ($identifier =~ m/^struct/) {
1681 $decl_type = 'struct';
1682 } elsif ($identifier =~ m/^union/) {
1683 $decl_type = 'union';
1684 } elsif ($identifier =~ m/^enum/) {
1685 $decl_type = 'enum';
1686 } elsif ($identifier =~ m/^typedef/) {
1687 $decl_type = 'typedef';
1688 } else {
1689 $decl_type = 'function';
1690 }
1691
1692 if ($verbose) {
1693 print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
1694 }
1695 } else {
1696 print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
1697 " - I thought it was a doc line\n";
1698 ++$warnings;
1699 $state = 0;
1700 }
1701 } elsif ($state == 2) { # look for head: lines, and include content
1702 if (/$doc_sect/o) {
1703 $newsection = $1;
1704 $newcontents = $2;
1705
1706 if ($contents ne "") {
1707 dump_section($section, xml_escape($contents));
1708 $section = $section_default;
1709 }
1710
1711 $contents = $newcontents;
1712 if ($contents ne "") {
1713 $contents .= "\n";
1714 }
1715 $section = $newsection;
1716 } elsif (/$doc_end/) {
1717
1718 if ($contents ne "") {
1719 dump_section($section, xml_escape($contents));
1720 $section = $section_default;
1721 $contents = "";
1722 }
1723
1724 $prototype = "";
1725 $state = 3;
1726 $brcount = 0;
1727# print STDERR "end of doc comment, looking for prototype\n";
1728 } elsif (/$doc_content/) {
1729 # miguel-style comment kludge, look for blank lines after
1730 # @parameter line to signify start of description
1731 if ($1 eq "" &&
1732 ($section =~ m/^@/ || $section eq $section_context)) {
1733 dump_section($section, xml_escape($contents));
1734 $section = $section_default;
1735 $contents = "";
1736 } else {
1737 $contents .= $1."\n";
1738 }
1739 } else {
1740 # i dont know - bad line? ignore.
1741 print STDERR "Warning(${file}:$.): bad line: $_";
1742 ++$warnings;
1743 }
1744 } elsif ($state == 3) { # scanning for function { (end of prototype)
1745 if ($decl_type eq 'function') {
1746 process_state3_function($_, $file);
1747 } else {
1748 process_state3_type($_, $file);
1749 }
1750 } elsif ($state == 4) {
1751 # Documentation block
1752 if (/$doc_block/) {
1753 dump_section($section, $contents);
1754 output_intro({'sectionlist' => \@sectionlist,
1755 'sections' => \%sections });
1756 $contents = "";
1757 $function = "";
1758 %constants = ();
1759 %parameterdescs = ();
1760 %parametertypes = ();
1761 @parameterlist = ();
1762 %sections = ();
1763 @sectionlist = ();
1764 $prototype = "";
1765 if ( $1 eq "" ) {
1766 $section = $section_intro;
1767 } else {
1768 $section = $1;
1769 }
1770 }
1771 elsif (/$doc_end/)
1772 {
1773 dump_section($section, $contents);
1774 output_intro({'sectionlist' => \@sectionlist,
1775 'sections' => \%sections });
1776 $contents = "";
1777 $function = "";
1778 %constants = ();
1779 %parameterdescs = ();
1780 %parametertypes = ();
1781 @parameterlist = ();
1782 %sections = ();
1783 @sectionlist = ();
1784 $prototype = "";
1785 $state = 0;
1786 }
1787 elsif (/$doc_content/)
1788 {
1789 if ( $1 eq "" )
1790 {
1791 $contents .= $blankline;
1792 }
1793 else
1794 {
1795 $contents .= $1 . "\n";
1796 }
1797 }
1798 }
1799 }
1800 if ($initial_section_counter == $section_counter) {
1801 print STDERR "Warning(${file}): no structured comments found\n";
1802 if ($output_mode eq "xml") {
1803 # The template wants at least one RefEntry here; make one.
1804 print "<refentry>\n";
1805 print " <refnamediv>\n";
1806 print " <refname>\n";
1807 print " ${file}\n";
1808 print " </refname>\n";
1809 print " <refpurpose>\n";
1810 print " Document generation inconsistency\n";
1811 print " </refpurpose>\n";
1812 print " </refnamediv>\n";
1813 print " <refsect1>\n";
1814 print " <title>\n";
1815 print " Oops\n";
1816 print " </title>\n";
1817 print " <warning>\n";
1818 print " <para>\n";
1819 print " The template for this document tried to insert\n";
1820 print " the structured comment from the file\n";
1821 print " <filename>${file}</filename> at this point,\n";
1822 print " but none was found.\n";
1823 print " This dummy section is inserted to allow\n";
1824 print " generation to continue.\n";
1825 print " </para>\n";
1826 print " </warning>\n";
1827 print " </refsect1>\n";
1828 print "</refentry>\n";
1829 }
1830 }
1831}
diff --git a/scripts/ksymoops/README b/scripts/ksymoops/README
new file mode 100644
index 000000000000..f6cb06e3f30e
--- /dev/null
+++ b/scripts/ksymoops/README
@@ -0,0 +1,8 @@
1ksymoops has been removed from the kernel. It was always meant to be a
2free standing utility, not linked to any particular kernel version.
3The latest version can be found in
4ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops together
5with patches to other utilities in order to give more accurate Oops
6debugging.
7
8Keith Owens <kaos@ocs.com.au> Sat Jun 19 10:30:34 EST 1999
diff --git a/scripts/lxdialog/BIG.FAT.WARNING b/scripts/lxdialog/BIG.FAT.WARNING
new file mode 100644
index 000000000000..a8999d82bdb3
--- /dev/null
+++ b/scripts/lxdialog/BIG.FAT.WARNING
@@ -0,0 +1,4 @@
1This is NOT the official version of dialog. This version has been
2significantly modified from the original. It is for use by the Linux
3kernel configuration script. Please do not bother Savio Lam with
4questions about this program.
diff --git a/scripts/lxdialog/Makefile b/scripts/lxdialog/Makefile
new file mode 100644
index 000000000000..a45a13fb26ed
--- /dev/null
+++ b/scripts/lxdialog/Makefile
@@ -0,0 +1,42 @@
1HOST_EXTRACFLAGS := -DLOCALE
2ifeq ($(shell uname),SunOS)
3HOST_LOADLIBES := -lcurses
4else
5HOST_LOADLIBES := -lncurses
6endif
7
8ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
9 HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
10else
11ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
12 HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
13else
14ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
15 HOST_EXTRACFLAGS += -DCURSES_LOC="<ncurses.h>"
16else
17 HOST_EXTRACFLAGS += -DCURSES_LOC="<curses.h>"
18endif
19endif
20endif
21
22hostprogs-y := lxdialog
23always := ncurses $(hostprogs-y)
24
25lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
26 util.o lxdialog.o msgbox.o
27
28.PHONY: $(obj)/ncurses
29$(obj)/ncurses:
30 @echo "main() {}" > lxtemp.c
31 @if $(HOSTCC) lxtemp.c $(HOST_LOADLIBES); then \
32 rm -f lxtemp.c a.out; \
33 else \
34 rm -f lxtemp.c; \
35 echo -e "\007" ;\
36 echo ">> Unable to find the Ncurses libraries." ;\
37 echo ">>" ;\
38 echo ">> You must install ncurses-devel in order" ;\
39 echo ">> to use 'make menuconfig'" ;\
40 echo ;\
41 exit 1 ;\
42 fi
diff --git a/scripts/lxdialog/checklist.c b/scripts/lxdialog/checklist.c
new file mode 100644
index 000000000000..7aba17c72e64
--- /dev/null
+++ b/scripts/lxdialog/checklist.c
@@ -0,0 +1,373 @@
1/*
2 * checklist.c -- implements the checklist box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
6 * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
7 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "dialog.h"
25
26static int list_width, check_x, item_x, checkflag;
27
28/*
29 * Print list item
30 */
31static void
32print_item (WINDOW * win, const char *item, int status,
33 int choice, int selected)
34{
35 int i;
36
37 /* Clear 'residue' of last item */
38 wattrset (win, menubox_attr);
39 wmove (win, choice, 0);
40 for (i = 0; i < list_width; i++)
41 waddch (win, ' ');
42
43 wmove (win, choice, check_x);
44 wattrset (win, selected ? check_selected_attr : check_attr);
45 if (checkflag == FLAG_CHECK)
46 wprintw (win, "[%c]", status ? 'X' : ' ');
47 else
48 wprintw (win, "(%c)", status ? 'X' : ' ');
49
50 wattrset (win, selected ? tag_selected_attr : tag_attr);
51 mvwaddch(win, choice, item_x, item[0]);
52 wattrset (win, selected ? item_selected_attr : item_attr);
53 waddstr (win, (char *)item+1);
54 if (selected) {
55 wmove (win, choice, check_x+1);
56 wrefresh (win);
57 }
58}
59
60/*
61 * Print the scroll indicators.
62 */
63static void
64print_arrows (WINDOW * win, int choice, int item_no, int scroll,
65 int y, int x, int height)
66{
67 wmove(win, y, x);
68
69 if (scroll > 0) {
70 wattrset (win, uarrow_attr);
71 waddch (win, ACS_UARROW);
72 waddstr (win, "(-)");
73 }
74 else {
75 wattrset (win, menubox_attr);
76 waddch (win, ACS_HLINE);
77 waddch (win, ACS_HLINE);
78 waddch (win, ACS_HLINE);
79 waddch (win, ACS_HLINE);
80 }
81
82 y = y + height + 1;
83 wmove(win, y, x);
84
85 if ((height < item_no) && (scroll + choice < item_no - 1)) {
86 wattrset (win, darrow_attr);
87 waddch (win, ACS_DARROW);
88 waddstr (win, "(+)");
89 }
90 else {
91 wattrset (win, menubox_border_attr);
92 waddch (win, ACS_HLINE);
93 waddch (win, ACS_HLINE);
94 waddch (win, ACS_HLINE);
95 waddch (win, ACS_HLINE);
96 }
97}
98
99/*
100 * Display the termination buttons
101 */
102static void
103print_buttons( WINDOW *dialog, int height, int width, int selected)
104{
105 int x = width / 2 - 11;
106 int y = height - 2;
107
108 print_button (dialog, "Select", y, x, selected == 0);
109 print_button (dialog, " Help ", y, x + 14, selected == 1);
110
111 wmove(dialog, y, x+1 + 14*selected);
112 wrefresh (dialog);
113}
114
115/*
116 * Display a dialog box with a list of options that can be turned on or off
117 * The `flag' parameter is used to select between radiolist and checklist.
118 */
119int
120dialog_checklist (const char *title, const char *prompt, int height, int width,
121 int list_height, int item_no, const char * const * items, int flag)
122
123{
124 int i, x, y, box_x, box_y;
125 int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
126 WINDOW *dialog, *list;
127
128 checkflag = flag;
129
130 /* Allocate space for storing item on/off status */
131 if ((status = malloc (sizeof (int) * item_no)) == NULL) {
132 endwin ();
133 fprintf (stderr,
134 "\nCan't allocate memory in dialog_checklist().\n");
135 exit (-1);
136 }
137
138 /* Initializes status */
139 for (i = 0; i < item_no; i++) {
140 status[i] = !strcasecmp (items[i * 3 + 2], "on");
141 if ((!choice && status[i]) || !strcasecmp (items[i * 3 + 2], "selected"))
142 choice = i + 1;
143 }
144 if (choice)
145 choice--;
146
147 max_choice = MIN (list_height, item_no);
148
149 /* center dialog box on screen */
150 x = (COLS - width) / 2;
151 y = (LINES - height) / 2;
152
153 draw_shadow (stdscr, y, x, height, width);
154
155 dialog = newwin (height, width, y, x);
156 keypad (dialog, TRUE);
157
158 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
159 wattrset (dialog, border_attr);
160 mvwaddch (dialog, height-3, 0, ACS_LTEE);
161 for (i = 0; i < width - 2; i++)
162 waddch (dialog, ACS_HLINE);
163 wattrset (dialog, dialog_attr);
164 waddch (dialog, ACS_RTEE);
165
166 if (title != NULL && strlen(title) >= width-2 ) {
167 /* truncate long title -- mec */
168 char * title2 = malloc(width-2+1);
169 memcpy( title2, title, width-2 );
170 title2[width-2] = '\0';
171 title = title2;
172 }
173
174 if (title != NULL) {
175 wattrset (dialog, title_attr);
176 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
177 waddstr (dialog, (char *)title);
178 waddch (dialog, ' ');
179 }
180
181 wattrset (dialog, dialog_attr);
182 print_autowrap (dialog, prompt, width - 2, 1, 3);
183
184 list_width = width - 6;
185 box_y = height - list_height - 5;
186 box_x = (width - list_width) / 2 - 1;
187
188 /* create new window for the list */
189 list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
190
191 keypad (list, TRUE);
192
193 /* draw a box around the list items */
194 draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
195 menubox_border_attr, menubox_attr);
196
197 /* Find length of longest item in order to center checklist */
198 check_x = 0;
199 for (i = 0; i < item_no; i++)
200 check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4);
201
202 check_x = (list_width - check_x) / 2;
203 item_x = check_x + 4;
204
205 if (choice >= list_height) {
206 scroll = choice - list_height + 1;
207 choice -= scroll;
208 }
209
210 /* Print the list */
211 for (i = 0; i < max_choice; i++) {
212 print_item (list, items[(scroll+i) * 3 + 1],
213 status[i+scroll], i, i == choice);
214 }
215
216 print_arrows(dialog, choice, item_no, scroll,
217 box_y, box_x + check_x + 5, list_height);
218
219 print_buttons(dialog, height, width, 0);
220
221 wnoutrefresh (list);
222 wnoutrefresh (dialog);
223 doupdate ();
224
225 while (key != ESC) {
226 key = wgetch (dialog);
227
228 for (i = 0; i < max_choice; i++)
229 if (toupper(key) == toupper(items[(scroll+i)*3+1][0]))
230 break;
231
232
233 if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
234 key == '+' || key == '-' ) {
235 if (key == KEY_UP || key == '-') {
236 if (!choice) {
237 if (!scroll)
238 continue;
239 /* Scroll list down */
240 if (list_height > 1) {
241 /* De-highlight current first item */
242 print_item (list, items[scroll * 3 + 1],
243 status[scroll], 0, FALSE);
244 scrollok (list, TRUE);
245 wscrl (list, -1);
246 scrollok (list, FALSE);
247 }
248 scroll--;
249 print_item (list, items[scroll * 3 + 1],
250 status[scroll], 0, TRUE);
251 wnoutrefresh (list);
252
253 print_arrows(dialog, choice, item_no, scroll,
254 box_y, box_x + check_x + 5, list_height);
255
256 wrefresh (dialog);
257
258 continue; /* wait for another key press */
259 } else
260 i = choice - 1;
261 } else if (key == KEY_DOWN || key == '+') {
262 if (choice == max_choice - 1) {
263 if (scroll + choice >= item_no - 1)
264 continue;
265 /* Scroll list up */
266 if (list_height > 1) {
267 /* De-highlight current last item before scrolling up */
268 print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
269 status[scroll + max_choice - 1],
270 max_choice - 1, FALSE);
271 scrollok (list, TRUE);
272 wscrl (list, 1);
273 scrollok (list, FALSE);
274 }
275 scroll++;
276 print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
277 status[scroll + max_choice - 1],
278 max_choice - 1, TRUE);
279 wnoutrefresh (list);
280
281 print_arrows(dialog, choice, item_no, scroll,
282 box_y, box_x + check_x + 5, list_height);
283
284 wrefresh (dialog);
285
286 continue; /* wait for another key press */
287 } else
288 i = choice + 1;
289 }
290 if (i != choice) {
291 /* De-highlight current item */
292 print_item (list, items[(scroll + choice) * 3 + 1],
293 status[scroll + choice], choice, FALSE);
294 /* Highlight new item */
295 choice = i;
296 print_item (list, items[(scroll + choice) * 3 + 1],
297 status[scroll + choice], choice, TRUE);
298 wnoutrefresh (list);
299 wrefresh (dialog);
300 }
301 continue; /* wait for another key press */
302 }
303 switch (key) {
304 case 'H':
305 case 'h':
306 case '?':
307 fprintf (stderr, "%s", items[(scroll + choice) * 3]);
308 delwin (dialog);
309 free (status);
310 return 1;
311 case TAB:
312 case KEY_LEFT:
313 case KEY_RIGHT:
314 button = ((key == KEY_LEFT ? --button : ++button) < 0)
315 ? 1 : (button > 1 ? 0 : button);
316
317 print_buttons(dialog, height, width, button);
318 wrefresh (dialog);
319 break;
320 case 'S':
321 case 's':
322 case ' ':
323 case '\n':
324 if (!button) {
325 if (flag == FLAG_CHECK) {
326 status[scroll + choice] = !status[scroll + choice];
327 wmove (list, choice, check_x);
328 wattrset (list, check_selected_attr);
329 wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
330 } else {
331 if (!status[scroll + choice]) {
332 for (i = 0; i < item_no; i++)
333 status[i] = 0;
334 status[scroll + choice] = 1;
335 for (i = 0; i < max_choice; i++)
336 print_item (list, items[(scroll + i) * 3 + 1],
337 status[scroll + i], i, i == choice);
338 }
339 }
340 wnoutrefresh (list);
341 wrefresh (dialog);
342
343 for (i = 0; i < item_no; i++) {
344 if (status[i]) {
345 if (flag == FLAG_CHECK) {
346 fprintf (stderr, "\"%s\" ", items[i * 3]);
347 } else {
348 fprintf (stderr, "%s", items[i * 3]);
349 }
350
351 }
352 }
353 } else
354 fprintf (stderr, "%s", items[(scroll + choice) * 3]);
355 delwin (dialog);
356 free (status);
357 return button;
358 case 'X':
359 case 'x':
360 key = ESC;
361 case ESC:
362 break;
363 }
364
365 /* Now, update everything... */
366 doupdate ();
367 }
368
369
370 delwin (dialog);
371 free (status);
372 return -1; /* ESC pressed */
373}
diff --git a/scripts/lxdialog/colors.h b/scripts/lxdialog/colors.h
new file mode 100644
index 000000000000..25c59528a251
--- /dev/null
+++ b/scripts/lxdialog/colors.h
@@ -0,0 +1,155 @@
1/*
2 * colors.h -- color attribute definitions
3 *
4 * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21
22/*
23 * Default color definitions
24 *
25 * *_FG = foreground
26 * *_BG = background
27 * *_HL = highlight?
28 */
29#define SCREEN_FG COLOR_CYAN
30#define SCREEN_BG COLOR_BLUE
31#define SCREEN_HL TRUE
32
33#define SHADOW_FG COLOR_BLACK
34#define SHADOW_BG COLOR_BLACK
35#define SHADOW_HL TRUE
36
37#define DIALOG_FG COLOR_BLACK
38#define DIALOG_BG COLOR_WHITE
39#define DIALOG_HL FALSE
40
41#define TITLE_FG COLOR_YELLOW
42#define TITLE_BG COLOR_WHITE
43#define TITLE_HL TRUE
44
45#define BORDER_FG COLOR_WHITE
46#define BORDER_BG COLOR_WHITE
47#define BORDER_HL TRUE
48
49#define BUTTON_ACTIVE_FG COLOR_WHITE
50#define BUTTON_ACTIVE_BG COLOR_BLUE
51#define BUTTON_ACTIVE_HL TRUE
52
53#define BUTTON_INACTIVE_FG COLOR_BLACK
54#define BUTTON_INACTIVE_BG COLOR_WHITE
55#define BUTTON_INACTIVE_HL FALSE
56
57#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
58#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
59#define BUTTON_KEY_ACTIVE_HL TRUE
60
61#define BUTTON_KEY_INACTIVE_FG COLOR_RED
62#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
63#define BUTTON_KEY_INACTIVE_HL FALSE
64
65#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
66#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
67#define BUTTON_LABEL_ACTIVE_HL TRUE
68
69#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
70#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
71#define BUTTON_LABEL_INACTIVE_HL TRUE
72
73#define INPUTBOX_FG COLOR_BLACK
74#define INPUTBOX_BG COLOR_WHITE
75#define INPUTBOX_HL FALSE
76
77#define INPUTBOX_BORDER_FG COLOR_BLACK
78#define INPUTBOX_BORDER_BG COLOR_WHITE
79#define INPUTBOX_BORDER_HL FALSE
80
81#define SEARCHBOX_FG COLOR_BLACK
82#define SEARCHBOX_BG COLOR_WHITE
83#define SEARCHBOX_HL FALSE
84
85#define SEARCHBOX_TITLE_FG COLOR_YELLOW
86#define SEARCHBOX_TITLE_BG COLOR_WHITE
87#define SEARCHBOX_TITLE_HL TRUE
88
89#define SEARCHBOX_BORDER_FG COLOR_WHITE
90#define SEARCHBOX_BORDER_BG COLOR_WHITE
91#define SEARCHBOX_BORDER_HL TRUE
92
93#define POSITION_INDICATOR_FG COLOR_YELLOW
94#define POSITION_INDICATOR_BG COLOR_WHITE
95#define POSITION_INDICATOR_HL TRUE
96
97#define MENUBOX_FG COLOR_BLACK
98#define MENUBOX_BG COLOR_WHITE
99#define MENUBOX_HL FALSE
100
101#define MENUBOX_BORDER_FG COLOR_WHITE
102#define MENUBOX_BORDER_BG COLOR_WHITE
103#define MENUBOX_BORDER_HL TRUE
104
105#define ITEM_FG COLOR_BLACK
106#define ITEM_BG COLOR_WHITE
107#define ITEM_HL FALSE
108
109#define ITEM_SELECTED_FG COLOR_WHITE
110#define ITEM_SELECTED_BG COLOR_BLUE
111#define ITEM_SELECTED_HL TRUE
112
113#define TAG_FG COLOR_YELLOW
114#define TAG_BG COLOR_WHITE
115#define TAG_HL TRUE
116
117#define TAG_SELECTED_FG COLOR_YELLOW
118#define TAG_SELECTED_BG COLOR_BLUE
119#define TAG_SELECTED_HL TRUE
120
121#define TAG_KEY_FG COLOR_YELLOW
122#define TAG_KEY_BG COLOR_WHITE
123#define TAG_KEY_HL TRUE
124
125#define TAG_KEY_SELECTED_FG COLOR_YELLOW
126#define TAG_KEY_SELECTED_BG COLOR_BLUE
127#define TAG_KEY_SELECTED_HL TRUE
128
129#define CHECK_FG COLOR_BLACK
130#define CHECK_BG COLOR_WHITE
131#define CHECK_HL FALSE
132
133#define CHECK_SELECTED_FG COLOR_WHITE
134#define CHECK_SELECTED_BG COLOR_BLUE
135#define CHECK_SELECTED_HL TRUE
136
137#define UARROW_FG COLOR_GREEN
138#define UARROW_BG COLOR_WHITE
139#define UARROW_HL TRUE
140
141#define DARROW_FG COLOR_GREEN
142#define DARROW_BG COLOR_WHITE
143#define DARROW_HL TRUE
144
145/* End of default color definitions */
146
147#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
148#define COLOR_NAME_LEN 10
149#define COLOR_COUNT 8
150
151/*
152 * Global variables
153 */
154
155extern int color_table[][3];
diff --git a/scripts/lxdialog/dialog.h b/scripts/lxdialog/dialog.h
new file mode 100644
index 000000000000..c571548daa82
--- /dev/null
+++ b/scripts/lxdialog/dialog.h
@@ -0,0 +1,187 @@
1
2/*
3 * dialog.h -- common declarations for all dialog modules
4 *
5 * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <sys/types.h>
23#include <fcntl.h>
24#include <unistd.h>
25#include <ctype.h>
26#include <stdlib.h>
27#include <string.h>
28
29#ifdef __sun__
30#define CURS_MACROS
31#endif
32#include CURSES_LOC
33
34/*
35 * Colors in ncurses 1.9.9e do not work properly since foreground and
36 * background colors are OR'd rather than separately masked. This version
37 * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
38 * with standard curses. The simplest fix (to make this work with standard
39 * curses) uses the wbkgdset() function, not used in the original hack.
40 * Turn it off if we're building with 1.9.9e, since it just confuses things.
41 */
42#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
43#define OLD_NCURSES 1
44#undef wbkgdset
45#define wbkgdset(w,p) /*nothing*/
46#else
47#define OLD_NCURSES 0
48#endif
49
50#define TR(params) _tracef params
51
52#define ESC 27
53#define TAB 9
54#define MAX_LEN 2048
55#define BUF_SIZE (10*1024)
56#define MIN(x,y) (x < y ? x : y)
57#define MAX(x,y) (x > y ? x : y)
58
59
60#ifndef ACS_ULCORNER
61#define ACS_ULCORNER '+'
62#endif
63#ifndef ACS_LLCORNER
64#define ACS_LLCORNER '+'
65#endif
66#ifndef ACS_URCORNER
67#define ACS_URCORNER '+'
68#endif
69#ifndef ACS_LRCORNER
70#define ACS_LRCORNER '+'
71#endif
72#ifndef ACS_HLINE
73#define ACS_HLINE '-'
74#endif
75#ifndef ACS_VLINE
76#define ACS_VLINE '|'
77#endif
78#ifndef ACS_LTEE
79#define ACS_LTEE '+'
80#endif
81#ifndef ACS_RTEE
82#define ACS_RTEE '+'
83#endif
84#ifndef ACS_UARROW
85#define ACS_UARROW '^'
86#endif
87#ifndef ACS_DARROW
88#define ACS_DARROW 'v'
89#endif
90
91/*
92 * Attribute names
93 */
94#define screen_attr attributes[0]
95#define shadow_attr attributes[1]
96#define dialog_attr attributes[2]
97#define title_attr attributes[3]
98#define border_attr attributes[4]
99#define button_active_attr attributes[5]
100#define button_inactive_attr attributes[6]
101#define button_key_active_attr attributes[7]
102#define button_key_inactive_attr attributes[8]
103#define button_label_active_attr attributes[9]
104#define button_label_inactive_attr attributes[10]
105#define inputbox_attr attributes[11]
106#define inputbox_border_attr attributes[12]
107#define searchbox_attr attributes[13]
108#define searchbox_title_attr attributes[14]
109#define searchbox_border_attr attributes[15]
110#define position_indicator_attr attributes[16]
111#define menubox_attr attributes[17]
112#define menubox_border_attr attributes[18]
113#define item_attr attributes[19]
114#define item_selected_attr attributes[20]
115#define tag_attr attributes[21]
116#define tag_selected_attr attributes[22]
117#define tag_key_attr attributes[23]
118#define tag_key_selected_attr attributes[24]
119#define check_attr attributes[25]
120#define check_selected_attr attributes[26]
121#define uarrow_attr attributes[27]
122#define darrow_attr attributes[28]
123
124/* number of attributes */
125#define ATTRIBUTE_COUNT 29
126
127/*
128 * Global variables
129 */
130extern bool use_colors;
131extern bool use_shadow;
132
133extern chtype attributes[];
134
135extern const char *backtitle;
136
137/*
138 * Function prototypes
139 */
140extern void create_rc (const char *filename);
141extern int parse_rc (void);
142
143
144void init_dialog (void);
145void end_dialog (void);
146void attr_clear (WINDOW * win, int height, int width, chtype attr);
147void dialog_clear (void);
148void color_setup (void);
149void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
150void print_button (WINDOW * win, const char *label, int y, int x, int selected);
151void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
152 chtype border);
153void draw_shadow (WINDOW * win, int y, int x, int height, int width);
154
155int first_alpha (const char *string, const char *exempt);
156int dialog_yesno (const char *title, const char *prompt, int height, int width);
157int dialog_msgbox (const char *title, const char *prompt, int height,
158 int width, int pause);
159int dialog_textbox (const char *title, const char *file, int height, int width);
160int dialog_menu (const char *title, const char *prompt, int height, int width,
161 int menu_height, const char *choice, int item_no,
162 const char * const * items);
163int dialog_checklist (const char *title, const char *prompt, int height,
164 int width, int list_height, int item_no,
165 const char * const * items, int flag);
166extern unsigned char dialog_input_result[];
167int dialog_inputbox (const char *title, const char *prompt, int height,
168 int width, const char *init);
169
170/*
171 * This is the base for fictitious keys, which activate
172 * the buttons.
173 *
174 * Mouse-generated keys are the following:
175 * -- the first 32 are used as numbers, in addition to '0'-'9'
176 * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
177 * -- uppercase chars are used to invoke the button (M_EVENT + 'O')
178 */
179#define M_EVENT (KEY_MAX+1)
180
181
182/*
183 * The `flag' parameter in checklist is used to select between
184 * radiolist and checklist
185 */
186#define FLAG_CHECK 1
187#define FLAG_RADIO 0
diff --git a/scripts/lxdialog/inputbox.c b/scripts/lxdialog/inputbox.c
new file mode 100644
index 000000000000..fa7bebc693b9
--- /dev/null
+++ b/scripts/lxdialog/inputbox.c
@@ -0,0 +1,240 @@
1/*
2 * inputbox.c -- implements the input box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24unsigned char dialog_input_result[MAX_LEN + 1];
25
26/*
27 * Print the termination buttons
28 */
29static void
30print_buttons(WINDOW *dialog, int height, int width, int selected)
31{
32 int x = width / 2 - 11;
33 int y = height - 2;
34
35 print_button (dialog, " Ok ", y, x, selected==0);
36 print_button (dialog, " Help ", y, x + 14, selected==1);
37
38 wmove(dialog, y, x+1+14*selected);
39 wrefresh(dialog);
40}
41
42/*
43 * Display a dialog box for inputing a string
44 */
45int
46dialog_inputbox (const char *title, const char *prompt, int height, int width,
47 const char *init)
48{
49 int i, x, y, box_y, box_x, box_width;
50 int input_x = 0, scroll = 0, key = 0, button = -1;
51 unsigned char *instr = dialog_input_result;
52 WINDOW *dialog;
53
54 /* center dialog box on screen */
55 x = (COLS - width) / 2;
56 y = (LINES - height) / 2;
57
58
59 draw_shadow (stdscr, y, x, height, width);
60
61 dialog = newwin (height, width, y, x);
62 keypad (dialog, TRUE);
63
64 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
65 wattrset (dialog, border_attr);
66 mvwaddch (dialog, height-3, 0, ACS_LTEE);
67 for (i = 0; i < width - 2; i++)
68 waddch (dialog, ACS_HLINE);
69 wattrset (dialog, dialog_attr);
70 waddch (dialog, ACS_RTEE);
71
72 if (title != NULL && strlen(title) >= width-2 ) {
73 /* truncate long title -- mec */
74 char * title2 = malloc(width-2+1);
75 memcpy( title2, title, width-2 );
76 title2[width-2] = '\0';
77 title = title2;
78 }
79
80 if (title != NULL) {
81 wattrset (dialog, title_attr);
82 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
83 waddstr (dialog, (char *)title);
84 waddch (dialog, ' ');
85 }
86
87 wattrset (dialog, dialog_attr);
88 print_autowrap (dialog, prompt, width - 2, 1, 3);
89
90 /* Draw the input field box */
91 box_width = width - 6;
92 getyx (dialog, y, x);
93 box_y = y + 2;
94 box_x = (width - box_width) / 2;
95 draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
96 border_attr, dialog_attr);
97
98 print_buttons(dialog, height, width, 0);
99
100 /* Set up the initial value */
101 wmove (dialog, box_y, box_x);
102 wattrset (dialog, inputbox_attr);
103
104 if (!init)
105 instr[0] = '\0';
106 else
107 strcpy (instr, init);
108
109 input_x = strlen (instr);
110
111 if (input_x >= box_width) {
112 scroll = input_x - box_width + 1;
113 input_x = box_width - 1;
114 for (i = 0; i < box_width - 1; i++)
115 waddch (dialog, instr[scroll + i]);
116 } else
117 waddstr (dialog, instr);
118
119 wmove (dialog, box_y, box_x + input_x);
120
121 wrefresh (dialog);
122
123 while (key != ESC) {
124 key = wgetch (dialog);
125
126 if (button == -1) { /* Input box selected */
127 switch (key) {
128 case TAB:
129 case KEY_UP:
130 case KEY_DOWN:
131 break;
132 case KEY_LEFT:
133 continue;
134 case KEY_RIGHT:
135 continue;
136 case KEY_BACKSPACE:
137 case 127:
138 if (input_x || scroll) {
139 wattrset (dialog, inputbox_attr);
140 if (!input_x) {
141 scroll = scroll < box_width - 1 ?
142 0 : scroll - (box_width - 1);
143 wmove (dialog, box_y, box_x);
144 for (i = 0; i < box_width; i++)
145 waddch (dialog, instr[scroll + input_x + i] ?
146 instr[scroll + input_x + i] : ' ');
147 input_x = strlen (instr) - scroll;
148 } else
149 input_x--;
150 instr[scroll + input_x] = '\0';
151 mvwaddch (dialog, box_y, input_x + box_x, ' ');
152 wmove (dialog, box_y, input_x + box_x);
153 wrefresh (dialog);
154 }
155 continue;
156 default:
157 if (key < 0x100 && isprint (key)) {
158 if (scroll + input_x < MAX_LEN) {
159 wattrset (dialog, inputbox_attr);
160 instr[scroll + input_x] = key;
161 instr[scroll + input_x + 1] = '\0';
162 if (input_x == box_width - 1) {
163 scroll++;
164 wmove (dialog, box_y, box_x);
165 for (i = 0; i < box_width - 1; i++)
166 waddch (dialog, instr[scroll + i]);
167 } else {
168 wmove (dialog, box_y, input_x++ + box_x);
169 waddch (dialog, key);
170 }
171 wrefresh (dialog);
172 } else
173 flash (); /* Alarm user about overflow */
174 continue;
175 }
176 }
177 }
178 switch (key) {
179 case 'O':
180 case 'o':
181 delwin (dialog);
182 return 0;
183 case 'H':
184 case 'h':
185 delwin (dialog);
186 return 1;
187 case KEY_UP:
188 case KEY_LEFT:
189 switch (button) {
190 case -1:
191 button = 1; /* Indicates "Cancel" button is selected */
192 print_buttons(dialog, height, width, 1);
193 break;
194 case 0:
195 button = -1; /* Indicates input box is selected */
196 print_buttons(dialog, height, width, 0);
197 wmove (dialog, box_y, box_x + input_x);
198 wrefresh (dialog);
199 break;
200 case 1:
201 button = 0; /* Indicates "OK" button is selected */
202 print_buttons(dialog, height, width, 0);
203 break;
204 }
205 break;
206 case TAB:
207 case KEY_DOWN:
208 case KEY_RIGHT:
209 switch (button) {
210 case -1:
211 button = 0; /* Indicates "OK" button is selected */
212 print_buttons(dialog, height, width, 0);
213 break;
214 case 0:
215 button = 1; /* Indicates "Cancel" button is selected */
216 print_buttons(dialog, height, width, 1);
217 break;
218 case 1:
219 button = -1; /* Indicates input box is selected */
220 print_buttons(dialog, height, width, 0);
221 wmove (dialog, box_y, box_x + input_x);
222 wrefresh (dialog);
223 break;
224 }
225 break;
226 case ' ':
227 case '\n':
228 delwin (dialog);
229 return (button == -1 ? 0 : button);
230 case 'X':
231 case 'x':
232 key = ESC;
233 case ESC:
234 break;
235 }
236 }
237
238 delwin (dialog);
239 return -1; /* ESC pressed */
240}
diff --git a/scripts/lxdialog/lxdialog.c b/scripts/lxdialog/lxdialog.c
new file mode 100644
index 000000000000..f283a8545426
--- /dev/null
+++ b/scripts/lxdialog/lxdialog.c
@@ -0,0 +1,226 @@
1/*
2 * dialog - Display simple dialog boxes from shell scripts
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24static void Usage (const char *name);
25
26typedef int (jumperFn) (const char *title, int argc, const char * const * argv);
27
28struct Mode {
29 char *name;
30 int argmin, argmax, argmod;
31 jumperFn *jumper;
32};
33
34jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox;
35jumperFn j_msgbox, j_infobox;
36
37static struct Mode modes[] =
38{
39 {"--menu", 9, 0, 3, j_menu},
40 {"--checklist", 9, 0, 3, j_checklist},
41 {"--radiolist", 9, 0, 3, j_radiolist},
42 {"--yesno", 5,5,1, j_yesno},
43 {"--textbox", 5,5,1, j_textbox},
44 {"--inputbox", 5, 6, 1, j_inputbox},
45 {"--msgbox", 5, 5, 1, j_msgbox},
46 {"--infobox", 5, 5, 1, j_infobox},
47 {NULL, 0, 0, 0, NULL}
48};
49
50static struct Mode *modePtr;
51
52#ifdef LOCALE
53#include <locale.h>
54#endif
55
56int
57main (int argc, const char * const * argv)
58{
59 int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
60 const char *title = NULL;
61
62#ifdef LOCALE
63 (void) setlocale (LC_ALL, "");
64#endif
65
66#ifdef TRACE
67 trace(TRACE_CALLS|TRACE_UPDATE);
68#endif
69 if (argc < 2) {
70 Usage (argv[0]);
71 exit (-1);
72 }
73
74 while (offset < argc - 1 && !end_common_opts) { /* Common options */
75 if (!strcmp (argv[offset + 1], "--title")) {
76 if (argc - offset < 3 || title != NULL) {
77 Usage (argv[0]);
78 exit (-1);
79 } else {
80 title = argv[offset + 2];
81 offset += 2;
82 }
83 } else if (!strcmp (argv[offset + 1], "--backtitle")) {
84 if (backtitle != NULL) {
85 Usage (argv[0]);
86 exit (-1);
87 } else {
88 backtitle = argv[offset + 2];
89 offset += 2;
90 }
91 } else if (!strcmp (argv[offset + 1], "--clear")) {
92 if (opt_clear) { /* Hey, "--clear" can't appear twice! */
93 Usage (argv[0]);
94 exit (-1);
95 } else if (argc == 2) { /* we only want to clear the screen */
96 init_dialog ();
97 refresh (); /* init_dialog() will clear the screen for us */
98 end_dialog ();
99 return 0;
100 } else {
101 opt_clear = 1;
102 offset++;
103 }
104 } else /* no more common options */
105 end_common_opts = 1;
106 }
107
108 if (argc - 1 == offset) { /* no more options */
109 Usage (argv[0]);
110 exit (-1);
111 }
112 /* use a table to look for the requested mode, to avoid code duplication */
113
114 for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */
115 if (!strcmp (argv[offset + 1], modePtr->name))
116 break;
117
118 if (!modePtr->name)
119 Usage (argv[0]);
120 if (argc - offset < modePtr->argmin)
121 Usage (argv[0]);
122 if (modePtr->argmax && argc - offset > modePtr->argmax)
123 Usage (argv[0]);
124
125
126
127 init_dialog ();
128 retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
129
130 if (opt_clear) { /* clear screen before exit */
131 attr_clear (stdscr, LINES, COLS, screen_attr);
132 refresh ();
133 }
134 end_dialog();
135
136 exit (retval);
137}
138
139/*
140 * Print program usage
141 */
142static void
143Usage (const char *name)
144{
145 fprintf (stderr, "\
146\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
147\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
148\n modified/gutted for use as a Linux kernel config tool by \
149\n William Roadcap (roadcapw@cfw.com)\
150\n\
151\n* Display dialog boxes from shell scripts *\
152\n\
153\nUsage: %s --clear\
154\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
155\n\
156\nBox options:\
157\n\
158\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\
159\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
160\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
161\n --textbox <file> <height> <width>\
162\n --inputbox <text> <height> <width> [<init>]\
163\n --yesno <text> <height> <width>\
164\n", name, name);
165 exit (-1);
166}
167
168/*
169 * These are the program jumpers
170 */
171
172int
173j_menu (const char *t, int ac, const char * const * av)
174{
175 return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]),
176 atoi (av[5]), av[6], (ac - 6) / 2, av + 7);
177}
178
179int
180j_checklist (const char *t, int ac, const char * const * av)
181{
182 return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
183 atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK);
184}
185
186int
187j_radiolist (const char *t, int ac, const char * const * av)
188{
189 return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
190 atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO);
191}
192
193int
194j_textbox (const char *t, int ac, const char * const * av)
195{
196 return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4]));
197}
198
199int
200j_yesno (const char *t, int ac, const char * const * av)
201{
202 return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4]));
203}
204
205int
206j_inputbox (const char *t, int ac, const char * const * av)
207{
208 int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]),
209 ac == 6 ? av[5] : (char *) NULL);
210 if (ret == 0)
211 fprintf(stderr, dialog_input_result);
212 return ret;
213}
214
215int
216j_msgbox (const char *t, int ac, const char * const * av)
217{
218 return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1);
219}
220
221int
222j_infobox (const char *t, int ac, const char * const * av)
223{
224 return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0);
225}
226
diff --git a/scripts/lxdialog/menubox.c b/scripts/lxdialog/menubox.c
new file mode 100644
index 000000000000..91d82ba17f8d
--- /dev/null
+++ b/scripts/lxdialog/menubox.c
@@ -0,0 +1,445 @@
1/*
2 * menubox.c -- implements the menu box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/*
23 * Changes by Clifford Wolf (god@clifford.at)
24 *
25 * [ 1998-06-13 ]
26 *
27 * *) A bugfix for the Page-Down problem
28 *
29 * *) Formerly when I used Page Down and Page Up, the cursor would be set
30 * to the first position in the menu box. Now lxdialog is a bit
31 * smarter and works more like other menu systems (just have a look at
32 * it).
33 *
34 * *) Formerly if I selected something my scrolling would be broken because
35 * lxdialog is re-invoked by the Menuconfig shell script, can't
36 * remember the last scrolling position, and just sets it so that the
37 * cursor is at the bottom of the box. Now it writes the temporary file
38 * lxdialog.scrltmp which contains this information. The file is
39 * deleted by lxdialog if the user leaves a submenu or enters a new
40 * one, but it would be nice if Menuconfig could make another "rm -f"
41 * just to be sure. Just try it out - you will recognise a difference!
42 *
43 * [ 1998-06-14 ]
44 *
45 * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
46 * and menus change their size on the fly.
47 *
48 * *) If for some reason the last scrolling position is not saved by
49 * lxdialog, it sets the scrolling so that the selected item is in the
50 * middle of the menu box, not at the bottom.
51 *
52 * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
53 * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
54 * This fixes a bug in Menuconfig where using ' ' to descend into menus
55 * would leave mis-synchronized lxdialog.scrltmp files lying around,
56 * fscanf would read in 'scroll', and eventually that value would get used.
57 */
58
59#include "dialog.h"
60
61static int menu_width, item_x;
62
63/*
64 * Print menu item
65 */
66static void
67print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
68{
69 int j;
70 char menu_item[menu_width+1];
71
72 strncpy(menu_item, item, menu_width);
73 menu_item[menu_width] = 0;
74 j = first_alpha(menu_item, "YyNnMmHh");
75
76 /* Clear 'residue' of last item */
77 wattrset (win, menubox_attr);
78 wmove (win, choice, 0);
79#if OLD_NCURSES
80 {
81 int i;
82 for (i = 0; i < menu_width; i++)
83 waddch (win, ' ');
84 }
85#else
86 wclrtoeol(win);
87#endif
88 wattrset (win, selected ? item_selected_attr : item_attr);
89 mvwaddstr (win, choice, item_x, menu_item);
90 if (hotkey) {
91 wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
92 mvwaddch(win, choice, item_x+j, menu_item[j]);
93 }
94 if (selected) {
95 wmove (win, choice, item_x+1);
96 wrefresh (win);
97 }
98}
99
100/*
101 * Print the scroll indicators.
102 */
103static void
104print_arrows (WINDOW * win, int item_no, int scroll,
105 int y, int x, int height)
106{
107 int cur_y, cur_x;
108
109 getyx(win, cur_y, cur_x);
110
111 wmove(win, y, x);
112
113 if (scroll > 0) {
114 wattrset (win, uarrow_attr);
115 waddch (win, ACS_UARROW);
116 waddstr (win, "(-)");
117 }
118 else {
119 wattrset (win, menubox_attr);
120 waddch (win, ACS_HLINE);
121 waddch (win, ACS_HLINE);
122 waddch (win, ACS_HLINE);
123 waddch (win, ACS_HLINE);
124 }
125
126 y = y + height + 1;
127 wmove(win, y, x);
128
129 if ((height < item_no) && (scroll + height < item_no)) {
130 wattrset (win, darrow_attr);
131 waddch (win, ACS_DARROW);
132 waddstr (win, "(+)");
133 }
134 else {
135 wattrset (win, menubox_border_attr);
136 waddch (win, ACS_HLINE);
137 waddch (win, ACS_HLINE);
138 waddch (win, ACS_HLINE);
139 waddch (win, ACS_HLINE);
140 }
141
142 wmove(win, cur_y, cur_x);
143}
144
145/*
146 * Display the termination buttons.
147 */
148static void
149print_buttons (WINDOW *win, int height, int width, int selected)
150{
151 int x = width / 2 - 16;
152 int y = height - 2;
153
154 print_button (win, "Select", y, x, selected == 0);
155 print_button (win, " Exit ", y, x + 12, selected == 1);
156 print_button (win, " Help ", y, x + 24, selected == 2);
157
158 wmove(win, y, x+1+12*selected);
159 wrefresh (win);
160}
161
162/*
163 * Display a menu for choosing among a number of options
164 */
165int
166dialog_menu (const char *title, const char *prompt, int height, int width,
167 int menu_height, const char *current, int item_no,
168 const char * const * items)
169
170{
171 int i, j, x, y, box_x, box_y;
172 int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
173 WINDOW *dialog, *menu;
174 FILE *f;
175
176 max_choice = MIN (menu_height, item_no);
177
178 /* center dialog box on screen */
179 x = (COLS - width) / 2;
180 y = (LINES - height) / 2;
181
182 draw_shadow (stdscr, y, x, height, width);
183
184 dialog = newwin (height, width, y, x);
185 keypad (dialog, TRUE);
186
187 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
188 wattrset (dialog, border_attr);
189 mvwaddch (dialog, height - 3, 0, ACS_LTEE);
190 for (i = 0; i < width - 2; i++)
191 waddch (dialog, ACS_HLINE);
192 wattrset (dialog, dialog_attr);
193 wbkgdset (dialog, dialog_attr & A_COLOR);
194 waddch (dialog, ACS_RTEE);
195
196 if (title != NULL && strlen(title) >= width-2 ) {
197 /* truncate long title -- mec */
198 char * title2 = malloc(width-2+1);
199 memcpy( title2, title, width-2 );
200 title2[width-2] = '\0';
201 title = title2;
202 }
203
204 if (title != NULL) {
205 wattrset (dialog, title_attr);
206 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
207 waddstr (dialog, (char *)title);
208 waddch (dialog, ' ');
209 }
210
211 wattrset (dialog, dialog_attr);
212 print_autowrap (dialog, prompt, width - 2, 1, 3);
213
214 menu_width = width - 6;
215 box_y = height - menu_height - 5;
216 box_x = (width - menu_width) / 2 - 1;
217
218 /* create new window for the menu */
219 menu = subwin (dialog, menu_height, menu_width,
220 y + box_y + 1, x + box_x + 1);
221 keypad (menu, TRUE);
222
223 /* draw a box around the menu items */
224 draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
225 menubox_border_attr, menubox_attr);
226
227 /*
228 * Find length of longest item in order to center menu.
229 * Set 'choice' to default item.
230 */
231 item_x = 0;
232 for (i = 0; i < item_no; i++) {
233 item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
234 if (strcmp(current, items[i*2]) == 0) choice = i;
235 }
236
237 item_x = (menu_width - item_x) / 2;
238
239 /* get the scroll info from the temp file */
240 if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
241 if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
242 (scroll+max_choice > choice) && (scroll >= 0) &&
243 (scroll+max_choice <= item_no) ) {
244 first_item = scroll;
245 choice = choice - scroll;
246 fclose(f);
247 } else {
248 scroll=0;
249 remove("lxdialog.scrltmp");
250 fclose(f);
251 f=NULL;
252 }
253 }
254 if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
255 if (choice >= item_no-max_choice/2)
256 scroll = first_item = item_no-max_choice;
257 else
258 scroll = first_item = choice - max_choice/2;
259 choice = choice - scroll;
260 }
261
262 /* Print the menu */
263 for (i=0; i < max_choice; i++) {
264 print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
265 (items[(first_item + i)*2][0] != ':'));
266 }
267
268 wnoutrefresh (menu);
269
270 print_arrows(dialog, item_no, scroll,
271 box_y, box_x+item_x+1, menu_height);
272
273 print_buttons (dialog, height, width, 0);
274 wmove (menu, choice, item_x+1);
275 wrefresh (menu);
276
277 while (key != ESC) {
278 key = wgetch(menu);
279
280 if (key < 256 && isalpha(key)) key = tolower(key);
281
282 if (strchr("ynmh", key))
283 i = max_choice;
284 else {
285 for (i = choice+1; i < max_choice; i++) {
286 j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
287 if (key == tolower(items[(scroll+i)*2+1][j]))
288 break;
289 }
290 if (i == max_choice)
291 for (i = 0; i < max_choice; i++) {
292 j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
293 if (key == tolower(items[(scroll+i)*2+1][j]))
294 break;
295 }
296 }
297
298 if (i < max_choice ||
299 key == KEY_UP || key == KEY_DOWN ||
300 key == '-' || key == '+' ||
301 key == KEY_PPAGE || key == KEY_NPAGE) {
302
303 print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
304 (items[(scroll+choice)*2][0] != ':'));
305
306 if (key == KEY_UP || key == '-') {
307 if (choice < 2 && scroll) {
308 /* Scroll menu down */
309 scrollok (menu, TRUE);
310 wscrl (menu, -1);
311 scrollok (menu, FALSE);
312
313 scroll--;
314
315 print_item (menu, items[scroll * 2 + 1], 0, FALSE,
316 (items[scroll*2][0] != ':'));
317 } else
318 choice = MAX(choice - 1, 0);
319
320 } else if (key == KEY_DOWN || key == '+') {
321
322 print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
323 (items[(scroll+choice)*2][0] != ':'));
324
325 if ((choice > max_choice-3) &&
326 (scroll + max_choice < item_no)
327 ) {
328 /* Scroll menu up */
329 scrollok (menu, TRUE);
330 wscrl (menu, 1);
331 scrollok (menu, FALSE);
332
333 scroll++;
334
335 print_item (menu, items[(scroll+max_choice-1)*2+1],
336 max_choice-1, FALSE,
337 (items[(scroll+max_choice-1)*2][0] != ':'));
338 } else
339 choice = MIN(choice+1, max_choice-1);
340
341 } else if (key == KEY_PPAGE) {
342 scrollok (menu, TRUE);
343 for (i=0; (i < max_choice); i++) {
344 if (scroll > 0) {
345 wscrl (menu, -1);
346 scroll--;
347 print_item (menu, items[scroll * 2 + 1], 0, FALSE,
348 (items[scroll*2][0] != ':'));
349 } else {
350 if (choice > 0)
351 choice--;
352 }
353 }
354 scrollok (menu, FALSE);
355
356 } else if (key == KEY_NPAGE) {
357 for (i=0; (i < max_choice); i++) {
358 if (scroll+max_choice < item_no) {
359 scrollok (menu, TRUE);
360 wscrl (menu, 1);
361 scrollok (menu, FALSE);
362 scroll++;
363 print_item (menu, items[(scroll+max_choice-1)*2+1],
364 max_choice-1, FALSE,
365 (items[(scroll+max_choice-1)*2][0] != ':'));
366 } else {
367 if (choice+1 < max_choice)
368 choice++;
369 }
370 }
371
372 } else
373 choice = i;
374
375 print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
376 (items[(scroll+choice)*2][0] != ':'));
377
378 print_arrows(dialog, item_no, scroll,
379 box_y, box_x+item_x+1, menu_height);
380
381 wnoutrefresh (dialog);
382 wrefresh (menu);
383
384 continue; /* wait for another key press */
385 }
386
387 switch (key) {
388 case KEY_LEFT:
389 case TAB:
390 case KEY_RIGHT:
391 button = ((key == KEY_LEFT ? --button : ++button) < 0)
392 ? 2 : (button > 2 ? 0 : button);
393
394 print_buttons(dialog, height, width, button);
395 wrefresh (menu);
396 break;
397 case ' ':
398 case 's':
399 case 'y':
400 case 'n':
401 case 'm':
402 case '/':
403 /* save scroll info */
404 if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
405 fprintf(f,"%d\n",scroll);
406 fclose(f);
407 }
408 delwin (dialog);
409 fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
410 switch (key) {
411 case 's': return 3;
412 case 'y': return 3;
413 case 'n': return 4;
414 case 'm': return 5;
415 case ' ': return 6;
416 case '/': return 7;
417 }
418 return 0;
419 case 'h':
420 case '?':
421 button = 2;
422 case '\n':
423 delwin (dialog);
424 if (button == 2)
425 fprintf(stderr, "%s \"%s\"\n",
426 items[(scroll + choice) * 2],
427 items[(scroll + choice) * 2 + 1] +
428 first_alpha(items[(scroll + choice) * 2 + 1],""));
429 else
430 fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
431
432 remove("lxdialog.scrltmp");
433 return button;
434 case 'e':
435 case 'x':
436 key = ESC;
437 case ESC:
438 break;
439 }
440 }
441
442 delwin (dialog);
443 remove("lxdialog.scrltmp");
444 return -1; /* ESC pressed */
445}
diff --git a/scripts/lxdialog/msgbox.c b/scripts/lxdialog/msgbox.c
new file mode 100644
index 000000000000..93692e1fbcc2
--- /dev/null
+++ b/scripts/lxdialog/msgbox.c
@@ -0,0 +1,85 @@
1/*
2 * msgbox.c -- implements the message box and info box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24/*
25 * Display a message box. Program will pause and display an "OK" button
26 * if the parameter 'pause' is non-zero.
27 */
28int
29dialog_msgbox (const char *title, const char *prompt, int height, int width,
30 int pause)
31{
32 int i, x, y, key = 0;
33 WINDOW *dialog;
34
35 /* center dialog box on screen */
36 x = (COLS - width) / 2;
37 y = (LINES - height) / 2;
38
39 draw_shadow (stdscr, y, x, height, width);
40
41 dialog = newwin (height, width, y, x);
42 keypad (dialog, TRUE);
43
44 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
45
46 if (title != NULL && strlen(title) >= width-2 ) {
47 /* truncate long title -- mec */
48 char * title2 = malloc(width-2+1);
49 memcpy( title2, title, width-2 );
50 title2[width-2] = '\0';
51 title = title2;
52 }
53
54 if (title != NULL) {
55 wattrset (dialog, title_attr);
56 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
57 waddstr (dialog, (char *)title);
58 waddch (dialog, ' ');
59 }
60 wattrset (dialog, dialog_attr);
61 print_autowrap (dialog, prompt, width - 2, 1, 2);
62
63 if (pause) {
64 wattrset (dialog, border_attr);
65 mvwaddch (dialog, height - 3, 0, ACS_LTEE);
66 for (i = 0; i < width - 2; i++)
67 waddch (dialog, ACS_HLINE);
68 wattrset (dialog, dialog_attr);
69 waddch (dialog, ACS_RTEE);
70
71 print_button (dialog, " Ok ",
72 height - 2, width / 2 - 4, TRUE);
73
74 wrefresh (dialog);
75 while (key != ESC && key != '\n' && key != ' ' &&
76 key != 'O' && key != 'o' && key != 'X' && key != 'x')
77 key = wgetch (dialog);
78 } else {
79 key = '\n';
80 wrefresh (dialog);
81 }
82
83 delwin (dialog);
84 return key == ESC ? -1 : 0;
85}
diff --git a/scripts/lxdialog/textbox.c b/scripts/lxdialog/textbox.c
new file mode 100644
index 000000000000..ed23df2d096a
--- /dev/null
+++ b/scripts/lxdialog/textbox.c
@@ -0,0 +1,556 @@
1/*
2 * textbox.c -- implements the text box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24static void back_lines (int n);
25static void print_page (WINDOW * win, int height, int width);
26static void print_line (WINDOW * win, int row, int width);
27static char *get_line (void);
28static void print_position (WINDOW * win, int height, int width);
29
30static int hscroll, fd, file_size, bytes_read;
31static int begin_reached = 1, end_reached, page_length;
32static char *buf, *page;
33
34/*
35 * Display text from a file in a dialog box.
36 */
37int
38dialog_textbox (const char *title, const char *file, int height, int width)
39{
40 int i, x, y, cur_x, cur_y, fpos, key = 0;
41 int passed_end;
42 char search_term[MAX_LEN + 1];
43 WINDOW *dialog, *text;
44
45 search_term[0] = '\0'; /* no search term entered yet */
46
47 /* Open input file for reading */
48 if ((fd = open (file, O_RDONLY)) == -1) {
49 endwin ();
50 fprintf (stderr,
51 "\nCan't open input file in dialog_textbox().\n");
52 exit (-1);
53 }
54 /* Get file size. Actually, 'file_size' is the real file size - 1,
55 since it's only the last byte offset from the beginning */
56 if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
57 endwin ();
58 fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
59 exit (-1);
60 }
61 /* Restore file pointer to beginning of file after getting file size */
62 if (lseek (fd, 0, SEEK_SET) == -1) {
63 endwin ();
64 fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
65 exit (-1);
66 }
67 /* Allocate space for read buffer */
68 if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
69 endwin ();
70 fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
71 exit (-1);
72 }
73 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
74 endwin ();
75 fprintf (stderr, "\nError reading file in dialog_textbox().\n");
76 exit (-1);
77 }
78 buf[bytes_read] = '\0'; /* mark end of valid data */
79 page = buf; /* page is pointer to start of page to be displayed */
80
81 /* center dialog box on screen */
82 x = (COLS - width) / 2;
83 y = (LINES - height) / 2;
84
85
86 draw_shadow (stdscr, y, x, height, width);
87
88 dialog = newwin (height, width, y, x);
89 keypad (dialog, TRUE);
90
91 /* Create window for text region, used for scrolling text */
92 text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
93 wattrset (text, dialog_attr);
94 wbkgdset (text, dialog_attr & A_COLOR);
95
96 keypad (text, TRUE);
97
98 /* register the new window, along with its borders */
99 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
100
101 wattrset (dialog, border_attr);
102 mvwaddch (dialog, height-3, 0, ACS_LTEE);
103 for (i = 0; i < width - 2; i++)
104 waddch (dialog, ACS_HLINE);
105 wattrset (dialog, dialog_attr);
106 wbkgdset (dialog, dialog_attr & A_COLOR);
107 waddch (dialog, ACS_RTEE);
108
109 if (title != NULL && strlen(title) >= width-2 ) {
110 /* truncate long title -- mec */
111 char * title2 = malloc(width-2+1);
112 memcpy( title2, title, width-2 );
113 title2[width-2] = '\0';
114 title = title2;
115 }
116
117 if (title != NULL) {
118 wattrset (dialog, title_attr);
119 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
120 waddstr (dialog, (char *)title);
121 waddch (dialog, ' ');
122 }
123 print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
124 wnoutrefresh (dialog);
125 getyx (dialog, cur_y, cur_x); /* Save cursor position */
126
127 /* Print first page of text */
128 attr_clear (text, height - 4, width - 2, dialog_attr);
129 print_page (text, height - 4, width - 2);
130 print_position (dialog, height, width);
131 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
132 wrefresh (dialog);
133
134 while ((key != ESC) && (key != '\n')) {
135 key = wgetch (dialog);
136 switch (key) {
137 case 'E': /* Exit */
138 case 'e':
139 case 'X':
140 case 'x':
141 delwin (dialog);
142 free (buf);
143 close (fd);
144 return 0;
145 case 'g': /* First page */
146 case KEY_HOME:
147 if (!begin_reached) {
148 begin_reached = 1;
149 /* First page not in buffer? */
150 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
151 endwin ();
152 fprintf (stderr,
153 "\nError moving file pointer in dialog_textbox().\n");
154 exit (-1);
155 }
156 if (fpos > bytes_read) { /* Yes, we have to read it in */
157 if (lseek (fd, 0, SEEK_SET) == -1) {
158 endwin ();
159 fprintf (stderr, "\nError moving file pointer in "
160 "dialog_textbox().\n");
161 exit (-1);
162 }
163 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
164 endwin ();
165 fprintf (stderr,
166 "\nError reading file in dialog_textbox().\n");
167 exit (-1);
168 }
169 buf[bytes_read] = '\0';
170 }
171 page = buf;
172 print_page (text, height - 4, width - 2);
173 print_position (dialog, height, width);
174 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
175 wrefresh (dialog);
176 }
177 break;
178 case 'G': /* Last page */
179 case KEY_END:
180
181 end_reached = 1;
182 /* Last page not in buffer? */
183 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
184 endwin ();
185 fprintf (stderr,
186 "\nError moving file pointer in dialog_textbox().\n");
187 exit (-1);
188 }
189 if (fpos < file_size) { /* Yes, we have to read it in */
190 if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
191 endwin ();
192 fprintf (stderr,
193 "\nError moving file pointer in dialog_textbox().\n");
194 exit (-1);
195 }
196 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
197 endwin ();
198 fprintf (stderr,
199 "\nError reading file in dialog_textbox().\n");
200 exit (-1);
201 }
202 buf[bytes_read] = '\0';
203 }
204 page = buf + bytes_read;
205 back_lines (height - 4);
206 print_page (text, height - 4, width - 2);
207 print_position (dialog, height, width);
208 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
209 wrefresh (dialog);
210 break;
211 case 'K': /* Previous line */
212 case 'k':
213 case KEY_UP:
214 if (!begin_reached) {
215 back_lines (page_length + 1);
216
217 /* We don't call print_page() here but use scrolling to ensure
218 faster screen update. However, 'end_reached' and
219 'page_length' should still be updated, and 'page' should
220 point to start of next page. This is done by calling
221 get_line() in the following 'for' loop. */
222 scrollok (text, TRUE);
223 wscrl (text, -1); /* Scroll text region down one line */
224 scrollok (text, FALSE);
225 page_length = 0;
226 passed_end = 0;
227 for (i = 0; i < height - 4; i++) {
228 if (!i) {
229 /* print first line of page */
230 print_line (text, 0, width - 2);
231 wnoutrefresh (text);
232 } else
233 /* Called to update 'end_reached' and 'page' */
234 get_line ();
235 if (!passed_end)
236 page_length++;
237 if (end_reached && !passed_end)
238 passed_end = 1;
239 }
240
241 print_position (dialog, height, width);
242 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
243 wrefresh (dialog);
244 }
245 break;
246 case 'B': /* Previous page */
247 case 'b':
248 case KEY_PPAGE:
249 if (begin_reached)
250 break;
251 back_lines (page_length + height - 4);
252 print_page (text, height - 4, width - 2);
253 print_position (dialog, height, width);
254 wmove (dialog, cur_y, cur_x);
255 wrefresh (dialog);
256 break;
257 case 'J': /* Next line */
258 case 'j':
259 case KEY_DOWN:
260 if (!end_reached) {
261 begin_reached = 0;
262 scrollok (text, TRUE);
263 scroll (text); /* Scroll text region up one line */
264 scrollok (text, FALSE);
265 print_line (text, height - 5, width - 2);
266 wnoutrefresh (text);
267 print_position (dialog, height, width);
268 wmove (dialog, cur_y, cur_x); /* Restore cursor position */
269 wrefresh (dialog);
270 }
271 break;
272 case KEY_NPAGE: /* Next page */
273 case ' ':
274 if (end_reached)
275 break;
276
277 begin_reached = 0;
278 print_page (text, height - 4, width - 2);
279 print_position (dialog, height, width);
280 wmove (dialog, cur_y, cur_x);
281 wrefresh (dialog);
282 break;
283 case '0': /* Beginning of line */
284 case 'H': /* Scroll left */
285 case 'h':
286 case KEY_LEFT:
287 if (hscroll <= 0)
288 break;
289
290 if (key == '0')
291 hscroll = 0;
292 else
293 hscroll--;
294 /* Reprint current page to scroll horizontally */
295 back_lines (page_length);
296 print_page (text, height - 4, width - 2);
297 wmove (dialog, cur_y, cur_x);
298 wrefresh (dialog);
299 break;
300 case 'L': /* Scroll right */
301 case 'l':
302 case KEY_RIGHT:
303 if (hscroll >= MAX_LEN)
304 break;
305 hscroll++;
306 /* Reprint current page to scroll horizontally */
307 back_lines (page_length);
308 print_page (text, height - 4, width - 2);
309 wmove (dialog, cur_y, cur_x);
310 wrefresh (dialog);
311 break;
312 case ESC:
313 break;
314 }
315 }
316
317 delwin (dialog);
318 free (buf);
319 close (fd);
320 return -1; /* ESC pressed */
321}
322
323/*
324 * Go back 'n' lines in text file. Called by dialog_textbox().
325 * 'page' will be updated to point to the desired line in 'buf'.
326 */
327static void
328back_lines (int n)
329{
330 int i, fpos;
331
332 begin_reached = 0;
333 /* We have to distinguish between end_reached and !end_reached
334 since at end of file, the line is not ended by a '\n'.
335 The code inside 'if' basically does a '--page' to move one
336 character backward so as to skip '\n' of the previous line */
337 if (!end_reached) {
338 /* Either beginning of buffer or beginning of file reached? */
339 if (page == buf) {
340 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
341 endwin ();
342 fprintf (stderr, "\nError moving file pointer in "
343 "back_lines().\n");
344 exit (-1);
345 }
346 if (fpos > bytes_read) { /* Not beginning of file yet */
347 /* We've reached beginning of buffer, but not beginning of
348 file yet, so read previous part of file into buffer.
349 Note that we only move backward for BUF_SIZE/2 bytes,
350 but not BUF_SIZE bytes to avoid re-reading again in
351 print_page() later */
352 /* Really possible to move backward BUF_SIZE/2 bytes? */
353 if (fpos < BUF_SIZE / 2 + bytes_read) {
354 /* No, move less then */
355 if (lseek (fd, 0, SEEK_SET) == -1) {
356 endwin ();
357 fprintf (stderr, "\nError moving file pointer in "
358 "back_lines().\n");
359 exit (-1);
360 }
361 page = buf + fpos - bytes_read;
362 } else { /* Move backward BUF_SIZE/2 bytes */
363 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
364 == -1) {
365 endwin ();
366 fprintf (stderr, "\nError moving file pointer "
367 "in back_lines().\n");
368 exit (-1);
369 }
370 page = buf + BUF_SIZE / 2;
371 }
372 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
373 endwin ();
374 fprintf (stderr, "\nError reading file in back_lines().\n");
375 exit (-1);
376 }
377 buf[bytes_read] = '\0';
378 } else { /* Beginning of file reached */
379 begin_reached = 1;
380 return;
381 }
382 }
383 if (*(--page) != '\n') { /* '--page' here */
384 /* Something's wrong... */
385 endwin ();
386 fprintf (stderr, "\nInternal error in back_lines().\n");
387 exit (-1);
388 }
389 }
390 /* Go back 'n' lines */
391 for (i = 0; i < n; i++)
392 do {
393 if (page == buf) {
394 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
395 endwin ();
396 fprintf (stderr,
397 "\nError moving file pointer in back_lines().\n");
398 exit (-1);
399 }
400 if (fpos > bytes_read) {
401 /* Really possible to move backward BUF_SIZE/2 bytes? */
402 if (fpos < BUF_SIZE / 2 + bytes_read) {
403 /* No, move less then */
404 if (lseek (fd, 0, SEEK_SET) == -1) {
405 endwin ();
406 fprintf (stderr, "\nError moving file pointer "
407 "in back_lines().\n");
408 exit (-1);
409 }
410 page = buf + fpos - bytes_read;
411 } else { /* Move backward BUF_SIZE/2 bytes */
412 if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
413 SEEK_CUR) == -1) {
414 endwin ();
415 fprintf (stderr, "\nError moving file pointer"
416 " in back_lines().\n");
417 exit (-1);
418 }
419 page = buf + BUF_SIZE / 2;
420 }
421 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
422 endwin ();
423 fprintf (stderr, "\nError reading file in "
424 "back_lines().\n");
425 exit (-1);
426 }
427 buf[bytes_read] = '\0';
428 } else { /* Beginning of file reached */
429 begin_reached = 1;
430 return;
431 }
432 }
433 } while (*(--page) != '\n');
434 page++;
435}
436
437/*
438 * Print a new page of text. Called by dialog_textbox().
439 */
440static void
441print_page (WINDOW * win, int height, int width)
442{
443 int i, passed_end = 0;
444
445 page_length = 0;
446 for (i = 0; i < height; i++) {
447 print_line (win, i, width);
448 if (!passed_end)
449 page_length++;
450 if (end_reached && !passed_end)
451 passed_end = 1;
452 }
453 wnoutrefresh (win);
454}
455
456/*
457 * Print a new line of text. Called by dialog_textbox() and print_page().
458 */
459static void
460print_line (WINDOW * win, int row, int width)
461{
462 int y, x;
463 char *line;
464
465 line = get_line ();
466 line += MIN (strlen (line), hscroll); /* Scroll horizontally */
467 wmove (win, row, 0); /* move cursor to correct line */
468 waddch (win, ' ');
469 waddnstr (win, line, MIN (strlen (line), width - 2));
470
471 getyx (win, y, x);
472 /* Clear 'residue' of previous line */
473#if OLD_NCURSES
474 {
475 int i;
476 for (i = 0; i < width - x; i++)
477 waddch (win, ' ');
478 }
479#else
480 wclrtoeol(win);
481#endif
482}
483
484/*
485 * Return current line of text. Called by dialog_textbox() and print_line().
486 * 'page' should point to start of current line before calling, and will be
487 * updated to point to start of next line.
488 */
489static char *
490get_line (void)
491{
492 int i = 0, fpos;
493 static char line[MAX_LEN + 1];
494
495 end_reached = 0;
496 while (*page != '\n') {
497 if (*page == '\0') {
498 /* Either end of file or end of buffer reached */
499 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
500 endwin ();
501 fprintf (stderr, "\nError moving file pointer in "
502 "get_line().\n");
503 exit (-1);
504 }
505 if (fpos < file_size) { /* Not end of file yet */
506 /* We've reached end of buffer, but not end of file yet,
507 so read next part of file into buffer */
508 if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
509 endwin ();
510 fprintf (stderr, "\nError reading file in get_line().\n");
511 exit (-1);
512 }
513 buf[bytes_read] = '\0';
514 page = buf;
515 } else {
516 if (!end_reached)
517 end_reached = 1;
518 break;
519 }
520 } else if (i < MAX_LEN)
521 line[i++] = *(page++);
522 else {
523 /* Truncate lines longer than MAX_LEN characters */
524 if (i == MAX_LEN)
525 line[i++] = '\0';
526 page++;
527 }
528 }
529 if (i <= MAX_LEN)
530 line[i] = '\0';
531 if (!end_reached)
532 page++; /* move pass '\n' */
533
534 return line;
535}
536
537/*
538 * Print current position
539 */
540static void
541print_position (WINDOW * win, int height, int width)
542{
543 int fpos, percent;
544
545 if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
546 endwin ();
547 fprintf (stderr, "\nError moving file pointer in print_position().\n");
548 exit (-1);
549 }
550 wattrset (win, position_indicator_attr);
551 wbkgdset (win, position_indicator_attr & A_COLOR);
552 percent = !file_size ?
553 100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
554 wmove (win, height - 3, width - 9);
555 wprintw (win, "(%3d%%)", percent);
556}
diff --git a/scripts/lxdialog/util.c b/scripts/lxdialog/util.c
new file mode 100644
index 000000000000..e7bce9be69c3
--- /dev/null
+++ b/scripts/lxdialog/util.c
@@ -0,0 +1,359 @@
1/*
2 * util.c
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24
25/* use colors by default? */
26bool use_colors = 1;
27
28const char *backtitle = NULL;
29
30const char *dialog_result;
31
32/*
33 * Attribute values, default is for mono display
34 */
35chtype attributes[] =
36{
37 A_NORMAL, /* screen_attr */
38 A_NORMAL, /* shadow_attr */
39 A_NORMAL, /* dialog_attr */
40 A_BOLD, /* title_attr */
41 A_NORMAL, /* border_attr */
42 A_REVERSE, /* button_active_attr */
43 A_DIM, /* button_inactive_attr */
44 A_REVERSE, /* button_key_active_attr */
45 A_BOLD, /* button_key_inactive_attr */
46 A_REVERSE, /* button_label_active_attr */
47 A_NORMAL, /* button_label_inactive_attr */
48 A_NORMAL, /* inputbox_attr */
49 A_NORMAL, /* inputbox_border_attr */
50 A_NORMAL, /* searchbox_attr */
51 A_BOLD, /* searchbox_title_attr */
52 A_NORMAL, /* searchbox_border_attr */
53 A_BOLD, /* position_indicator_attr */
54 A_NORMAL, /* menubox_attr */
55 A_NORMAL, /* menubox_border_attr */
56 A_NORMAL, /* item_attr */
57 A_REVERSE, /* item_selected_attr */
58 A_BOLD, /* tag_attr */
59 A_REVERSE, /* tag_selected_attr */
60 A_BOLD, /* tag_key_attr */
61 A_REVERSE, /* tag_key_selected_attr */
62 A_BOLD, /* check_attr */
63 A_REVERSE, /* check_selected_attr */
64 A_BOLD, /* uarrow_attr */
65 A_BOLD /* darrow_attr */
66};
67
68
69#include "colors.h"
70
71/*
72 * Table of color values
73 */
74int color_table[][3] =
75{
76 {SCREEN_FG, SCREEN_BG, SCREEN_HL},
77 {SHADOW_FG, SHADOW_BG, SHADOW_HL},
78 {DIALOG_FG, DIALOG_BG, DIALOG_HL},
79 {TITLE_FG, TITLE_BG, TITLE_HL},
80 {BORDER_FG, BORDER_BG, BORDER_HL},
81 {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
82 {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
83 {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
84 {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
85 {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
86 {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
87 BUTTON_LABEL_INACTIVE_HL},
88 {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
89 {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
90 {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
91 {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
92 {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
93 {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
94 {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
95 {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
96 {ITEM_FG, ITEM_BG, ITEM_HL},
97 {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
98 {TAG_FG, TAG_BG, TAG_HL},
99 {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
100 {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
101 {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
102 {CHECK_FG, CHECK_BG, CHECK_HL},
103 {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
104 {UARROW_FG, UARROW_BG, UARROW_HL},
105 {DARROW_FG, DARROW_BG, DARROW_HL},
106}; /* color_table */
107
108/*
109 * Set window to attribute 'attr'
110 */
111void
112attr_clear (WINDOW * win, int height, int width, chtype attr)
113{
114 int i, j;
115
116 wattrset (win, attr);
117 for (i = 0; i < height; i++) {
118 wmove (win, i, 0);
119 for (j = 0; j < width; j++)
120 waddch (win, ' ');
121 }
122 touchwin (win);
123}
124
125void dialog_clear (void)
126{
127 attr_clear (stdscr, LINES, COLS, screen_attr);
128 /* Display background title if it exists ... - SLH */
129 if (backtitle != NULL) {
130 int i;
131
132 wattrset (stdscr, screen_attr);
133 mvwaddstr (stdscr, 0, 1, (char *)backtitle);
134 wmove (stdscr, 1, 1);
135 for (i = 1; i < COLS - 1; i++)
136 waddch (stdscr, ACS_HLINE);
137 }
138 wnoutrefresh (stdscr);
139}
140
141/*
142 * Do some initialization for dialog
143 */
144void
145init_dialog (void)
146{
147 initscr (); /* Init curses */
148 keypad (stdscr, TRUE);
149 cbreak ();
150 noecho ();
151
152
153 if (use_colors) /* Set up colors */
154 color_setup ();
155
156
157 dialog_clear ();
158}
159
160/*
161 * Setup for color display
162 */
163void
164color_setup (void)
165{
166 int i;
167
168 if (has_colors ()) { /* Terminal supports color? */
169 start_color ();
170
171 /* Initialize color pairs */
172 for (i = 0; i < ATTRIBUTE_COUNT; i++)
173 init_pair (i + 1, color_table[i][0], color_table[i][1]);
174
175 /* Setup color attributes */
176 for (i = 0; i < ATTRIBUTE_COUNT; i++)
177 attributes[i] = C_ATTR (color_table[i][2], i + 1);
178 }
179}
180
181/*
182 * End using dialog functions.
183 */
184void
185end_dialog (void)
186{
187 endwin ();
188}
189
190
191/*
192 * Print a string of text in a window, automatically wrap around to the
193 * next line if the string is too long to fit on one line. Newline
194 * characters '\n' are replaced by spaces. We start on a new line
195 * if there is no room for at least 4 nonblanks following a double-space.
196 */
197void
198print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
199{
200 int newl, cur_x, cur_y;
201 int i, prompt_len, room, wlen;
202 char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
203
204 strcpy (tempstr, prompt);
205
206 prompt_len = strlen(tempstr);
207
208 /*
209 * Remove newlines
210 */
211 for(i=0; i<prompt_len; i++) {
212 if(tempstr[i] == '\n') tempstr[i] = ' ';
213 }
214
215 if (prompt_len <= width - x * 2) { /* If prompt is short */
216 wmove (win, y, (width - prompt_len) / 2);
217 waddstr (win, tempstr);
218 } else {
219 cur_x = x;
220 cur_y = y;
221 newl = 1;
222 word = tempstr;
223 while (word && *word) {
224 sp = index(word, ' ');
225 if (sp)
226 *sp++ = 0;
227
228 /* Wrap to next line if either the word does not fit,
229 or it is the first word of a new sentence, and it is
230 short, and the next word does not fit. */
231 room = width - cur_x;
232 wlen = strlen(word);
233 if (wlen > room ||
234 (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
235 && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
236 cur_y++;
237 cur_x = x;
238 }
239 wmove (win, cur_y, cur_x);
240 waddstr (win, word);
241 getyx (win, cur_y, cur_x);
242 cur_x++;
243 if (sp && *sp == ' ') {
244 cur_x++; /* double space */
245 while (*++sp == ' ');
246 newl = 1;
247 } else
248 newl = 0;
249 word = sp;
250 }
251 }
252}
253
254/*
255 * Print a button
256 */
257void
258print_button (WINDOW * win, const char *label, int y, int x, int selected)
259{
260 int i, temp;
261
262 wmove (win, y, x);
263 wattrset (win, selected ? button_active_attr : button_inactive_attr);
264 waddstr (win, "<");
265 temp = strspn (label, " ");
266 label += temp;
267 wattrset (win, selected ? button_label_active_attr
268 : button_label_inactive_attr);
269 for (i = 0; i < temp; i++)
270 waddch (win, ' ');
271 wattrset (win, selected ? button_key_active_attr
272 : button_key_inactive_attr);
273 waddch (win, label[0]);
274 wattrset (win, selected ? button_label_active_attr
275 : button_label_inactive_attr);
276 waddstr (win, (char *)label + 1);
277 wattrset (win, selected ? button_active_attr : button_inactive_attr);
278 waddstr (win, ">");
279 wmove (win, y, x + temp + 1);
280}
281
282/*
283 * Draw a rectangular box with line drawing characters
284 */
285void
286draw_box (WINDOW * win, int y, int x, int height, int width,
287 chtype box, chtype border)
288{
289 int i, j;
290
291 wattrset (win, 0);
292 for (i = 0; i < height; i++) {
293 wmove (win, y + i, x);
294 for (j = 0; j < width; j++)
295 if (!i && !j)
296 waddch (win, border | ACS_ULCORNER);
297 else if (i == height - 1 && !j)
298 waddch (win, border | ACS_LLCORNER);
299 else if (!i && j == width - 1)
300 waddch (win, box | ACS_URCORNER);
301 else if (i == height - 1 && j == width - 1)
302 waddch (win, box | ACS_LRCORNER);
303 else if (!i)
304 waddch (win, border | ACS_HLINE);
305 else if (i == height - 1)
306 waddch (win, box | ACS_HLINE);
307 else if (!j)
308 waddch (win, border | ACS_VLINE);
309 else if (j == width - 1)
310 waddch (win, box | ACS_VLINE);
311 else
312 waddch (win, box | ' ');
313 }
314}
315
316/*
317 * Draw shadows along the right and bottom edge to give a more 3D look
318 * to the boxes
319 */
320void
321draw_shadow (WINDOW * win, int y, int x, int height, int width)
322{
323 int i;
324
325 if (has_colors ()) { /* Whether terminal supports color? */
326 wattrset (win, shadow_attr);
327 wmove (win, y + height, x + 2);
328 for (i = 0; i < width; i++)
329 waddch (win, winch (win) & A_CHARTEXT);
330 for (i = y + 1; i < y + height + 1; i++) {
331 wmove (win, i, x + width);
332 waddch (win, winch (win) & A_CHARTEXT);
333 waddch (win, winch (win) & A_CHARTEXT);
334 }
335 wnoutrefresh (win);
336 }
337}
338
339/*
340 * Return the position of the first alphabetic character in a string.
341 */
342int
343first_alpha(const char *string, const char *exempt)
344{
345 int i, in_paren=0, c;
346
347 for (i = 0; i < strlen(string); i++) {
348 c = tolower(string[i]);
349
350 if (strchr("<[(", c)) ++in_paren;
351 if (strchr(">])", c) && in_paren > 0) --in_paren;
352
353 if ((! in_paren) && isalpha(c) &&
354 strchr(exempt, c) == 0)
355 return i;
356 }
357
358 return 0;
359}
diff --git a/scripts/lxdialog/yesno.c b/scripts/lxdialog/yesno.c
new file mode 100644
index 000000000000..11fcc25f5159
--- /dev/null
+++ b/scripts/lxdialog/yesno.c
@@ -0,0 +1,118 @@
1/*
2 * yesno.c -- implements the yes/no box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24/*
25 * Display termination buttons
26 */
27static void
28print_buttons(WINDOW *dialog, int height, int width, int selected)
29{
30 int x = width / 2 - 10;
31 int y = height - 2;
32
33 print_button (dialog, " Yes ", y, x, selected == 0);
34 print_button (dialog, " No ", y, x + 13, selected == 1);
35
36 wmove(dialog, y, x+1 + 13*selected );
37 wrefresh (dialog);
38}
39
40/*
41 * Display a dialog box with two buttons - Yes and No
42 */
43int
44dialog_yesno (const char *title, const char *prompt, int height, int width)
45{
46 int i, x, y, key = 0, button = 0;
47 WINDOW *dialog;
48
49 /* center dialog box on screen */
50 x = (COLS - width) / 2;
51 y = (LINES - height) / 2;
52
53 draw_shadow (stdscr, y, x, height, width);
54
55 dialog = newwin (height, width, y, x);
56 keypad (dialog, TRUE);
57
58 draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
59 wattrset (dialog, border_attr);
60 mvwaddch (dialog, height-3, 0, ACS_LTEE);
61 for (i = 0; i < width - 2; i++)
62 waddch (dialog, ACS_HLINE);
63 wattrset (dialog, dialog_attr);
64 waddch (dialog, ACS_RTEE);
65
66 if (title != NULL && strlen(title) >= width-2 ) {
67 /* truncate long title -- mec */
68 char * title2 = malloc(width-2+1);
69 memcpy( title2, title, width-2 );
70 title2[width-2] = '\0';
71 title = title2;
72 }
73
74 if (title != NULL) {
75 wattrset (dialog, title_attr);
76 mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
77 waddstr (dialog, (char *)title);
78 waddch (dialog, ' ');
79 }
80
81 wattrset (dialog, dialog_attr);
82 print_autowrap (dialog, prompt, width - 2, 1, 3);
83
84 print_buttons(dialog, height, width, 0);
85
86 while (key != ESC) {
87 key = wgetch (dialog);
88 switch (key) {
89 case 'Y':
90 case 'y':
91 delwin (dialog);
92 return 0;
93 case 'N':
94 case 'n':
95 delwin (dialog);
96 return 1;
97
98 case TAB:
99 case KEY_LEFT:
100 case KEY_RIGHT:
101 button = ((key == KEY_LEFT ? --button : ++button) < 0)
102 ? 1 : (button > 1 ? 0 : button);
103
104 print_buttons(dialog, height, width, button);
105 wrefresh (dialog);
106 break;
107 case ' ':
108 case '\n':
109 delwin (dialog);
110 return button;
111 case ESC:
112 break;
113 }
114 }
115
116 delwin (dialog);
117 return -1; /* ESC pressed */
118}
diff --git a/scripts/makelst b/scripts/makelst
new file mode 100755
index 000000000000..34bd72391238
--- /dev/null
+++ b/scripts/makelst
@@ -0,0 +1,31 @@
1#!/bin/bash
2# A script to dump mixed source code & assembly
3# with correct relocations from System.map
4# Requires the following lines in Rules.make.
5# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
6# William Stearns <wstearns@pobox.com>
7#%.lst: %.c
8# $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
9# $(TOPDIR)/scripts/makelst $*.o $(TOPDIR)/System.map $(OBJDUMP)
10#
11# Copyright (C) 2000 IBM Corporation
12# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
13#
14
15t1=`$3 --syms $1 | grep .text | grep " F " | head -n 1`
16if [ -n "$t1" ]; then
17 t2=`echo $t1 | gawk '{ print $6 }'`
18 if [ ! -r $2 ]; then
19 echo "No System.map" >&2
20 t7=0
21 else
22 t3=`grep $t2 $2`
23 t4=`echo $t3 | gawk '{ print $1 }'`
24 t5=`echo $t1 | gawk '{ print $1 }'`
25 t6=`echo $t4 - $t5 | tr a-f A-F`
26 t7=`( echo ibase=16 ; echo $t6 ) | bc`
27 fi
28else
29 t7=0
30fi
31$3 -r --source --adjust-vma=$t7 $1
diff --git a/scripts/makeman b/scripts/makeman
new file mode 100755
index 000000000000..db3af647ee17
--- /dev/null
+++ b/scripts/makeman
@@ -0,0 +1,185 @@
1#!/usr/bin/perl
2
3use strict;
4
5## Copyright (C) Michael Still (mikal@stillhq.com)
6## Released under the terms of the GNU GPL
7##
8## A script to make or install the manpages extracted by split-man
9##
10## Arguements: $1 -- the word "convert" or "install"
11## $2 -- the directory containing the SGML files for the manpages
12## $3 -- the filename which contained the sgmldoc output
13## (I need this so I know which manpages to convert)
14
15my($LISTING, $GENERATED, $INPUT, $OUTPUT, $front, $mode, $filename, $tmpdir);
16
17if($ARGV[0] eq ""){
18 die "Usage: makeman [convert | install] <dir> <file>\n";
19}
20
21if( ! -d "$ARGV[1]" ){
22 die "Output directory \"$ARGV[1]\" does not exist\n";
23}
24
25if($ENV{"TMPDIR"} ne ""){
26 $tmpdir = $ENV{"TMPDIR"};
27}
28else{
29 $tmpdir = "/tmp";
30}
31
32if($ARGV[0] eq "convert"){
33 open LISTING, "grep \"<refentrytitle>\" $ARGV[2] |";
34 while(<LISTING>){
35 s/<\/.*$//;
36 s/^.*>//;
37 s/\.sgml//;
38 s/struct //;
39 s/typedef //;
40
41 chomp;
42 $filename = $_;
43 print "Processing $filename\n";
44
45 # Open the input file to extract the front matter, generate the man page,
46 # and open it, and the rearrange everything until it is happy
47 open INPUT, "< $ARGV[1]/$filename.sgml";
48 $front = "";
49 $mode = 0;
50
51 # The modes used here are:
52 # mode = 0
53 # <!-- BEGINFRONTTAG -->
54 # <!-- <bookinfo> mode = 1
55 # <!-- <legalnotice> mode = 2
56 # <!-- ...GPL or whatever...
57 # <!-- </legalnotice> mode = 4
58 # <!-- </bookinfo> mode = 3
59 # <!-- ENDFRONTTAG -->
60 #
61 # ...doco...
62
63 # I know that some of the if statements in this while loop are in a funny
64 # order, but that is deliberate...
65 while(<INPUT>){
66 if($mode > 0){
67 s/<!-- //;
68 s/ -->//;
69 s/<docinfo>//i;
70 s<\/docinfo>//i;
71 s/^[ \t]*//i;
72 }
73
74 if($mode == 2){
75 if(/<para>/i){
76 }
77 elsif(/<\/para>/i){
78 $front = "$front.\\\" \n";
79 }
80 elsif(/<\/legalnotice>/i){
81 $mode = 4;
82 }
83 elsif(/^[ \t]*$/){
84 }
85 else{
86 $front = "$front.\\\" $_";
87 }
88 }
89
90 if($mode == 1){
91 if(/<title>(.*)<\/title>/i){
92 $front = "$front.\\\" This documentation was generated from the book titled \"$1\", which is part of the Linux kernel source.\n.\\\" \n";
93 }
94 elsif(/<legalnotice>/i){
95 $front = "$front.\\\" This documentation comes with the following legal notice:\n.\\\" \n";
96 $mode = 2;
97 }
98
99 elsif(/<author>/i){
100 $front = "$front.\\\" Documentation by: ";
101 }
102 elsif(/<firstname>(.*)<\/firstname>/i){
103 $front = "$front$1 ";
104 }
105 elsif(/<surname>(.*)<\/surname>/i){
106 $front = "$front$1 ";
107 }
108 elsif(/<email>(.*)<\/email>/i){
109 $front = "$front($1)";
110 }
111 elsif(/\/author>/i){
112 $front = "$front\n";
113 }
114
115 elsif(/<copyright>/i){
116 $front = "$front.\\\" Documentation copyright: ";
117 }
118 elsif(/<holder>(.*)<\/holder>/i){
119 $front = "$front$1 ";
120 }
121 elsif(/<year>(.*)<\/year>/i){
122 $front = "$front$1 ";
123 }
124 elsif(/\/copyright>/i){
125 $front = "$front\n";
126 }
127
128 elsif(/^[ \t]*$/
129 || /<affiliation>/i
130 || /<\/affiliation>/i
131 || /<address>/i
132 || /<\/address>/i
133 || /<authorgroup>/i
134 || /<\/authorgroup>/i
135 || /<\/legalnotice>/i
136 || /<date>/i
137 || /<\/date>/i
138 || /<edition>/i
139 || /<\/edition>/i
140 || /<pubdate>/i
141 || /<\/pubdate>/i){
142 }
143 else{
144 print "Unknown tag in manpage conversion: $_";
145 }
146 }
147
148 if($mode == 0){
149 if(/<bookinfo>/i){
150 $mode = 1;
151 }
152 }
153
154 if($mode == 4){
155 if(/<\/bookinfo>/i){
156 $mode = 3;
157 }
158 }
159 }
160 close INPUT;
161
162 system("cd $ARGV[1]; docbook2man $filename.sgml; mv $filename.9 $tmpdir/$$.9\n");
163 open GENERATED, "< $tmpdir/$$.9";
164 open OUTPUT, "> $ARGV[1]/$filename.9";
165
166 print OUTPUT "$front";
167 print OUTPUT ".\\\" For comments on the formatting of this manpage, please contact Michael Still <mikal\@stillhq.com>\n\n";
168 while(<GENERATED>){
169 print OUTPUT "$_";
170 }
171 close OUTPUT;
172 close GENERATED;
173
174 system("gzip -f $ARGV[1]/$filename.9\n");
175 unlink("$tmpdir/$$.9");
176 }
177}
178elsif($ARGV[0] eq "install"){
179 system("mkdir -p /usr/local/man/man9/; install $ARGV[1]/*.9.gz /usr/local/man/man9/");
180}
181else{
182 die "Usage: makeman [convert | install] <dir> <file>\n";
183}
184
185print "Done\n";
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
new file mode 100755
index 000000000000..8d118d181950
--- /dev/null
+++ b/scripts/mkcompile_h
@@ -0,0 +1,78 @@
1TARGET=$1
2ARCH=$2
3SMP=$3
4CC=$4
5
6# If compile.h exists already and we don't own autoconf.h
7# (i.e. we're not the same user who did make *config), don't
8# modify compile.h
9# So "sudo make install" won't change the "compiled by <user>"
10# do "compiled by root"
11
12if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then
13 echo " SKIPPED $TARGET"
14 exit 0
15fi
16
17# Do not expand names
18set -f
19
20if [ -r .version ]; then
21 VERSION=`cat .version`
22else
23 VERSION=0
24 echo 0 > .version
25fi
26
27
28UTS_VERSION="#$VERSION"
29if [ -n "$SMP" ] ; then UTS_VERSION="$UTS_VERSION SMP"; fi
30UTS_VERSION="$UTS_VERSION `LC_ALL=C LANG=C date`"
31
32# Truncate to maximum length
33
34UTS_LEN=64
35UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
36
37# Generate a temporary compile.h
38
39( echo /\* This file is auto generated, version $VERSION \*/
40
41 echo \#define UTS_MACHINE \"$ARCH\"
42
43 echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\"
44
45 echo \#define LINUX_COMPILE_TIME \"`LC_ALL=C LANG=C date +%T`\"
46 echo \#define LINUX_COMPILE_BY \"`whoami`\"
47 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
48
49 if [ -x /bin/dnsdomainname ]; then
50 echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname | $UTS_TRUNCATE`\"
51 elif [ -x /bin/domainname ]; then
52 echo \#define LINUX_COMPILE_DOMAIN \"`domainname | $UTS_TRUNCATE`\"
53 else
54 echo \#define LINUX_COMPILE_DOMAIN
55 fi
56
57 echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\"
58) > .tmpcompile
59
60# Only replace the real compile.h if the new one is different,
61# in order to preserve the timestamp and avoid unnecessary
62# recompilations.
63# We don't consider the file changed if only the date/time changed.
64# A kernel config change will increase the generation number, thus
65# causing compile.h to be updated (including date/time) due to the
66# changed comment in the
67# first line.
68
69if [ -r $TARGET ] && \
70 grep -v 'UTS_VERSION\|LINUX_COMPILE_TIME' $TARGET > .tmpver.1 && \
71 grep -v 'UTS_VERSION\|LINUX_COMPILE_TIME' .tmpcompile > .tmpver.2 && \
72 cmp -s .tmpver.1 .tmpver.2; then
73 rm -f .tmpcompile
74else
75 echo " UPD $TARGET"
76 mv -f .tmpcompile $TARGET
77fi
78rm -f .tmpver.1 .tmpver.2
diff --git a/scripts/mkmakefile b/scripts/mkmakefile
new file mode 100644
index 000000000000..c4d621b30d0d
--- /dev/null
+++ b/scripts/mkmakefile
@@ -0,0 +1,31 @@
1#!/bin/sh
2# Generates a small Makefile used in the root of the output
3# directory, to allow make to be started from there.
4# The Makefile also allow for more convinient build of external modules
5
6# Usage
7# $1 - Kernel src directory
8# $2 - Output directory
9# $3 - version
10# $4 - patchlevel
11
12
13cat << EOF
14# Automatically generated by $0: don't edit
15
16VERSION = $3
17PATCHLEVEL = $4
18
19KERNELSRC := $1
20KERNELOUTPUT := $2
21
22MAKEFLAGS += --no-print-directory
23
24all:
25 \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT)
26
27%::
28 \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@
29
30EOF
31
diff --git a/scripts/mksysmap b/scripts/mksysmap
new file mode 100644
index 000000000000..a6430e05972d
--- /dev/null
+++ b/scripts/mksysmap
@@ -0,0 +1,44 @@
1#!/bin/sh -x
2# Based on the vmlinux file create the System.map file
3# System.map is used by module-init tools and some debugging
4# tools to retreive the actual addresses of symbols in the kernel.
5#
6# Usage
7# mksysmap vmlinux System.map
8
9
10#####
11# Generate System.map (actual filename passed as second argument)
12
13# $NM produces the following output:
14# f0081e80 T alloc_vfsmnt
15
16# The second row specify the type of the symbol:
17# A = Absolute
18# B = Uninitialised data (.bss)
19# C = Comon symbol
20# D = Initialised data
21# G = Initialised data for small objects
22# I = Indirect reference to another symbol
23# N = Debugging symbol
24# R = Read only
25# S = Uninitialised data for small objects
26# T = Text code symbol
27# U = Undefined symbol
28# V = Weak symbol
29# W = Weak symbol
30# Corresponding small letters are local symbols
31
32# For System.map filter away:
33# a - local absolute symbols
34# U - undefined global symbols
35# w - local weak symbols
36
37# readprofile starts reading symbols when _stext is found, and
38# continue until it finds a symbol which is not either of 'T', 't',
39# 'W' or 'w'. __crc_ are 'A' and placed in the middle
40# so we just ignore them to let readprofile continue to work.
41# (At least sparc64 has __crc_ in the middle).
42
43$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2
44
diff --git a/scripts/mkuboot.sh b/scripts/mkuboot.sh
new file mode 100755
index 000000000000..52a17ab97eb0
--- /dev/null
+++ b/scripts/mkuboot.sh
@@ -0,0 +1,16 @@
1#!/bin/bash
2
3#
4# Build U-Boot image when `mkimage' tool is available.
5#
6
7MKIMAGE=$(type -path mkimage)
8
9if [ -z "${MKIMAGE}" ]; then
10 # Doesn't exist
11 echo '"mkimage" command not found - U-Boot images will not be built' >&2
12 exit 0;
13fi
14
15# Call "mkimage" to create U-Boot image
16${MKIMAGE} "$@"
diff --git a/scripts/mkversion b/scripts/mkversion
new file mode 100644
index 000000000000..c12addc9c7ef
--- /dev/null
+++ b/scripts/mkversion
@@ -0,0 +1,6 @@
1if [ ! -f .version ]
2then
3 echo 1
4else
5 expr 0`cat .version` + 1
6fi
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile
new file mode 100644
index 000000000000..11d69c35e5b4
--- /dev/null
+++ b/scripts/mod/Makefile
@@ -0,0 +1,16 @@
1hostprogs-y := modpost mk_elfconfig
2always := $(hostprogs-y) empty.o
3
4modpost-objs := modpost.o file2alias.o sumversion.o
5
6# dependencies on generated files need to be listed explicitly
7
8$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h
9
10quiet_cmd_elfconfig = MKELF $@
11 cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
12
13$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
14 $(call if_changed,elfconfig)
15
16targets += elfconfig.h
diff --git a/scripts/mod/empty.c b/scripts/mod/empty.c
new file mode 100644
index 000000000000..49839cc4ff26
--- /dev/null
+++ b/scripts/mod/empty.c
@@ -0,0 +1 @@
/* empty file to figure out endianness / word size */
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
new file mode 100644
index 000000000000..d54b52d3bb6f
--- /dev/null
+++ b/scripts/mod/file2alias.c
@@ -0,0 +1,308 @@
1/* Simple code to turn various tables in an ELF file into alias definitions.
2 * This deals with kernel datastructures where they should be
3 * dealt with: in the kernel source.
4 *
5 * Copyright 2002-2003 Rusty Russell, IBM Corporation
6 * 2003 Kai Germaschewski
7 *
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 */
12
13#include "modpost.h"
14
15/* We use the ELF typedefs for kernel_ulong_t but bite the bullet and
16 * use either stdint.h or inttypes.h for the rest. */
17#if KERNEL_ELFCLASS == ELFCLASS32
18typedef Elf32_Addr kernel_ulong_t;
19#else
20typedef Elf64_Addr kernel_ulong_t;
21#endif
22#ifdef __sun__
23#include <inttypes.h>
24#else
25#include <stdint.h>
26#endif
27
28typedef uint32_t __u32;
29typedef uint16_t __u16;
30typedef unsigned char __u8;
31
32/* Big exception to the "don't include kernel headers into userspace, which
33 * even potentially has different endianness and word sizes, since
34 * we handle those differences explicitly below */
35#include "../../include/linux/mod_devicetable.h"
36
37#define ADD(str, sep, cond, field) \
38do { \
39 strcat(str, sep); \
40 if (cond) \
41 sprintf(str + strlen(str), \
42 sizeof(field) == 1 ? "%02X" : \
43 sizeof(field) == 2 ? "%04X" : \
44 sizeof(field) == 4 ? "%08X" : "", \
45 field); \
46 else \
47 sprintf(str + strlen(str), "*"); \
48} while(0)
49
50/* Looks like "usb:vNpNdlNdhNdcNdscNdpNicNiscNipN" */
51static int do_usb_entry(const char *filename,
52 struct usb_device_id *id, char *alias)
53{
54 id->match_flags = TO_NATIVE(id->match_flags);
55 id->idVendor = TO_NATIVE(id->idVendor);
56 id->idProduct = TO_NATIVE(id->idProduct);
57 id->bcdDevice_lo = TO_NATIVE(id->bcdDevice_lo);
58 id->bcdDevice_hi = TO_NATIVE(id->bcdDevice_hi);
59
60 /*
61 * Some modules (visor) have empty slots as placeholder for
62 * run-time specification that results in catch-all alias
63 */
64 if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
65 return 1;
66
67 strcpy(alias, "usb:");
68 ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR,
69 id->idVendor);
70 ADD(alias, "p", id->match_flags&USB_DEVICE_ID_MATCH_PRODUCT,
71 id->idProduct);
72 ADD(alias, "dl", id->match_flags&USB_DEVICE_ID_MATCH_DEV_LO,
73 id->bcdDevice_lo);
74 ADD(alias, "dh", id->match_flags&USB_DEVICE_ID_MATCH_DEV_HI,
75 id->bcdDevice_hi);
76 ADD(alias, "dc", id->match_flags&USB_DEVICE_ID_MATCH_DEV_CLASS,
77 id->bDeviceClass);
78 ADD(alias, "dsc",
79 id->match_flags&USB_DEVICE_ID_MATCH_DEV_SUBCLASS,
80 id->bDeviceSubClass);
81 ADD(alias, "dp",
82 id->match_flags&USB_DEVICE_ID_MATCH_DEV_PROTOCOL,
83 id->bDeviceProtocol);
84 ADD(alias, "ic",
85 id->match_flags&USB_DEVICE_ID_MATCH_INT_CLASS,
86 id->bInterfaceClass);
87 ADD(alias, "isc",
88 id->match_flags&USB_DEVICE_ID_MATCH_INT_SUBCLASS,
89 id->bInterfaceSubClass);
90 ADD(alias, "ip",
91 id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
92 id->bInterfaceProtocol);
93 return 1;
94}
95
96/* Looks like: ieee1394:venNmoNspNverN */
97static int do_ieee1394_entry(const char *filename,
98 struct ieee1394_device_id *id, char *alias)
99{
100 id->match_flags = TO_NATIVE(id->match_flags);
101 id->vendor_id = TO_NATIVE(id->vendor_id);
102 id->model_id = TO_NATIVE(id->model_id);
103 id->specifier_id = TO_NATIVE(id->specifier_id);
104 id->version = TO_NATIVE(id->version);
105
106 strcpy(alias, "ieee1394:");
107 ADD(alias, "ven", id->match_flags & IEEE1394_MATCH_VENDOR_ID,
108 id->vendor_id);
109 ADD(alias, "mo", id->match_flags & IEEE1394_MATCH_MODEL_ID,
110 id->model_id);
111 ADD(alias, "sp", id->match_flags & IEEE1394_MATCH_SPECIFIER_ID,
112 id->specifier_id);
113 ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION,
114 id->version);
115
116 return 1;
117}
118
119/* Looks like: pci:vNdNsvNsdNbcNscNiN. */
120static int do_pci_entry(const char *filename,
121 struct pci_device_id *id, char *alias)
122{
123 /* Class field can be divided into these three. */
124 unsigned char baseclass, subclass, interface,
125 baseclass_mask, subclass_mask, interface_mask;
126
127 id->vendor = TO_NATIVE(id->vendor);
128 id->device = TO_NATIVE(id->device);
129 id->subvendor = TO_NATIVE(id->subvendor);
130 id->subdevice = TO_NATIVE(id->subdevice);
131 id->class = TO_NATIVE(id->class);
132 id->class_mask = TO_NATIVE(id->class_mask);
133
134 strcpy(alias, "pci:");
135 ADD(alias, "v", id->vendor != PCI_ANY_ID, id->vendor);
136 ADD(alias, "d", id->device != PCI_ANY_ID, id->device);
137 ADD(alias, "sv", id->subvendor != PCI_ANY_ID, id->subvendor);
138 ADD(alias, "sd", id->subdevice != PCI_ANY_ID, id->subdevice);
139
140 baseclass = (id->class) >> 16;
141 baseclass_mask = (id->class_mask) >> 16;
142 subclass = (id->class) >> 8;
143 subclass_mask = (id->class_mask) >> 8;
144 interface = id->class;
145 interface_mask = id->class_mask;
146
147 if ((baseclass_mask != 0 && baseclass_mask != 0xFF)
148 || (subclass_mask != 0 && subclass_mask != 0xFF)
149 || (interface_mask != 0 && interface_mask != 0xFF)) {
150 fprintf(stderr,
151 "*** Warning: Can't handle masks in %s:%04X\n",
152 filename, id->class_mask);
153 return 0;
154 }
155
156 ADD(alias, "bc", baseclass_mask == 0xFF, baseclass);
157 ADD(alias, "sc", subclass_mask == 0xFF, subclass);
158 ADD(alias, "i", interface_mask == 0xFF, interface);
159 return 1;
160}
161
162/* looks like: "ccw:tNmNdtNdmN" */
163static int do_ccw_entry(const char *filename,
164 struct ccw_device_id *id, char *alias)
165{
166 id->match_flags = TO_NATIVE(id->match_flags);
167 id->cu_type = TO_NATIVE(id->cu_type);
168 id->cu_model = TO_NATIVE(id->cu_model);
169 id->dev_type = TO_NATIVE(id->dev_type);
170 id->dev_model = TO_NATIVE(id->dev_model);
171
172 strcpy(alias, "ccw:");
173 ADD(alias, "t", id->match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE,
174 id->cu_type);
175 ADD(alias, "m", id->match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL,
176 id->cu_model);
177 ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE,
178 id->dev_type);
179 ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE,
180 id->dev_model);
181 return 1;
182}
183
184/* Looks like: "serio:tyNprNidNexN" */
185static int do_serio_entry(const char *filename,
186 struct serio_device_id *id, char *alias)
187{
188 id->type = TO_NATIVE(id->type);
189 id->proto = TO_NATIVE(id->proto);
190 id->id = TO_NATIVE(id->id);
191 id->extra = TO_NATIVE(id->extra);
192
193 strcpy(alias, "serio:");
194 ADD(alias, "ty", id->type != SERIO_ANY, id->type);
195 ADD(alias, "pr", id->proto != SERIO_ANY, id->proto);
196 ADD(alias, "id", id->id != SERIO_ANY, id->id);
197 ADD(alias, "ex", id->extra != SERIO_ANY, id->extra);
198
199 return 1;
200}
201
202/* looks like: "pnp:dD" */
203static int do_pnp_entry(const char *filename,
204 struct pnp_device_id *id, char *alias)
205{
206 sprintf(alias, "pnp:d%s", id->id);
207 return 1;
208}
209
210/* looks like: "pnp:cCdD..." */
211static int do_pnp_card_entry(const char *filename,
212 struct pnp_card_device_id *id, char *alias)
213{
214 int i;
215
216 sprintf(alias, "pnp:c%s", id->id);
217 for (i = 0; i < PNP_MAX_DEVICES; i++) {
218 if (! *id->devs[i].id)
219 break;
220 sprintf(alias + strlen(alias), "d%s", id->devs[i].id);
221 }
222 return 1;
223}
224
225/* Ignore any prefix, eg. v850 prepends _ */
226static inline int sym_is(const char *symbol, const char *name)
227{
228 const char *match;
229
230 match = strstr(symbol, name);
231 if (!match)
232 return 0;
233 return match[strlen(symbol)] == '\0';
234}
235
236static void do_table(void *symval, unsigned long size,
237 unsigned long id_size,
238 void *function,
239 struct module *mod)
240{
241 unsigned int i;
242 char alias[500];
243 int (*do_entry)(const char *, void *entry, char *alias) = function;
244
245 if (size % id_size || size < id_size) {
246 fprintf(stderr, "*** Warning: %s ids %lu bad size "
247 "(each on %lu)\n", mod->name, size, id_size);
248 }
249 /* Leave last one: it's the terminator. */
250 size -= id_size;
251
252 for (i = 0; i < size; i += id_size) {
253 if (do_entry(mod->name, symval+i, alias)) {
254 /* Always end in a wildcard, for future extension */
255 if (alias[strlen(alias)-1] != '*')
256 strcat(alias, "*");
257 buf_printf(&mod->dev_table_buf,
258 "MODULE_ALIAS(\"%s\");\n", alias);
259 }
260 }
261}
262
263/* Create MODULE_ALIAS() statements.
264 * At this time, we cannot write the actual output C source yet,
265 * so we write into the mod->dev_table_buf buffer. */
266void handle_moddevtable(struct module *mod, struct elf_info *info,
267 Elf_Sym *sym, const char *symname)
268{
269 void *symval;
270
271 /* We're looking for a section relative symbol */
272 if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
273 return;
274
275 symval = (void *)info->hdr
276 + info->sechdrs[sym->st_shndx].sh_offset
277 + sym->st_value;
278
279 if (sym_is(symname, "__mod_pci_device_table"))
280 do_table(symval, sym->st_size, sizeof(struct pci_device_id),
281 do_pci_entry, mod);
282 else if (sym_is(symname, "__mod_usb_device_table"))
283 do_table(symval, sym->st_size, sizeof(struct usb_device_id),
284 do_usb_entry, mod);
285 else if (sym_is(symname, "__mod_ieee1394_device_table"))
286 do_table(symval, sym->st_size, sizeof(struct ieee1394_device_id),
287 do_ieee1394_entry, mod);
288 else if (sym_is(symname, "__mod_ccw_device_table"))
289 do_table(symval, sym->st_size, sizeof(struct ccw_device_id),
290 do_ccw_entry, mod);
291 else if (sym_is(symname, "__mod_serio_device_table"))
292 do_table(symval, sym->st_size, sizeof(struct serio_device_id),
293 do_serio_entry, mod);
294 else if (sym_is(symname, "__mod_pnp_device_table"))
295 do_table(symval, sym->st_size, sizeof(struct pnp_device_id),
296 do_pnp_entry, mod);
297 else if (sym_is(symname, "__mod_pnp_card_device_table"))
298 do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id),
299 do_pnp_card_entry, mod);
300}
301
302/* Now add out buffered information to the generated C source */
303void add_moddevtable(struct buffer *buf, struct module *mod)
304{
305 buf_printf(buf, "\n");
306 buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos);
307 free(mod->dev_table_buf.p);
308}
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c
new file mode 100644
index 000000000000..de2aabf89fb3
--- /dev/null
+++ b/scripts/mod/mk_elfconfig.c
@@ -0,0 +1,65 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <elf.h>
5
6int
7main(int argc, char **argv)
8{
9 unsigned char ei[EI_NIDENT];
10 union { short s; char c[2]; } endian_test;
11
12 if (argc != 2) {
13 fprintf(stderr, "Error: no arch\n");
14 }
15 if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
16 fprintf(stderr, "Error: input truncated\n");
17 return 1;
18 }
19 if (memcmp(ei, ELFMAG, SELFMAG) != 0) {
20 fprintf(stderr, "Error: not ELF\n");
21 return 1;
22 }
23 switch (ei[EI_CLASS]) {
24 case ELFCLASS32:
25 printf("#define KERNEL_ELFCLASS ELFCLASS32\n");
26 break;
27 case ELFCLASS64:
28 printf("#define KERNEL_ELFCLASS ELFCLASS64\n");
29 break;
30 default:
31 abort();
32 }
33 switch (ei[EI_DATA]) {
34 case ELFDATA2LSB:
35 printf("#define KERNEL_ELFDATA ELFDATA2LSB\n");
36 break;
37 case ELFDATA2MSB:
38 printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
39 break;
40 default:
41 abort();
42 }
43
44 if (sizeof(unsigned long) == 4) {
45 printf("#define HOST_ELFCLASS ELFCLASS32\n");
46 } else if (sizeof(unsigned long) == 8) {
47 printf("#define HOST_ELFCLASS ELFCLASS64\n");
48 }
49
50 endian_test.s = 0x0102;
51 if (memcmp(endian_test.c, "\x01\x02", 2) == 0)
52 printf("#define HOST_ELFDATA ELFDATA2MSB\n");
53 else if (memcmp(endian_test.c, "\x02\x01", 2) == 0)
54 printf("#define HOST_ELFDATA ELFDATA2LSB\n");
55 else
56 abort();
57
58 if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0))
59 printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
60 else
61 printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
62
63 return 0;
64}
65
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
new file mode 100644
index 000000000000..9b9f94c915d2
--- /dev/null
+++ b/scripts/mod/modpost.c
@@ -0,0 +1,797 @@
1/* Postprocess module symbol versions
2 *
3 * Copyright 2003 Kai Germaschewski
4 * Copyright 2002-2004 Rusty Russell, IBM Corporation
5 *
6 * Based in part on module-init-tools/depmod.c,file2alias
7 *
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
10 *
11 * Usage: modpost vmlinux module1.o module2.o ...
12 */
13
14#include <ctype.h>
15#include "modpost.h"
16
17/* Are we using CONFIG_MODVERSIONS? */
18int modversions = 0;
19/* Warn about undefined symbols? (do so if we have vmlinux) */
20int have_vmlinux = 0;
21/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
22static int all_versions = 0;
23
24void
25fatal(const char *fmt, ...)
26{
27 va_list arglist;
28
29 fprintf(stderr, "FATAL: ");
30
31 va_start(arglist, fmt);
32 vfprintf(stderr, fmt, arglist);
33 va_end(arglist);
34
35 exit(1);
36}
37
38void
39warn(const char *fmt, ...)
40{
41 va_list arglist;
42
43 fprintf(stderr, "WARNING: ");
44
45 va_start(arglist, fmt);
46 vfprintf(stderr, fmt, arglist);
47 va_end(arglist);
48}
49
50void *do_nofail(void *ptr, const char *expr)
51{
52 if (!ptr) {
53 fatal("modpost: Memory allocation failure: %s.\n", expr);
54 }
55 return ptr;
56}
57
58/* A list of all modules we processed */
59
60static struct module *modules;
61
62struct module *
63find_module(char *modname)
64{
65 struct module *mod;
66
67 for (mod = modules; mod; mod = mod->next)
68 if (strcmp(mod->name, modname) == 0)
69 break;
70 return mod;
71}
72
73struct module *
74new_module(char *modname)
75{
76 struct module *mod;
77 char *p, *s;
78
79 mod = NOFAIL(malloc(sizeof(*mod)));
80 memset(mod, 0, sizeof(*mod));
81 p = NOFAIL(strdup(modname));
82
83 /* strip trailing .o */
84 if ((s = strrchr(p, '.')) != NULL)
85 if (strcmp(s, ".o") == 0)
86 *s = '\0';
87
88 /* add to list */
89 mod->name = p;
90 mod->next = modules;
91 modules = mod;
92
93 return mod;
94}
95
96/* A hash of all exported symbols,
97 * struct symbol is also used for lists of unresolved symbols */
98
99#define SYMBOL_HASH_SIZE 1024
100
101struct symbol {
102 struct symbol *next;
103 struct module *module;
104 unsigned int crc;
105 int crc_valid;
106 unsigned int weak:1;
107 char name[0];
108};
109
110static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
111
112/* This is based on the hash agorithm from gdbm, via tdb */
113static inline unsigned int tdb_hash(const char *name)
114{
115 unsigned value; /* Used to compute the hash value. */
116 unsigned i; /* Used to cycle through random values. */
117
118 /* Set the initial value from the key size. */
119 for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
120 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
121
122 return (1103515243 * value + 12345);
123}
124
125/* Allocate a new symbols for use in the hash of exported symbols or
126 * the list of unresolved symbols per module */
127
128struct symbol *
129alloc_symbol(const char *name, unsigned int weak, struct symbol *next)
130{
131 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
132
133 memset(s, 0, sizeof(*s));
134 strcpy(s->name, name);
135 s->weak = weak;
136 s->next = next;
137 return s;
138}
139
140/* For the hash of exported symbols */
141
142void
143new_symbol(const char *name, struct module *module, unsigned int *crc)
144{
145 unsigned int hash;
146 struct symbol *new;
147
148 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
149 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
150 new->module = module;
151 if (crc) {
152 new->crc = *crc;
153 new->crc_valid = 1;
154 }
155}
156
157struct symbol *
158find_symbol(const char *name)
159{
160 struct symbol *s;
161
162 /* For our purposes, .foo matches foo. PPC64 needs this. */
163 if (name[0] == '.')
164 name++;
165
166 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
167 if (strcmp(s->name, name) == 0)
168 return s;
169 }
170 return NULL;
171}
172
173/* Add an exported symbol - it may have already been added without a
174 * CRC, in this case just update the CRC */
175void
176add_exported_symbol(const char *name, struct module *module, unsigned int *crc)
177{
178 struct symbol *s = find_symbol(name);
179
180 if (!s) {
181 new_symbol(name, module, crc);
182 return;
183 }
184 if (crc) {
185 s->crc = *crc;
186 s->crc_valid = 1;
187 }
188}
189
190void *
191grab_file(const char *filename, unsigned long *size)
192{
193 struct stat st;
194 void *map;
195 int fd;
196
197 fd = open(filename, O_RDONLY);
198 if (fd < 0 || fstat(fd, &st) != 0)
199 return NULL;
200
201 *size = st.st_size;
202 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
203 close(fd);
204
205 if (map == MAP_FAILED)
206 return NULL;
207 return map;
208}
209
210/*
211 Return a copy of the next line in a mmap'ed file.
212 spaces in the beginning of the line is trimmed away.
213 Return a pointer to a static buffer.
214*/
215char*
216get_next_line(unsigned long *pos, void *file, unsigned long size)
217{
218 static char line[4096];
219 int skip = 1;
220 size_t len = 0;
221 signed char *p = (signed char *)file + *pos;
222 char *s = line;
223
224 for (; *pos < size ; (*pos)++)
225 {
226 if (skip && isspace(*p)) {
227 p++;
228 continue;
229 }
230 skip = 0;
231 if (*p != '\n' && (*pos < size)) {
232 len++;
233 *s++ = *p++;
234 if (len > 4095)
235 break; /* Too long, stop */
236 } else {
237 /* End of string */
238 *s = '\0';
239 return line;
240 }
241 }
242 /* End of buffer */
243 return NULL;
244}
245
246void
247release_file(void *file, unsigned long size)
248{
249 munmap(file, size);
250}
251
252void
253parse_elf(struct elf_info *info, const char *filename)
254{
255 unsigned int i;
256 Elf_Ehdr *hdr = info->hdr;
257 Elf_Shdr *sechdrs;
258 Elf_Sym *sym;
259
260 hdr = grab_file(filename, &info->size);
261 if (!hdr) {
262 perror(filename);
263 abort();
264 }
265 info->hdr = hdr;
266 if (info->size < sizeof(*hdr))
267 goto truncated;
268
269 /* Fix endianness in ELF header */
270 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
271 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
272 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
273 hdr->e_machine = TO_NATIVE(hdr->e_machine);
274 sechdrs = (void *)hdr + hdr->e_shoff;
275 info->sechdrs = sechdrs;
276
277 /* Fix endianness in section headers */
278 for (i = 0; i < hdr->e_shnum; i++) {
279 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
280 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
281 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
282 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
283 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
284 }
285 /* Find symbol table. */
286 for (i = 1; i < hdr->e_shnum; i++) {
287 const char *secstrings
288 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
289
290 if (sechdrs[i].sh_offset > info->size)
291 goto truncated;
292 if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) {
293 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
294 info->modinfo_len = sechdrs[i].sh_size;
295 }
296 if (sechdrs[i].sh_type != SHT_SYMTAB)
297 continue;
298
299 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
300 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
301 + sechdrs[i].sh_size;
302 info->strtab = (void *)hdr +
303 sechdrs[sechdrs[i].sh_link].sh_offset;
304 }
305 if (!info->symtab_start) {
306 fprintf(stderr, "modpost: %s no symtab?\n", filename);
307 abort();
308 }
309 /* Fix endianness in symbols */
310 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
311 sym->st_shndx = TO_NATIVE(sym->st_shndx);
312 sym->st_name = TO_NATIVE(sym->st_name);
313 sym->st_value = TO_NATIVE(sym->st_value);
314 sym->st_size = TO_NATIVE(sym->st_size);
315 }
316 return;
317
318 truncated:
319 fprintf(stderr, "modpost: %s is truncated.\n", filename);
320 abort();
321}
322
323void
324parse_elf_finish(struct elf_info *info)
325{
326 release_file(info->hdr, info->size);
327}
328
329#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
330#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
331
332void
333handle_modversions(struct module *mod, struct elf_info *info,
334 Elf_Sym *sym, const char *symname)
335{
336 unsigned int crc;
337
338 switch (sym->st_shndx) {
339 case SHN_COMMON:
340 fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n",
341 symname, mod->name);
342 break;
343 case SHN_ABS:
344 /* CRC'd symbol */
345 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
346 crc = (unsigned int) sym->st_value;
347 add_exported_symbol(symname + strlen(CRC_PFX),
348 mod, &crc);
349 }
350 break;
351 case SHN_UNDEF:
352 /* undefined symbol */
353 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
354 ELF_ST_BIND(sym->st_info) != STB_WEAK)
355 break;
356 /* ignore global offset table */
357 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
358 break;
359 /* ignore __this_module, it will be resolved shortly */
360 if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
361 break;
362#ifdef STT_REGISTER
363 if (info->hdr->e_machine == EM_SPARC ||
364 info->hdr->e_machine == EM_SPARCV9) {
365 /* Ignore register directives. */
366 if (ELF_ST_TYPE(sym->st_info) == STT_REGISTER)
367 break;
368 }
369#endif
370
371 if (memcmp(symname, MODULE_SYMBOL_PREFIX,
372 strlen(MODULE_SYMBOL_PREFIX)) == 0)
373 mod->unres = alloc_symbol(symname +
374 strlen(MODULE_SYMBOL_PREFIX),
375 ELF_ST_BIND(sym->st_info) == STB_WEAK,
376 mod->unres);
377 break;
378 default:
379 /* All exported symbols */
380 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
381 add_exported_symbol(symname + strlen(KSYMTAB_PFX),
382 mod, NULL);
383 }
384 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
385 mod->has_init = 1;
386 if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)
387 mod->has_cleanup = 1;
388 break;
389 }
390}
391
392int
393is_vmlinux(const char *modname)
394{
395 const char *myname;
396
397 if ((myname = strrchr(modname, '/')))
398 myname++;
399 else
400 myname = modname;
401
402 return strcmp(myname, "vmlinux") == 0;
403}
404
405/* Parse tag=value strings from .modinfo section */
406static char *next_string(char *string, unsigned long *secsize)
407{
408 /* Skip non-zero chars */
409 while (string[0]) {
410 string++;
411 if ((*secsize)-- <= 1)
412 return NULL;
413 }
414
415 /* Skip any zero padding. */
416 while (!string[0]) {
417 string++;
418 if ((*secsize)-- <= 1)
419 return NULL;
420 }
421 return string;
422}
423
424static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
425 const char *tag)
426{
427 char *p;
428 unsigned int taglen = strlen(tag);
429 unsigned long size = modinfo_len;
430
431 for (p = modinfo; p; p = next_string(p, &size)) {
432 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
433 return p + taglen + 1;
434 }
435 return NULL;
436}
437
438void
439read_symbols(char *modname)
440{
441 const char *symname;
442 char *version;
443 struct module *mod;
444 struct elf_info info = { };
445 Elf_Sym *sym;
446
447 parse_elf(&info, modname);
448
449 mod = new_module(modname);
450
451 /* When there's no vmlinux, don't print warnings about
452 * unresolved symbols (since there'll be too many ;) */
453 if (is_vmlinux(modname)) {
454 unsigned int fake_crc = 0;
455 have_vmlinux = 1;
456 add_exported_symbol("struct_module", mod, &fake_crc);
457 mod->skip = 1;
458 }
459
460 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
461 symname = info.strtab + sym->st_name;
462
463 handle_modversions(mod, &info, sym, symname);
464 handle_moddevtable(mod, &info, sym, symname);
465 }
466
467 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
468 if (version)
469 maybe_frob_rcs_version(modname, version, info.modinfo,
470 version - (char *)info.hdr);
471 if (version || (all_versions && !is_vmlinux(modname)))
472 get_src_version(modname, mod->srcversion,
473 sizeof(mod->srcversion)-1);
474
475 parse_elf_finish(&info);
476
477 /* Our trick to get versioning for struct_module - it's
478 * never passed as an argument to an exported function, so
479 * the automatic versioning doesn't pick it up, but it's really
480 * important anyhow */
481 if (modversions)
482 mod->unres = alloc_symbol("struct_module", 0, mod->unres);
483}
484
485#define SZ 500
486
487/* We first write the generated file into memory using the
488 * following helper, then compare to the file on disk and
489 * only update the later if anything changed */
490
491void __attribute__((format(printf, 2, 3)))
492buf_printf(struct buffer *buf, const char *fmt, ...)
493{
494 char tmp[SZ];
495 int len;
496 va_list ap;
497
498 va_start(ap, fmt);
499 len = vsnprintf(tmp, SZ, fmt, ap);
500 if (buf->size - buf->pos < len + 1) {
501 buf->size += 128;
502 buf->p = realloc(buf->p, buf->size);
503 }
504 strncpy(buf->p + buf->pos, tmp, len + 1);
505 buf->pos += len;
506 va_end(ap);
507}
508
509void
510buf_write(struct buffer *buf, const char *s, int len)
511{
512 if (buf->size - buf->pos < len) {
513 buf->size += len;
514 buf->p = realloc(buf->p, buf->size);
515 }
516 strncpy(buf->p + buf->pos, s, len);
517 buf->pos += len;
518}
519
520/* Header for the generated file */
521
522void
523add_header(struct buffer *b, struct module *mod)
524{
525 buf_printf(b, "#include <linux/module.h>\n");
526 buf_printf(b, "#include <linux/vermagic.h>\n");
527 buf_printf(b, "#include <linux/compiler.h>\n");
528 buf_printf(b, "\n");
529 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
530 buf_printf(b, "\n");
531 buf_printf(b, "#undef unix\n"); /* We have a module called "unix" */
532 buf_printf(b, "struct module __this_module\n");
533 buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
534 buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n");
535 if (mod->has_init)
536 buf_printf(b, " .init = init_module,\n");
537 if (mod->has_cleanup)
538 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
539 " .exit = cleanup_module,\n"
540 "#endif\n");
541 buf_printf(b, "};\n");
542}
543
544/* Record CRCs for unresolved symbols */
545
546void
547add_versions(struct buffer *b, struct module *mod)
548{
549 struct symbol *s, *exp;
550
551 for (s = mod->unres; s; s = s->next) {
552 exp = find_symbol(s->name);
553 if (!exp || exp->module == mod) {
554 if (have_vmlinux && !s->weak)
555 fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
556 "undefined!\n", s->name, mod->name);
557 continue;
558 }
559 s->module = exp->module;
560 s->crc_valid = exp->crc_valid;
561 s->crc = exp->crc;
562 }
563
564 if (!modversions)
565 return;
566
567 buf_printf(b, "\n");
568 buf_printf(b, "static const struct modversion_info ____versions[]\n");
569 buf_printf(b, "__attribute_used__\n");
570 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");
571
572 for (s = mod->unres; s; s = s->next) {
573 if (!s->module) {
574 continue;
575 }
576 if (!s->crc_valid) {
577 fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
578 "has no CRC!\n",
579 s->name, mod->name);
580 continue;
581 }
582 buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name);
583 }
584
585 buf_printf(b, "};\n");
586}
587
588void
589add_depends(struct buffer *b, struct module *mod, struct module *modules)
590{
591 struct symbol *s;
592 struct module *m;
593 int first = 1;
594
595 for (m = modules; m; m = m->next) {
596 m->seen = is_vmlinux(m->name);
597 }
598
599 buf_printf(b, "\n");
600 buf_printf(b, "static const char __module_depends[]\n");
601 buf_printf(b, "__attribute_used__\n");
602 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
603 buf_printf(b, "\"depends=");
604 for (s = mod->unres; s; s = s->next) {
605 if (!s->module)
606 continue;
607
608 if (s->module->seen)
609 continue;
610
611 s->module->seen = 1;
612 buf_printf(b, "%s%s", first ? "" : ",",
613 strrchr(s->module->name, '/') + 1);
614 first = 0;
615 }
616 buf_printf(b, "\";\n");
617}
618
619void
620add_srcversion(struct buffer *b, struct module *mod)
621{
622 if (mod->srcversion[0]) {
623 buf_printf(b, "\n");
624 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
625 mod->srcversion);
626 }
627}
628
629void
630write_if_changed(struct buffer *b, const char *fname)
631{
632 char *tmp;
633 FILE *file;
634 struct stat st;
635
636 file = fopen(fname, "r");
637 if (!file)
638 goto write;
639
640 if (fstat(fileno(file), &st) < 0)
641 goto close_write;
642
643 if (st.st_size != b->pos)
644 goto close_write;
645
646 tmp = NOFAIL(malloc(b->pos));
647 if (fread(tmp, 1, b->pos, file) != b->pos)
648 goto free_write;
649
650 if (memcmp(tmp, b->p, b->pos) != 0)
651 goto free_write;
652
653 free(tmp);
654 fclose(file);
655 return;
656
657 free_write:
658 free(tmp);
659 close_write:
660 fclose(file);
661 write:
662 file = fopen(fname, "w");
663 if (!file) {
664 perror(fname);
665 exit(1);
666 }
667 if (fwrite(b->p, 1, b->pos, file) != b->pos) {
668 perror(fname);
669 exit(1);
670 }
671 fclose(file);
672}
673
674void
675read_dump(const char *fname)
676{
677 unsigned long size, pos = 0;
678 void *file = grab_file(fname, &size);
679 char *line;
680
681 if (!file)
682 /* No symbol versions, silently ignore */
683 return;
684
685 while ((line = get_next_line(&pos, file, size))) {
686 char *symname, *modname, *d;
687 unsigned int crc;
688 struct module *mod;
689
690 if (!(symname = strchr(line, '\t')))
691 goto fail;
692 *symname++ = '\0';
693 if (!(modname = strchr(symname, '\t')))
694 goto fail;
695 *modname++ = '\0';
696 if (strchr(modname, '\t'))
697 goto fail;
698 crc = strtoul(line, &d, 16);
699 if (*symname == '\0' || *modname == '\0' || *d != '\0')
700 goto fail;
701
702 if (!(mod = find_module(modname))) {
703 if (is_vmlinux(modname)) {
704 have_vmlinux = 1;
705 }
706 mod = new_module(NOFAIL(strdup(modname)));
707 mod->skip = 1;
708 }
709 add_exported_symbol(symname, mod, &crc);
710 }
711 return;
712fail:
713 fatal("parse error in symbol dump file\n");
714}
715
716void
717write_dump(const char *fname)
718{
719 struct buffer buf = { };
720 struct symbol *symbol;
721 int n;
722
723 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
724 symbol = symbolhash[n];
725 while (symbol) {
726 symbol = symbol->next;
727 }
728 }
729
730 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
731 symbol = symbolhash[n];
732 while (symbol) {
733 buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc,
734 symbol->name, symbol->module->name);
735 symbol = symbol->next;
736 }
737 }
738 write_if_changed(&buf, fname);
739}
740
741int
742main(int argc, char **argv)
743{
744 struct module *mod;
745 struct buffer buf = { };
746 char fname[SZ];
747 char *dump_read = NULL, *dump_write = NULL;
748 int opt;
749
750 while ((opt = getopt(argc, argv, "i:mo:a")) != -1) {
751 switch(opt) {
752 case 'i':
753 dump_read = optarg;
754 break;
755 case 'm':
756 modversions = 1;
757 break;
758 case 'o':
759 dump_write = optarg;
760 break;
761 case 'a':
762 all_versions = 1;
763 break;
764 default:
765 exit(1);
766 }
767 }
768
769 if (dump_read)
770 read_dump(dump_read);
771
772 while (optind < argc) {
773 read_symbols(argv[optind++]);
774 }
775
776 for (mod = modules; mod; mod = mod->next) {
777 if (mod->skip)
778 continue;
779
780 buf.pos = 0;
781
782 add_header(&buf, mod);
783 add_versions(&buf, mod);
784 add_depends(&buf, mod, modules);
785 add_moddevtable(&buf, mod);
786 add_srcversion(&buf, mod);
787
788 sprintf(fname, "%s.mod.c", mod->name);
789 write_if_changed(&buf, fname);
790 }
791
792 if (dump_write)
793 write_dump(dump_write);
794
795 return 0;
796}
797
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
new file mode 100644
index 000000000000..7334d839145d
--- /dev/null
+++ b/scripts/mod/modpost.h
@@ -0,0 +1,107 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <stdarg.h>
4#include <string.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/mman.h>
8#include <fcntl.h>
9#include <unistd.h>
10#include <elf.h>
11
12#include "elfconfig.h"
13
14#if KERNEL_ELFCLASS == ELFCLASS32
15
16#define Elf_Ehdr Elf32_Ehdr
17#define Elf_Shdr Elf32_Shdr
18#define Elf_Sym Elf32_Sym
19#define ELF_ST_BIND ELF32_ST_BIND
20#define ELF_ST_TYPE ELF32_ST_TYPE
21
22#else
23
24#define Elf_Ehdr Elf64_Ehdr
25#define Elf_Shdr Elf64_Shdr
26#define Elf_Sym Elf64_Sym
27#define ELF_ST_BIND ELF64_ST_BIND
28#define ELF_ST_TYPE ELF64_ST_TYPE
29
30#endif
31
32#if KERNEL_ELFDATA != HOST_ELFDATA
33
34static inline void __endian(const void *src, void *dest, unsigned int size)
35{
36 unsigned int i;
37 for (i = 0; i < size; i++)
38 ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
39}
40
41
42
43#define TO_NATIVE(x) \
44({ \
45 typeof(x) __x; \
46 __endian(&(x), &(__x), sizeof(__x)); \
47 __x; \
48})
49
50#else /* endianness matches */
51
52#define TO_NATIVE(x) (x)
53
54#endif
55
56#define NOFAIL(ptr) do_nofail((ptr), #ptr)
57void *do_nofail(void *ptr, const char *expr);
58
59struct buffer {
60 char *p;
61 int pos;
62 int size;
63};
64
65void __attribute__((format(printf, 2, 3)))
66buf_printf(struct buffer *buf, const char *fmt, ...);
67
68void
69buf_write(struct buffer *buf, const char *s, int len);
70
71struct module {
72 struct module *next;
73 const char *name;
74 struct symbol *unres;
75 int seen;
76 int skip;
77 int has_init;
78 int has_cleanup;
79 struct buffer dev_table_buf;
80 char srcversion[25];
81};
82
83struct elf_info {
84 unsigned long size;
85 Elf_Ehdr *hdr;
86 Elf_Shdr *sechdrs;
87 Elf_Sym *symtab_start;
88 Elf_Sym *symtab_stop;
89 const char *strtab;
90 char *modinfo;
91 unsigned int modinfo_len;
92};
93
94void handle_moddevtable(struct module *mod, struct elf_info *info,
95 Elf_Sym *sym, const char *symname);
96
97void add_moddevtable(struct buffer *buf, struct module *mod);
98
99void maybe_frob_rcs_version(const char *modfilename,
100 char *version,
101 void *modinfo,
102 unsigned long modinfo_offset);
103void get_src_version(const char *modname, char sum[], unsigned sumlen);
104
105void *grab_file(const char *filename, unsigned long *size);
106char* get_next_line(unsigned long *pos, void *file, unsigned long size);
107void release_file(void *file, unsigned long size);
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c
new file mode 100644
index 000000000000..1112347245c0
--- /dev/null
+++ b/scripts/mod/sumversion.c
@@ -0,0 +1,498 @@
1#include <netinet/in.h>
2#ifdef __sun__
3#include <inttypes.h>
4#else
5#include <stdint.h>
6#endif
7#include <ctype.h>
8#include <errno.h>
9#include <string.h>
10#include "modpost.h"
11
12/*
13 * Stolen form Cryptographic API.
14 *
15 * MD4 Message Digest Algorithm (RFC1320).
16 *
17 * Implementation derived from Andrew Tridgell and Steve French's
18 * CIFS MD4 implementation, and the cryptoapi implementation
19 * originally based on the public domain implementation written
20 * by Colin Plumb in 1993.
21 *
22 * Copyright (c) Andrew Tridgell 1997-1998.
23 * Modified by Steve French (sfrench@us.ibm.com) 2002
24 * Copyright (c) Cryptoapi developers.
25 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
26 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
27 *
28 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation; either version 2 of the License, or
31 * (at your option) any later version.
32 *
33 */
34#define MD4_DIGEST_SIZE 16
35#define MD4_HMAC_BLOCK_SIZE 64
36#define MD4_BLOCK_WORDS 16
37#define MD4_HASH_WORDS 4
38
39struct md4_ctx {
40 uint32_t hash[MD4_HASH_WORDS];
41 uint32_t block[MD4_BLOCK_WORDS];
42 uint64_t byte_count;
43};
44
45static inline uint32_t lshift(uint32_t x, unsigned int s)
46{
47 x &= 0xFFFFFFFF;
48 return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
49}
50
51static inline uint32_t F(uint32_t x, uint32_t y, uint32_t z)
52{
53 return (x & y) | ((~x) & z);
54}
55
56static inline uint32_t G(uint32_t x, uint32_t y, uint32_t z)
57{
58 return (x & y) | (x & z) | (y & z);
59}
60
61static inline uint32_t H(uint32_t x, uint32_t y, uint32_t z)
62{
63 return x ^ y ^ z;
64}
65
66#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
67#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (uint32_t)0x5A827999,s))
68#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (uint32_t)0x6ED9EBA1,s))
69
70/* XXX: this stuff can be optimized */
71static inline void le32_to_cpu_array(uint32_t *buf, unsigned int words)
72{
73 while (words--) {
74 *buf = ntohl(*buf);
75 buf++;
76 }
77}
78
79static inline void cpu_to_le32_array(uint32_t *buf, unsigned int words)
80{
81 while (words--) {
82 *buf = htonl(*buf);
83 buf++;
84 }
85}
86
87static void md4_transform(uint32_t *hash, uint32_t const *in)
88{
89 uint32_t a, b, c, d;
90
91 a = hash[0];
92 b = hash[1];
93 c = hash[2];
94 d = hash[3];
95
96 ROUND1(a, b, c, d, in[0], 3);
97 ROUND1(d, a, b, c, in[1], 7);
98 ROUND1(c, d, a, b, in[2], 11);
99 ROUND1(b, c, d, a, in[3], 19);
100 ROUND1(a, b, c, d, in[4], 3);
101 ROUND1(d, a, b, c, in[5], 7);
102 ROUND1(c, d, a, b, in[6], 11);
103 ROUND1(b, c, d, a, in[7], 19);
104 ROUND1(a, b, c, d, in[8], 3);
105 ROUND1(d, a, b, c, in[9], 7);
106 ROUND1(c, d, a, b, in[10], 11);
107 ROUND1(b, c, d, a, in[11], 19);
108 ROUND1(a, b, c, d, in[12], 3);
109 ROUND1(d, a, b, c, in[13], 7);
110 ROUND1(c, d, a, b, in[14], 11);
111 ROUND1(b, c, d, a, in[15], 19);
112
113 ROUND2(a, b, c, d,in[ 0], 3);
114 ROUND2(d, a, b, c, in[4], 5);
115 ROUND2(c, d, a, b, in[8], 9);
116 ROUND2(b, c, d, a, in[12], 13);
117 ROUND2(a, b, c, d, in[1], 3);
118 ROUND2(d, a, b, c, in[5], 5);
119 ROUND2(c, d, a, b, in[9], 9);
120 ROUND2(b, c, d, a, in[13], 13);
121 ROUND2(a, b, c, d, in[2], 3);
122 ROUND2(d, a, b, c, in[6], 5);
123 ROUND2(c, d, a, b, in[10], 9);
124 ROUND2(b, c, d, a, in[14], 13);
125 ROUND2(a, b, c, d, in[3], 3);
126 ROUND2(d, a, b, c, in[7], 5);
127 ROUND2(c, d, a, b, in[11], 9);
128 ROUND2(b, c, d, a, in[15], 13);
129
130 ROUND3(a, b, c, d,in[ 0], 3);
131 ROUND3(d, a, b, c, in[8], 9);
132 ROUND3(c, d, a, b, in[4], 11);
133 ROUND3(b, c, d, a, in[12], 15);
134 ROUND3(a, b, c, d, in[2], 3);
135 ROUND3(d, a, b, c, in[10], 9);
136 ROUND3(c, d, a, b, in[6], 11);
137 ROUND3(b, c, d, a, in[14], 15);
138 ROUND3(a, b, c, d, in[1], 3);
139 ROUND3(d, a, b, c, in[9], 9);
140 ROUND3(c, d, a, b, in[5], 11);
141 ROUND3(b, c, d, a, in[13], 15);
142 ROUND3(a, b, c, d, in[3], 3);
143 ROUND3(d, a, b, c, in[11], 9);
144 ROUND3(c, d, a, b, in[7], 11);
145 ROUND3(b, c, d, a, in[15], 15);
146
147 hash[0] += a;
148 hash[1] += b;
149 hash[2] += c;
150 hash[3] += d;
151}
152
153static inline void md4_transform_helper(struct md4_ctx *ctx)
154{
155 le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(uint32_t));
156 md4_transform(ctx->hash, ctx->block);
157}
158
159static void md4_init(struct md4_ctx *mctx)
160{
161 mctx->hash[0] = 0x67452301;
162 mctx->hash[1] = 0xefcdab89;
163 mctx->hash[2] = 0x98badcfe;
164 mctx->hash[3] = 0x10325476;
165 mctx->byte_count = 0;
166}
167
168static void md4_update(struct md4_ctx *mctx,
169 const unsigned char *data, unsigned int len)
170{
171 const uint32_t avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
172
173 mctx->byte_count += len;
174
175 if (avail > len) {
176 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
177 data, len);
178 return;
179 }
180
181 memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
182 data, avail);
183
184 md4_transform_helper(mctx);
185 data += avail;
186 len -= avail;
187
188 while (len >= sizeof(mctx->block)) {
189 memcpy(mctx->block, data, sizeof(mctx->block));
190 md4_transform_helper(mctx);
191 data += sizeof(mctx->block);
192 len -= sizeof(mctx->block);
193 }
194
195 memcpy(mctx->block, data, len);
196}
197
198static void md4_final_ascii(struct md4_ctx *mctx, char *out, unsigned int len)
199{
200 const unsigned int offset = mctx->byte_count & 0x3f;
201 char *p = (char *)mctx->block + offset;
202 int padding = 56 - (offset + 1);
203
204 *p++ = 0x80;
205 if (padding < 0) {
206 memset(p, 0x00, padding + sizeof (uint64_t));
207 md4_transform_helper(mctx);
208 p = (char *)mctx->block;
209 padding = 56;
210 }
211
212 memset(p, 0, padding);
213 mctx->block[14] = mctx->byte_count << 3;
214 mctx->block[15] = mctx->byte_count >> 29;
215 le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
216 sizeof(uint64_t)) / sizeof(uint32_t));
217 md4_transform(mctx->hash, mctx->block);
218 cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(uint32_t));
219
220 snprintf(out, len, "%08X%08X%08X%08X",
221 mctx->hash[0], mctx->hash[1], mctx->hash[2], mctx->hash[3]);
222}
223
224static inline void add_char(unsigned char c, struct md4_ctx *md)
225{
226 md4_update(md, &c, 1);
227}
228
229static int parse_string(const char *file, unsigned long len,
230 struct md4_ctx *md)
231{
232 unsigned long i;
233
234 add_char(file[0], md);
235 for (i = 1; i < len; i++) {
236 add_char(file[i], md);
237 if (file[i] == '"' && file[i-1] != '\\')
238 break;
239 }
240 return i;
241}
242
243static int parse_comment(const char *file, unsigned long len)
244{
245 unsigned long i;
246
247 for (i = 2; i < len; i++) {
248 if (file[i-1] == '*' && file[i] == '/')
249 break;
250 }
251 return i;
252}
253
254/* FIXME: Handle .s files differently (eg. # starts comments) --RR */
255static int parse_file(const signed char *fname, struct md4_ctx *md)
256{
257 signed char *file;
258 unsigned long i, len;
259
260 file = grab_file(fname, &len);
261 if (!file)
262 return 0;
263
264 for (i = 0; i < len; i++) {
265 /* Collapse and ignore \ and CR. */
266 if (file[i] == '\\' && (i+1 < len) && file[i+1] == '\n') {
267 i++;
268 continue;
269 }
270
271 /* Ignore whitespace */
272 if (isspace(file[i]))
273 continue;
274
275 /* Handle strings as whole units */
276 if (file[i] == '"') {
277 i += parse_string(file+i, len - i, md);
278 continue;
279 }
280
281 /* Comments: ignore */
282 if (file[i] == '/' && file[i+1] == '*') {
283 i += parse_comment(file+i, len - i);
284 continue;
285 }
286
287 add_char(file[i], md);
288 }
289 release_file(file, len);
290 return 1;
291}
292
293/* We have dir/file.o. Open dir/.file.o.cmd, look for deps_ line to
294 * figure out source file. */
295static int parse_source_files(const char *objfile, struct md4_ctx *md)
296{
297 char *cmd, *file, *line, *dir;
298 const char *base;
299 unsigned long flen, pos = 0;
300 int dirlen, ret = 0, check_files = 0;
301
302 cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd")));
303
304 base = strrchr(objfile, '/');
305 if (base) {
306 base++;
307 dirlen = base - objfile;
308 sprintf(cmd, "%.*s.%s.cmd", dirlen, objfile, base);
309 } else {
310 dirlen = 0;
311 sprintf(cmd, ".%s.cmd", objfile);
312 }
313 dir = NOFAIL(malloc(dirlen + 1));
314 strncpy(dir, objfile, dirlen);
315 dir[dirlen] = '\0';
316
317 file = grab_file(cmd, &flen);
318 if (!file) {
319 fprintf(stderr, "Warning: could not find %s for %s\n",
320 cmd, objfile);
321 goto out;
322 }
323
324 /* There will be a line like so:
325 deps_drivers/net/dummy.o := \
326 drivers/net/dummy.c \
327 $(wildcard include/config/net/fastroute.h) \
328 include/linux/config.h \
329 $(wildcard include/config/h.h) \
330 include/linux/module.h \
331
332 Sum all files in the same dir or subdirs.
333 */
334 while ((line = get_next_line(&pos, file, flen)) != NULL) {
335 signed char* p = line;
336 if (strncmp(line, "deps_", sizeof("deps_")-1) == 0) {
337 check_files = 1;
338 continue;
339 }
340 if (!check_files)
341 continue;
342
343 /* Continue until line does not end with '\' */
344 if ( *(p + strlen(p)-1) != '\\')
345 break;
346 /* Terminate line at first space, to get rid of final ' \' */
347 while (*p) {
348 if (isspace(*p)) {
349 *p = '\0';
350 break;
351 }
352 p++;
353 }
354
355 /* Check if this file is in same dir as objfile */
356 if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) {
357 if (!parse_file(line, md)) {
358 fprintf(stderr,
359 "Warning: could not open %s: %s\n",
360 line, strerror(errno));
361 goto out_file;
362 }
363
364 }
365
366 }
367
368 /* Everyone parsed OK */
369 ret = 1;
370out_file:
371 release_file(file, flen);
372out:
373 free(dir);
374 free(cmd);
375 return ret;
376}
377
378/* Calc and record src checksum. */
379void get_src_version(const char *modname, char sum[], unsigned sumlen)
380{
381 void *file;
382 unsigned long len;
383 struct md4_ctx md;
384 char *sources, *end, *fname;
385 const char *basename;
386 char filelist[strlen(getenv("MODVERDIR")) + strlen("/") +
387 strlen(modname) - strlen(".o") + strlen(".mod") + 1 ];
388
389 /* Source files for module are in .tmp_versions/modname.mod,
390 after the first line. */
391 if (strrchr(modname, '/'))
392 basename = strrchr(modname, '/') + 1;
393 else
394 basename = modname;
395 sprintf(filelist, "%s/%.*s.mod", getenv("MODVERDIR"),
396 (int) strlen(basename) - 2, basename);
397
398 file = grab_file(filelist, &len);
399 if (!file) {
400 fprintf(stderr, "Warning: could not find versions for %s\n",
401 filelist);
402 return;
403 }
404
405 sources = strchr(file, '\n');
406 if (!sources) {
407 fprintf(stderr, "Warning: malformed versions file for %s\n",
408 modname);
409 goto release;
410 }
411
412 sources++;
413 end = strchr(sources, '\n');
414 if (!end) {
415 fprintf(stderr, "Warning: bad ending versions file for %s\n",
416 modname);
417 goto release;
418 }
419 *end = '\0';
420
421 md4_init(&md);
422 while ((fname = strsep(&sources, " ")) != NULL) {
423 if (!*fname)
424 continue;
425 if (!parse_source_files(fname, &md))
426 goto release;
427 }
428
429 md4_final_ascii(&md, sum, sumlen);
430release:
431 release_file(file, len);
432}
433
434static void write_version(const char *filename, const char *sum,
435 unsigned long offset)
436{
437 int fd;
438
439 fd = open(filename, O_RDWR);
440 if (fd < 0) {
441 fprintf(stderr, "Warning: changing sum in %s failed: %s\n",
442 filename, strerror(errno));
443 return;
444 }
445
446 if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
447 fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n",
448 filename, offset, strerror(errno));
449 goto out;
450 }
451
452 if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {
453 fprintf(stderr, "Warning: writing sum in %s failed: %s\n",
454 filename, strerror(errno));
455 goto out;
456 }
457out:
458 close(fd);
459}
460
461static int strip_rcs_crap(signed char *version)
462{
463 unsigned int len, full_len;
464
465 if (strncmp(version, "$Revision", strlen("$Revision")) != 0)
466 return 0;
467
468 /* Space for version string follows. */
469 full_len = strlen(version) + strlen(version + strlen(version) + 1) + 2;
470
471 /* Move string to start with version number: prefix will be
472 * $Revision$ or $Revision: */
473 len = strlen("$Revision");
474 if (version[len] == ':' || version[len] == '$')
475 len++;
476 while (isspace(version[len]))
477 len++;
478 memmove(version, version+len, full_len-len);
479 full_len -= len;
480
481 /* Preserve up to next whitespace. */
482 len = 0;
483 while (version[len] && !isspace(version[len]))
484 len++;
485 memmove(version + len, version + strlen(version),
486 full_len - strlen(version));
487 return 1;
488}
489
490/* Clean up RCS-style version numbers. */
491void maybe_frob_rcs_version(const char *modfilename,
492 char *version,
493 void *modinfo,
494 unsigned long version_offset)
495{
496 if (strip_rcs_crap(version))
497 write_version(modfilename, version, version_offset);
498}
diff --git a/scripts/namespace.pl b/scripts/namespace.pl
new file mode 100644
index 000000000000..88e30e82f1ca
--- /dev/null
+++ b/scripts/namespace.pl
@@ -0,0 +1,454 @@
1#!/usr/bin/perl -w
2#
3# namespace.pl. Mon Aug 30 2004
4#
5# Perform a name space analysis on the linux kernel.
6#
7# Copyright Keith Owens <kaos@ocs.com.au>. GPL.
8#
9# Invoke by changing directory to the top of the kernel object
10# tree then namespace.pl, no parameters.
11#
12# Tuned for 2.1.x kernels with the new module handling, it will
13# work with 2.0 kernels as well.
14#
15# Last change 2.6.9-rc1, adding support for separate source and object
16# trees.
17#
18# The source must be compiled/assembled first, the object files
19# are the primary input to this script. Incomplete or missing
20# objects will result in a flawed analysis. Compile both vmlinux
21# and modules.
22#
23# Even with complete objects, treat the result of the analysis
24# with caution. Some external references are only used by
25# certain architectures, others with certain combinations of
26# configuration parameters. Ideally the source should include
27# something like
28#
29# #ifndef CONFIG_...
30# static
31# #endif
32# symbol_definition;
33#
34# so the symbols are defined as static unless a particular
35# CONFIG_... requires it to be external.
36#
37# A symbol that is suffixed with '(export only)' has these properties
38#
39# * It is global.
40# * It is marked EXPORT_SYMBOL or EXPORT_SYMBOL_GPL, either in the same
41# source file or a different source file.
42# * Given the current .config, nothing uses the symbol.
43#
44# The symbol is a candidate for conversion to static, plus removal of the
45# export. But be careful that a different .config might use the symbol.
46#
47#
48# Name space analysis and cleanup is an iterative process. You cannot
49# expect to find all the problems in a single pass.
50#
51# * Identify possibly unnecessary global declarations, verify that they
52# really are unnecessary and change them to static.
53# * Compile and fix up gcc warnings about static, removing dead symbols
54# as necessary.
55# * make clean and rebuild with different configs (especially
56# CONFIG_MODULES=n) to see which symbols are being defined when the
57# config does not require them. These symbols bloat the kernel object
58# for no good reason, which is frustrating for embedded systems.
59# * Wrap config sensitive symbols in #ifdef CONFIG_foo, as long as the
60# code does not get too ugly.
61# * Repeat the name space analysis until you can live with with the
62# result.
63#
64
65require 5; # at least perl 5
66use strict;
67use File::Find;
68
69my $nm = "/usr/bin/nm -p";
70my $objdump = "/usr/bin/objdump -s -j .comment";
71my $srctree = "";
72my $objtree = "";
73$srctree = "$ENV{'srctree'}/" if (exists($ENV{'srctree'}));
74$objtree = "$ENV{'objtree'}/" if (exists($ENV{'objtree'}));
75
76if ($#ARGV != -1) {
77 print STDERR "usage: $0 takes no parameters\n";
78 die("giving up\n");
79}
80
81my %nmdata = (); # nm data for each object
82my %def = (); # all definitions for each name
83my %ksymtab = (); # names that appear in __ksymtab_
84my %ref = (); # $ref{$name} exists if there is a true external reference to $name
85my %export = (); # $export{$name} exists if there is an EXPORT_... of $name
86
87&find(\&linux_objects, '.'); # find the objects and do_nm on them
88&list_multiply_defined();
89&resolve_external_references();
90&list_extra_externals();
91
92exit(0);
93
94sub linux_objects
95{
96 # Select objects, ignoring objects which are only created by
97 # merging other objects. Also ignore all of modules, scripts
98 # and compressed. Most conglomerate objects are handled by do_nm,
99 # this list only contains the special cases. These include objects
100 # that are linked from just one other object and objects for which
101 # there is really no permanent source file.
102 my $basename = $_;
103 $_ = $File::Find::name;
104 s:^\./::;
105 if (/.*\.o$/ &&
106 ! (
107 m:/built-in.o$:
108 || m:arch/i386/kernel/vsyscall-syms.o$:
109 || m:arch/ia64/ia32/ia32.o$:
110 || m:arch/ia64/kernel/gate-syms.o$:
111 || m:arch/ia64/lib/__divdi3.o$:
112 || m:arch/ia64/lib/__divsi3.o$:
113 || m:arch/ia64/lib/__moddi3.o$:
114 || m:arch/ia64/lib/__modsi3.o$:
115 || m:arch/ia64/lib/__udivdi3.o$:
116 || m:arch/ia64/lib/__udivsi3.o$:
117 || m:arch/ia64/lib/__umoddi3.o$:
118 || m:arch/ia64/lib/__umodsi3.o$:
119 || m:arch/ia64/scripts/check_gas_for_hint.o$:
120 || m:arch/ia64/sn/kernel/xp.o$:
121 || m:boot/bbootsect.o$:
122 || m:boot/bsetup.o$:
123 || m:/bootsect.o$:
124 || m:/boot/setup.o$:
125 || m:/compressed/:
126 || m:drivers/cdrom/driver.o$:
127 || m:drivers/char/drm/tdfx_drv.o$:
128 || m:drivers/ide/ide-detect.o$:
129 || m:drivers/ide/pci/idedriver-pci.o$:
130 || m:drivers/media/media.o$:
131 || m:drivers/scsi/sd_mod.o$:
132 || m:drivers/video/video.o$:
133 || m:fs/devpts/devpts.o$:
134 || m:fs/exportfs/exportfs.o$:
135 || m:fs/hugetlbfs/hugetlbfs.o$:
136 || m:fs/msdos/msdos.o$:
137 || m:fs/nls/nls.o$:
138 || m:fs/ramfs/ramfs.o$:
139 || m:fs/romfs/romfs.o$:
140 || m:fs/vfat/vfat.o$:
141 || m:init/mounts.o$:
142 || m:^modules/:
143 || m:net/netlink/netlink.o$:
144 || m:net/sched/sched.o$:
145 || m:/piggy.o$:
146 || m:^scripts/:
147 || m:sound/.*/snd-:
148 || m:^.*/\.tmp_:
149 || m:^\.tmp_:
150 || m:/vmlinux-obj.o$:
151 )
152 ) {
153 do_nm($basename, $_);
154 }
155 $_ = $basename; # File::Find expects $_ untouched (undocumented)
156}
157
158sub do_nm
159{
160 my ($basename, $fullname) = @_;
161 my ($source, $type, $name);
162 if (! -e $basename) {
163 printf STDERR "$basename does not exist\n";
164 return;
165 }
166 if ($fullname !~ /\.o$/) {
167 printf STDERR "$fullname is not an object file\n";
168 return;
169 }
170 ($source = $fullname) =~ s/\.o$//;
171 if (-e "$objtree$source.c" || -e "$objtree$source.S") {
172 $source = "$objtree$source";
173 } else {
174 $source = "$srctree$source";
175 }
176 if (! -e "$source.c" && ! -e "$source.S") {
177 # No obvious source, exclude the object if it is conglomerate
178 if (! open(OBJDUMPDATA, "$objdump $basename|")) {
179 printf STDERR "$objdump $fullname failed $!\n";
180 return;
181 }
182 my $comment;
183 while (<OBJDUMPDATA>) {
184 chomp();
185 if (/^In archive/) {
186 # Archives are always conglomerate
187 $comment = "GCC:GCC:";
188 last;
189 }
190 next if (! /^[ 0-9a-f]{5,} /);
191 $comment .= substr($_, 43);
192 }
193 close(OBJDUMPDATA);
194 if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
195 printf STDERR "No source file found for $fullname\n";
196 }
197 return;
198 }
199 if (! open(NMDATA, "$nm $basename|")) {
200 printf STDERR "$nm $fullname failed $!\n";
201 return;
202 }
203 my @nmdata;
204 while (<NMDATA>) {
205 chop;
206 ($type, $name) = (split(/ +/, $_, 3))[1..2];
207 # Expected types
208 # A absolute symbol
209 # B weak external reference to data that has been resolved
210 # C global variable, uninitialised
211 # D global variable, initialised
212 # G global variable, initialised, small data section
213 # R global array, initialised
214 # S global variable, uninitialised, small bss
215 # T global label/procedure
216 # U external reference
217 # W weak external reference to text that has been resolved
218 # a assembler equate
219 # b static variable, uninitialised
220 # d static variable, initialised
221 # g static variable, initialised, small data section
222 # r static array, initialised
223 # s static variable, uninitialised, small bss
224 # t static label/procedures
225 # w weak external reference to text that has not been resolved
226 # ? undefined type, used a lot by modules
227 if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) {
228 printf STDERR "nm output for $fullname contains unknown type '$_'\n";
229 }
230 elsif ($name =~ /\./) {
231 # name with '.' is local static
232 }
233 else {
234 $type = 'R' if ($type eq '?'); # binutils replaced ? with R at one point
235 # binutils keeps changing the type for exported symbols, force it to R
236 $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/);
237 $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this
238 if ($type =~ /[ABCDGRSTW]/ &&
239 $name ne 'init_module' &&
240 $name ne 'cleanup_module' &&
241 $name ne 'Using_Versions' &&
242 $name !~ /^Version_[0-9]+$/ &&
243 $name !~ /^__parm_/ &&
244 $name !~ /^__kstrtab/ &&
245 $name !~ /^__ksymtab/ &&
246 $name !~ /^__kcrctab_/ &&
247 $name !~ /^__exitcall_/ &&
248 $name !~ /^__initcall_/ &&
249 $name !~ /^__kdb_initcall_/ &&
250 $name !~ /^__kdb_exitcall_/ &&
251 $name !~ /^__module_/ &&
252 $name !~ /^__mod_/ &&
253 $name !~ /^__crc_/ &&
254 $name ne '__this_module' &&
255 $name ne 'kernel_version') {
256 if (!exists($def{$name})) {
257 $def{$name} = [];
258 }
259 push(@{$def{$name}}, $fullname);
260 }
261 push(@nmdata, "$type $name");
262 if ($name =~ /^__ksymtab_/) {
263 $name = substr($name, 10);
264 if (!exists($ksymtab{$name})) {
265 $ksymtab{$name} = [];
266 }
267 push(@{$ksymtab{$name}}, $fullname);
268 }
269 }
270 }
271 close(NMDATA);
272 if ($#nmdata < 0) {
273 if (
274 $fullname ne "lib/brlock.o"
275 && $fullname ne "lib/dec_and_lock.o"
276 && $fullname ne "fs/xfs/xfs_macros.o"
277 && $fullname ne "drivers/ide/ide-probe-mini.o"
278 && $fullname ne "usr/initramfs_data.o"
279 && $fullname ne "drivers/acpi/executer/exdump.o"
280 && $fullname ne "drivers/acpi/resources/rsdump.o"
281 && $fullname ne "drivers/acpi/namespace/nsdumpdv.o"
282 && $fullname ne "drivers/acpi/namespace/nsdump.o"
283 && $fullname ne "arch/ia64/sn/kernel/sn2/io.o"
284 && $fullname ne "arch/ia64/kernel/gate-data.o"
285 && $fullname ne "drivers/ieee1394/oui.o"
286 && $fullname ne "security/capability.o"
287 && $fullname ne "sound/core/wrappers.o"
288 && $fullname ne "fs/ntfs/sysctl.o"
289 && $fullname ne "fs/jfs/jfs_debug.o"
290 ) {
291 printf "No nm data for $fullname\n";
292 }
293 return;
294 }
295 $nmdata{$fullname} = \@nmdata;
296}
297
298sub drop_def
299{
300 my ($object, $name) = @_;
301 my $nmdata = $nmdata{$object};
302 my ($i, $j);
303 for ($i = 0; $i <= $#{$nmdata}; ++$i) {
304 if ($name eq (split(' ', $nmdata->[$i], 2))[1]) {
305 splice(@{$nmdata{$object}}, $i, 1);
306 my $def = $def{$name};
307 for ($j = 0; $j < $#{$def{$name}}; ++$j) {
308 if ($def{$name}[$j] eq $object) {
309 splice(@{$def{$name}}, $j, 1);
310 }
311 }
312 last;
313 }
314 }
315}
316
317sub list_multiply_defined
318{
319 my ($name, $module);
320 foreach $name (keys(%def)) {
321 if ($#{$def{$name}} > 0) {
322 # Special case for cond_syscall
323 if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
324 ($def{$name}[0] eq "kernel/sys.o" ||
325 $def{$name}[1] eq "kernel/sys.o")) {
326 &drop_def("kernel/sys.o", $name);
327 next;
328 }
329 # Special case for i386 entry code
330 if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ &&
331 $def{$name}[0] eq "arch/i386/kernel/vsyscall-int80.o" &&
332 $def{$name}[1] eq "arch/i386/kernel/vsyscall-sysenter.o") {
333 &drop_def("arch/i386/kernel/vsyscall-sysenter.o", $name);
334 next;
335 }
336 printf "$name is multiply defined in :-\n";
337 foreach $module (@{$def{$name}}) {
338 printf "\t$module\n";
339 }
340 }
341 }
342}
343
344sub resolve_external_references
345{
346 my ($object, $type, $name, $i, $j, $kstrtab, $ksymtab, $export);
347 printf "\n";
348 foreach $object (keys(%nmdata)) {
349 my $nmdata = $nmdata{$object};
350 for ($i = 0; $i <= $#{$nmdata}; ++$i) {
351 ($type, $name) = split(' ', $nmdata->[$i], 2);
352 if ($type eq "U" || $type eq "w") {
353 if (exists($def{$name}) || exists($ksymtab{$name})) {
354 # add the owning object to the nmdata
355 $nmdata->[$i] = "$type $name $object";
356 # only count as a reference if it is not EXPORT_...
357 $kstrtab = "R __kstrtab_$name";
358 $ksymtab = "R __ksymtab_$name";
359 $export = 0;
360 for ($j = 0; $j <= $#{$nmdata}; ++$j) {
361 if ($nmdata->[$j] eq $kstrtab ||
362 $nmdata->[$j] eq $ksymtab) {
363 $export = 1;
364 last;
365 }
366 }
367 if ($export) {
368 $export{$name} = "";
369 }
370 else {
371 $ref{$name} = ""
372 }
373 }
374 elsif ( $name ne "mod_use_count_"
375 && $name ne "__initramfs_end"
376 && $name ne "__initramfs_start"
377 && $name ne "_einittext"
378 && $name ne "_sinittext"
379 && $name ne "kallsyms_names"
380 && $name ne "kallsyms_num_syms"
381 && $name ne "kallsyms_addresses"
382 && $name ne "__this_module"
383 && $name ne "_etext"
384 && $name ne "_edata"
385 && $name ne "_end"
386 && $name ne "__bss_start"
387 && $name ne "_text"
388 && $name ne "_stext"
389 && $name ne "__gp"
390 && $name ne "ia64_unw_start"
391 && $name ne "ia64_unw_end"
392 && $name ne "__init_begin"
393 && $name ne "__init_end"
394 && $name ne "__bss_stop"
395 && $name ne "__nosave_begin"
396 && $name ne "__nosave_end"
397 && $name ne "pg0"
398 && $name ne "__module_text_address"
399 && $name !~ /^__sched_text_/
400 && $name !~ /^__start_/
401 && $name !~ /^__end_/
402 && $name !~ /^__stop_/
403 && $name !~ /^__scheduling_functions_.*_here/
404 && $name !~ /^__.*initcall_/
405 && $name !~ /^__.*per_cpu_start/
406 && $name !~ /^__.*per_cpu_end/
407 && $name !~ /^__alt_instructions/
408 && $name !~ /^__setup_/
409 && $name !~ /^jiffies/
410 && $name !~ /^__mod_timer/
411 && $name !~ /^__mod_page_state/
412 && $name !~ /^init_module/
413 && $name !~ /^cleanup_module/
414 ) {
415 printf "Cannot resolve ";
416 printf "weak " if ($type eq "w");
417 printf "reference to $name from $object\n";
418 }
419 }
420 }
421 }
422}
423
424sub list_extra_externals
425{
426 my %noref = ();
427 my ($name, @module, $module, $export);
428 foreach $name (keys(%def)) {
429 if (! exists($ref{$name})) {
430 @module = @{$def{$name}};
431 foreach $module (@module) {
432 if (! exists($noref{$module})) {
433 $noref{$module} = [];
434 }
435 push(@{$noref{$module}}, $name);
436 }
437 }
438 }
439 if (%noref) {
440 printf "\nExternally defined symbols with no external references\n";
441 foreach $module (sort(keys(%noref))) {
442 printf " $module\n";
443 foreach (sort(@{$noref{$module}})) {
444 if (exists($export{$_})) {
445 $export = " (export only)";
446 }
447 else {
448 $export = "";
449 }
450 printf " $_$export\n";
451 }
452 }
453 }
454}
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
new file mode 100644
index 000000000000..3b1f2eff2584
--- /dev/null
+++ b/scripts/package/Makefile
@@ -0,0 +1,89 @@
1# Makefile for the different targets used to generate full packages of a kernel
2# It uses the generic clean infrastructure of kbuild
3
4# Ignore the following files/directories during tar operation
5TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS
6
7
8# RPM target
9# ---------------------------------------------------------------------------
10# The rpm target generates two rpm files:
11# /usr/src/packages/SRPMS/kernel-2.6.7rc2-1.src.rpm
12# /usr/src/packages/RPMS/i386/kernel-2.6.7rc2-1.<arch>.rpm
13# The src.rpm files includes all source for the kernel being built
14# The <arch>.rpm includes kernel configuration, modules etc.
15#
16# Process to create the rpm files
17# a) clean the kernel
18# b) Generate .spec file
19# c) Build a tar ball, using symlink to make kernel version
20# first entry in the path
21# d) and pack the result to a tar.gz file
22# e) generate the rpm files, based on kernel.spec
23# - Use /. to avoid tar packing just the symlink
24
25# Do we have rpmbuild, otherwise fall back to the older rpm
26RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
27 else echo rpm; fi)
28
29# Remove hyphens since they have special meaning in RPM filenames
30KERNELPATH := kernel-$(subst -,,$(KERNELRELEASE))
31MKSPEC := $(srctree)/scripts/package/mkspec
32PREV := set -e; cd ..;
33
34# rpm-pkg
35.PHONY: rpm-pkg rpm
36
37$(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile
38 $(CONFIG_SHELL) $(MKSPEC) > $@
39
40rpm-pkg rpm: $(objtree)/kernel.spec
41 $(MAKE) clean
42 $(PREV) ln -sf $(srctree) $(KERNELPATH)
43 $(PREV) tar -cz $(RCS_TAR_IGNORE) -f $(KERNELPATH).tar.gz $(KERNELPATH)/.
44 $(PREV) rm $(KERNELPATH)
45
46 set -e; \
47 $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
48 set -e; \
49 mv -f $(objtree)/.tmp_version $(objtree)/.version
50
51 $(RPM) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz
52 rm ../$(KERNELPATH).tar.gz
53
54clean-files := $(objtree)/kernel.spec
55
56# binrpm-pkg
57.PHONY: binrpm-pkg
58$(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile
59 $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@
60
61binrpm-pkg: $(objtree)/binkernel.spec
62 $(MAKE)
63 set -e; \
64 $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
65 set -e; \
66 mv -f $(objtree)/.tmp_version $(objtree)/.version
67
68 $(RPM) --define "_builddir $(srctree)" --target $(UTS_MACHINE) -bb $<
69
70clean-files += $(objtree)/binkernel.spec
71
72# Deb target
73# ---------------------------------------------------------------------------
74#
75.PHONY: deb-pkg
76deb-pkg:
77 $(MAKE)
78 $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb
79
80clean-dirs += $(objtree)/debian/
81
82
83# Help text displayed when executing 'make help'
84# ---------------------------------------------------------------------------
85help:
86 @echo ' rpm-pkg - Build the kernel as an RPM package'
87 @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel & modules'
88 @echo ' deb-pkg - Build the kernel as an deb package'
89
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
new file mode 100644
index 000000000000..c279b6310f02
--- /dev/null
+++ b/scripts/package/builddeb
@@ -0,0 +1,79 @@
1#!/bin/sh
2#
3# builddeb 1.2
4# Copyright 2003 Wichert Akkerman <wichert@wiggy.net>
5#
6# Simple script to generate a deb package for a Linux kernel. All the
7# complexity of what to do with a kernel after it is installer or removed
8# is left to other scripts and packages: they can install scripts in the
9# /etc/kernel/{pre,post}{inst,rm}.d/ directories that will be called on
10# package install and removal.
11
12set -e
13
14# Some variables and settings used throughout the script
15version=$KERNELRELEASE
16tmpdir="$objtree/debian/tmp"
17
18# Setup the directory structure
19rm -rf "$tmpdir"
20mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot"
21
22# Build and install the kernel
23cp System.map "$tmpdir/boot/System.map-$version"
24cp .config "$tmpdir/boot/config-$version"
25cp $KBUILD_IMAGE "$tmpdir/boot/vmlinuz-$version"
26
27if grep -q '^CONFIG_MODULES=y' .config ; then
28 INSTALL_MOD_PATH="$tmpdir" make modules_install
29fi
30
31# Install the maintainer scripts
32for script in postinst postrm preinst prerm ; do
33 mkdir -p "$tmpdir/etc/kernel/$script.d"
34 cat <<EOF > "$tmpdir/DEBIAN/$script"
35#!/bin/sh
36
37set -e
38
39test -d /etc/kernel/$script.d && run-parts --arg="$version" /etc/kernel/$script.d
40exit 0
41EOF
42 chmod 755 "$tmpdir/DEBIAN/$script"
43done
44
45name="Kernel Compiler <$(id -nu)@$(hostname -f)>"
46# Generate a simple changelog template
47cat <<EOF > debian/changelog
48linux ($version) unstable; urgency=low
49
50 * A standard release
51
52 -- $name $(date -R)
53EOF
54
55# Generate a control file
56cat <<EOF > debian/control
57Source: linux
58Section: base
59Priority: optional
60Maintainer: $name
61Standards-Version: 3.6.1
62
63Package: linux-$version
64Architecture: any
65Description: Linux kernel, version $version
66 This package contains the Linux kernel, modules and corresponding other
67 files version $version.
68EOF
69
70# Fix some ownership and permissions
71chown -R root:root "$tmpdir"
72chmod -R go-w "$tmpdir"
73
74# Perform the final magic
75dpkg-gencontrol -isp
76dpkg --build "$tmpdir" ..
77
78exit 0
79
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
new file mode 100755
index 000000000000..6e7a58f145ad
--- /dev/null
+++ b/scripts/package/mkspec
@@ -0,0 +1,82 @@
1#!/bin/sh
2#
3# Output a simple RPM spec file that uses no fancy features requring
4# RPM v4. This is intended to work with any RPM distro.
5#
6# The only gothic bit here is redefining install_post to avoid
7# stripping the symbols from files in the kernel which we want
8#
9# Patched for non-x86 by Opencon (L) 2002 <opencon@rio.skydome.net>
10#
11
12# how we were called determines which rpms we build and how we build them
13if [ "$1" = "prebuilt" ]; then
14 PREBUILT=true
15else
16 PREBUILT=false
17fi
18
19# starting to output the spec
20if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then
21 PROVIDES=kernel-drm
22fi
23
24PROVIDES="$PROVIDES kernel-$KERNELRELEASE"
25__KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-//g"`
26
27echo "Name: kernel"
28echo "Summary: The Linux Kernel"
29echo "Version: $__KERNELRELEASE"
30# we need to determine the NEXT version number so that uname and
31# rpm -q will agree
32echo "Release: `. $srctree/scripts/mkversion`"
33echo "License: GPL"
34echo "Group: System Environment/Kernel"
35echo "Vendor: The Linux Community"
36echo "URL: http://www.kernel.org"
37
38if ! $PREBUILT; then
39echo "Source: kernel-$__KERNELRELEASE.tar.gz"
40fi
41
42echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root"
43echo "Provides: $PROVIDES"
44echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
45echo "%define debug_package %{nil}"
46echo ""
47echo "%description"
48echo "The Linux Kernel, the operating system core itself"
49echo ""
50
51if ! $PREBUILT; then
52echo "%prep"
53echo "%setup -q"
54echo ""
55fi
56
57echo "%build"
58
59if ! $PREBUILT; then
60echo "make clean && make %{_smp_mflags}"
61echo ""
62fi
63
64echo "%install"
65echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules'
66
67echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install'
68echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE"
69
70echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE"
71
72echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE"
73echo ""
74echo "%clean"
75echo '#echo -rf $RPM_BUILD_ROOT'
76echo ""
77echo "%files"
78echo '%defattr (-, root, root)'
79echo "%dir /lib/modules"
80echo "/lib/modules/$KERNELRELEASE"
81echo "/boot/*"
82echo ""
diff --git a/scripts/patch-kernel b/scripts/patch-kernel
new file mode 100755
index 000000000000..43af01075612
--- /dev/null
+++ b/scripts/patch-kernel
@@ -0,0 +1,257 @@
1#! /bin/sh
2# Script to apply kernel patches.
3# usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
4# The source directory defaults to /usr/src/linux, and the patch
5# directory defaults to the current directory.
6# e.g.
7# scripts/patch-kernel . ..
8# Update the kernel tree in the current directory using patches in the
9# directory above to the latest Linus kernel
10# scripts/patch-kernel . .. -ac
11# Get the latest Linux kernel and patch it with the latest ac patch
12# scripts/patch-kernel . .. 2.4.9
13# Gets standard kernel 2.4.9
14# scripts/patch-kernel . .. 2.4.9 -ac
15# Gets 2.4.9 with latest ac patches
16# scripts/patch-kernel . .. 2.4.9 -ac11
17# Gets 2.4.9 with ac patch ac11
18# Note: It uses the patches relative to the Linus kernels, not the
19# ac to ac relative patches
20#
21# It determines the current kernel version from the top-level Makefile.
22# It then looks for patches for the next sublevel in the patch directory.
23# This is applied using "patch -p1 -s" from within the kernel directory.
24# A check is then made for "*.rej" files to see if the patch was
25# successful. If it is, then all of the "*.orig" files are removed.
26#
27# Nick Holloway <Nick.Holloway@alfie.demon.co.uk>, 2nd January 1995.
28#
29# Added support for handling multiple types of compression. What includes
30# gzip, bzip, bzip2, zip, compress, and plaintext.
31#
32# Adam Sulmicki <adam@cfar.umd.edu>, 1st January 1997.
33#
34# Added ability to stop at a given version number
35# Put the full version number (i.e. 2.3.31) as the last parameter
36# Dave Gilbert <linux@treblig.org>, 11th December 1999.
37
38# Fixed previous patch so that if we are already at the correct version
39# not to patch up.
40#
41# Added -ac option, use -ac or -ac9 (say) to stop at a particular version
42# Dave Gilbert <linux@treblig.org>, 29th September 2001.
43#
44# Add support for (use of) EXTRAVERSION (to support 2.6.8.x, e.g.);
45# update usage message;
46# fix some whitespace damage;
47# be smarter about stopping when current version is larger than requested;
48# Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18.
49
50# Set directories from arguments, or use defaults.
51sourcedir=${1-/usr/src/linux}
52patchdir=${2-.}
53stopvers=${3-default}
54
55if [ "$1" == -h -o "$1" == --help -o ! -r "$sourcedir/Makefile" ]; then
56cat << USAGE
57usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
58 source directory defaults to /usr/src/linux,
59 patch directory defaults to the current directory,
60 stopversion defaults to <all in patchdir>.
61USAGE
62exit 1
63fi
64
65# See if we have any -ac options
66for PARM in $*
67do
68 case $PARM in
69 -ac*)
70 gotac=$PARM;
71
72 esac;
73done
74
75# ---------------------------------------------------------------------------
76# Find a file, first parameter is basename of file
77# it tries many compression mechanisms and sets variables to say how to get it
78findFile () {
79 filebase=$1;
80
81 if [ -r ${filebase}.gz ]; then
82 ext=".gz"
83 name="gzip"
84 uncomp="gunzip -dc"
85 elif [ -r ${filebase}.bz ]; then
86 ext=".bz"
87 name="bzip"
88 uncomp="bunzip -dc"
89 elif [ -r ${filebase}.bz2 ]; then
90 ext=".bz2"
91 name="bzip2"
92 uncomp="bunzip2 -dc"
93 elif [ -r ${filebase}.zip ]; then
94 ext=".zip"
95 name="zip"
96 uncomp="unzip -d"
97 elif [ -r ${filebase}.Z ]; then
98 ext=".Z"
99 name="uncompress"
100 uncomp="uncompress -c"
101 elif [ -r ${filebase} ]; then
102 ext=""
103 name="plaintext"
104 uncomp="cat"
105 else
106 return 1;
107 fi
108
109 return 0;
110}
111
112# ---------------------------------------------------------------------------
113# Apply a patch and check it goes in cleanly
114# First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension
115
116applyPatch () {
117 echo -n "Applying $1 (${name})... "
118 if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir
119 then
120 echo "done."
121 else
122 echo "failed. Clean up yourself."
123 return 1;
124 fi
125 if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ]
126 then
127 echo "Aborting. Reject files found."
128 return 1;
129 fi
130 # Remove backup files
131 find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \;
132
133 return 0;
134}
135
136# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
137TMPFILE=`mktemp .tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; }
138grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE
139tr -d [:blank:] < $TMPFILE > $TMPFILE.1
140source $TMPFILE.1
141rm -f $TMPFILE*
142if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
143then
144 echo "unable to determine current kernel version" >&2
145 exit 1
146fi
147
148NAME=`grep ^NAME $sourcedir/Makefile`
149NAME=${NAME##*=}
150
151echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} ($NAME)"
152
153# strip EXTRAVERSION to just a number (drop leading '.' and trailing additions)
154EXTRAVER=
155if [ x$EXTRAVERSION != "x" ]
156then
157 if [ ${EXTRAVERSION:0:1} == "." ]; then
158 EXTRAVER=${EXTRAVERSION:1}
159 else
160 EXTRAVER=$EXTRAVERSION
161 fi
162 EXTRAVER=${EXTRAVER%%[[:punct:]]*}
163 #echo "patch-kernel: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER"
164fi
165
166#echo "stopvers=$stopvers"
167if [ $stopvers != "default" ]; then
168 STOPSUBLEVEL=`echo $stopvers | cut -d. -f3`
169 STOPEXTRA=`echo $stopvers | cut -d. -f4`
170 #echo "STOPSUBLEVEL=$STOPSUBLEVEL, STOPEXTRA=$STOPEXTRA"
171else
172 STOPSUBLEVEL=9999
173 STOPEXTRA=9999
174fi
175
176while : # incrementing SUBLEVEL (s in v.p.s)
177do
178 if [ x$EXTRAVER != "x" ]; then
179 CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
180 else
181 CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
182 fi
183
184 if [ $stopvers == $CURRENTFULLVERSION ]; then
185 echo "Stopping at $CURRENTFULLVERSION base as requested."
186 break
187 fi
188
189 while : # incrementing EXTRAVER (x in v.p.s.x)
190 do
191 EXTRAVER=$((EXTRAVER + 1))
192 FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
193 #echo "... trying $FULLVERSION ..."
194
195 patch=patch-$FULLVERSION
196
197 # See if the file exists and find extension
198 findFile $patchdir/${patch} || break
199
200 # Apply the patch and check all is OK
201 applyPatch $patch || break
202
203 continue 2
204 done
205
206 EXTRAVER=
207 SUBLEVEL=$((SUBLEVEL + 1))
208 FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
209 #echo "___ trying $FULLVERSION ___"
210
211 if [ $((SUBLEVEL)) -gt $((STOPSUBLEVEL)) ]; then
212 echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)"
213 exit 1
214 fi
215
216 patch=patch-$FULLVERSION
217
218 # See if the file exists and find extension
219 findFile $patchdir/${patch} || break
220
221 # Apply the patch and check all is OK
222 applyPatch $patch || break
223done
224#echo "base all done"
225
226if [ x$gotac != x ]; then
227 # Out great user wants the -ac patches
228 # They could have done -ac (get latest) or -acxx where xx=version they want
229 if [ $gotac == "-ac" ]; then
230 # They want the latest version
231 HIGHESTPATCH=0
232 for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.*
233 do
234 ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'`
235 # Check it is actually a recognised patch type
236 findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break
237
238 if [ $ACVALUE -gt $HIGHESTPATCH ]; then
239 HIGHESTPATCH=$ACVALUE
240 fi
241 done
242
243 if [ $HIGHESTPATCH -ne 0 ]; then
244 findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break
245 applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH}
246 else
247 echo "No -ac patches found"
248 fi
249 else
250 # They want an exact version
251 findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || {
252 echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION. Hohum."
253 exit 1
254 }
255 applyPatch patch-${CURRENTFULLVERSION}${gotac}
256 fi
257fi
diff --git a/scripts/pnmtologo.c b/scripts/pnmtologo.c
new file mode 100644
index 000000000000..6aa2a2483f8d
--- /dev/null
+++ b/scripts/pnmtologo.c
@@ -0,0 +1,508 @@
1
2/*
3 * Convert a logo in ASCII PNM format to C source suitable for inclusion in
4 * the Linux kernel
5 *
6 * (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org>
7 *
8 * --------------------------------------------------------------------------
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of the Linux
12 * distribution for more details.
13 */
14
15#include <ctype.h>
16#include <errno.h>
17#include <stdarg.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <unistd.h>
22
23
24static const char *programname;
25static const char *filename;
26static const char *logoname = "linux_logo";
27static const char *outputname;
28static FILE *out;
29
30
31#define LINUX_LOGO_MONO 1 /* monochrome black/white */
32#define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */
33#define LINUX_LOGO_CLUT224 3 /* 224 colors */
34#define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */
35
36static const char *logo_types[LINUX_LOGO_GRAY256+1] = {
37 [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",
38 [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",
39 [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",
40 [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
41};
42
43#define MAX_LINUX_LOGO_COLORS 224
44
45struct color {
46 unsigned char red;
47 unsigned char green;
48 unsigned char blue;
49};
50
51static const struct color clut_vga16[16] = {
52 { 0x00, 0x00, 0x00 },
53 { 0x00, 0x00, 0xaa },
54 { 0x00, 0xaa, 0x00 },
55 { 0x00, 0xaa, 0xaa },
56 { 0xaa, 0x00, 0x00 },
57 { 0xaa, 0x00, 0xaa },
58 { 0xaa, 0x55, 0x00 },
59 { 0xaa, 0xaa, 0xaa },
60 { 0x55, 0x55, 0x55 },
61 { 0x55, 0x55, 0xff },
62 { 0x55, 0xff, 0x55 },
63 { 0x55, 0xff, 0xff },
64 { 0xff, 0x55, 0x55 },
65 { 0xff, 0x55, 0xff },
66 { 0xff, 0xff, 0x55 },
67 { 0xff, 0xff, 0xff },
68};
69
70
71static int logo_type = LINUX_LOGO_CLUT224;
72static unsigned int logo_width;
73static unsigned int logo_height;
74static struct color **logo_data;
75static struct color logo_clut[MAX_LINUX_LOGO_COLORS];
76static unsigned int logo_clutsize;
77
78static void die(const char *fmt, ...)
79 __attribute__ ((noreturn)) __attribute ((format (printf, 1, 2)));
80static void usage(void) __attribute ((noreturn));
81
82
83static unsigned int get_number(FILE *fp)
84{
85 int c, val;
86
87 /* Skip leading whitespace */
88 do {
89 c = fgetc(fp);
90 if (c == EOF)
91 die("%s: end of file\n", filename);
92 if (c == '#') {
93 /* Ignore comments 'till end of line */
94 do {
95 c = fgetc(fp);
96 if (c == EOF)
97 die("%s: end of file\n", filename);
98 } while (c != '\n');
99 }
100 } while (isspace(c));
101
102 /* Parse decimal number */
103 val = 0;
104 while (isdigit(c)) {
105 val = 10*val+c-'0';
106 c = fgetc(fp);
107 if (c == EOF)
108 die("%s: end of file\n", filename);
109 }
110 return val;
111}
112
113static unsigned int get_number255(FILE *fp, unsigned int maxval)
114{
115 unsigned int val = get_number(fp);
116 return (255*val+maxval/2)/maxval;
117}
118
119static void read_image(void)
120{
121 FILE *fp;
122 unsigned int i, j;
123 int magic;
124 unsigned int maxval;
125
126 /* open image file */
127 fp = fopen(filename, "r");
128 if (!fp)
129 die("Cannot open file %s: %s\n", filename, strerror(errno));
130
131 /* check file type and read file header */
132 magic = fgetc(fp);
133 if (magic != 'P')
134 die("%s is not a PNM file\n", filename);
135 magic = fgetc(fp);
136 switch (magic) {
137 case '1':
138 case '2':
139 case '3':
140 /* Plain PBM/PGM/PPM */
141 break;
142
143 case '4':
144 case '5':
145 case '6':
146 /* Binary PBM/PGM/PPM */
147 die("%s: Binary PNM is not supported\n"
148 "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);
149
150 default:
151 die("%s is not a PNM file\n", filename);
152 }
153 logo_width = get_number(fp);
154 logo_height = get_number(fp);
155
156 /* allocate image data */
157 logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));
158 if (!logo_data)
159 die("%s\n", strerror(errno));
160 for (i = 0; i < logo_height; i++) {
161 logo_data[i] = malloc(logo_width*sizeof(struct color));
162 if (!logo_data[i])
163 die("%s\n", strerror(errno));
164 }
165
166 /* read image data */
167 switch (magic) {
168 case '1':
169 /* Plain PBM */
170 for (i = 0; i < logo_height; i++)
171 for (j = 0; j < logo_width; j++)
172 logo_data[i][j].red = logo_data[i][j].green =
173 logo_data[i][j].blue = 255*(1-get_number(fp));
174 break;
175
176 case '2':
177 /* Plain PGM */
178 maxval = get_number(fp);
179 for (i = 0; i < logo_height; i++)
180 for (j = 0; j < logo_width; j++)
181 logo_data[i][j].red = logo_data[i][j].green =
182 logo_data[i][j].blue = get_number255(fp, maxval);
183 break;
184
185 case '3':
186 /* Plain PPM */
187 maxval = get_number(fp);
188 for (i = 0; i < logo_height; i++)
189 for (j = 0; j < logo_width; j++) {
190 logo_data[i][j].red = get_number255(fp, maxval);
191 logo_data[i][j].green = get_number255(fp, maxval);
192 logo_data[i][j].blue = get_number255(fp, maxval);
193 }
194 break;
195 }
196
197 /* close file */
198 fclose(fp);
199}
200
201static inline int is_black(struct color c)
202{
203 return c.red == 0 && c.green == 0 && c.blue == 0;
204}
205
206static inline int is_white(struct color c)
207{
208 return c.red == 255 && c.green == 255 && c.blue == 255;
209}
210
211static inline int is_gray(struct color c)
212{
213 return c.red == c.green && c.red == c.blue;
214}
215
216static inline int is_equal(struct color c1, struct color c2)
217{
218 return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
219}
220
221static void write_header(void)
222{
223 /* open logo file */
224 if (outputname) {
225 out = fopen(outputname, "w");
226 if (!out)
227 die("Cannot create file %s: %s\n", outputname, strerror(errno));
228 } else {
229 out = stdout;
230 }
231
232 fputs("/*\n", out);
233 fputs(" * DO NOT EDIT THIS FILE!\n", out);
234 fputs(" *\n", out);
235 fprintf(out, " * It was automatically generated from %s\n", filename);
236 fputs(" *\n", out);
237 fprintf(out, " * Linux logo %s\n", logoname);
238 fputs(" */\n\n", out);
239 fputs("#include <linux/linux_logo.h>\n\n", out);
240 fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
241 logoname);
242}
243
244static void write_footer(void)
245{
246 fputs("\n};\n\n", out);
247 fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
248 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
249 fprintf(out, " .width\t= %d,\n", logo_width);
250 fprintf(out, " .height\t= %d,\n", logo_height);
251 if (logo_type == LINUX_LOGO_CLUT224) {
252 fprintf(out, " .clutsize\t= %d,\n", logo_clutsize);
253 fprintf(out, " .clut\t= %s_clut,\n", logoname);
254 }
255 fprintf(out, " .data\t= %s_data\n", logoname);
256 fputs("};\n\n", out);
257
258 /* close logo file */
259 if (outputname)
260 fclose(out);
261}
262
263static int write_hex_cnt;
264
265static void write_hex(unsigned char byte)
266{
267 if (write_hex_cnt % 12)
268 fprintf(out, ", 0x%02x", byte);
269 else if (write_hex_cnt)
270 fprintf(out, ",\n\t0x%02x", byte);
271 else
272 fprintf(out, "\t0x%02x", byte);
273 write_hex_cnt++;
274}
275
276static void write_logo_mono(void)
277{
278 unsigned int i, j;
279 unsigned char val, bit;
280
281 /* validate image */
282 for (i = 0; i < logo_height; i++)
283 for (j = 0; j < logo_width; j++)
284 if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
285 die("Image must be monochrome\n");
286
287 /* write file header */
288 write_header();
289
290 /* write logo data */
291 for (i = 0; i < logo_height; i++) {
292 for (j = 0; j < logo_width;) {
293 for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)
294 if (logo_data[i][j].red)
295 val |= bit;
296 write_hex(val);
297 }
298 }
299
300 /* write logo structure and file footer */
301 write_footer();
302}
303
304static void write_logo_vga16(void)
305{
306 unsigned int i, j, k;
307 unsigned char val;
308
309 /* validate image */
310 for (i = 0; i < logo_height; i++)
311 for (j = 0; j < logo_width; j++) {
312 for (k = 0; k < 16; k++)
313 if (is_equal(logo_data[i][j], clut_vga16[k]))
314 break;
315 if (k == 16)
316 die("Image must use the 16 console colors only\n"
317 "Use ppmquant(1) -map clut_vga16.ppm to reduce the number "
318 "of colors\n");
319 }
320
321 /* write file header */
322 write_header();
323
324 /* write logo data */
325 for (i = 0; i < logo_height; i++)
326 for (j = 0; j < logo_width; j++) {
327 for (k = 0; k < 16; k++)
328 if (is_equal(logo_data[i][j], clut_vga16[k]))
329 break;
330 val = k<<4;
331 if (++j < logo_width) {
332 for (k = 0; k < 16; k++)
333 if (is_equal(logo_data[i][j], clut_vga16[k]))
334 break;
335 val |= k;
336 }
337 write_hex(val);
338 }
339
340 /* write logo structure and file footer */
341 write_footer();
342}
343
344static void write_logo_clut224(void)
345{
346 unsigned int i, j, k;
347
348 /* validate image */
349 for (i = 0; i < logo_height; i++)
350 for (j = 0; j < logo_width; j++) {
351 for (k = 0; k < logo_clutsize; k++)
352 if (is_equal(logo_data[i][j], logo_clut[k]))
353 break;
354 if (k == logo_clutsize) {
355 if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
356 die("Image has more than %d colors\n"
357 "Use ppmquant(1) to reduce the number of colors\n",
358 MAX_LINUX_LOGO_COLORS);
359 logo_clut[logo_clutsize++] = logo_data[i][j];
360 }
361 }
362
363 /* write file header */
364 write_header();
365
366 /* write logo data */
367 for (i = 0; i < logo_height; i++)
368 for (j = 0; j < logo_width; j++) {
369 for (k = 0; k < logo_clutsize; k++)
370 if (is_equal(logo_data[i][j], logo_clut[k]))
371 break;
372 write_hex(k+32);
373 }
374 fputs("\n};\n\n", out);
375
376 /* write logo clut */
377 fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
378 logoname);
379 write_hex_cnt = 0;
380 for (i = 0; i < logo_clutsize; i++) {
381 write_hex(logo_clut[i].red);
382 write_hex(logo_clut[i].green);
383 write_hex(logo_clut[i].blue);
384 }
385
386 /* write logo structure and file footer */
387 write_footer();
388}
389
390static void write_logo_gray256(void)
391{
392 unsigned int i, j;
393
394 /* validate image */
395 for (i = 0; i < logo_height; i++)
396 for (j = 0; j < logo_width; j++)
397 if (!is_gray(logo_data[i][j]))
398 die("Image must be grayscale\n");
399
400 /* write file header */
401 write_header();
402
403 /* write logo data */
404 for (i = 0; i < logo_height; i++)
405 for (j = 0; j < logo_width; j++)
406 write_hex(logo_data[i][j].red);
407
408 /* write logo structure and file footer */
409 write_footer();
410}
411
412static void die(const char *fmt, ...)
413{
414 va_list ap;
415
416 va_start(ap, fmt);
417 vfprintf(stderr, fmt, ap);
418 va_end(ap);
419
420 exit(1);
421}
422
423static void usage(void)
424{
425 die("\n"
426 "Usage: %s [options] <filename>\n"
427 "\n"
428 "Valid options:\n"
429 " -h : display this usage information\n"
430 " -n <name> : specify logo name (default: linux_logo)\n"
431 " -o <output> : output to file <output> instead of stdout\n"
432 " -t <type> : specify logo type, one of\n"
433 " mono : monochrome black/white\n"
434 " vga16 : 16 colors VGA text palette\n"
435 " clut224 : 224 colors (default)\n"
436 " gray256 : 256 levels grayscale\n"
437 "\n", programname);
438}
439
440int main(int argc, char *argv[])
441{
442 int opt;
443
444 programname = argv[0];
445
446 opterr = 0;
447 while (1) {
448 opt = getopt(argc, argv, "hn:o:t:");
449 if (opt == -1)
450 break;
451
452 switch (opt) {
453 case 'h':
454 usage();
455 break;
456
457 case 'n':
458 logoname = optarg;
459 break;
460
461 case 'o':
462 outputname = optarg;
463 break;
464
465 case 't':
466 if (!strcmp(optarg, "mono"))
467 logo_type = LINUX_LOGO_MONO;
468 else if (!strcmp(optarg, "vga16"))
469 logo_type = LINUX_LOGO_VGA16;
470 else if (!strcmp(optarg, "clut224"))
471 logo_type = LINUX_LOGO_CLUT224;
472 else if (!strcmp(optarg, "gray256"))
473 logo_type = LINUX_LOGO_GRAY256;
474 else
475 usage();
476 break;
477
478 default:
479 usage();
480 break;
481 }
482 }
483 if (optind != argc-1)
484 usage();
485
486 filename = argv[optind];
487
488 read_image();
489 switch (logo_type) {
490 case LINUX_LOGO_MONO:
491 write_logo_mono();
492 break;
493
494 case LINUX_LOGO_VGA16:
495 write_logo_vga16();
496 break;
497
498 case LINUX_LOGO_CLUT224:
499 write_logo_clut224();
500 break;
501
502 case LINUX_LOGO_GRAY256:
503 write_logo_gray256();
504 break;
505 }
506 exit(0);
507}
508
diff --git a/scripts/reference_discarded.pl b/scripts/reference_discarded.pl
new file mode 100644
index 000000000000..d5cabb81bd1b
--- /dev/null
+++ b/scripts/reference_discarded.pl
@@ -0,0 +1,110 @@
1#!/usr/bin/perl -w
2#
3# reference_discarded.pl (C) Keith Owens 2001 <kaos@ocs.com.au>
4#
5# Released under GPL V2.
6#
7# List dangling references to vmlinux discarded sections.
8
9use strict;
10die($0 . " takes no arguments\n") if($#ARGV >= 0);
11
12my %object;
13my $object;
14my $line;
15my $ignore;
16my $errorcount;
17
18$| = 1;
19
20# printf("Finding objects, ");
21open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed";
22while (defined($line = <OBJDUMP_LIST>)) {
23 chomp($line);
24 if ($line =~ /:\s+file format/) {
25 ($object = $line) =~ s/:.*//;
26 $object{$object}->{'module'} = 0;
27 $object{$object}->{'size'} = 0;
28 $object{$object}->{'off'} = 0;
29 }
30 if ($line =~ /^\s*\d+\s+\.modinfo\s+/) {
31 $object{$object}->{'module'} = 1;
32 }
33 if ($line =~ /^\s*\d+\s+\.comment\s+/) {
34 ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5];
35 }
36}
37close(OBJDUMP_LIST);
38# printf("%d objects, ", scalar keys(%object));
39$ignore = 0;
40foreach $object (keys(%object)) {
41 if ($object{$object}->{'module'}) {
42 ++$ignore;
43 delete($object{$object});
44 }
45}
46# printf("ignoring %d module(s)\n", $ignore);
47
48# Ignore conglomerate objects, they have been built from multiple objects and we
49# only care about the individual objects. If an object has more than one GCC:
50# string in the comment section then it is conglomerate. This does not filter
51# out conglomerates that consist of exactly one object, can't be helped.
52
53# printf("Finding conglomerates, ");
54$ignore = 0;
55foreach $object (keys(%object)) {
56 if (exists($object{$object}->{'off'})) {
57 my ($off, $size, $comment, $l);
58 $off = hex($object{$object}->{'off'});
59 $size = hex($object{$object}->{'size'});
60 open(OBJECT, "<$object") || die "cannot read $object";
61 seek(OBJECT, $off, 0) || die "seek to $off in $object failed";
62 $l = read(OBJECT, $comment, $size);
63 die "read $size bytes from $object .comment failed" if ($l != $size);
64 close(OBJECT);
65 if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
66 ++$ignore;
67 delete($object{$object});
68 }
69 }
70}
71# printf("ignoring %d conglomerate(s)\n", $ignore);
72
73# printf("Scanning objects\n");
74$errorcount = 0;
75foreach $object (keys(%object)) {
76 my $from;
77 open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object";
78 while (defined($line = <OBJDUMP>)) {
79 chomp($line);
80 if ($line =~ /RELOCATION RECORDS FOR /) {
81 ($from = $line) =~ s/.*\[([^]]*).*/$1/;
82 }
83 if (($line =~ /\.text\.exit$/ ||
84 $line =~ /\.exit\.text$/ ||
85 $line =~ /\.data\.exit$/ ||
86 $line =~ /\.exit\.data$/ ||
87 $line =~ /\.exitcall\.exit$/) &&
88 ($from !~ /\.text\.exit$/ &&
89 $from !~ /\.exit\.text$/ &&
90 $from !~ /\.data\.exit$/ &&
91 $from !~ /\.exit\.data$/ &&
92 $from !~ /\.altinstructions$/ &&
93 $from !~ /\.pdr$/ &&
94 $from !~ /\.debug_info$/ &&
95 $from !~ /\.debug_aranges$/ &&
96 $from !~ /\.debug_ranges$/ &&
97 $from !~ /\.debug_line$/ &&
98 $from !~ /\.debug_frame$/ &&
99 $from !~ /\.exitcall\.exit$/ &&
100 $from !~ /\.eh_frame$/ &&
101 $from !~ /\.stab$/)) {
102 printf("Error: %s %s refers to %s\n", $object, $from, $line);
103 $errorcount = $errorcount + 1;
104 }
105 }
106 close(OBJDUMP);
107}
108# printf("Done\n");
109
110exit(0);
diff --git a/scripts/reference_init.pl b/scripts/reference_init.pl
new file mode 100644
index 000000000000..9a2408453869
--- /dev/null
+++ b/scripts/reference_init.pl
@@ -0,0 +1,107 @@
1#!/usr/bin/perl -w
2#
3# reference_init.pl (C) Keith Owens 2002 <kaos@ocs.com.au>
4#
5# List references to vmlinux init sections from non-init sections.
6
7# Unfortunately I had to exclude references from read only data to .init
8# sections, almost all of these are false positives, they are created by
9# gcc. The downside of excluding rodata is that there really are some
10# user references from rodata to init code, e.g. drivers/video/vgacon.c
11#
12# const struct consw vga_con = {
13# con_startup: vgacon_startup,
14#
15# where vgacon_startup is __init. If you want to wade through the false
16# positives, take out the check for rodata.
17
18use strict;
19die($0 . " takes no arguments\n") if($#ARGV >= 0);
20
21my %object;
22my $object;
23my $line;
24my $ignore;
25
26$| = 1;
27
28printf("Finding objects, ");
29open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed";
30while (defined($line = <OBJDUMP_LIST>)) {
31 chomp($line);
32 if ($line =~ /:\s+file format/) {
33 ($object = $line) =~ s/:.*//;
34 $object{$object}->{'module'} = 0;
35 $object{$object}->{'size'} = 0;
36 $object{$object}->{'off'} = 0;
37 }
38 if ($line =~ /^\s*\d+\s+\.modinfo\s+/) {
39 $object{$object}->{'module'} = 1;
40 }
41 if ($line =~ /^\s*\d+\s+\.comment\s+/) {
42 ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5];
43 }
44}
45close(OBJDUMP_LIST);
46printf("%d objects, ", scalar keys(%object));
47$ignore = 0;
48foreach $object (keys(%object)) {
49 if ($object{$object}->{'module'}) {
50 ++$ignore;
51 delete($object{$object});
52 }
53}
54printf("ignoring %d module(s)\n", $ignore);
55
56# Ignore conglomerate objects, they have been built from multiple objects and we
57# only care about the individual objects. If an object has more than one GCC:
58# string in the comment section then it is conglomerate. This does not filter
59# out conglomerates that consist of exactly one object, can't be helped.
60
61printf("Finding conglomerates, ");
62$ignore = 0;
63foreach $object (keys(%object)) {
64 if (exists($object{$object}->{'off'})) {
65 my ($off, $size, $comment, $l);
66 $off = hex($object{$object}->{'off'});
67 $size = hex($object{$object}->{'size'});
68 open(OBJECT, "<$object") || die "cannot read $object";
69 seek(OBJECT, $off, 0) || die "seek to $off in $object failed";
70 $l = read(OBJECT, $comment, $size);
71 die "read $size bytes from $object .comment failed" if ($l != $size);
72 close(OBJECT);
73 if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
74 ++$ignore;
75 delete($object{$object});
76 }
77 }
78}
79printf("ignoring %d conglomerate(s)\n", $ignore);
80
81printf("Scanning objects\n");
82foreach $object (sort(keys(%object))) {
83 my $from;
84 open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object";
85 while (defined($line = <OBJDUMP>)) {
86 chomp($line);
87 if ($line =~ /RELOCATION RECORDS FOR /) {
88 ($from = $line) =~ s/.*\[([^]]*).*/$1/;
89 }
90 if (($line =~ /\.init$/ || $line =~ /\.init\./) &&
91 ($from !~ /\.init$/ &&
92 $from !~ /\.init\./ &&
93 $from !~ /\.stab$/ &&
94 $from !~ /\.rodata$/ &&
95 $from !~ /\.text\.lock$/ &&
96 $from !~ /\.pci_fixup_header$/ &&
97 $from !~ /\.pci_fixup_final$/ &&
98 $from !~ /\.pdr$/ &&
99 $from !~ /\__param$/ &&
100 $from !~ /\.altinstructions/ &&
101 $from !~ /\.debug_/)) {
102 printf("Error: %s %s refers to %s\n", $object, $from, $line);
103 }
104 }
105 close(OBJDUMP);
106}
107printf("Done\n");
diff --git a/scripts/show_delta b/scripts/show_delta
new file mode 100644
index 000000000000..48a706ab3d0c
--- /dev/null
+++ b/scripts/show_delta
@@ -0,0 +1,129 @@
1#!/usr/bin/env python
2#
3# show_deltas: Read list of printk messages instrumented with
4# time data, and format with time deltas.
5#
6# Also, you can show the times relative to a fixed point.
7#
8# Copyright 2003 Sony Corporation
9#
10# GPL 2.0 applies.
11
12import sys
13import string
14
15def usage():
16 print """usage: show_delta [<options>] <filename>
17
18This program parses the output from a set of printk message lines which
19have time data prefixed because the CONFIG_PRINTK_TIME option is set, or
20the kernel command line option "time" is specified. When run with no
21options, the time information is converted to show the time delta between
22each printk line and the next. When run with the '-b' option, all times
23are relative to a single (base) point in time.
24
25Options:
26 -h Show this usage help.
27 -b <base> Specify a base for time references.
28 <base> can be a number or a string.
29 If it is a string, the first message line
30 which matches (at the beginning of the
31 line) is used as the time reference.
32
33ex: $ dmesg >timefile
34 $ show_delta -b NET4 timefile
35
36will show times relative to the line in the kernel output
37starting with "NET4".
38"""
39 sys.exit(1)
40
41# returns a tuple containing the seconds and text for each message line
42# seconds is returned as a float
43# raise an exception if no timing data was found
44def get_time(line):
45 if line[0]!="[":
46 raise ValueError
47
48 # split on closing bracket
49 (time_str, rest) = string.split(line[1:],']',1)
50 time = string.atof(time_str)
51
52 #print "time=", time
53 return (time, rest)
54
55
56# average line looks like:
57# [ 0.084282] VFS: Mounted root (romfs filesystem) readonly
58# time data is expressed in seconds.useconds,
59# convert_line adds a delta for each line
60last_time = 0.0
61def convert_line(line, base_time):
62 global last_time
63
64 try:
65 (time, rest) = get_time(line)
66 except:
67 # if any problem parsing time, don't convert anything
68 return line
69
70 if base_time:
71 # show time from base
72 delta = time - base_time
73 else:
74 # just show time from last line
75 delta = time - last_time
76 last_time = time
77
78 return ("[%5.6f < %5.6f >]" % (time, delta)) + rest
79
80def main():
81 base_str = ""
82 filein = ""
83 for arg in sys.argv[1:]:
84 if arg=="-b":
85 base_str = sys.argv[sys.argv.index("-b")+1]
86 elif arg=="-h":
87 usage()
88 else:
89 filein = arg
90
91 if not filein:
92 usage()
93
94 try:
95 lines = open(filein,"r").readlines()
96 except:
97 print "Problem opening file: %s" % filein
98 sys.exit(1)
99
100 if base_str:
101 print 'base= "%s"' % base_str
102 # assume a numeric base. If that fails, try searching
103 # for a matching line.
104 try:
105 base_time = float(base_str)
106 except:
107 # search for line matching <base> string
108 found = 0
109 for line in lines:
110 try:
111 (time, rest) = get_time(line)
112 except:
113 continue
114 if string.find(rest, base_str)==1:
115 base_time = time
116 found = 1
117 # stop at first match
118 break
119 if not found:
120 print 'Couldn\'t find line matching base pattern "%s"' % base_str
121 sys.exit(1)
122 else:
123 base_time = 0.0
124
125 for line in lines:
126 print convert_line(line, base_time),
127
128main()
129
diff --git a/scripts/split-man b/scripts/split-man
new file mode 100755
index 000000000000..03897fe6a75d
--- /dev/null
+++ b/scripts/split-man
@@ -0,0 +1,112 @@
1#!/usr/bin/perl
2
3use strict;
4
5## Copyright (C) Michael Still (mikal@stillhq.com)
6## Released under the terms of the GNU GPL
7##
8## Hoon through the specified DocBook SGML file, and split out the
9## man pages. These can then be processed into groff format, and
10## installed if desired...
11##
12## Arguements: $1 -- the name of the sgml file
13## $2 -- the directory to put the generated SGML files in
14## $3 -- kernel version
15
16my($SGML, $REF, $front, $refdata, $mode, $filename);
17
18if(($ARGV[0] eq "") || ($ARGV[1] eq "") || ($ARGV[2] eq "")){
19 die "Usage: split-man <sgml file> <output dir> <kernel version>\n";
20}
21
22open SGML, "< $ARGV[0]" or die "Could not open input file \"$ARGV[0]\"\n";
23if( ! -d "$ARGV[1]" ){
24 die "Output directory \"$ARGV[1]\" does not exist\n";
25}
26
27# Possible modes:
28# 0: Looking for input I care about
29# 1: Inside book front matter
30# 2: Inside a refentry
31# 3: Inside a refentry, and we know the filename
32
33$mode = 0;
34$refdata = "";
35$front = "";
36while(<SGML>){
37 # Starting modes
38 if(/<bookinfo>/ || /<docinfo>/){
39 $mode = 1;
40 }
41 elsif(/<refentry>/){
42 $mode = 2;
43 }
44 elsif(/<refentrytitle><phrase[^>]*>([^<]*)<.*$/){
45 $mode = 3;
46 $filename = $1;
47
48 $filename =~ s/struct //;
49 $filename =~ s/typedef //;
50
51 print "Found manpage for $filename\n";
52 open REF, "> $ARGV[1]/$filename.sgml" or
53 die "Couldn't open output file \"$ARGV[1]/$filename.sgml\": $!\n";
54 print REF <<EOF;
55<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
56
57<!-- BEGINFRONTTAG: The following is front matter for the parent book -->
58$front
59<!-- ENDFRONTTAG: End front matter -->
60
61$refdata
62EOF
63 $refdata = "";
64 }
65
66 # Extraction
67 if($mode == 1){
68 chomp $_;
69 $front = "$front<!-- $_ -->\n";
70 }
71 elsif($mode == 2){
72 $refdata = "$refdata$_";
73 }
74 elsif($mode == 3){
75 # There are some fixups which need to be applied
76 if(/<\/refmeta>/){
77 print REF "<manvolnum>9</manvolnum>\n";
78 }
79 if(/<\/refentry>/){
80 print REF <<EOF;
81<refsect1><title>About this document</title>
82<para>
83This documentation was generated with kernel version $ARGV[2].
84</para>
85</refsect1>
86EOF
87 }
88
89 # For some reason, we title the synopsis twice in the main DocBook
90 if(! /<title>Synopsis<\/title>/){
91 if(/<refentrytitle>/){
92 s/struct //;
93 s/typedef //;
94 }
95
96 print REF "$_";
97 }
98 }
99
100 # Ending modes
101 if(/<\/bookinfo>/ || /<\/docinfo>/){
102 $mode = 0;
103 }
104 elsif(/<\/refentry>/){
105 $mode = 0;
106 close REF;
107 }
108}
109
110# And make sure we don't process this unnessesarily
111$ARGV[0] =~ s/\.sgml/.9/;
112`touch $ARGV[0]`;
diff --git a/scripts/ver_linux b/scripts/ver_linux
new file mode 100755
index 000000000000..bb195a1c0f2d
--- /dev/null
+++ b/scripts/ver_linux
@@ -0,0 +1,95 @@
1#!/bin/sh
2# Before running this script please ensure that your PATH is
3# typical as you use for compilation/istallation. I use
4# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
5# differ on your system.
6#
7PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:$PATH
8echo 'If some fields are empty or look unusual you may have an old version.'
9echo 'Compare to the current minimal requirements in Documentation/Changes.'
10echo ' '
11
12uname -a
13echo ' '
14
15gcc --version 2>&1| head -n 1 | grep -v gcc | awk \
16'NR==1{print "Gnu C ", $1}'
17
18gcc --version 2>&1| grep gcc | awk \
19'NR==1{print "Gnu C ", $3}'
20
21make --version 2>&1 | awk -F, '{print $1}' | awk \
22 '/GNU Make/{print "Gnu make ",$NF}'
23
24ld -v | awk -F\) '{print $1}' | awk \
25'/BFD/{print "binutils ",$NF} \
26/^GNU/{print "binutils ",$4}'
27
28fdformat --version | awk -F\- '{print "util-linux ", $NF}'
29
30mount --version | awk -F\- '{print "mount ", $NF}'
31
32depmod -V 2>&1 | awk 'NR==1 {print "module-init-tools ",$NF}'
33
34tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' | awk \
35'NR==1 {print "e2fsprogs ", $2}'
36
37fsck.jfs -V 2>&1 | grep version | sed 's/,//' | awk \
38'NR==1 {print "jfsutils ", $3}'
39
40reiserfsck -V 2>&1 | grep reiserfsck | awk \
41'NR==1{print "reiserfsprogs ", $2}'
42
43fsck.reiser4 -V 2>&1 | grep fsck.reiser4 | awk \
44'NR==1{print "reiser4progs ", $2}'
45
46xfs_db -V 2>&1 | grep version | awk \
47'NR==1{print "xfsprogs ", $3}'
48
49cardmgr -V 2>&1| grep version | awk \
50'NR==1{print "pcmcia-cs ", $3}'
51
52quota -V 2>&1 | grep version | awk \
53'NR==1{print "quota-tools ", $NF}'
54
55pppd --version 2>&1| grep version | awk \
56'NR==1{print "PPP ", $3}'
57
58isdnctrl 2>&1 | grep version | awk \
59'NR==1{print "isdn4k-utils ", $NF}'
60
61showmount --version 2>&1 | grep nfs-utils | awk \
62'NR==1{print "nfs-utils ", $NF}'
63
64ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed \
65-e 's/\.so$//' | awk -F'[.-]' '{print "Linux C Library " \
66$(NF-2)"."$(NF-1)"."$NF}'
67
68ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -n 1 | awk \
69'NR==1{print "Dynamic linker (ldd) ", $NF}'
70
71ls -l /usr/lib/lib{g,stdc}++.so 2>/dev/null | awk -F. \
72 '{print "Linux C++ Library " $4"."$5"."$6}'
73
74ps --version 2>&1 | grep version | awk \
75'NR==1{print "Procps ", $NF}'
76
77ifconfig --version 2>&1 | grep tools | awk \
78'NR==1{print "Net-tools ", $NF}'
79
80# Kbd needs 'loadkeys -h',
81loadkeys -h 2>&1 | awk \
82'(NR==1 && ($3 !~ /option/)) {print "Kbd ", $3}'
83
84# while console-tools needs 'loadkeys -V'.
85loadkeys -V 2>&1 | awk \
86'(NR==1 && ($2 ~ /console-tools/)) {print "Console-tools ", $3}'
87
88expr --v 2>&1 | awk 'NR==1{print "Sh-utils ", $NF}'
89
90udevinfo -V | awk '{print "udev ", $3}'
91
92if [ -e /proc/modules ]; then
93 X=`cat /proc/modules | sed -e "s/ .*$//"`
94 echo "Modules Loaded "$X
95fi